Conditional replaces can now be nested
This commit is contained in:
parent
5a42d16499
commit
47a7948526
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
7
test.py
7
test.py
@ -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/}")
|
||||
|
Loading…
Reference in New Issue
Block a user