Conditional replaces can now be nested
This commit is contained in:
parent
5a42d16499
commit
47a7948526
@ -1,4 +1,5 @@
|
|||||||
trunk:
|
trunk:
|
||||||
|
- Conditional Inserts can now be nested
|
||||||
- Added support for b option. This only considers a snippet at the beginning
|
- Added support for b option. This only considers a snippet at the beginning
|
||||||
of a line ( *UltiSnips-adding-snippets* )
|
of a line ( *UltiSnips-adding-snippets* )
|
||||||
- Added support for ! option. This overwrites previously defined snippets
|
- Added support for ! option. This overwrites previously defined snippets
|
||||||
|
@ -240,10 +240,13 @@ can be used: >
|
|||||||
fn - The current filename
|
fn - The current filename
|
||||||
path - The complete path to the current file
|
path - The complete path to the current file
|
||||||
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 != ""
|
||||||
|
to make sure that the interpolation is only done once
|
||||||
|
|
||||||
Also, the re and os modules are already imported inside the snippet code. This
|
Also, the vim, re, os, string and random modules are already imported inside
|
||||||
allows for very flexible snippets. For example, the following snippet mirrors
|
the snippet code. This allows for very flexible snippets. For example, the
|
||||||
the first Tab Stops value on the same line in uppercase and right aligned:
|
following snippet mirrors the first Tab Stops value on the same line in
|
||||||
|
uppercase and right aligned:
|
||||||
|
|
||||||
------------------- SNIP -------------------
|
------------------- SNIP -------------------
|
||||||
snippet wow
|
snippet wow
|
||||||
|
@ -23,7 +23,7 @@ class _CleverReplace(object):
|
|||||||
_DOLLAR = re.compile(r"\$(\d+)", re.DOTALL)
|
_DOLLAR = re.compile(r"\$(\d+)", re.DOTALL)
|
||||||
_SIMPLE_CASEFOLDINGS = re.compile(r"\\([ul].)", re.DOTALL)
|
_SIMPLE_CASEFOLDINGS = re.compile(r"\\([ul].)", re.DOTALL)
|
||||||
_LONG_CASEFOLDINGS = re.compile(r"\\([UL].*?)\\E", 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]')
|
_UNESCAPE = re.compile(r'\\[^ntrab]')
|
||||||
|
|
||||||
@ -41,6 +41,56 @@ class _CleverReplace(object):
|
|||||||
else:
|
else:
|
||||||
return m.group(1)[1:].lower()
|
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):
|
def _unescape(self, v):
|
||||||
return self._UNESCAPE.subn(lambda m: m.group(0)[-1], v)[0]
|
return self._UNESCAPE.subn(lambda m: m.group(0)[-1], v)[0]
|
||||||
def replace(self, match):
|
def replace(self, match):
|
||||||
@ -53,18 +103,11 @@ class _CleverReplace(object):
|
|||||||
|
|
||||||
def _conditional(m):
|
def _conditional(m):
|
||||||
args = m.group(2).split(':')
|
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
|
# Replace CaseFoldings
|
||||||
tv = self._SIMPLE_CASEFOLDINGS.subn(self._scase_folding, tv)[0]
|
tv = self._SIMPLE_CASEFOLDINGS.subn(self._scase_folding, tv)[0]
|
||||||
tv = self._LONG_CASEFOLDINGS.subn(self._lcase_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")
|
rv = tv.decode("string-escape")
|
||||||
|
|
||||||
@ -624,7 +667,7 @@ class PythonCode(TextObject):
|
|||||||
code = code.replace("\\`", "`")
|
code = code.replace("\\`", "`")
|
||||||
|
|
||||||
# Add Some convenience to the code
|
# 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, "")
|
TextObject.__init__(self, parent, start, end, "")
|
||||||
|
|
||||||
@ -634,10 +677,13 @@ class PythonCode(TextObject):
|
|||||||
path = ""
|
path = ""
|
||||||
fn = os.path.basename(path)
|
fn = os.path.basename(path)
|
||||||
|
|
||||||
|
ct = self.current_text
|
||||||
d = {
|
d = {
|
||||||
't': _Tabs(self),
|
't': _Tabs(self),
|
||||||
'fn': fn,
|
'fn': fn,
|
||||||
'path': path,
|
'path': path,
|
||||||
|
'cur': ct,
|
||||||
|
'res': ct,
|
||||||
}
|
}
|
||||||
|
|
||||||
exec self._code in d
|
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:...)/}")
|
snippets = ("test", r"$1 ${1/(\w+(?:\W+\w+){,7})\W*(.+)?/$1(?2:...)/}")
|
||||||
keys = "test" + EX + "a b c d e f ghhh h oha"
|
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..."
|
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):
|
class Transformation_CINewlines_ECR(_VimTest):
|
||||||
snippets = ("test", r"$1 ${1/, */\n/}")
|
snippets = ("test", r"$1 ${1/, */\n/}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user