More linting warnings and a small bug fix.

This commit is contained in:
Holger Rapp 2014-02-07 09:50:20 +01:00
parent 2377a4405b
commit bd132bc379
4 changed files with 57 additions and 44 deletions

View File

@ -180,21 +180,21 @@ function! UltiSnips_FileTypeChanged()
return "" return ""
endfunction endfunction
function! UltiSnips_AddSnippet(trigger, value, descr, options, ...) function! UltiSnips_AddSnippet(trigger, value, description, options, ...)
" Takes the same arguments as SnippetManager.add_snippet: " Takes the same arguments as SnippetManager.add_snippet:
" (trigger, value, descr, options, ft = "all", globals = None) " (trigger, value, description, options, ft = "all", globals = None)
exec g:_uspy "args = vim.eval(\"a:000\")" exec g:_uspy "args = vim.eval(\"a:000\")"
exec g:_uspy "trigger = vim.eval(\"a:trigger\")" exec g:_uspy "trigger = vim.eval(\"a:trigger\")"
exec g:_uspy "value = vim.eval(\"a:value\")" exec g:_uspy "value = vim.eval(\"a:value\")"
exec g:_uspy "descr = vim.eval(\"a:descr\")" exec g:_uspy "description = vim.eval(\"a:description\")"
exec g:_uspy "options = vim.eval(\"a:options\")" exec g:_uspy "options = vim.eval(\"a:options\")"
exec g:_uspy "UltiSnips_Manager.add_snippet(trigger, value, descr, options, *args)" exec g:_uspy "UltiSnips_Manager.add_snippet(trigger, value, description, options, *args)"
return "" return ""
endfunction endfunction
function! UltiSnips_Anon(value, ...) function! UltiSnips_Anon(value, ...)
" Takes the same arguments as SnippetManager.expand_anon: " Takes the same arguments as SnippetManager.expand_anon:
" (value, trigger="", descr="", options="", globals = None) " (value, trigger="", description="", options="", globals = None)
exec g:_uspy "args = vim.eval(\"a:000\")" exec g:_uspy "args = vim.eval(\"a:000\")"
exec g:_uspy "value = vim.eval(\"a:value\")" exec g:_uspy "value = vim.eval(\"a:value\")"
exec g:_uspy "UltiSnips_Manager.expand_anon(value, *args)" exec g:_uspy "UltiSnips_Manager.expand_anon(value, *args)"

View File

