diff --git a/pythonx/UltiSnips/snippet/source/_base.py b/pythonx/UltiSnips/snippet/source/_base.py index 03de530..d051b46 100644 --- a/pythonx/UltiSnips/snippet/source/_base.py +++ b/pythonx/UltiSnips/snippet/source/_base.py @@ -24,66 +24,57 @@ class SnippetSource(object): Returns a list of SnippetDefinition s. """ - found_snippets = [] - for ft in filetypes: - found_snippets += self._find_snippets(ft, before, possible) - return found_snippets + def __inner(fts): + result = [] + existing_fts = filter(lambda ft: ft in self._snippets, fts) + for ft in existing_fts: + snips = self._snippets[ft] + result.extend(snips.get_matching_snippets(before, possible)) + return result + return __inner(filetypes) + __inner(self._extends_all(filetypes)) - def get_clear_priority(self, filetypes, seen=None): - priority = None - if not seen: - seen = set() - for ft in filetypes: - seen.add(ft) - snippets = self._snippets[ft] - if priority is None or snippets._clear_priority > priority: - priority = snippets._clear_priority - todo_parent_fts = [] - for ft in filetypes: - extends = self._snippets[ft].extends - havnt_seen = filter(lambda ft: ft not in seen, extends) + def get_clear_priority(self, filetypes): + def __inner(fts): + pri = None + existing_fts = filter(lambda ft: ft in self._snippets, fts) + for ft in existing_fts: + snippets = self._snippets[ft] + if pri is None or snippets._clear_priority > pri: + pri = snippets._clear_priority + return pri + priority = __inner(filetypes) + deep_clear_priority = __inner(self._extends_all(filetypes)) + if deep_clear_priority is None: + return priority + elif priority is None: + return deep_clear_priority + else: + return max(priority, deep_clear_priority) + + def get_cleared(self, filetypes): + def __inner(fts): + cleared = {} + existing_fts = filter(lambda ft: ft in self._snippets, fts) + for ft in existing_fts: + snippets = self._snippets[ft] + for key, value in snippets._cleared.items(): + if key not in cleared or value > cleared[key]: + cleared[key] = value + return cleared + return dict(__inner(filetypes).items() + __inner(self._extends_all(filetypes)).items()) + + def _extends_all(self, filetypes, seen=None): + """Return deep extends dependency, excluding the filetype itself + """ + if seen is None: + seen = set(filetypes) + + shallow_extends = set() + for filetype in filetypes: + ft_extends = self._snippets[filetype].extends + havnt_seen = set(filter(lambda ft: ft not in seen, ft_extends)) seen.update(havnt_seen) - todo_parent_fts.extend(havnt_seen) - if todo_parent_fts: - return max(priority, self.get_clear_priority(todo_parent_fts, seen)) - return priority - - def get_cleared(self, filetypes, seen=None): - cleared = {} - if not seen: - seen = set() - for ft in filetypes: - seen.add(ft) - snippets = self._snippets[ft] - for key, value in snippets._cleared.items(): - if key not in cleared or value > cleared[key]: - cleared[key] = value - todo_parent_fts = [] - for ft in filetypes: - extends = self._snippets[ft].extends - havnt_seen = filter(lambda ft: ft not in seen, extends) - seen.update(havnt_seen) - todo_parent_fts.extend(havnt_seen) - if todo_parent_fts: - cleared.update(self.get_cleared(todo_parent_fts, seen)) - return cleared - - def _find_snippets(self, ft, trigger, potentially=False, seen=None): - """Find snippets matching 'trigger' for 'ft'. If 'potentially' is True, - partial matches are enough.""" - snips = self._snippets.get(ft, None) - if not snips: - return [] - if not seen: - seen = set() - seen.add(ft) - parent_results = [] - # TODO(sirver): extends information is not bound to one - # source. It should be tracked further up. - for parent_ft in snips.extends: - if parent_ft not in seen: - seen.add(parent_ft) - parent_results += self._find_snippets(parent_ft, trigger, - potentially, seen) - return parent_results + snips.get_matching_snippets( - trigger, potentially) + shallow_extends.update(havnt_seen) + if not shallow_extends: + return shallow_extends + return shallow_extends | self._extends_all(shallow_extends, seen) diff --git a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py index b075333..89b92cf 100644 --- a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py +++ b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py @@ -30,13 +30,13 @@ class SnippetDictionary(object): """Mark snippets as cleared with priority. When 'triggers' is None, then it updated the clear_priority.""" if not triggers: - if self._clear_priority is None or priority > self._clear_priority: - self._clear_priority = priority + if self._clear_priority is None or priority > self._clear_priority: + self._clear_priority = priority else: - for trigger in triggers: - if (trigger not in self._cleared or - priority > self._cleared[trigger]): - self._cleared[trigger] = priority + for trigger in triggers: + if (trigger not in self._cleared or + priority > self._cleared[trigger]): + self._cleared[trigger] = priority @property def extends(self):