From 324a4f8ffc491b05346c284fcbbb6f77318d6b82 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Sat, 11 Jul 2015 18:11:19 +0200 Subject: [PATCH] Support regexp trigger ending in whitespace. Fixes #178. --- pythonx/UltiSnips/snippet/definition/_base.py | 41 +++++++++---------- .../snippet/source/_snippet_dictionary.py | 1 - pythonx/UltiSnips/snippet_manager.py | 2 - test/test_SnippetOptions.py | 6 +++ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pythonx/UltiSnips/snippet/definition/_base.py b/pythonx/UltiSnips/snippet/definition/_base.py index 0c8e096..225807a 100644 --- a/pythonx/UltiSnips/snippet/definition/_base.py +++ b/pythonx/UltiSnips/snippet/definition/_base.py @@ -13,6 +13,10 @@ from UltiSnips.indent_util import IndentUtil from UltiSnips.text import escape from UltiSnips.text_objects import SnippetInstance +__WHITESPACE_SPLIT = re.compile(r"\s") +def split_at_whitespace(string): + """Like string.split(), but keeps empty words as empty words.""" + return re.split(__WHITESPACE_SPLIT, string) def _words_for_line(trigger, before, num_words=None): """Gets the final 'num_words' words from 'before'. @@ -20,13 +24,10 @@ def _words_for_line(trigger, before, num_words=None): If num_words is None, then use the number of words in 'trigger'. """ - if not len(before): - return '' - if num_words is None: - num_words = len(trigger.split()) + num_words = len(split_at_whitespace(trigger)) - word_list = before.split() + word_list = split_at_whitespace(before) if len(word_list) <= num_words: return before.strip() else: @@ -143,22 +144,18 @@ class SnippetDefinition(object): """The matched context.""" return self._context - def matches(self, trigger): - """Returns True if this snippet matches 'trigger'.""" + def matches(self, before): + """Returns True if this snippet matches 'before'.""" # If user supplies both "w" and "i", it should perhaps be an # error, but if permitted it seems that "w" should take precedence # (since matching at word boundary and within a word == matching at word # boundary). self._matched = '' - # Don't expand on whitespace - if trigger and trigger.rstrip() != trigger: - return False - - words = _words_for_line(self._trigger, trigger) + words = _words_for_line(self._trigger, before) if 'r' in self._opts: - match = self._re_match(trigger) + match = self._re_match(before) elif 'w' in self._opts: words_len = len(self._trigger) words_prefix = words[:-words_len] @@ -182,7 +179,7 @@ class SnippetDefinition(object): # Ensure the match was on a word boundry if needed if 'b' in self._opts and match: - text_before = trigger.rstrip()[:-len(self._matched)] + text_before = before.rstrip()[:-len(self._matched)] if text_before.strip(' \t') != '': self._matched = '' return False @@ -194,21 +191,21 @@ class SnippetDefinition(object): return match - def could_match(self, trigger): - """Return True if this snippet could match the (partial) 'trigger'.""" + def could_match(self, before): + """Return True if this snippet could match the (partial) 'before'.""" self._matched = '' # List all on whitespace. - if trigger and trigger[-1] in (' ', '\t'): - trigger = '' - if trigger and trigger.rstrip() is not trigger: + if before and before[-1] in (' ', '\t'): + before = '' + if before and before.rstrip() is not before: return False - words = _words_for_line(self._trigger, trigger) + words = _words_for_line(self._trigger, before) if 'r' in self._opts: # Test for full match only - match = self._re_match(trigger) + match = self._re_match(before) elif 'w' in self._opts: # Trim non-empty prefix up to word boundary, if present. qwords = escape(words, r'\"') @@ -234,7 +231,7 @@ class SnippetDefinition(object): # Ensure the match was on a word boundry if needed if 'b' in self._opts and match: - text_before = trigger.rstrip()[:-len(self._matched)] + text_before = before.rstrip()[:-len(self._matched)] if text_before.strip(' \t') != '': self._matched = '' return False diff --git a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py index 197cf8b..a8b3d65 100644 --- a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py +++ b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py @@ -3,7 +3,6 @@ """Implements a container for parsed snippets.""" - class SnippetDictionary(object): """See module docstring.""" diff --git a/pythonx/UltiSnips/snippet_manager.py b/pythonx/UltiSnips/snippet_manager.py index 4271495..d6bdd50 100644 --- a/pythonx/UltiSnips/snippet_manager.py +++ b/pythonx/UltiSnips/snippet_manager.py @@ -592,8 +592,6 @@ class SnippetManager(object): def _try_expand(self): """Try to expand a snippet in the current place.""" before = _vim.buf.line_till_cursor - if not before: - return False snippets = self._snips(before, False) if snippets: # prefer snippets with context if any diff --git a/test/test_SnippetOptions.py b/test/test_SnippetOptions.py index 8d7b615..cd18b6a 100644 --- a/test/test_SnippetOptions.py +++ b/test/test_SnippetOptions.py @@ -209,6 +209,12 @@ class SnippetOptions_Regex_Expand(_VimTest): wanted = 'Expand me!' +class SnippetOptions_Regex_WithSpace(_VimTest): + snippets = ('test ', 'Expand me!', '', 'r') + keys = 'test ' + EX + wanted = 'Expand me!' + + class SnippetOptions_Regex_Multiple(_VimTest): snippets = ('(test *)+', 'Expand me!', '', 'r') keys = 'test test test' + EX