3 # Author: A. S. Budden <abudden _at_ gmail _dot_ com>
4 # Copyright: Copyright (C) 2009-2012 A. S. Budden
5 # Permission is hereby granted to use and distribute this code,
6 # with or without modifications, provided that this copyright
7 # notice is copied with it. Like anything else that's free,
8 # the TagHighlight plugin is provided *as is* and comes with no
9 # warranty of any kind, either expressed or implied. By using
10 # this plugin, you agree that in no event will the copyright
11 # holder be liable for any damages resulting from the use
14 # ---------------------------------------------------------------------
15 from __future__ import print_function
19 # Used for timing a function; from http://www.daniweb.com/code/snippet368.html
20 # decorator: put @print_timing before a function to time it.
21 def print_timing(func):
26 print('{name} took {time:0.3f} ms'.format(name=func.__name__, time=(t2-t1)*1000.0))
30 class TagHighlightOptionDict(dict):
31 """Customised version of a dictionary that allows access by attribute."""
32 def __getattr__(self, name):
35 def __getitem__(self, name):
37 from .options import AllOptions
38 for option in AllOptions.keys():
40 return AllOptions[option]['Default']
41 return super(TagHighlightOptionDict, self).__getitem__(name)
43 def __setattr__(self, name, value):
47 """Customised version of a dictionary that auto-creates non-existent keys as sets."""
48 def __getitem__(self, key):
51 return super(SetDict, self).__getitem__(key)
53 def __setitem__(self, key, value):
54 if isinstance(value, set):
55 super(SetDict, self).__setitem__(key, value)
57 super(SetDict, self).__setitem__(key, set([value]))
60 """Customised version of a dictionary that auto-creates non-existent keys as SetDicts."""
61 def __getitem__(self, key):
64 return super(DictDict, self).__getitem__(key)
66 def __setitem__(self, key, value):
67 if isinstance(value, SetDict):
68 super(DictDict, self).__setitem__(key, value)
70 raise NotImplementedError
72 def GenerateValidKeywordRange(iskeyword):
73 # Generally obeys Vim's iskeyword setting, but
74 # only allows characters in ascii range
75 ValidKeywordSets = iskeyword.split(',')
76 rangeMatcher = re.compile('^(?P<from>(?:\d+|\S))-(?P<to>(?:\d+|\S))$')
77 falseRangeMatcher = re.compile('^^(?P<from>(?:\d+|\S))-(?P<to>(?:\d+|\S))$')
79 for valid in ValidKeywordSets:
80 m = rangeMatcher.match(valid)
81 fm = falseRangeMatcher.match(valid)
83 for ch in [chr(i) for i in range(0,128)]:
87 # We have a range of ascii values
88 if m.group('from').isdigit():
89 rangeFrom = int(m.group('from'))
91 rangeFrom = ord(m.group('from'))
93 if m.group('to').isdigit():
94 rangeTo = int(m.group('to'))
96 rangeTo = ord(m.group('to'))
98 validRange = list(range(rangeFrom, rangeTo+1))
100 validRange = [i for i in validRange if i < 128]
101 for ch in [chr(i) for i in validRange]:
105 # We have a range of ascii values: remove them!
106 if fm.group('from').isdigit():
107 rangeFrom = int(fm.group('from'))
109 rangeFrom = ord(fm.group('from'))
111 if fm.group('to').isdigit():
112 rangeTo = int(fm.group('to'))
114 rangeTo = ord(fm.group('to'))
116 validRange = range(rangeFrom, rangeTo+1)
117 for ch in [chr(i) for i in validRange]:
118 for i in range(validList.count(ch)):
121 elif len(valid) == 1:
124 validList.append(valid)
127 raise ValueError('Unrecognised iskeyword part: ' + valid)
132 def IsValidKeyword(keyword, iskeyword):
134 if not char in iskeyword:
138 def rglob(path, pattern):
139 # Tweaked version of the stackoverflow answer:
140 # http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python#2186565
143 for root, dirnames, filenames in os.walk(path):
144 matches += [os.path.join(root, i) for i in fnmatch.filter(filenames, pattern)]
147 if __name__ == "__main__":
150 # Should be able to add an item to the list
151 pprint.pprint(test_obj)
152 test_obj['MyIndex'].add('Hello')
153 test_obj['SetList'] = ['This', 'Is', 'A', 'List']
154 test_obj['SetString'] = 'This is a string'
155 # These should all be lists:
156 pprint.pprint(test_obj)