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
|
||||
class ${1:MyClass}(${2:object}):
|
||||
""" ${3:Docstring for $1} """
|
||||
""" ${3:Docstring for $1 }"""
|
||||
|
||||
def __init__(self$4):
|
||||
""" ${5:TODO: Fill me in}
|
||||
`!p
|
||||
res.clear()
|
||||
res.shift(2)
|
||||
""" ${5:TODO: Fill me in}`!p
|
||||
res = ""
|
||||
print "test"
|
||||
snip.reset_indent()
|
||||
snip.shift(2)
|
||||
|
||||
args = [arg.split('=')[0].strip() for arg in t[4].split(',') if arg]
|
||||
args = [arg for arg in args if arg and arg != "self"]
|
||||
|
||||
if args:
|
||||
res.write_line()
|
||||
res += snip.mkline('\n')
|
||||
|
||||
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":
|
||||
res.write_line(t[2] + ".__init__(self)\n")
|
||||
res += snip.mkline(t[2] + ".__init__(self)\n")
|
||||
|
||||
for arg in args:
|
||||
res.write_line("self._%s = %s\n" % (arg, arg))
|
||||
res += snip.mkline("self._%s = %s" % (arg, arg))
|
||||
`
|
||||
$0
|
||||
endsnippet
|
||||
@ -51,18 +55,19 @@ endsnippet
|
||||
snippet def "smart def" b
|
||||
def ${1:function}(${2:self}):
|
||||
""" ${3:TODO: Docstring for $1}
|
||||
`!p
|
||||
res.clear()
|
||||
`!p res = ""
|
||||
snip.reset_indent()
|
||||
|
||||
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"]
|
||||
|
||||
if args:
|
||||
res.write_line()
|
||||
res += snip.mkline()
|
||||
|
||||
res.shift()
|
||||
snip.shift()
|
||||
for arg in args:
|
||||
res.write_line(":%s: description" % arg)
|
||||
res += snip.mkline(":%s: description" % arg)
|
||||
|
||||
`
|
||||
:returns: description
|
||||
"""
|
||||
|
@ -271,7 +271,28 @@ can be used: >
|
||||
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 != ""
|
||||
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
|
||||
the snippet code. This allows for very flexible snippets. For example, the
|
||||
|
@ -197,6 +197,7 @@ class _TOParser(object):
|
||||
###############
|
||||
def _parse_pythoncode(self):
|
||||
m = self._PYTHONCODE.search(self._v)
|
||||
print "sea: %s" % m
|
||||
while m:
|
||||
self._handle_pythoncode(m)
|
||||
m = self._PYTHONCODE.search(self._v)
|
||||
@ -704,14 +705,25 @@ class _Tabs(object):
|
||||
return ""
|
||||
return ts.current_text
|
||||
|
||||
class PythonResult(object):
|
||||
""" Provides easy access to indentation, etc
|
||||
for python snippets. """
|
||||
class SnippetUtil(object):
|
||||
""" Provides easy access to indentation, and
|
||||
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
|
||||
if snippet:
|
||||
self._locals = snippet.locals
|
||||
else:
|
||||
self._locals = {}
|
||||
|
||||
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):
|
||||
""" Shifts the indentation level.
|
||||
@ -730,36 +742,41 @@ class PythonResult(object):
|
||||
self.indent = self.indent[:by]
|
||||
except IndexError:
|
||||
indent = ""
|
||||
|
||||
def result(self):
|
||||
if vim.eval("&expandtab") == 0:
|
||||
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.
|
||||
def mkline(self, line="", indent=None):
|
||||
""" Gets a properly set up line.
|
||||
|
||||
:line: the text to add
|
||||
:indent: the indentation to have at the beginning
|
||||
if None, it uses the default amount
|
||||
"""
|
||||
if indent == None:
|
||||
indent = self.indent
|
||||
if len(self.lines) == 0:
|
||||
# Deal with special case: first line is handled already
|
||||
try:
|
||||
indent = indent[len(self._initial_indent):]
|
||||
except IndexError:
|
||||
indent = ""
|
||||
self.lines.append((indent, line))
|
||||
# this deals with the fact that the first line is
|
||||
# already properly indented
|
||||
if self._first:
|
||||
try:
|
||||
indent = indent[len(self._initial_indent):]
|
||||
except IndexError:
|
||||
indent = ""
|
||||
self._first = False
|
||||
|
||||
def clear(self):
|
||||
""" Clears the result.
|
||||
"""
|
||||
self.lines = []
|
||||
if not self._et:
|
||||
indent = indent.replace(" " * self._ts, '\t')
|
||||
return indent + line + '\n'
|
||||
|
||||
def reset_indent(self):
|
||||
""" Clears the indentation. """
|
||||
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):
|
||||
@ -768,11 +785,19 @@ class PythonCode(TextObject):
|
||||
code = code.replace("\\`", "`")
|
||||
|
||||
# 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._res = PythonResult(indent)
|
||||
self._snip = SnippetUtil(indent, snippet)
|
||||
|
||||
TextObject.__init__(self, parent, start, end, "")
|
||||
|
||||
|
||||
def _do_update(self):
|
||||
path = vim.eval('expand("%")')
|
||||
if path is None:
|
||||
@ -785,11 +810,12 @@ class PythonCode(TextObject):
|
||||
'fn': fn,
|
||||
'path': path,
|
||||
'cur': ct,
|
||||
'res': self._res,
|
||||
'res': ct,
|
||||
'snip' : self._snip,
|
||||
}
|
||||
|
||||
exec self._code in d
|
||||
self.current_text = str(self._res.result())
|
||||
self.current_text = str(d["res"])
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
@ -827,6 +853,8 @@ class SnippetInstance(TextObject):
|
||||
if end is None:
|
||||
end = Position(0,0)
|
||||
|
||||
self.locals = {}
|
||||
|
||||
TextObject.__init__(self, parent, start, end, initial_text)
|
||||
|
||||
_TOParser(self, initial_text, indent).parse()
|
||||
|
Loading…
Reference in New Issue
Block a user