orestis / pysmell

PySmell is an attempt to create an IDE completion helper for python.

This URL has Read+Write access

frac (author)
Tue May 05 06:07:15 -0700 2009
orestis (committer)
Tue May 05 06:13:36 -0700 2009
pysmell / pysmell / matchers.py
100644 97 lines (81 sloc) 2.682 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# matchers.py
# Original author: Krzysiek Goj
# Copyright (C) 2008 Orestis Markou
# All rights reserved
# E-mail: orestis@orestis.gr
 
# http://orestis.gr
 
# Released subject to the BSD License
 
import re
try:
    all
except:
     def all(iterable):
         for element in iterable:
             if not element:
                 return False
         return True
 
def matchCaseInsensitively(base):
    return lambda comp: comp.lower().startswith(base.lower())
 
def matchCaseSensitively(base):
    return lambda comp: comp.startswith(base)
 
def camelGroups(word):
    groups = []
    rest = word
    while rest:
        i, limit = 0, len(rest)
        while i < limit:
            suspect = rest[1:i+1]
            if i and not (suspect.islower() and suspect.isalnum()):
                break
            i += 1
        part, rest = rest[:i], rest[i:]
        groups.append(part)
    return groups
 
def matchCamelCasedPrecise(base):
    baseGr = camelGroups(base)
    baseLen = len(baseGr)
    def check(comp):
        compGr = camelGroups(comp)
        return baseLen <= len(compGr) and all(matchCaseSensitively(bg)(cg) for bg, cg in zip(baseGr, compGr))
    return check
 
def matchCamelCased(base):
    baseGr = camelGroups(base)
    baseLen = len(baseGr)
    def check(comp):
        compGr = camelGroups(comp)
        return baseLen <= len(compGr) and all(matchCaseInsensitively(bg)(cg) for bg, cg in zip(baseGr, compGr))
    return check
 
def matchSmartass(base):
    rev_base_letters = list(reversed(base.lower()))
    def check(comp):
        stack = rev_base_letters[:]
        for group in camelGroups(comp):
            lowered = group.lower()
            while True:
                if lowered and stack:
                    if lowered.startswith(stack[-1]):
                        stack.pop()
                    lowered = lowered[1:]
                else:
                    break
        return not stack
    return check
 
def matchFuzzyCS(base):
    regex = re.compile('.*'.join([] + list(base) + []))
    return lambda comp: bool(regex.match(comp))
 
def matchFuzzyCI(base):
    regex = re.compile('.*'.join([] + list(base) + []), re.IGNORECASE)
    return lambda comp: bool(regex.match(comp))
 
 
class MatchDict(object):
    _MATCHERS = {
        'case-sensitive': matchCaseSensitively,
        'case-insensitive': matchCaseInsensitively,
        'camel-case': matchCamelCased,
        'camel-case-sensitive': matchCamelCasedPrecise,
        'smartass': matchSmartass,
        'fuzzy-ci': matchFuzzyCI,
        'fuzzy-cs': matchFuzzyCS,
    }
 
    def __getitem__(self, item):
        return self._MATCHERS.get(item, matchCaseInsensitively)
 
MATCHERS = MatchDict()