documentation, pull-requests fixes
This commit is contained in:
parent
0beefd4a19
commit
66bc2e8f6e
@ -653,6 +653,11 @@ The options currently supported are: >
|
||||
Without this option empty lines in snippets definition will have
|
||||
indentation too.
|
||||
|
||||
e Context snippets - With this option expansion of snippet can be
|
||||
controlled not only by previous characters in line, but by any given python
|
||||
expression. This option can be specified along with other options,
|
||||
like 'b'. See |UltiSnips-context-snippets| for more info.
|
||||
|
||||
The end line is the 'endsnippet' keyword on a line by itself. >
|
||||
|
||||
endsnippet
|
||||
@ -818,6 +823,7 @@ The variables automatically defined in python code are: >
|
||||
t - The values of the placeholders, t[1] is the text of ${1}, and so on
|
||||
snip - UltiSnips.TextObjects.SnippetUtil object instance. Has methods that
|
||||
simplify indentation handling.
|
||||
context - Result of context condition. See |UltiSnips-context-snippets|.
|
||||
|
||||
The 'snip' object provides the following methods: >
|
||||
|
||||
@ -1293,6 +1299,96 @@ clearsnippets trigger1 trigger2
|
||||
------------------- SNAP -------------------
|
||||
|
||||
|
||||
4.9 Context snippets *UltiSnips-context-snippets*
|
||||
|
||||
Context snippets can be enabled by using 'e' option in snippet definition.
|
||||
|
||||
In that case snippet should be defined using this syntax: >
|
||||
|
||||
snippet tab_trigger "description" "expression" options
|
||||
|
||||
'expression' can be any python expression. If 'expression' evaluates to
|
||||
'True', then this snippet will be chosen for expansion. 'expression' must be
|
||||
wrapped with double-quotes.
|
||||
|
||||
Following python modules are automatically imported: 're', 'os', 'vim',
|
||||
'string', 'random'.
|
||||
|
||||
Also, variables are declared in local scope for use in expression: >
|
||||
'window' - alias for 'vim.current.window'
|
||||
'buffer' - alias for 'vim.current.window.buffer'
|
||||
'line' and 'column' - aliases for cursor position
|
||||
|
||||
Keep in mind, that lines in vim numbered from 1, and lists in python starts
|
||||
from 0, so to access current line you need to use 'line-1' expression.
|
||||
|
||||
------------------- SNIP -------------------
|
||||
snippet r "return" "re.match('^\s+if err ', buffer[line-2])" be
|
||||
return err
|
||||
endsnippet
|
||||
------------------- SNAP -------------------
|
||||
|
||||
That snippet will expand to 'return err' only if previous line is starting
|
||||
from 'if err' prefix.
|
||||
|
||||
Note: context snippets prioritized over non-context ones. So, if there are
|
||||
two snippets with the same trigger, and one of them is context snippet and
|
||||
it's expression evaluates to 'True', then context snippet will be used for
|
||||
expansion and first will be ignored.
|
||||
|
||||
------------------- SNIP -------------------
|
||||
snippet i "if ..." b
|
||||
if $1 {
|
||||
$2
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet i "if err != nil" "re.match('^\s+[^=]*err\s*:?=', buffer[line-2])" be
|
||||
if err != nil {
|
||||
$1
|
||||
}
|
||||
endsnippet
|
||||
------------------- SNAP -------------------
|
||||
|
||||
That snippet will expand into 'if err != nil' if previous line will
|
||||
match 'err :=' prefix, otherwise default 'if' snippet will be expanded.
|
||||
|
||||
It's good idea to move context conditions to separate library, so it can be
|
||||
used with other UltiSnips user. In that case, library should be imported
|
||||
using 'global' keyword, like this:
|
||||
|
||||
------------------- SNIP -------------------
|
||||
global !p
|
||||
import my_utils
|
||||
endglobal
|
||||
|
||||
snippet , "return ..., nil/err" "my_utils.is_return_argument(buffer, line, column)" ie
|
||||
, `!p if my_utils.is_in_err_condition():
|
||||
snip.rv = "err"
|
||||
else:
|
||||
snip.rv = "nil"`
|
||||
endsnippet
|
||||
------------------- SNAP -------------------
|
||||
|
||||
That snippet will expand only if cursor is located in the return statement,
|
||||
and then it will expand either to 'err' or to 'nil' depending in which 'if'
|
||||
statement it's located. 'is_return_argument' and 'is_in_err_condition' are
|
||||
part of custom python library which is called 'my_utils' in this example.
|
||||
|
||||
Context condition can return any value which python can use as
|
||||
condition in it's 'if' statement, and if it's considired 'True', then snippet
|
||||
will be expanded. Moreover, result of condition will be accessed in the
|
||||
'context' variable:
|
||||
|
||||
------------------- SNIP -------------------
|
||||
snippet + "var +=" "re.match('\s*(.*?)\s*:?=', buffer[line-2])" ie
|
||||
`!p snip.rv = context.group(1)` += $1
|
||||
endsnippet
|
||||
------------------- SNAP -------------------
|
||||
|
||||
That snippet will expand to 'var1 +=' after line, which begins from 'var1 :='.
|
||||
|
||||
|
||||
==============================================================================
|
||||
5. UltiSnips and Other Plugins *UltiSnips-other-plugins*
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
"""Snippet representation after parsing."""
|
||||
|
||||
import re
|
||||
|
||||
import vim
|
||||
|
||||
from UltiSnips import _vim
|
||||
@ -44,7 +45,7 @@ class SnippetDefinition(object):
|
||||
_TABS = re.compile(r"^\t*")
|
||||
|
||||
def __init__(self, priority, trigger, value, description,
|
||||
options, globals, location, context=None):
|
||||
options, globals, location, context):
|
||||
self._priority = int(priority)
|
||||
self._trigger = as_unicode(trigger)
|
||||
self._value = as_unicode(value)
|
||||
@ -90,17 +91,17 @@ class SnippetDefinition(object):
|
||||
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"] = ' + 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],
|
||||
'context': context,
|
||||
'window': current.window,
|
||||
'buffer': current.buffer,
|
||||
'line': current.window.cursor[0],
|
||||
'column': current.window.cursor[1],
|
||||
}
|
||||
|
||||
exec(code, locals)
|
||||
|
@ -15,7 +15,8 @@ class SnipMateSnippetDefinition(SnippetDefinition):
|
||||
|
||||
def __init__(self, trigger, value, description, location):
|
||||
SnippetDefinition.__init__(self, self.SNIPMATE_SNIPPET_PRIORITY,
|
||||
trigger, value, description, '', {}, location)
|
||||
trigger, value, description, '', {}, location,
|
||||
None)
|
||||
|
||||
def instantiate(self, snippet_instance, initial_text, indent):
|
||||
parse_and_instantiate(snippet_instance, initial_text, indent)
|
||||
|
@ -72,12 +72,11 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
|
||||
opts = words[-1]
|
||||
remain = remain[:-len(opts) - 1].rstrip()
|
||||
|
||||
if 'x' in opts:
|
||||
context = None
|
||||
if 'e' 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()
|
||||
@ -111,10 +110,12 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
|
||||
if snip == 'global':
|
||||
python_globals[trig].append(content)
|
||||
elif snip == 'snippet':
|
||||
return 'snippet', (UltiSnipsSnippetDefinition(priority, trig, content,
|
||||
descr, opts, python_globals,
|
||||
'%s:%i' % (filename, start_line_index),
|
||||
context),)
|
||||
definition = UltiSnipsSnippetDefinition(
|
||||
priority, trig, content,
|
||||
descr, opts, python_globals,
|
||||
'%s:%i' % (filename, start_line_index),
|
||||
context)
|
||||
return 'snippet', (definition,)
|
||||
else:
|
||||
return 'error', ("Invalid snippet type: '%s'" % snip, lines.line_index)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user