proof of concept for context snips
This commit is contained in:
parent
aeb2e24204
commit
b3aec07053
@ -4,6 +4,7 @@
|
||||
"""Snippet representation after parsing."""
|
||||
|
||||
import re
|
||||
import vim
|
||||
|
||||
from UltiSnips import _vim
|
||||
from UltiSnips.compatibility import as_unicode
|
||||
@ -43,7 +44,7 @@ class SnippetDefinition(object):
|
||||
_TABS = re.compile(r"^\t*")
|
||||
|
||||
def __init__(self, priority, trigger, value, description,
|
||||
options, globals, location):
|
||||
options, globals, location, context):
|
||||
self._priority = int(priority)
|
||||
self._trigger = as_unicode(trigger)
|
||||
self._value = as_unicode(value)
|
||||
@ -53,6 +54,8 @@ class SnippetDefinition(object):
|
||||
self._last_re = None
|
||||
self._globals = globals
|
||||
self._location = location
|
||||
self._context_code = context
|
||||
self._context = None
|
||||
|
||||
# Make sure that we actually match our trigger in case we are
|
||||
# immediately expanded.
|
||||
@ -78,6 +81,32 @@ class SnippetDefinition(object):
|
||||
return match
|
||||
return False
|
||||
|
||||
def _context_match(self):
|
||||
current = vim.current
|
||||
# skip on empty buffer
|
||||
if len(current.buffer) == 1 and current.buffer[0] == "":
|
||||
return
|
||||
|
||||
code = "\n".join([
|
||||
'import re, os, vim, string, random',
|
||||
'\n'.join(self._globals.get('!p', [])).replace('\r\n', '\n'),
|
||||
'ctx["match"] = ' + self._context_code,
|
||||
''
|
||||
])
|
||||
|
||||
context = {'match': False}
|
||||
locals = {
|
||||
'ctx': context,
|
||||
'w': current.window,
|
||||
'b': current.buffer,
|
||||
'l': current.window.cursor[0],
|
||||
'c': current.window.cursor[1],
|
||||
}
|
||||
|
||||
exec(code, locals)
|
||||
|
||||
return context["match"]
|
||||
|
||||
def has_option(self, opt):
|
||||
"""Check if the named option is set."""
|
||||
return opt in self._opts
|
||||
@ -109,6 +138,11 @@ class SnippetDefinition(object):
|
||||
"""Where this snippet was defined."""
|
||||
return self._location
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
"""Returns matched context."""
|
||||
return self._context
|
||||
|
||||
def matches(self, trigger):
|
||||
"""Returns True if this snippet matches 'trigger'."""
|
||||
# If user supplies both "w" and "i", it should perhaps be an
|
||||
@ -152,6 +186,12 @@ class SnippetDefinition(object):
|
||||
if text_before.strip(' \t') != '':
|
||||
self._matched = ''
|
||||
return False
|
||||
|
||||
if match and self._context_code:
|
||||
self._context = self._context_match()
|
||||
print(match, self._trigger, self._context)
|
||||
match = self._context != None
|
||||
|
||||
return match
|
||||
|
||||
def could_match(self, trigger):
|
||||
@ -236,7 +276,8 @@ class SnippetDefinition(object):
|
||||
|
||||
snippet_instance = SnippetInstance(
|
||||
self, parent, initial_text, start, end, visual_content,
|
||||
last_re=self._last_re, globals=self._globals)
|
||||
last_re=self._last_re, globals=self._globals,
|
||||
context=self._context)
|
||||
self.instantiate(snippet_instance, initial_text, indent)
|
||||
|
||||
snippet_instance.update_textobjects()
|
||||
|
@ -65,12 +65,21 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
|
||||
# Get and strip options if they exist
|
||||
remain = line[len(snip):].strip()
|
||||
words = remain.split()
|
||||
|
||||
if len(words) > 2:
|
||||
# second to last word ends with a quote
|
||||
if '"' not in words[-1] and words[-2][-1] == '"':
|
||||
opts = words[-1]
|
||||
remain = remain[:-len(opts) - 1].rstrip()
|
||||
|
||||
if 'x' in opts:
|
||||
left = remain[:-1].rfind('"')
|
||||
if left != -1 and left != 0:
|
||||
context, remain = remain[left:].strip('"'), remain[:left]
|
||||
else:
|
||||
context = None
|
||||
|
||||
|
||||
# Get and strip description if it exists
|
||||
remain = remain.strip()
|
||||
if len(remain.split()) > 1 and remain[-1] == '"':
|
||||
@ -105,7 +114,8 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
|
||||
elif snip == 'snippet':
|
||||
return 'snippet', (UltiSnipsSnippetDefinition(priority, trig, content,
|
||||
descr, opts, python_globals,
|
||||
'%s:%i' % (filename, start_line_index)),)
|
||||
'%s:%i' % (filename, start_line_index),
|
||||
context),)
|
||||
else:
|
||||
return 'error', ("Invalid snippet type: '%s'" % snip, lines.line_index)
|
||||
|
||||
|
@ -475,6 +475,7 @@ class SnippetManager(object):
|
||||
elif feedkey:
|
||||
_vim.command('return %s' % _vim.escape(feedkey))
|
||||
|
||||
@err_to_scratch_buffer
|
||||
def _snips(self, before, partial):
|
||||
"""Returns all the snippets for the given text before the cursor.
|
||||
|
||||
@ -572,6 +573,10 @@ class SnippetManager(object):
|
||||
if not before:
|
||||
return False
|
||||
snippets = self._snips(before, False)
|
||||
# prefer snippets with context if any
|
||||
snippets_with_context = [s for s in snippets if s.context]
|
||||
if snippets_with_context:
|
||||
snippets = snippets_with_context
|
||||
if not snippets:
|
||||
# No snippet found
|
||||
return False
|
||||
|
@ -21,7 +21,7 @@ class SnippetInstance(EditableTextObject):
|
||||
# pylint:disable=protected-access
|
||||
|
||||
def __init__(self, snippet, parent, initial_text,
|
||||
start, end, visual_content, last_re, globals):
|
||||
start, end, visual_content, last_re, globals, context):
|
||||
if start is None:
|
||||
start = Position(0, 0)
|
||||
if end is None:
|
||||
@ -29,7 +29,7 @@ class SnippetInstance(EditableTextObject):
|
||||
self.snippet = snippet
|
||||
self._cts = 0
|
||||
|
||||
self.locals = {'match': last_re}
|
||||
self.locals = {'match': last_re, 'context': context}
|
||||
self.globals = globals
|
||||
self.visual_content = visual_content
|
||||
|
||||
|
@ -78,7 +78,7 @@ syn match snipSnippetTrigger ,".\{-}"\ze\%(\s\+"\%(\s*\S\)\@=[^"]*\%("\s\+[^"[:s
|
||||
syn match snipSnippetTriggerInvalid ,\S\@=.\{-}\S\ze\%(\s\+"[^"]*\%("\s\+[^"[:space:]]\+\s*\|"\s*\)\=\|\s*\)$, contained nextgroup=snipSnippetDocString skipwhite
|
||||
syn match snipSnippetDocString ,"[^"]*\%("\ze\s*\%(\s[^"[:space:]]\+\s*\)\=\)\=$, contained nextgroup=snipSnippetOptions skipwhite
|
||||
syn match snipSnippetOptions ,\S\+, contained contains=snipSnippetOptionFlag
|
||||
syn match snipSnippetOptionFlag ,[biwrts], contained
|
||||
syn match snipSnippetOptionFlag ,[biwrtsmx], contained
|
||||
|
||||
" Command substitution {{{4
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user