Conditional replaces can now be nested

This commit is contained in:
Holger Rapp 2009-07-19 16:44:29 +02:00
parent 5a42d16499
commit 47a7948526
4 changed files with 70 additions and 13 deletions

View File

@ -1,4 +1,5 @@
trunk:
- Conditional Inserts can now be nested
- Added support for b option. This only considers a snippet at the beginning
of a line ( *UltiSnips-adding-snippets* )
- Added support for ! option. This overwrites previously defined snippets

View File

@ -240,10 +240,13 @@ can be used: >
fn - The current filename
path - The complete path to the current file
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
Also, the re and os modules are already imported inside the snippet code. This
allows for very flexible snippets. For example, the following snippet mirrors
the first Tab Stops value on the same line in uppercase and right aligned:
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
following snippet mirrors the first Tab Stops value on the same line in
uppercase and right aligned:
------------------- SNIP -------------------
snippet wow

View File

@ -23,7 +23,7 @@ class _CleverReplace(object):
_DOLLAR = re.compile(r"\$(\d+)", re.DOTALL)
_SIMPLE_CASEFOLDINGS = re.compile(r"\\([ul].)", re.DOTALL)
_LONG_CASEFOLDINGS = re.compile(r"\\([UL].*?)\\E", re.DOTALL)
_CONDITIONAL = re.compile(r"\(\?(\d+):(.*?)(?<!\\)\)", re.DOTALL)
_CONDITIONAL = re.compile(r"\(\?(\d+):", re.DOTALL)
_UNESCAPE = re.compile(r'\\[^ntrab]')
@ -41,6 +41,56 @@ class _CleverReplace(object):
else:
return m.group(1)[1:].lower()
def _replace_conditional(self, match, v):
def _find_closingbrace(v,start_pos):
bracks_open = 1
for idx, c in enumerate(v[start_pos:]):
if c == '(':
if v[idx+start_pos-1] != '\\':
bracks_open += 1
elif c == ')':
if v[idx+start_pos-1] != '\\':
bracks_open -= 1
if not bracks_open:
return start_pos+idx+1
m = self._CONDITIONAL.search(v)
def _part_conditional(v):
bracks_open = 0
args = []
carg = ""
for idx, c in enumerate(v):
if c == '(':
if v[idx-1] != '\\':
bracks_open += 1
elif c == ')':
if v[idx-1] != '\\':
bracks_open -= 1
elif c == ':' and not bracks_open:
args.append(carg)
carg = ""
continue
carg += c
args.append(carg)
return args
while m:
start = m.start()
end = _find_closingbrace(v,start+4)
args = _part_conditional(v[start+4:end-1])
rv = ""
if match.group(int(m.group(1))):
rv = self._unescape(self._replace_conditional(match,args[0]))
elif len(args) > 1:
rv = self._unescape(self._replace_conditional(match,args[1]))
v = v[:start] + rv + v[end:]
m = self._CONDITIONAL.search(v)
return v
def _unescape(self, v):
return self._UNESCAPE.subn(lambda m: m.group(0)[-1], v)[0]
def replace(self, match):
@ -53,18 +103,11 @@ class _CleverReplace(object):
def _conditional(m):
args = m.group(2).split(':')
# TODO: the returned string should be checked for conditionals
if match.group(int(m.group(1))):
return self._unescape(args[0])
elif len(args) > 1:
return self._unescape(args[1])
else:
return ""
# Replace CaseFoldings
tv = self._SIMPLE_CASEFOLDINGS.subn(self._scase_folding, tv)[0]
tv = self._LONG_CASEFOLDINGS.subn(self._lcase_folding, tv)[0]
tv = self._CONDITIONAL.subn(_conditional, tv)[0]
tv = self._replace_conditional(match, tv)
rv = tv.decode("string-escape")
@ -624,7 +667,7 @@ class PythonCode(TextObject):
code = code.replace("\\`", "`")
# Add Some convenience to the code
self._code = "import re, os, vim\n" + code.strip()
self._code = "import re, os, vim, string, random\n" + code.strip()
TextObject.__init__(self, parent, start, end, "")
@ -634,10 +677,13 @@ class PythonCode(TextObject):
path = ""
fn = os.path.basename(path)
ct = self.current_text
d = {
't': _Tabs(self),
'fn': fn,
'path': path,
'cur': ct,
'res': ct,
}
exec self._code in d

View File

@ -838,6 +838,13 @@ class Transformation_ConditionalInsertRWEllipsis_ECR(_VimTest):
snippets = ("test", r"$1 ${1/(\w+(?:\W+\w+){,7})\W*(.+)?/$1(?2:...)/}")
keys = "test" + EX + "a b c d e f ghhh h oha"
wanted = "a b c d e f ghhh h oha a b c d e f ghhh h..."
class Transformation_ConditionalInConditional_ECR(_VimTest):
# TODO: here lingers a bug
snippets = ("test", r"$1 ${1/^.*?(-)?(>)?$/(?2::(?1:>:.))/}")
keys = "test" + EX + "hallo" + ESC + "$a\n" + \
"test" + EX + "hallo-" + ESC + "$a\n" + \
"test" + EX + "hallo->"
wanted = "hallo .\nhallo- >\nhallo-> "
class Transformation_CINewlines_ECR(_VimTest):
snippets = ("test", r"$1 ${1/, */\n/}")