'Implemented triggers
calltip-space-call-signature
calltip-call-signature
complete-package-members
complete-*-subs meaning the actual trigger is one of:
complete-package-subs
complete-object-subs
complete-available-imports
Not yet implemented:
complete-module-exports'

def trg_from_pos(self, buf, pos, implicit=True):

    DEBUG = False
    if DEBUG:
        print banner(('trg_from_pos(pos=%r,    implicit=%r)' % (pos, implicit)))
    accessor = buf.accessor
    last_pos = (pos - 1)
    last_ch = accessor.char_at_pos(last_pos)
    if DEBUG:
        print ('        last_pos:    %s' % last_pos)
        print ('        last_ch:    %r' % last_ch)
    if (last_ch not in self.trg_chars):
        if DEBUG:
            print ('no:    %r    is    not    in    %r' % (last_ch, self.trg_chars))
        return None
    elif ((last_ch == ':') and (not ((last_pos > 0) and (accessor.char_at_pos((last_pos - 1)) == ':')))):
        if DEBUG:
            penultimate_ch = (((last_pos > 0) and accessor.char_at_pos((last_pos - 1))) or '')
            print ("no:    %r    is    not    '::'" % (penultimate_ch + last_ch))
        return None
    elif ((last_ch == '>') and (not ((last_pos > 0) and (accessor.char_at_pos((last_pos - 1)) == '-')))):
        if DEBUG:
            penultimate_ch = (((last_pos > 0) and accessor.char_at_pos((last_pos - 1))) or '')
            print ("no:    %r    is    not    '->'" % (penultimate_ch + last_ch))
        return None
    last_style = accessor.style_at_pos(last_pos)
    if DEBUG:
        last_style_names = buf.style_names_from_style_num(last_style)
        print ('        style:    %s    %s' % (last_style, last_style_names))
    if ((implicit and (last_style in buf.implicit_completion_skip_styles)) or (last_style in buf.completion_skip_styles)):
        if DEBUG:
            print ('no:    completion    is    suppressed    in    style    at    %s:    %s    %s' % (last_pos, last_style, last_style_names))
        return None
    WHITESPACE = tuple('     DCTB \n\r')
    if (last_ch == '    '):
        LIMIT = 50
        text = accessor.text_range(max(0, (last_pos - LIMIT)), last_pos)
        if DEBUG:
            print ('        working    text:    %r' % text)
        i = (len(text) - 1)
        if ((i >= 0) and (not (isident(text[i]) or isdigit(text[i])))):
            if DEBUG:
                print ("no:    two    before    trigger    point    is    not    an    ident    char:    '%s'" % text[i])
            return None
        while (i >= 0):
            if (not isident(text[i])):
                identifier = text[(i + 1):]
                j = i
                while ((j >= 0) and (text[j] in WHITESPACE)):
                    j -= 1
                if (j >= 0):
                    preceding_ch = text[j]
                else:
                    preceding_ch = None
                break
            i -= 1
        else:
            preceding_ch = None
            identifier = text
        if DEBUG:
            print ('        identifier:    %r' % identifier)
        if (not identifier):
            if DEBUG:
                print 'no:    no    identifier    preceding    trigger    point'
            return None
        if DEBUG:
            print ('        preceding    char:    %r' % preceding_ch)
        if (identifier in ('use', 'require', 'no')):
            return Trigger('Perl', TRG_FORM_CPLN, 'available-imports', pos, implicit, prefix='')
        if (preceding_ch and (preceding_ch in '$@&%\\*')):
            if DEBUG:
                print 'no:    triggering    on    space    after    Perl    variables    not    supported'
            return None
        if (identifier not in self._allow_trg_on_space_from_identifier):
            if DEBUG:
                print 'no:    identifier    not    in    set    for    which    space-triggering    is    supported    (_allow_trg_on_space_from_identifier)'
            return None
        if ((i >= 3) and (text[(i - 3):(i + 1)] == 'sub    ')):
            if DEBUG:
                print 'no:    do    not    trigger    in    sub    definition'
            return None
        if DEBUG:
            print 'calltip-space-call-signature'
        return Trigger('Perl', TRG_FORM_CALLTIP, 'space-call-signature', pos, implicit)
    elif (last_ch == '('):
        LIMIT = 100
        text = accessor.text_range(max(0, (last_pos - LIMIT)), last_pos)
        if DEBUG:
            print ('        working    text:    %r' % text)
        i = (len(text) - 1)
        while ((i >= 0) and (text[i] in WHITESPACE)):
            i -= 1
        if ((i >= 0) and (not (isident(text[i]) or isdigit(text[i])))):
            if DEBUG:
                print ("no:    first    non-ws    char    before    trigger    point    is    not    an    ident    char:    '%s'" % text[i])
            return None
        end = (i + 1)
        while (i >= 0):
            if (not isident(text[i])):
                identifier = text[(i + 1):end]
                j = i
                while ((j >= 0) and (text[j] in WHITESPACE)):
                    j -= 1
                if (j >= 0):
                    preceding_ch = text[j]
                else:
                    preceding_ch = None
                break
            i -= 1
        else:
            preceding_ch = None
            identifier = text[:end]
        if DEBUG:
            print ('        identifier:    %r' % identifier)
        if DEBUG:
            assert ('    ' not in identifier), ('parse    error:    space    in    identifier:    %r' % identifier)
        if (not identifier):
            if DEBUG:
                print 'no:    no    identifier    preceding    trigger    point'
            return None
        if DEBUG:
            print ('        preceding    char:    %r' % preceding_ch)
        if (preceding_ch and (preceding_ch in '$@%\\*')):
            if DEBUG:
                print 'no:    calltip    trigger    on    Perl    var    not    supported'
            return None
        if (identifier in ('if', 'else', 'elsif', 'while', 'for', 'sub', 'unless', 'my', 'our')):
            if DEBUG:
                print 'no:    no    trigger    on    anonymous    sub    or    control    structure'
            return None
        line = text[:end].splitlines(0)[(-1)]
        if DEBUG:
            print ('        trigger    line:    %r' % line)
        if ('sub    ' in line):
            if DEBUG:
                print '        *could*    be    a    subroutine    definition'
            if self._sub_pat.search(line):
                if DEBUG:
                    print 'no:    no    trigger    on    Perl    sub    definition'
                return None
        if DEBUG:
            print 'calltip-call-signature'
        return Trigger('Perl', TRG_FORM_CALLTIP, 'call-signature', pos, implicit)
    elif (last_ch == '>'):
        LIMIT = 50
        text = accessor.text_range(max(0, ((last_pos - 1) - LIMIT)), (last_pos - 1))
        if DEBUG:
            print ('        working    text:    %r' % text)
        i = (len(text) - 1)
        while ((i >= 0) and (text[i] in WHITESPACE)):
            i -= 1
        if (i < 0):
            if DEBUG:
                print "no:    no    non-whitespace    text    preceding    '->'"
            return None
        elif (not (isident(text[i]) or text[i].isdigit())):
            if DEBUG:
                print ("no:    first    non-ws    char    before    trigger    point    is    not    an    ident    char:    '%s'" % text[i])
            return None
        if DEBUG:
            print 'complete-*-subs'
        return Trigger('Perl', TRG_FORM_CPLN, '*-subs', pos, implicit, length=2)
    elif (last_ch == ':'):
        LIMIT = 50
        text = accessor.text_range(max(0, ((last_pos - 1) - LIMIT)), (last_pos - 1))
        if DEBUG:
            print ('        working    text:    %r' % text)
        i = (len(text) - 1)
        if (i < 0):
            if DEBUG:
                print "no:    no    text    preceding    '::'"
            return None
        ch = text[i]
        if (not (isident(ch) or isdigit(ch) or (ch == '$'))):
            if DEBUG:
                print ("no:    first    char    before    trigger    point    is    not    an    ident    char    or    '$':    '%s'" % ch)
            return None
        while ((i > 0) and (text[(i - 1)] not in WHITESPACE)):
            i -= 1
        prefix = text[i:(pos - 2)]
        while ((i > 0) and (text[(i - 1)] in WHITESPACE)):
            i -= 1
        start_idx = end_idx = i
        while ((start_idx > 0) and (isident(text[(start_idx - 1)]) or (text[(start_idx - 1)] in '$@%'))):
            start_idx -= 1
        ident = text[start_idx:end_idx]
        if (ident in ('use', 'require', 'no')):
            if DEBUG:
                print ('complete-available-imports    (prefix=%r)' % prefix)
            return Trigger('Perl', TRG_FORM_CPLN, 'available-imports', pos, implicit, length=2, prefix=prefix)
        if DEBUG:
            print ('complete-package-members    (prefix=%r)' % prefix)
        return Trigger('Perl', TRG_FORM_CPLN, 'package-members', pos, implicit, length=2, prefix=prefix)
    return None