@ -285,11 +285,11 @@ class SnippetManager(object):
return self._snippets[ft] return self._snippets[ft]
@err_to_scratch_buffer @err_to_scratch_buffer
def add_snippet(self, trigger, value, descr, def add_snippet(self, trigger, value, description,
options, ft="all", globals=None, fn=None): options, ft="all", globals=None, fn=None):
"""Add a snippet to the list of known snippets of the given 'ft'.""" """Add a snippet to the list of known snippets of the given 'ft'."""
self.snippet_dict(ft).add_snippet( self.snippet_dict(ft).add_snippet(
Snippet(trigger, value, descr, options, globals or {}), fn Snippet(trigger, value, description, options, globals or {}), fn
) )
@err_to_scratch_buffer @err_to_scratch_buffer
@ -299,14 +299,14 @@ class SnippetManager(object):
sd.addfile(path) sd.addfile(path)
@err_to_scratch_buffer @err_to_scratch_buffer
def expand_anon(self, value, trigger="", descr="", def expand_anon(self, value, trigger="", description="",
options="", globals=None): options="", globals=None):
"""Expand an anonymous snippet right here.""" """Expand an anonymous snippet right here."""
if globals is None: if globals is None:
globals = {} globals = {}
before = _vim.buf.line_till_cursor before = _vim.buf.line_till_cursor
snip = Snippet(trigger, value, descr, options, globals) snip = Snippet(trigger, value, description, options, globals)
if not trigger or snip.matches(before): if not trigger or snip.matches(before):
self._do_snippet(snip, before) self._do_snippet(snip, before)

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
"""Snippet representation after parsing."""
import re import re
from UltiSnips.compatibility import as_unicode from UltiSnips.compatibility import as_unicode
@ -14,7 +16,6 @@ def _words_for_line(trigger, before, num_words=None):
If num_words is None, then use the number of words in If num_words is None, then use the number of words in
'trigger'. 'trigger'.
""" """
words = ''
if not len(before): if not len(before):
return '' return ''
@ -33,27 +34,29 @@ def _words_for_line(trigger, before, num_words=None):
class Snippet(object): class Snippet(object):
"""Represents a snippet as parsed from a file."""
_INDENT = re.compile(r"^[ \t]*") _INDENT = re.compile(r"^[ \t]*")
_TABS = re.compile(r"^\t*") _TABS = re.compile(r"^\t*")
def __init__(self, trigger, value, descr, options, globals): def __init__(self, trigger, value, description, options, globals):
"""Represents a snippet as parsed from a file.""" self._trigger = as_unicode(trigger)
self._t = as_unicode(trigger) self._value = as_unicode(value)
self._v = as_unicode(value) self._description = as_unicode(description)
self._d = as_unicode(descr)
self._opts = options self._opts = options
self._matched = "" self._matched = ""
self._last_re = None self._last_re = None
self._globals = globals self._globals = globals
def __repr__(self): def __repr__(self):
return "Snippet(%s,%s,%s)" % (self._t, self._d, self._opts) return "Snippet(%s,%s,%s)" % (
self._trigger, self._description, self._opts)
def _re_match(self, trigger): def _re_match(self, trigger):
""" Test if a the current regex trigger matches """ Test if a the current regex trigger matches
`trigger`. If so, set _last_re and _matched. `trigger`. If so, set _last_re and _matched.
""" """
for match in re.finditer(self._t, trigger): for match in re.finditer(self._trigger, trigger):
if match.end() != len(trigger): if match.end() != len(trigger):
continue continue
else: else:
@ -68,6 +71,7 @@ class Snippet(object):
return opt in self._opts return opt in self._opts
def matches(self, trigger): def matches(self, trigger):
"""Returns True if this snippet matches 'trigger'."""
# If user supplies both "w" and "i", it should perhaps be an # If user supplies both "w" and "i", it should perhaps be an
# error, but if permitted it seems that "w" should take precedence # error, but if permitted it seems that "w" should take precedence
# (since matching at word boundary and within a word == matching at word # (since matching at word boundary and within a word == matching at word
@ -78,28 +82,28 @@ class Snippet(object):
if trigger and trigger.rstrip() != trigger: if trigger and trigger.rstrip() != trigger:
return False return False
words = _words_for_line(self._t, trigger) words = _words_for_line(self._trigger, trigger)
if "r" in self._opts: if "r" in self._opts:
match = self._re_match(trigger) match = self._re_match(trigger)
elif "w" in self._opts: elif "w" in self._opts:
words_len = len(self._t) words_len = len(self._trigger)
words_prefix = words[:-words_len] words_prefix = words[:-words_len]
words_suffix = words[-words_len:] words_suffix = words[-words_len:]
match = (words_suffix == self._t) match = (words_suffix == self._trigger)
if match and words_prefix: if match and words_prefix:
# Require a word boundary between prefix and suffix. # Require a word boundary between prefix and suffix.
boundaryChars = words_prefix[-1:] + words_suffix[:1] boundary_chars = words_prefix[-1:] + words_suffix[:1]
boundaryChars = boundaryChars.replace('"', '\\"') boundary_chars = boundary_chars.replace('"', '\\"')
match = _vim.eval('"%s" =~# "\\\\v.<."' % boundaryChars) != '0' match = _vim.eval('"%s" =~# "\\\\v.<."' % boundary_chars) != '0'
elif "i" in self._opts: elif "i" in self._opts:
match = words.endswith(self._t) match = words.endswith(self._trigger)
else: else:
match = (words == self._t) match = (words == self._trigger)
# By default, we match the whole trigger # By default, we match the whole trigger
if match and not self._matched: if match and not self._matched:
self._matched = self._t self._matched = self._trigger
# Ensure the match was on a word boundry if needed # Ensure the match was on a word boundry if needed
if "b" in self._opts and match: if "b" in self._opts and match:
@ -107,10 +111,10 @@ class Snippet(object):
if text_before.strip(" \t") != '': if text_before.strip(" \t") != '':
self._matched = "" self._matched = ""
return False return False
return match return match
def could_match(self, trigger): def could_match(self, trigger):
"""Return True if this snippet could match the (partial) 'trigger'."""
self._matched = "" self._matched = ""
# List all on whitespace. # List all on whitespace.
@ -119,7 +123,7 @@ class Snippet(object):
if trigger and trigger.rstrip() is not trigger: if trigger and trigger.rstrip() is not trigger:
return False return False
words = _words_for_line(self._t, trigger) words = _words_for_line(self._trigger, trigger)
if "r" in self._opts: if "r" in self._opts:
# Test for full match only # Test for full match only
@ -127,8 +131,9 @@ class Snippet(object):
elif "w" in self._opts: elif "w" in self._opts:
# Trim non-empty prefix up to word boundary, if present. # Trim non-empty prefix up to word boundary, if present.
qwords = words.replace('"', '\\"') qwords = words.replace('"', '\\"')
words_suffix = _vim.eval('substitute("%s", "\\\\v^.+<(.+)", "\\\\1", "")' % qwords) words_suffix = _vim.eval(
match = self._t.startswith(words_suffix) 'substitute("%s", "\\\\v^.+<(.+)", "\\\\1", "")' % qwords)
match = self._trigger.startswith(words_suffix)
self._matched = words_suffix self._matched = words_suffix
# TODO: list_snippets() function cannot handle partial-trigger # TODO: list_snippets() function cannot handle partial-trigger
@ -138,9 +143,9 @@ class Snippet(object):
elif "i" in self._opts: elif "i" in self._opts:
# TODO: It is hard to define when a inword snippet could match, # TODO: It is hard to define when a inword snippet could match,
# therefore we check only for full-word trigger. # therefore we check only for full-word trigger.
match = self._t.startswith(words) match = self._trigger.startswith(words)
else: else:
match = self._t.startswith(words) match = self._trigger.startswith(words)
# By default, we match the words from the trigger # By default, we match the words from the trigger
if match and not self._matched: if match and not self._matched:
@ -157,28 +162,35 @@ class Snippet(object):
@property @property
def overwrites_previous(self): def overwrites_previous(self):
"""Does this snippet overwrite previous with the same trigger?"""
return "!" in self._opts return "!" in self._opts
@property @property
def description(self): def description(self):
return ("(%s) %s" % (self._t, self._d)).strip() """Descriptive text for this snippet."""
return ("(%s) %s" % (self._trigger, self._description)).strip()
@property @property
def trigger(self): def trigger(self):
return self._t """The trigger text for the snippet."""
return self._trigger
@property @property
def matched(self): def matched(self):
""" The last text that was matched. """ """The last text that matched this snippet in match() or
could_match()."""
return self._matched return self._matched
def launch(self, text_before, visual_content, parent, start, end): def launch(self, text_before, visual_content, parent, start, end):
"""Launch this snippet, overwriting the text 'start' to 'end' and
keeping the 'text_before' on the launch line. 'Parent' is the parent
snippet instance if any."""
indent = self._INDENT.match(text_before).group(0) indent = self._INDENT.match(text_before).group(0)
lines = (self._v + "\n").splitlines() lines = (self._value + "\n").splitlines()
ind_util = IndentUtil() ind_util = IndentUtil()
# Replace leading tabs in the snippet definition via proper indenting # Replace leading tabs in the snippet definition via proper indenting
v = [] snippet_definition = []
for line_num, line in enumerate(lines): for line_num, line in enumerate(lines):
if "t" in self._opts: if "t" in self._opts:
tabs = 0 tabs = 0
@ -190,10 +202,11 @@ class Snippet(object):
if line_num != 0: if line_num != 0:
line_ind = indent + line_ind line_ind = indent + line_ind
v.append(line_ind + line[tabs:]) snippet_definition.append(line_ind + line[tabs:])
v = '\n'.join(v) snippet_definition = '\n'.join(snippet_definition)
si = SnippetInstance(self, parent, indent, v, start, end, visual_content, si = SnippetInstance(self, parent, indent, snippet_definition, start,
last_re = self._last_re, globals = self._globals) end, visual_content, last_re=self._last_re,
globals=self._globals)
return si return si

View File

@ -291,15 +291,15 @@ class _VimTest(unittest.TestCase):
for s in self.snippets: for s in self.snippets:
sv,content = s[:2] sv,content = s[:2]
descr = "" description = ""
options = "" options = ""
if len(s) > 2: if len(s) > 2:
descr = s[2] description = s[2]
if len(s) > 3: if len(s) > 3:
options = s[3] options = s[3]
self.send_py("UltiSnips_Manager.add_snippet(%r, %r, %r, %r)" % self.send_py("UltiSnips_Manager.add_snippet(%r, %r, %r, %r)" %
(sv, content, descr, options)) (sv, content, description, options))
ft, fn, file_data = self.snippets_test_file ft, fn, file_data = self.snippets_test_file
if ft: if ft: