use a helper object, rather than replacing 'res', also provide 'snippet-local' variables
This commit is contained in:
parent
e8125051d3
commit
513a635c51
@ -20,30 +20,34 @@ endsnippet
|
|||||||
##########
|
##########
|
||||||
snippet class "smart class" b
|
snippet class "smart class" b
|
||||||
class ${1:MyClass}(${2:object}):
|
class ${1:MyClass}(${2:object}):
|
||||||
""" ${3:Docstring for $1} """
|
""" ${3:Docstring for $1 }"""
|
||||||
|
|
||||||
def __init__(self$4):
|
def __init__(self$4):
|
||||||
""" ${5:TODO: Fill me in}
|
""" ${5:TODO: Fill me in}`!p
|
||||||
`!p
|
res = ""
|
||||||
res.clear()
|
print "test"
|
||||||
res.shift(2)
|
snip.reset_indent()
|
||||||
|
snip.shift(2)
|
||||||
|
|
||||||
args = [arg.split('=')[0].strip() for arg in t[4].split(',') if arg]
|
args = [arg.split('=')[0].strip() for arg in t[4].split(',') if arg]
|
||||||
args = [arg for arg in args if arg and arg != "self"]
|
args = [arg for arg in args if arg and arg != "self"]
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
res.write_line()
|
res += snip.mkline('\n')
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
res.write_line(":%s: description" % arg)
|
res += snip.mkline(":%s: description" % arg)
|
||||||
|
|
||||||
res.write_line('"""')
|
if args:
|
||||||
|
res += snip.mkline('"""')
|
||||||
|
else:
|
||||||
|
res += snip.mkline(' """', '')
|
||||||
|
|
||||||
if t[2] != "object":
|
if t[2] != "object":
|
||||||
res.write_line(t[2] + ".__init__(self)\n")
|
res += snip.mkline(t[2] + ".__init__(self)\n")
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
res.write_line("self._%s = %s\n" % (arg, arg))
|
res += snip.mkline("self._%s = %s" % (arg, arg))
|
||||||
`
|
`
|
||||||
$0
|
$0
|
||||||
endsnippet
|
endsnippet
|
||||||
@ -51,18 +55,19 @@ endsnippet
|
|||||||
snippet def "smart def" b
|
snippet def "smart def" b
|
||||||
def ${1:function}(${2:self}):
|
def ${1:function}(${2:self}):
|
||||||
""" ${3:TODO: Docstring for $1}
|
""" ${3:TODO: Docstring for $1}
|
||||||
`!p
|
`!p res = ""
|
||||||
res.clear()
|
snip.reset_indent()
|
||||||
|
|
||||||
args = [arg.split('=')[0].strip() for arg in t[2].split(',') if arg.strip()]
|
args = [arg.split('=')[0].strip() for arg in t[2].split(',') if arg.strip()]
|
||||||
args = [arg for arg in args if arg and arg != "self"]
|
args = [arg for arg in args if arg and arg != "self"]
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
res.write_line()
|
res += snip.mkline()
|
||||||
|
|
||||||
res.shift()
|
snip.shift()
|
||||||
for arg in args:
|
for arg in args:
|
||||||
res.write_line(":%s: description" % arg)
|
res += snip.mkline(":%s: description" % arg)
|
||||||
|
|
||||||
`
|
`
|
||||||
:returns: description
|
:returns: description
|
||||||
"""
|
"""
|
||||||
|
@ -271,7 +271,28 @@ can be used: >
|
|||||||
t - The values of the placeholders, t[1] -> current text of ${1} and so on
|
t - The values of the placeholders, t[1] -> current text of ${1} and so on
|
||||||
cur - The current text of the placeholder. You can check if this is != ""
|
cur - The current text of the placeholder. You can check if this is != ""
|
||||||
to make sure that the interpolation is only done once
|
to make sure that the interpolation is only done once
|
||||||
ind - The indentation text appearing before the first line of the snippet
|
snip - Provides easy indentation handling, and snippet-local variables.
|
||||||
|
|
||||||
|
The snip variable provides four methods >
|
||||||
|
|
||||||
|
snip.mkline(line="", indent=None):
|
||||||
|
Returns a line ready to be appended to the result. If indent
|
||||||
|
is None, then mkline prepends spaces and/or tabs appropriate to the
|
||||||
|
current tabstop and expandtab variables.
|
||||||
|
|
||||||
|
snip.shift(amount=1):
|
||||||
|
Shifts the default indentatation level used by mkline right by the
|
||||||
|
number of spaces defined by shiftwidth, 'amount' times.
|
||||||
|
|
||||||
|
snip.unshift(amount=1):
|
||||||
|
Shifts the default indentatation level used by mkline left by the
|
||||||
|
number of spaces defined by shiftwidth, 'amount' times.
|
||||||
|
|
||||||
|
snip.reset_indent():
|
||||||
|
Resets the indentation level to its initial value.
|
||||||
|
|
||||||
|
The snip variable also acts as dictionary which can be accessed by any of the
|
||||||
|
python code in the snippet.
|
||||||
|
|
||||||
Also, the vim, re, os, string and random modules are already imported inside
|
Also, the vim, re, os, string and random modules are already imported inside
|
||||||
the snippet code. This allows for very flexible snippets. For example, the
|
the snippet code. This allows for very flexible snippets. For example, the
|
||||||
|
@ -197,6 +197,7 @@ class _TOParser(object):
|
|||||||
###############
|
###############
|
||||||
def _parse_pythoncode(self):
|
def _parse_pythoncode(self):
|
||||||
m = self._PYTHONCODE.search(self._v)
|
m = self._PYTHONCODE.search(self._v)
|
||||||
|
print "sea: %s" % m
|
||||||
while m:
|
while m:
|
||||||
self._handle_pythoncode(m)
|
self._handle_pythoncode(m)
|
||||||
m = self._PYTHONCODE.search(self._v)
|
m = self._PYTHONCODE.search(self._v)
|
||||||
@ -704,14 +705,25 @@ class _Tabs(object):
|
|||||||
return ""
|
return ""
|
||||||
return ts.current_text
|
return ts.current_text
|
||||||
|
|
||||||
class PythonResult(object):
|
class SnippetUtil(object):
|
||||||
""" Provides easy access to indentation, etc
|
""" Provides easy access to indentation, and
|
||||||
for python snippets. """
|
snippet-local variables, which can be accessed by
|
||||||
|
any PythonCode object in the snippet.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, initial_indent):
|
def __init__(self, initial_indent, snippet=None):
|
||||||
self._initial_indent = initial_indent
|
self._initial_indent = initial_indent
|
||||||
|
if snippet:
|
||||||
|
self._locals = snippet.locals
|
||||||
|
else:
|
||||||
|
self._locals = {}
|
||||||
|
|
||||||
self._shift = int(vim.eval("&sw"))
|
self._shift = int(vim.eval("&sw"))
|
||||||
self.clear()
|
self._et = (vim.eval("&expandtab") == "1")
|
||||||
|
self._ts = int(vim.eval("&ts"))
|
||||||
|
|
||||||
|
self._first = True # hack to make first line work right
|
||||||
|
self.reset_indent()
|
||||||
|
|
||||||
def shift(self, amount=1):
|
def shift(self, amount=1):
|
||||||
""" Shifts the indentation level.
|
""" Shifts the indentation level.
|
||||||
@ -731,35 +743,40 @@ class PythonResult(object):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
indent = ""
|
indent = ""
|
||||||
|
|
||||||
def result(self):
|
def mkline(self, line="", indent=None):
|
||||||
if vim.eval("&expandtab") == 0:
|
""" Gets a properly set up line.
|
||||||
ts = int(vim.eval("&ts"))
|
|
||||||
for line in self.lines:
|
|
||||||
line[0] = line[0].replace(" " * ts, '\t')
|
|
||||||
return os.linesep.join([ind + line for ind, line in self.lines])
|
|
||||||
|
|
||||||
|
|
||||||
def write_line(self, line="", indent=None):
|
|
||||||
""" Adds a line to the result.
|
|
||||||
|
|
||||||
:line: the text to add
|
:line: the text to add
|
||||||
:indent: the indentation to have at the beginning
|
:indent: the indentation to have at the beginning
|
||||||
|
if None, it uses the default amount
|
||||||
"""
|
"""
|
||||||
if indent == None:
|
if indent == None:
|
||||||
indent = self.indent
|
indent = self.indent
|
||||||
if len(self.lines) == 0:
|
# this deals with the fact that the first line is
|
||||||
# Deal with special case: first line is handled already
|
# already properly indented
|
||||||
|
if self._first:
|
||||||
try:
|
try:
|
||||||
indent = indent[len(self._initial_indent):]
|
indent = indent[len(self._initial_indent):]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
indent = ""
|
indent = ""
|
||||||
self.lines.append((indent, line))
|
self._first = False
|
||||||
|
|
||||||
def clear(self):
|
if not self._et:
|
||||||
""" Clears the result.
|
indent = indent.replace(" " * self._ts, '\t')
|
||||||
"""
|
return indent + line + '\n'
|
||||||
self.lines = []
|
|
||||||
|
def reset_indent(self):
|
||||||
|
""" Clears the indentation. """
|
||||||
self.indent = self._initial_indent
|
self.indent = self._initial_indent
|
||||||
|
self._first = True
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
""" Gets an item from the snippet. """
|
||||||
|
return self._locals[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
""" Sets an item in the snippet locals. """
|
||||||
|
self._locals[key] = value
|
||||||
|
|
||||||
|
|
||||||
class PythonCode(TextObject):
|
class PythonCode(TextObject):
|
||||||
@ -768,11 +785,19 @@ class PythonCode(TextObject):
|
|||||||
code = code.replace("\\`", "`")
|
code = code.replace("\\`", "`")
|
||||||
|
|
||||||
# Add Some convenience to the code
|
# Add Some convenience to the code
|
||||||
|
snippet = parent
|
||||||
|
while snippet and not isinstance(snippet, SnippetInstance):
|
||||||
|
try:
|
||||||
|
snippet = snippet._parent
|
||||||
|
except AttributeError:
|
||||||
|
snippet = None
|
||||||
|
|
||||||
self._code = "import re, os, vim, string, random\n" + code
|
self._code = "import re, os, vim, string, random\n" + code
|
||||||
self._res = PythonResult(indent)
|
self._snip = SnippetUtil(indent, snippet)
|
||||||
|
|
||||||
TextObject.__init__(self, parent, start, end, "")
|
TextObject.__init__(self, parent, start, end, "")
|
||||||
|
|
||||||
|
|
||||||
def _do_update(self):
|
def _do_update(self):
|
||||||
path = vim.eval('expand("%")')
|
path = vim.eval('expand("%")')
|
||||||
if path is None:
|
if path is None:
|
||||||
@ -785,11 +810,12 @@ class PythonCode(TextObject):
|
|||||||
'fn': fn,
|
'fn': fn,
|
||||||
'path': path,
|
'path': path,
|
||||||
'cur': ct,
|
'cur': ct,
|
||||||
'res': self._res,
|
'res': ct,
|
||||||
|
'snip' : self._snip,
|
||||||
}
|
}
|
||||||
|
|
||||||
exec self._code in d
|
exec self._code in d
|
||||||
self.current_text = str(self._res.result())
|
self.current_text = str(d["res"])
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -827,6 +853,8 @@ class SnippetInstance(TextObject):
|
|||||||
if end is None:
|
if end is None:
|
||||||
end = Position(0,0)
|
end = Position(0,0)
|
||||||
|
|
||||||
|
self.locals = {}
|
||||||
|
|
||||||
TextObject.__init__(self, parent, start, end, initial_text)
|
TextObject.__init__(self, parent, start, end, initial_text)
|
||||||
|
|
||||||
_TOParser(self, initial_text, indent).parse()
|
_TOParser(self, initial_text, indent).parse()
|
||||||
|
Loading…
Reference in New Issue
Block a user