From 66d35419a4a9060ce4f6b578ae6fed3298c8554b Mon Sep 17 00:00:00 2001 From: Michael Henry Date: Sun, 23 Aug 2009 18:44:19 -0400 Subject: [PATCH] Added support for snippet option "w" for word-boundary triggers. --- doc/UltiSnips.txt | 8 +++++++- plugin/UltiSnips/__init__.py | 40 ++++++++++++++++++++++++++++++------ test.py | 22 ++++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/doc/UltiSnips.txt b/doc/UltiSnips.txt index c08f51e..9e1bb0a 100644 --- a/doc/UltiSnips.txt +++ b/doc/UltiSnips.txt @@ -180,9 +180,15 @@ snippet on. The options currently supported are > of the cursor). Default is to expand snippets at every position, even mitten in the line. Most of my snippets have this option set, it keeps UltiSnips out of the way. - i Inword expansion - normally, triggers need whitespace before them to be + i Inword expansion - Normally, triggers need whitespace before them to be expanded. With this option, triggers are also expanded in the middle of a word. + w Word boundary - Normally, triggers need whitespace before them to be + expanded. With this option, the trigger will be expanded at a "word" + boundary as well, where word characters are letters, digits, and the + underscore character ('_'). This enables expansion of a trigger that + adjoins punctuation (for example) without expanding suffixes of larger + words. 4.2 Plaintext snippets *UltiSnips-plaintext-snippets* ---------------------- diff --git a/plugin/UltiSnips/__init__.py b/plugin/UltiSnips/__init__.py index dcf37ad..1db3fcb 100644 --- a/plugin/UltiSnips/__init__.py +++ b/plugin/UltiSnips/__init__.py @@ -96,14 +96,42 @@ class Snippet(object): return "Snippet(%s,%s,%s)" % (self._t,self._d,self._opts) def matches(self, trigger): - if "i" not in self._opts: - return trigger == self._t - return trigger.endswith(self._t) + # 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). + if "w" in self._opts: + trigger_len = len(self._t) + trigger_prefix = trigger[:-trigger_len] + trigger_suffix = trigger[-trigger_len:] + match = (trigger_suffix == self._t) + if match and trigger_prefix: + # Require a word boundary between prefix and suffix. + boundaryChars = trigger_prefix[-1:] + trigger_suffix[:1] + match = re.match(r'.\b.', boundaryChars) + elif "i" in self._opts: + match = trigger.endswith(self._t) + else: + match = (trigger == self._t) + return match def could_match(self, trigger): - # it i hard to define when a inword snippet could match - # therefore we do not specially look for it - return self._t.startswith(trigger) + if "w" in self._opts: + # Trim non-empty prefix up to word boundary, if present. + trigger_suffix = re.sub(r'^.+\b(.+)$', r'\1', trigger) + match = self._t.startswith(trigger_suffix) + + # TODO: list_snippets() function cannot handle partial-trigger + # matches yet, so for now fail if we trimmed the prefix. + if trigger_suffix != trigger: + match = False + elif "i" in self._opts: + # TODO: It is hard to define when a inword snippet could match, + # therefore we check only for full-word trigger. + match = self._t.startswith(trigger) + else: + match = self._t.startswith(trigger) + return match def overwrites_previous(self): return "!" in self._opts diff --git a/test.py b/test.py index 7bd8202..61d94f8 100755 --- a/test.py +++ b/test.py @@ -1099,6 +1099,28 @@ class SnippetOptions_ExpandInwordSnippetsWithOtherChars_Expand3(_VimTest): keys = "ätest" + EX wanted = "äExpand me!" +class _SnippetOptions_ExpandWordSnippets(_VimTest): + snippets = (("test", "Expand me!", "", "w"), ) +class SnippetOptions_ExpandWordSnippets_NormalExpand( + _SnippetOptions_ExpandWordSnippets): + keys = "test" + EX + wanted = "Expand me!" +class SnippetOptions_ExpandWordSnippets_NoExpand( + _SnippetOptions_ExpandWordSnippets): + keys = "atest" + EX + wanted = "atest" +class SnippetOptions_ExpandWordSnippets_ExpandSuffix( + _SnippetOptions_ExpandWordSnippets): + keys = "a-test" + EX + wanted = "a-Expand me!" +class SnippetOptions_ExpandWordSnippets_ExpandSuffix2( + _SnippetOptions_ExpandWordSnippets): + keys = "a(test" + EX + wanted = "a(Expand me!" +class SnippetOptions_ExpandWordSnippets_ExpandSuffix3( + _SnippetOptions_ExpandWordSnippets): + keys = "[[test" + EX + wanted = "[[Expand me!" ######################