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)