Applied pyformat on entire codebase.

This commit is contained in:
Holger Rapp 2015-01-20 21:26:03 +01:00
parent e1436a8aeb
commit 6a787cdc7b
65 changed files with 3734 additions and 2457 deletions

View File

@ -10,39 +10,45 @@ import sys
from UltiSnips import _vim
from UltiSnips.position import Position
def is_complete_edit(initial_line, original, wanted, cmds):
"""Returns true if 'original' is changed to 'wanted' with the edit commands
in 'cmds'. Initial line is to change the line numbers in 'cmds'."""
in 'cmds'.
Initial line is to change the line numbers in 'cmds'.
"""
buf = original[:]
for cmd in cmds:
ctype, line, col, char = cmd
line -= initial_line
if ctype == "D":
if ctype == 'D':
if char != '\n':
buf[line] = buf[line][:col] + buf[line][col+len(char):]
buf[line] = buf[line][:col] + buf[line][col + len(char):]
else:
if line + 1 < len(buf):
buf[line] = buf[line] + buf[line+1]
del buf[line+1]
buf[line] = buf[line] + buf[line + 1]
del buf[line + 1]
else:
del buf[line]
elif ctype == "I":
elif ctype == 'I':
buf[line] = buf[line][:col] + char + buf[line][col:]
buf = '\n'.join(buf).split('\n')
return (len(buf) == len(wanted) and
all(j == k for j, k in zip(buf, wanted)))
def guess_edit(initial_line, last_text, current_text, vim_state):
"""
Try to guess what the user might have done by heuristically looking at
"""Try to guess what the user might have done by heuristically looking at
cursor movement, number of changed lines and if they got longer or shorter.
This will detect most simple movements like insertion, deletion of a line
or carriage return. 'initial_text' is the index of where the comparison
starts, 'last_text' is the last text of the snippet, 'current_text' is the
current text of the snippet and 'vim_state' is the cached vim state.
Returns (True, edit_cmds) when the edit could be guessed, (False, None)
otherwise.
Returns (True, edit_cmds) when the edit could be guessed, (False,
None) otherwise.
"""
if not len(last_text) and not len(current_text):
return True, ()
@ -53,83 +59,84 @@ def guess_edit(initial_line, last_text, current_text, vim_state):
if (len(last_text) and
(not current_text or
(len(current_text) == 1 and not current_text[0]))
):
):
es = []
if not current_text:
current_text = ['']
for i in last_text:
es.append(("D", initial_line, 0, i))
es.append(("D", initial_line, 0, "\n"))
es.pop() # Remove final \n because it is not really removed
es.append(('D', initial_line, 0, i))
es.append(('D', initial_line, 0, '\n'))
es.pop() # Remove final \n because it is not really removed
if is_complete_edit(initial_line, last_text, current_text, es):
return True, es
if ppos.mode == 'v': # Maybe selectmode?
if ppos.mode == 'v': # Maybe selectmode?
sv = list(map(int, _vim.eval("""getpos("'<")""")))
sv = Position(sv[1]-1, sv[2]-1)
sv = Position(sv[1] - 1, sv[2] - 1)
ev = list(map(int, _vim.eval("""getpos("'>")""")))
ev = Position(ev[1]-1, ev[2]-1)
if "exclusive" in _vim.eval("&selection"):
ppos.col -= 1 # We want to be inclusive, sorry.
ev = Position(ev[1] - 1, ev[2] - 1)
if 'exclusive' in _vim.eval('&selection'):
ppos.col -= 1 # We want to be inclusive, sorry.
ev.col -= 1
es = []
if sv.line == ev.line:
es.append(("D", sv.line, sv.col,
last_text[sv.line - initial_line][sv.col:ev.col+1]))
es.append(('D', sv.line, sv.col,
last_text[sv.line - initial_line][sv.col:ev.col + 1]))
if sv != pos and sv.line == pos.line:
es.append(("I", sv.line, sv.col,
current_text[sv.line - initial_line][sv.col:pos.col+1]))
es.append(('I', sv.line, sv.col,
current_text[sv.line - initial_line][sv.col:pos.col + 1]))
if is_complete_edit(initial_line, last_text, current_text, es):
return True, es
if pos.line == ppos.line:
if len(last_text) == len(current_text): # Movement only in one line
if len(last_text) == len(current_text): # Movement only in one line
llen = len(last_text[ppos.line - initial_line])
clen = len(current_text[pos.line - initial_line])
if ppos < pos and clen > llen: # maybe only chars have been added
if ppos < pos and clen > llen: # maybe only chars have been added
es = (
("I", ppos.line, ppos.col,
('I', ppos.line, ppos.col,
current_text[ppos.line - initial_line]
[ppos.col:pos.col]),
[ppos.col:pos.col]),
)
if is_complete_edit(initial_line, last_text, current_text, es):
return True, es
if clen < llen:
if ppos == pos: # 'x' or DEL or dt or something
if ppos == pos: # 'x' or DEL or dt or something
es = (
("D", pos.line, pos.col,
('D', pos.line, pos.col,
last_text[ppos.line - initial_line]
[ppos.col:ppos.col + (llen - clen)]),
[ppos.col:ppos.col + (llen - clen)]),
)
if is_complete_edit(initial_line, last_text,
current_text, es):
current_text, es):
return True, es
if pos < ppos: # Backspacing or dT dF?
if pos < ppos: # Backspacing or dT dF?
es = (
("D", pos.line, pos.col,
('D', pos.line, pos.col,
last_text[pos.line - initial_line]
[pos.col:pos.col + llen - clen]),
[pos.col:pos.col + llen - clen]),
)
if is_complete_edit(initial_line, last_text,
current_text, es):
current_text, es):
return True, es
elif len(current_text) < len(last_text):
# where some lines deleted? (dd or so)
es = []
for i in range(len(last_text)-len(current_text)):
es.append(("D", pos.line, 0,
last_text[pos.line - initial_line + i]))
es.append(("D", pos.line, 0, '\n'))
for i in range(len(last_text) - len(current_text)):
es.append(('D', pos.line, 0,
last_text[pos.line - initial_line + i]))
es.append(('D', pos.line, 0, '\n'))
if is_complete_edit(initial_line, last_text,
current_text, es):
current_text, es):
return True, es
else:
# Movement in more than one line
if ppos.line + 1 == pos.line and pos.col == 0: # Carriage return?
es = (("I", ppos.line, ppos.col, "\n"),)
if ppos.line + 1 == pos.line and pos.col == 0: # Carriage return?
es = (('I', ppos.line, ppos.col, '\n'),)
if is_complete_edit(initial_line, last_text,
current_text, es):
current_text, es):
return True, es
return False, None
def diff(a, b, sline=0):
"""
Return a list of deletions and insertions that will turn 'a' into 'b'. This
@ -154,8 +161,8 @@ def diff(a, b, sline=0):
d[0] = [(0, 0, sline, 0, ())]
cost = 0
deletion_cost = len(a)+len(b)
insertion_cost = len(a)+len(b)
deletion_cost = len(a) + len(b)
insertion_cost = len(a) + len(b)
while True:
while len(d[cost]):
x, y, line, col, what = d[cost].pop()
@ -170,50 +177,50 @@ def diff(a, b, sline=0):
ncol = 0
nline += 1
lcost = cost + 1
if (what and what[-1][0] == "D" and what[-1][1] == line and
if (what and what[-1][0] == 'D' and what[-1][1] == line and
what[-1][2] == col and a[x] != '\n'):
# Matching directly after a deletion should be as costly as
# DELETE + INSERT + a bit
lcost = (deletion_cost + insertion_cost)*1.5
if seen[x+1, y+1] > lcost:
d[lcost].append((x+1, y+1, nline, ncol, what))
seen[x+1, y+1] = lcost
if y < len(b): # INSERT
lcost = (deletion_cost + insertion_cost) * 1.5
if seen[x + 1, y + 1] > lcost:
d[lcost].append((x + 1, y + 1, nline, ncol, what))
seen[x + 1, y + 1] = lcost
if y < len(b): # INSERT
ncol = col + 1
nline = line
if b[y] == '\n':
ncol = 0
nline += 1
if (what and what[-1][0] == "I" and what[-1][1] == nline and
what[-1][2]+len(what[-1][-1]) == col and b[y] != '\n' and
seen[x, y+1] > cost + (insertion_cost + ncol) // 2
):
seen[x, y+1] = cost + (insertion_cost + ncol) // 2
if (what and what[-1][0] == 'I' and what[-1][1] == nline and
what[-1][2] + len(what[-1][-1]) == col and b[y] != '\n' and
seen[x, y + 1] > cost + (insertion_cost + ncol) // 2
):
seen[x, y + 1] = cost + (insertion_cost + ncol) // 2
d[cost + (insertion_cost + ncol) // 2].append(
(x, y+1, line, ncol, what[:-1] + (
("I", what[-1][1], what[-1][2],
(x, y + 1, line, ncol, what[:-1] + (
('I', what[-1][1], what[-1][2],
what[-1][-1] + b[y]),)
)
)
)
elif seen[x, y+1] > cost + insertion_cost + ncol:
seen[x, y+1] = cost + insertion_cost + ncol
d[cost + ncol + insertion_cost].append((x, y+1, nline, ncol,
what + (("I", line, col, b[y]),))
)
if x < len(a): # DELETE
if (what and what[-1][0] == "D" and what[-1][1] == line and
what[-1][2] == col and a[x] != '\n' and
what[-1][-1] != '\n' and
seen[x+1, y] > cost + deletion_cost // 2
):
seen[x+1, y] = cost + deletion_cost // 2
elif seen[x, y + 1] > cost + insertion_cost + ncol:
seen[x, y + 1] = cost + insertion_cost + ncol
d[cost + ncol + insertion_cost].append((x, y + 1, nline, ncol,
what + (('I', line, col, b[y]),))
)
if x < len(a): # DELETE
if (what and what[-1][0] == 'D' and what[-1][1] == line and
what[-1][2] == col and a[x] != '\n' and
what[-1][-1] != '\n' and
seen[x + 1, y] > cost + deletion_cost // 2
):
seen[x + 1, y] = cost + deletion_cost // 2
d[cost + deletion_cost // 2].append(
(x+1, y, line, col, what[:-1] + (
("D", line, col, what[-1][-1] + a[x]),))
)
elif seen[x+1, y] > cost + deletion_cost:
seen[x+1, y] = cost + deletion_cost
d[cost + deletion_cost].append((x+1, y, line, col, what +
(("D", line, col, a[x]),))
(x + 1, y, line, col, what[:-1] + (
('D', line, col, what[-1][-1] + a[x]),))
)
elif seen[x + 1, y] > cost + deletion_cost:
seen[x + 1, y] = cost + deletion_cost
d[cost + deletion_cost].append((x + 1, y, line, col, what +
(('D', line, col, a[x]),))
)
cost += 1

View File

@ -9,35 +9,37 @@ import vim # pylint:disable=import-error
from vim import error # pylint:disable=import-error,unused-import
from UltiSnips.compatibility import col2byte, byte2col, \
as_unicode, as_vimencoding
as_unicode, as_vimencoding
from UltiSnips.position import Position
class VimBuffer(object):
"""Wrapper around the current Vim buffer."""
def __getitem__(self, idx):
if isinstance(idx, slice): # Py3
if isinstance(idx, slice): # Py3
return self.__getslice__(idx.start, idx.stop)
rv = vim.current.buffer[idx]
return as_unicode(rv)
def __getslice__(self, i, j): # pylint:disable=no-self-use
def __getslice__(self, i, j): # pylint:disable=no-self-use
rv = vim.current.buffer[i:j]
return [as_unicode(l) for l in rv]
def __setitem__(self, idx, text):
if isinstance(idx, slice): # Py3
if isinstance(idx, slice): # Py3
return self.__setslice__(idx.start, idx.stop, text)
vim.current.buffer[idx] = as_vimencoding(text)
def __setslice__(self, i, j, text): # pylint:disable=no-self-use
def __setslice__(self, i, j, text): # pylint:disable=no-self-use
vim.current.buffer[i:j] = [as_vimencoding(l) for l in text]
def __len__(self):
return len(vim.current.buffer)
@property
def line_till_cursor(self): # pylint:disable=no-self-use
def line_till_cursor(self): # pylint:disable=no-self-use
"""Returns the text before the cursor."""
# Note: we want byte position here
_, col = vim.current.window.cursor
@ -46,27 +48,30 @@ class VimBuffer(object):
return before
@property
def number(self): # pylint:disable=no-self-use
def number(self): # pylint:disable=no-self-use
"""The bufnr() of this buffer."""
return int(eval("bufnr('%')"))
@property
def cursor(self): # pylint:disable=no-self-use
"""
The current windows cursor. Note that this is 0 based in col and 0
based in line which is different from Vim's cursor.
def cursor(self): # pylint:disable=no-self-use
"""The current windows cursor.
Note that this is 0 based in col and 0 based in line which is
different from Vim's cursor.
"""
line, nbyte = vim.current.window.cursor
col = byte2col(line, nbyte)
return Position(line - 1, col)
@cursor.setter
def cursor(self, pos): # pylint:disable=no-self-use
def cursor(self, pos): # pylint:disable=no-self-use
"""See getter."""
nbyte = col2byte(pos.line + 1, pos.col)
vim.current.window.cursor = pos.line + 1, nbyte
buf = VimBuffer() # pylint:disable=invalid-name
def escape(inp):
"""Creates a vim-friendly string from a group of
dicts, lists and strings."""
@ -76,17 +81,19 @@ def escape(inp):
rv = as_unicode('[' + ','.join(conv(o) for o in obj) + ']')
elif isinstance(obj, dict):
rv = as_unicode('{' + ','.join([
"%s:%s" % (conv(key), conv(value))
'%s:%s' % (conv(key), conv(value))
for key, value in obj.iteritems()]) + '}')
else:
rv = as_unicode('"%s"') % as_unicode(obj).replace('"', '\\"')
return rv
return conv(inp)
def command(cmd):
"""Wraps vim.command."""
return as_unicode(vim.command(as_vimencoding(cmd)))
def eval(text):
"""Wraps vim.eval."""
rv = vim.eval(as_vimencoding(text))
@ -94,77 +101,88 @@ def eval(text):
return as_unicode(rv)
return rv
def feedkeys(keys, mode='n'):
"""Wrapper around vim's feedkeys function. Mainly for convenience."""
"""Wrapper around vim's feedkeys function.
Mainly for convenience.
"""
command(as_unicode(r'call feedkeys("%s", "%s")') % (keys, mode))
def new_scratch_buffer(text):
"""Create a new scratch buffer with the text given"""
vim.command("botright new")
vim.command("set ft=")
vim.command("set buftype=nofile")
"""Create a new scratch buffer with the text given."""
vim.command('botright new')
vim.command('set ft=')
vim.command('set buftype=nofile')
vim.current.buffer[:] = text.splitlines()
feedkeys(r"\<Esc>")
def virtual_position(line, col):
"""Runs the position through virtcol() and returns the result."""
nbytes = col2byte(line, col)
return line, int(eval('virtcol([%d, %d])' % (line, nbytes)))
def select(start, end):
"""Select the span in Select mode"""
"""Select the span in Select mode."""
_unmap_select_mode_mapping()
selection = eval("&selection")
selection = eval('&selection')
col = col2byte(start.line + 1, start.col)
vim.current.window.cursor = start.line + 1, col
move_cmd = ""
if eval("mode()") != 'n':
move_cmd = ''
if eval('mode()') != 'n':
move_cmd += r"\<Esc>"
if start == end:
# Zero Length Tabstops, use 'i' or 'a'.
if col == 0 or eval("mode()") not in 'i' and \
if col == 0 or eval('mode()') not in 'i' and \
col < len(buf[start.line]):
move_cmd += "i"
move_cmd += 'i'
else:
move_cmd += "a"
move_cmd += 'a'
else:
# Non zero length, use Visual selection.
move_cmd += "v"
if "inclusive" in selection:
move_cmd += 'v'
if 'inclusive' in selection:
if end.col == 0:
move_cmd += "%iG$" % end.line
move_cmd += '%iG$' % end.line
else:
move_cmd += "%iG%i|" % virtual_position(end.line + 1, end.col)
elif "old" in selection:
move_cmd += "%iG%i|" % virtual_position(end.line + 1, end.col)
move_cmd += '%iG%i|' % virtual_position(end.line + 1, end.col)
elif 'old' in selection:
move_cmd += '%iG%i|' % virtual_position(end.line + 1, end.col)
else:
move_cmd += "%iG%i|" % virtual_position(end.line + 1, end.col + 1)
move_cmd += "o%iG%i|o\\<c-g>" % virtual_position(
start.line + 1, start.col + 1)
move_cmd += '%iG%i|' % virtual_position(end.line + 1, end.col + 1)
move_cmd += 'o%iG%i|o\\<c-g>' % virtual_position(
start.line + 1, start.col + 1)
feedkeys(_LangMapTranslator().translate(move_cmd))
def _unmap_select_mode_mapping():
"""This function unmaps select mode mappings if so wished by the user.
Removes select mode mappings that can actually be typed by the user
(ie, ignores things like <Plug>).
"""
if int(eval("g:UltiSnipsRemoveSelectModeMappings")):
ignores = eval("g:UltiSnipsMappingsToIgnore") + ['UltiSnips']
for option in ("<buffer>", ""):
"""
if int(eval('g:UltiSnipsRemoveSelectModeMappings')):
ignores = eval('g:UltiSnipsMappingsToIgnore') + ['UltiSnips']
for option in ('<buffer>', ''):
# Put all smaps into a var, and then read the var
command(r"redir => _tmp_smaps | silent smap %s " % option +
"| redir END")
'| redir END')
# Check if any mappings where found
all_maps = list(filter(len, eval(r"_tmp_smaps").splitlines()))
if len(all_maps) == 1 and all_maps[0][0] not in " sv":
if len(all_maps) == 1 and all_maps[0][0] not in ' sv':
# "No maps found". String could be localized. Hopefully
# it doesn't start with any of these letters in any
# language
@ -172,37 +190,38 @@ def _unmap_select_mode_mapping():
# Only keep mappings that should not be ignored
maps = [m for m in all_maps if
not any(i in m for i in ignores) and len(m.strip())]
not any(i in m for i in ignores) and len(m.strip())]
for map in maps:
# The first three chars are the modes, that might be listed.
# We are not interested in them here.
trig = map[3:].split()[0] if len(map[3:].split()) != 0 else None
trig = map[3:].split()[0] if len(
map[3:].split()) != 0 else None
if trig is None:
continue
# The bar separates commands
if trig[-1] == "|":
trig = trig[:-1] + "<Bar>"
if trig[-1] == '|':
trig = trig[:-1] + '<Bar>'
# Special ones
if trig[0] == "<":
if trig[0] == '<':
add = False
# Only allow these
for valid in ["Tab", "NL", "CR", "C-Tab", "BS"]:
if trig == "<%s>" % valid:
for valid in ['Tab', 'NL', 'CR', 'C-Tab', 'BS']:
if trig == '<%s>' % valid:
add = True
if not add:
continue
# UltiSnips remaps <BS>. Keep this around.
if trig == "<BS>":
if trig == '<BS>':
continue
# Actually unmap it
try:
command("silent! sunmap %s %s" % (option, trig))
command('silent! sunmap %s %s' % (option, trig))
except: # pylint:disable=bare-except
# Bug 908139: ignore unmaps that fail because of
# unprintable characters. This is not ideal because we
@ -214,16 +233,19 @@ def _unmap_select_mode_mapping():
# though.
pass
class _RealLangMapTranslator(object):
"""This cares for the Vim langmap option and basically reverses the
mappings. This was the only solution to get UltiSnips to work nicely with
langmap; other stuff I tried was using inoremap movement commands and
caching and restoring the langmap option.
Note that this will not work if the langmap overwrites a character
completely, for example if 'j' is remapped, but nothing is mapped back to
'j', then moving one line down is no longer possible and UltiSnips will
fail.
completely, for example if 'j' is remapped, but nothing is mapped
back to 'j', then moving one line down is no longer possible and
UltiSnips will fail.
"""
_maps = {}
_SEMICOLONS = re.compile(r"(?<!\\);")
@ -231,12 +253,12 @@ class _RealLangMapTranslator(object):
def _create_translation(self, langmap):
"""Create the reverse mapping from 'langmap'."""
from_chars, to_chars = "", ""
from_chars, to_chars = '', ''
for char in self._COMMA.split(langmap):
char = char.replace("\\,", ",")
char = char.replace('\\,', ',')
res = self._SEMICOLONS.split(char)
if len(res) > 1:
from_char, to_char = [a.replace("\\;", ";") for a in res]
from_char, to_char = [a.replace('\\;', ';') for a in res]
from_chars += from_char
to_chars += to_char
else:
@ -246,8 +268,8 @@ class _RealLangMapTranslator(object):
def translate(self, text):
"""Inverse map 'text' through langmap."""
langmap = eval("&langmap").strip()
if langmap == "":
langmap = eval('&langmap').strip()
if langmap == '':
return text
text = as_unicode(text)
if langmap not in self._maps:
@ -256,9 +278,14 @@ class _RealLangMapTranslator(object):
text = text.replace(before, after)
return text
class _DummyLangMapTranslator(object):
"""If vim hasn't got the langmap compiled in, we never have to do anything.
Then this class is used. """
Then this class is used.
"""
translate = lambda self, s: s
_LangMapTranslator = _RealLangMapTranslator

View File

@ -1,10 +1,8 @@
#!/usr/bin/env python
# encoding: utf-8
"""
This file contains compatibility code to stay compatible with
as many python versions as possible.
"""
"""This file contains compatibility code to stay compatible with as many python
versions as possible."""
import sys
@ -16,34 +14,30 @@ if sys.version_info >= (3, 0):
# We don't have the luxury here of failing, everything
# falls apart if we don't return a bytearray from the
# passed in string
return string.decode(vim.eval("&encoding"), "replace")
return string.decode(vim.eval('&encoding'), 'replace')
def _vim_enc(bytearray):
"""Encode 'string' using &encoding."""
# We don't have the luxury here of failing, everything
# falls apart if we don't return a string from the passed
# in bytearray
return bytearray.encode(vim.eval("&encoding"), "replace")
return bytearray.encode(vim.eval('&encoding'), 'replace')
def open_ascii_file(filename, mode):
"""Opens a file in "r" mode."""
return open(filename, mode, encoding="utf-8")
return open(filename, mode, encoding='utf-8')
def col2byte(line, col):
"""
Convert a valid column index into a byte index inside
of vims buffer.
"""
"""Convert a valid column index into a byte index inside of vims
buffer."""
# We pad the line so that selecting the +1 st column still works.
pre_chars = (vim.current.buffer[line-1] + " ")[:col]
pre_chars = (vim.current.buffer[line - 1] + ' ')[:col]
return len(_vim_enc(pre_chars))
def byte2col(line, nbyte):
"""
Convert a column into a byteidx suitable for a mark or cursor
position inside of vim
"""
line = vim.current.buffer[line-1]
"""Convert a column into a byteidx suitable for a mark or cursor
position inside of vim."""
line = vim.current.buffer[line - 1]
raw_bytes = _vim_enc(line)[:nbyte]
return len(_vim_dec(raw_bytes))
@ -58,12 +52,12 @@ if sys.version_info >= (3, 0):
return string
else:
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
warnings.filterwarnings('ignore', category=DeprecationWarning)
def _vim_dec(string):
"""Decode 'string' using &encoding."""
try:
return string.decode(vim.eval("&encoding"))
return string.decode(vim.eval('&encoding'))
except UnicodeDecodeError:
# At least we tried. There might be some problems down the road now
return string
@ -71,7 +65,7 @@ else:
def _vim_enc(string):
"""Encode 'string' using &encoding."""
try:
return string.encode(vim.eval("&encoding"))
return string.encode(vim.eval('&encoding'))
except UnicodeDecodeError:
return string
except UnicodeEncodeError:
@ -82,21 +76,17 @@ else:
return open(filename, mode)
def col2byte(line, col):
"""
Convert a valid column index into a byte index inside
of vims buffer.
"""
"""Convert a valid column index into a byte index inside of vims
buffer."""
# We pad the line so that selecting the +1 st column still works.
pre_chars = _vim_dec(vim.current.buffer[line-1] + " ")[:col]
pre_chars = _vim_dec(vim.current.buffer[line - 1] + ' ')[:col]
return len(_vim_enc(pre_chars))
def byte2col(line, nbyte):
"""
Convert a column into a byteidx suitable for a mark or cursor
position inside of vim
"""
line = vim.current.buffer[line-1]
if nbyte >= len(line): # This is beyond end of line
"""Convert a column into a byteidx suitable for a mark or cursor
position inside of vim."""
line = vim.current.buffer[line - 1]
if nbyte >= len(line): # This is beyond end of line
return nbyte
return len(_vim_dec(line[:nbyte]))

View File

@ -1,17 +1,21 @@
#!/usr/bin/env python
# encoding: utf-8
"""Convenience methods that help with debugging. They should never be used in
production code."""
"""Convenience methods that help with debugging.
They should never be used in production code.
"""
import sys
from UltiSnips.compatibility import as_unicode
DUMP_FILENAME = "/tmp/file.txt" if not sys.platform.lower().startswith("win") \
else "C:/windows/temp/ultisnips.txt"
with open(DUMP_FILENAME, "w"):
pass # clears the file
DUMP_FILENAME = '/tmp/file.txt' if not sys.platform.lower().startswith('win') \
else 'C:/windows/temp/ultisnips.txt'
with open(DUMP_FILENAME, 'w'):
pass # clears the file
def echo_to_hierarchy(text_object):
"""Outputs the given 'text_object' and its children hierarchically."""
@ -20,24 +24,26 @@ def echo_to_hierarchy(text_object):
while parent._parent:
parent = parent._parent
def _do_print(text_object, indent=""):
def _do_print(text_object, indent=''):
"""prints recursively."""
debug(indent + as_unicode(text_object))
try:
for child in text_object._children:
_do_print(child, indent=indent + " ")
_do_print(child, indent=indent + ' ')
except AttributeError:
pass
_do_print(parent)
def debug(msg):
"""Dumb 'msg' into the debug file."""
msg = as_unicode(msg)
with open(DUMP_FILENAME, "ab") as dump_file:
dump_file.write((msg + '\n').encode("utf-8"))
with open(DUMP_FILENAME, 'ab') as dump_file:
dump_file.write((msg + '\n').encode('utf-8'))
def print_stack():
"""Dump a stack trace into the debug file."""
import traceback
with open(DUMP_FILENAME, "ab") as dump_file:
with open(DUMP_FILENAME, 'ab') as dump_file:
traceback.print_stack(file=dump_file)

View File

@ -5,35 +5,38 @@
from UltiSnips import _vim
class IndentUtil(object):
"""Utility class for dealing properly with indentation. """
"""Utility class for dealing properly with indentation."""
def __init__(self):
self.reset()
def reset(self):
""" Gets the spacing properties from Vim. """
self.shiftwidth = int(_vim.eval("exists('*shiftwidth') ? shiftwidth() : &shiftwidth"))
self._expandtab = (_vim.eval("&expandtab") == "1")
self._tabstop = int(_vim.eval("&tabstop"))
"""Gets the spacing properties from Vim."""
self.shiftwidth = int(
_vim.eval("exists('*shiftwidth') ? shiftwidth() : &shiftwidth"))
self._expandtab = (_vim.eval('&expandtab') == '1')
self._tabstop = int(_vim.eval('&tabstop'))
def ntabs_to_proper_indent(self, ntabs):
"""Convert 'ntabs' number of tabs to the proper indent prefix."""
line_ind = ntabs * self.shiftwidth * " "
line_ind = ntabs * self.shiftwidth * ' '
line_ind = self.indent_to_spaces(line_ind)
line_ind = self.spaces_to_indent(line_ind)
return line_ind
def indent_to_spaces(self, indent):
""" Converts indentation to spaces respecting Vim settings. """
"""Converts indentation to spaces respecting Vim settings."""
indent = indent.expandtabs(self._tabstop)
right = (len(indent) - len(indent.rstrip(" "))) * " "
indent = indent.replace(" ", "")
indent = indent.replace('\t', " " * self._tabstop)
right = (len(indent) - len(indent.rstrip(' '))) * ' '
indent = indent.replace(' ', '')
indent = indent.replace('\t', ' ' * self._tabstop)
return indent + right
def spaces_to_indent(self, indent):
""" Converts spaces to proper indentation respecting Vim settings """
"""Converts spaces to proper indentation respecting Vim settings."""
if not self._expandtab:
indent = indent.replace(" " * self._tabstop, '\t')
indent = indent.replace(' ' * self._tabstop, '\t')
return indent

View File

@ -4,7 +4,9 @@
"""Represents a Position in a text file: (0 based line index, 0 based column
index) and provides methods for moving them around."""
class Position(object):
"""See module docstring."""
def __init__(self, line, col):
@ -13,7 +15,7 @@ class Position(object):
def move(self, pivot, delta):
"""'pivot' is the position of the first changed character, 'delta' is
how text after it moved"""
how text after it moved."""
if self < pivot:
return
if delta.line == 0:
@ -62,4 +64,4 @@ class Position(object):
return (self.line, self.col) <= (other.line, other.col)
def __repr__(self):
return "(%i,%i)" % (self.line, self.col)
return '(%i,%i)' % (self.line, self.col)

View File

@ -11,10 +11,12 @@ from UltiSnips.indent_util import IndentUtil
from UltiSnips.text import escape
from UltiSnips.text_objects import SnippetInstance
def _words_for_line(trigger, before, num_words=None):
""" Gets the final 'num_words' words from 'before'.
If num_words is None, then use the number of words in
'trigger'.
"""Gets the final 'num_words' words from 'before'.
If num_words is None, then use the number of words in 'trigger'.
"""
if not len(before):
return ''
@ -32,20 +34,22 @@ def _words_for_line(trigger, before, num_words=None):
before_words = before_words[:left]
return before[len(before_words):].strip()
class SnippetDefinition(object):
"""Represents a snippet as parsed from a file."""
_INDENT = re.compile(r"^[ \t]*")
_TABS = re.compile(r"^\t*")
def __init__(self, priority, trigger, value, description,
options, globals, location):
options, globals, location):
self._priority = priority
self._trigger = as_unicode(trigger)
self._value = as_unicode(value)
self._description = as_unicode(description)
self._opts = options
self._matched = ""
self._matched = ''
self._last_re = None
self._globals = globals
self._location = location
@ -55,12 +59,14 @@ class SnippetDefinition(object):
self.matches(self._trigger)
def __repr__(self):
return "_SnippetDefinition(%r,%s,%s,%s)" % (
self._priority, self._trigger, self._description, self._opts)
return '_SnippetDefinition(%r,%s,%s,%s)' % (
self._priority, self._trigger, self._description, self._opts)
def _re_match(self, trigger):
""" Test if a the current regex trigger matches
`trigger`. If so, set _last_re and _matched.
"""Test if a the current regex trigger matches `trigger`.
If so, set _last_re and _matched.
"""
for match in re.finditer(self._trigger, trigger):
if match.end() != len(trigger):
@ -73,13 +79,13 @@ class SnippetDefinition(object):
return False
def has_option(self, opt):
""" Check if the named option is set """
"""Check if the named option is set."""
return opt in self._opts
@property
def description(self):
"""Descriptive text for this snippet."""
return ("(%s) %s" % (self._trigger, self._description)).strip()
return ('(%s) %s' % (self._trigger, self._description)).strip()
@property
def priority(self):
@ -109,7 +115,7 @@ class SnippetDefinition(object):
# error, but if permitted it seems that "w" should take precedence
# (since matching at word boundary and within a word == matching at word
# boundary).
self._matched = ""
self._matched = ''
# Don't expand on whitespace
if trigger and trigger.rstrip() != trigger:
@ -117,19 +123,21 @@ class SnippetDefinition(object):
words = _words_for_line(self._trigger, trigger)
if "r" in self._opts:
if 'r' in self._opts:
match = self._re_match(trigger)
elif "w" in self._opts:
elif 'w' in self._opts:
words_len = len(self._trigger)
words_prefix = words[:-words_len]
words_suffix = words[-words_len:]
match = (words_suffix == self._trigger)
if match and words_prefix:
# Require a word boundary between prefix and suffix.
boundary_chars = escape(words_prefix[-1:] + \
words_suffix[:1], r'\"')
match = _vim.eval('"%s" =~# "\\\\v.<."' % boundary_chars) != '0'
elif "i" in self._opts:
boundary_chars = escape(words_prefix[-1:] +
words_suffix[:1], r'\"')
match = _vim.eval(
'"%s" =~# "\\\\v.<."' %
boundary_chars) != '0'
elif 'i' in self._opts:
match = words.endswith(self._trigger)
else:
match = (words == self._trigger)
@ -139,33 +147,33 @@ class SnippetDefinition(object):
self._matched = self._trigger
# Ensure the match was on a word boundry if needed
if "b" in self._opts and match:
if 'b' in self._opts and match:
text_before = trigger.rstrip()[:-len(self._matched)]
if text_before.strip(" \t") != '':
self._matched = ""
if text_before.strip(' \t') != '':
self._matched = ''
return False
return match
def could_match(self, trigger):
"""Return True if this snippet could match the (partial) 'trigger'."""
self._matched = ""
self._matched = ''
# List all on whitespace.
if trigger and trigger[-1] in (" ", "\t"):
trigger = ""
if trigger and trigger[-1] in (' ', '\t'):
trigger = ''
if trigger and trigger.rstrip() is not trigger:
return False
words = _words_for_line(self._trigger, trigger)
if "r" in self._opts:
if 'r' in self._opts:
# Test for full match only
match = self._re_match(trigger)
elif "w" in self._opts:
elif 'w' in self._opts:
# Trim non-empty prefix up to word boundary, if present.
qwords = escape(words, r'\"')
words_suffix = _vim.eval(
'substitute("%s", "\\\\v^.+<(.+)", "\\\\1", "")' % qwords)
'substitute("%s", "\\\\v^.+<(.+)", "\\\\1", "")' % qwords)
match = self._trigger.startswith(words_suffix)
self._matched = words_suffix
@ -173,7 +181,7 @@ class SnippetDefinition(object):
# matches yet, so for now fail if we trimmed the prefix.
if words_suffix != words:
match = False
elif "i" in self._opts:
elif 'i' in self._opts:
# TODO: It is hard to define when a inword snippet could match,
# therefore we check only for full-word trigger.
match = self._trigger.startswith(words)
@ -185,10 +193,10 @@ class SnippetDefinition(object):
self._matched = words
# Ensure the match was on a word boundry if needed
if "b" in self._opts and match:
if 'b' in self._opts and match:
text_before = trigger.rstrip()[:-len(self._matched)]
if text_before.strip(" \t") != '':
self._matched = ""
if text_before.strip(' \t') != '':
self._matched = ''
return False
return match
@ -200,16 +208,19 @@ class SnippetDefinition(object):
def launch(self, text_before, visual_content, parent, start, end):
"""Launch this snippet, overwriting the text 'start' to 'end' and
keeping the 'text_before' on the launch line. 'Parent' is the parent
snippet instance if any."""
keeping the 'text_before' on the launch line.
'Parent' is the parent snippet instance if any.
"""
indent = self._INDENT.match(text_before).group(0)
lines = (self._value + "\n").splitlines()
lines = (self._value + '\n').splitlines()
ind_util = IndentUtil()
# Replace leading tabs in the snippet definition via proper indenting
initial_text = []
for line_num, line in enumerate(lines):
if "t" in self._opts:
if 't' in self._opts:
tabs = 0
else:
tabs = len(self._TABS.match(line).group(0))
@ -221,8 +232,8 @@ class SnippetDefinition(object):
initial_text = '\n'.join(initial_text)
snippet_instance = SnippetInstance(
self, parent, initial_text, start, end, visual_content,
last_re=self._last_re, globals=self._globals)
self, parent, initial_text, start, end, visual_content,
last_re=self._last_re, globals=self._globals)
self.instantiate(snippet_instance, initial_text, indent)
snippet_instance.update_textobjects()

View File

@ -6,14 +6,16 @@
from UltiSnips.snippet.definition._base import SnippetDefinition
from UltiSnips.snippet.parsing.snipmate import parse_and_instantiate
class SnipMateSnippetDefinition(SnippetDefinition):
"""See module doc."""
SNIPMATE_SNIPPET_PRIORITY = -1000
def __init__(self, trigger, value, description, location):
SnippetDefinition.__init__(self, self.SNIPMATE_SNIPPET_PRIORITY,
trigger, value, description, "", {}, location)
trigger, value, description, '', {}, location)
def instantiate(self, snippet_instance, initial_text, indent):
parse_and_instantiate(snippet_instance, initial_text, indent)

View File

@ -6,7 +6,9 @@
from UltiSnips.snippet.definition._base import SnippetDefinition
from UltiSnips.snippet.parsing.ultisnips import parse_and_instantiate
class UltiSnipsSnippetDefinition(SnippetDefinition):
"""See module doc."""
def instantiate(self, snippet_instance, initial_text, indent):

View File

@ -7,14 +7,19 @@ from UltiSnips.position import Position
from UltiSnips.snippet.parsing._lexer import tokenize, TabStopToken
from UltiSnips.text_objects import TabStop
def tokenize_snippet_text(snippet_instance, text, indent,
allowed_tokens_in_text, allowed_tokens_in_tabstops,
token_to_textobject):
allowed_tokens_in_text, allowed_tokens_in_tabstops,
token_to_textobject):
"""Turns 'text' into a stream of tokens and creates the text objects from
those tokens that are mentioned in 'token_to_textobject' assuming the
current 'indent'. The 'allowed_tokens_in_text' define which tokens will be
recognized in 'text' while 'allowed_tokens_in_tabstops' are the tokens that
will be recognized in TabStop placeholder text."""
current 'indent'.
The 'allowed_tokens_in_text' define which tokens will be recognized
in 'text' while 'allowed_tokens_in_tabstops' are the tokens that
will be recognized in TabStop placeholder text.
"""
seen_ts = {}
all_tokens = []
@ -27,7 +32,7 @@ def tokenize_snippet_text(snippet_instance, text, indent,
ts = TabStop(parent, token)
seen_ts[token.number] = ts
_do_parse(ts, token.initial_text,
allowed_tokens_in_tabstops)
allowed_tokens_in_tabstops)
else:
klass = token_to_textobject.get(token.__class__, None)
if klass is not None:
@ -35,11 +40,12 @@ def tokenize_snippet_text(snippet_instance, text, indent,
_do_parse(snippet_instance, text, allowed_tokens_in_text)
return all_tokens, seen_ts
def finalize(all_tokens, seen_ts, snippet_instance):
"""Adds a tabstop 0 if non is in 'seen_ts' and brings the text of the
snippet instance into Vim."""
if 0 not in seen_ts:
mark = all_tokens[-1][1].end # Last token is always EndOfText
mark = all_tokens[-1][1].end # Last token is always EndOfText
m1 = Position(mark.line, mark.col)
TabStop(snippet_instance, 0, mark, m1)
snippet_instance.replace_initial_text()

View File

@ -1,10 +1,8 @@
#!/usr/bin/env python
# encoding: utf-8
"""
Not really a lexer in the classical sense, but code to convert snippet
definitions into logical units called Tokens.
"""
"""Not really a lexer in the classical sense, but code to convert snippet
definitions into logical units called Tokens."""
import string
import re
@ -13,7 +11,9 @@ from UltiSnips.compatibility import as_unicode
from UltiSnips.position import Position
from UltiSnips.text import unescape
class _TextIterator(object):
"""Helper class to make iterating over text easier."""
def __init__(self, text, offset):
@ -44,7 +44,7 @@ class _TextIterator(object):
def peek(self, count=1):
"""Returns the next 'count' characters without advancing the stream."""
if count > 1: # This might return '' if nothing is found
if count > 1: # This might return '' if nothing is found
return self._text[self._idx:self._idx + count]
try:
return self._text[self._idx]
@ -56,17 +56,17 @@ class _TextIterator(object):
"""Current position in the text."""
return Position(self._line, self._col)
def _parse_number(stream):
"""
Expects the stream to contain a number next, returns the number
without consuming any more bytes
"""
rv = ""
"""Expects the stream to contain a number next, returns the number without
consuming any more bytes."""
rv = ''
while stream.peek() and stream.peek() in string.digits:
rv += next(stream)
return int(rv)
def _parse_till_closing_brace(stream):
"""
Returns all chars till a non-escaped } is found. Other
@ -74,7 +74,7 @@ def _parse_till_closing_brace(stream):
Will also consume the closing }, but not return it
"""
rv = ""
rv = ''
in_braces = 1
while True:
if EscapeCharToken.starts_here(stream, '{}'):
@ -90,6 +90,7 @@ def _parse_till_closing_brace(stream):
rv += char
return rv
def _parse_till_unescaped_char(stream, chars):
"""
Returns all chars till a non-escaped char is found.
@ -97,7 +98,7 @@ def _parse_till_unescaped_char(stream, chars):
Will also consume the closing char, but and return it as second
return value
"""
rv = ""
rv = ''
while True:
escaped = False
for char in chars:
@ -111,20 +112,24 @@ def _parse_till_unescaped_char(stream, chars):
rv += char
return rv, char
class Token(object):
"""Represents a Token as parsed from a snippet definition."""
def __init__(self, gen, indent):
self.initial_text = as_unicode("")
self.initial_text = as_unicode('')
self.start = gen.pos
self._parse(gen, indent)
self.end = gen.pos
def _parse(self, stream, indent):
"""Parses the token from 'stream' with the current 'indent'."""
pass # Does nothing
pass # Does nothing
class TabStopToken(Token):
"""${1:blub}"""
CHECK = re.compile(r'^\${\d+[:}]')
@ -135,21 +140,23 @@ class TabStopToken(Token):
return cls.CHECK.match(stream.peek(10)) is not None
def _parse(self, stream, indent):
next(stream) # $
next(stream) # {
next(stream) # $
next(stream) # {
self.number = _parse_number(stream)
if stream.peek() == ":":
if stream.peek() == ':':
next(stream)
self.initial_text = _parse_till_closing_brace(stream)
def __repr__(self):
return "TabStopToken(%r,%r,%r,%r)" % (
return 'TabStopToken(%r,%r,%r,%r)' % (
self.start, self.end, self.number, self.initial_text
)
class VisualToken(Token):
"""${VISUAL}"""
CHECK = re.compile(r"^\${VISUAL[:}/]")
@ -160,15 +167,15 @@ class VisualToken(Token):
return cls.CHECK.match(stream.peek(10)) is not None
def _parse(self, stream, indent):
for _ in range(8): # ${VISUAL
for _ in range(8): # ${VISUAL
next(stream)
if stream.peek() == ":":
if stream.peek() == ':':
next(stream)
self.alternative_text, char = _parse_till_unescaped_char(stream, '/}')
self.alternative_text = unescape(self.alternative_text)
if char == '/': # Transformation going on
if char == '/': # Transformation going on
try:
self.search = _parse_till_unescaped_char(stream, '/')[0]
self.replace = _parse_till_unescaped_char(stream, '/')[0]
@ -182,11 +189,13 @@ class VisualToken(Token):
self.options = None
def __repr__(self):
return "VisualToken(%r,%r)" % (
return 'VisualToken(%r,%r)' % (
self.start, self.end
)
class TransformationToken(Token):
"""${1/match/replace/options}"""
CHECK = re.compile(r'^\${\d+\/')
@ -198,24 +207,26 @@ class TransformationToken(Token):
return cls.CHECK.match(stream.peek(10)) is not None
def _parse(self, stream, indent):
next(stream) # $
next(stream) # {
next(stream) # $
next(stream) # {
self.number = _parse_number(stream)
next(stream) # /
next(stream) # /
self.search = _parse_till_unescaped_char(stream, '/')[0]
self.replace = _parse_till_unescaped_char(stream, '/')[0]
self.options = _parse_till_closing_brace(stream)
def __repr__(self):
return "TransformationToken(%r,%r,%r,%r,%r)" % (
return 'TransformationToken(%r,%r,%r,%r,%r)' % (
self.start, self.end, self.number, self.search, self.replace
)
class MirrorToken(Token):
"""$1"""
"""$1."""
CHECK = re.compile(r'^\$\d+')
@classmethod
@ -225,16 +236,18 @@ class MirrorToken(Token):
return cls.CHECK.match(stream.peek(10)) is not None
def _parse(self, stream, indent):
next(stream) # $
next(stream) # $
self.number = _parse_number(stream)
def __repr__(self):
return "MirrorToken(%r,%r,%r)" % (
return 'MirrorToken(%r,%r,%r)' % (
self.start, self.end, self.number
)
class EscapeCharToken(Token):
"""\\n"""
"""\\n."""
@classmethod
def starts_here(cls, stream, chars=r'{}\$`'):
"""Returns true if this token starts at the current position in
@ -244,15 +257,17 @@ class EscapeCharToken(Token):
return True
def _parse(self, stream, indent):
next(stream) # \
next(stream) # \
self.initial_text = next(stream)
def __repr__(self):
return "EscapeCharToken(%r,%r,%r)" % (
return 'EscapeCharToken(%r,%r,%r)' % (
self.start, self.end, self.initial_text
)
class ShellCodeToken(Token):
"""`echo "hi"`"""
@classmethod
def starts_here(cls, stream):
@ -261,15 +276,17 @@ class ShellCodeToken(Token):
return stream.peek(1) == '`'
def _parse(self, stream, indent):
next(stream) # `
next(stream) # `
self.code = _parse_till_unescaped_char(stream, '`')[0]
def __repr__(self):
return "ShellCodeToken(%r,%r,%r)" % (
return 'ShellCodeToken(%r,%r,%r)' % (
self.start, self.end, self.code
)
class PythonCodeToken(Token):
"""`!p snip.rv = "Hi"`"""
CHECK = re.compile(r'^`!p\s')
@ -281,7 +298,7 @@ class PythonCodeToken(Token):
def _parse(self, stream, indent):
for _ in range(3):
next(stream) # `!p
next(stream) # `!p
if stream.peek() in '\t ':
next(stream)
@ -292,17 +309,19 @@ class PythonCodeToken(Token):
lines = code.splitlines()
self.code = lines[0] + '\n'
self.code += '\n'.join([l[len(indent):]
for l in lines[1:]])
for l in lines[1:]])
else:
self.code = code
self.indent = indent
def __repr__(self):
return "PythonCodeToken(%r,%r,%r)" % (
return 'PythonCodeToken(%r,%r,%r)' % (
self.start, self.end, self.code
)
class VimLCodeToken(Token):
"""`!v g:hi`"""
CHECK = re.compile(r'^`!v\s')
@ -314,18 +333,22 @@ class VimLCodeToken(Token):
def _parse(self, stream, indent):
for _ in range(4):
next(stream) # `!v
next(stream) # `!v
self.code = _parse_till_unescaped_char(stream, '`')[0]
def __repr__(self):
return "VimLCodeToken(%r,%r,%r)" % (
return 'VimLCodeToken(%r,%r,%r)' % (
self.start, self.end, self.code
)
class EndOfTextToken(Token):
"""Appears at the end of the text."""
def __repr__(self):
return "EndOfText(%r)" % self.end
return 'EndOfText(%r)' % self.end
def tokenize(text, indent, offset, allowed_tokens):
"""Returns an iterator of tokens of 'text'['offset':] which is assumed to

View File

@ -22,18 +22,24 @@ __ALLOWED_TOKENS_IN_TABSTOPS = [
EscapeCharToken, VisualToken, MirrorToken, ShellCodeToken
]
def _create_mirrors(all_tokens, seen_ts):
"""Now that all tabstops are known, we can create mirrors."""
for parent, token in all_tokens:
if isinstance(token, MirrorToken):
Mirror(parent, seen_ts[token.number], token)
def parse_and_instantiate(parent_to, text, indent):
"""Parses a snippet definition in snipMate format from 'text' assuming the
current 'indent'. Will instantiate all the objects and link them as
children to parent_to. Will also put the initial text into Vim."""
current 'indent'.
Will instantiate all the objects and link them as children to
parent_to. Will also put the initial text into Vim.
"""
all_tokens, seen_ts = tokenize_snippet_text(parent_to, text, indent,
__ALLOWED_TOKENS, __ALLOWED_TOKENS_IN_TABSTOPS,
_TOKEN_TO_TEXTOBJECT)
__ALLOWED_TOKENS, __ALLOWED_TOKENS_IN_TABSTOPS,
_TOKEN_TO_TEXTOBJECT)
_create_mirrors(all_tokens, seen_ts)
finalize(all_tokens, seen_ts, parent_to)

View File

@ -8,7 +8,7 @@ from UltiSnips.snippet.parsing._lexer import EscapeCharToken, \
VisualToken, TransformationToken, TabStopToken, MirrorToken, \
PythonCodeToken, VimLCodeToken, ShellCodeToken
from UltiSnips.text_objects import EscapedChar, Mirror, PythonCode, \
ShellCode, TabStop, Transformation, VimLCode, Visual
ShellCode, TabStop, Transformation, VimLCode, Visual
_TOKEN_TO_TEXTOBJECT = {
EscapeCharToken: EscapedChar,
@ -23,8 +23,13 @@ __ALLOWED_TOKENS = [
MirrorToken, PythonCodeToken, VimLCodeToken, ShellCodeToken
]
def _resolve_ambiguity(all_tokens, seen_ts):
"""$1 could be a Mirror or a TabStop. This figures this out."""
"""$1 could be a Mirror or a TabStop.
This figures this out.
"""
for parent, token in all_tokens:
if isinstance(token, MirrorToken):
if token.number not in seen_ts:
@ -32,23 +37,28 @@ def _resolve_ambiguity(all_tokens, seen_ts):
else:
Mirror(parent, seen_ts[token.number], token)
def _create_transformations(all_tokens, seen_ts):
"""Create the objects that need to know about tabstops."""
for parent, token in all_tokens:
if isinstance(token, TransformationToken):
if token.number not in seen_ts:
raise RuntimeError(
"Tabstop %i is not known but is used by a Transformation"
'Tabstop %i is not known but is used by a Transformation'
% token.number)
Transformation(parent, seen_ts[token.number], token)
def parse_and_instantiate(parent_to, text, indent):
"""Parses a snippet definition in UltiSnips format from 'text' assuming the
current 'indent'. Will instantiate all the objects and link them as
children to parent_to. Will also put the initial text into Vim."""
current 'indent'.
Will instantiate all the objects and link them as children to
parent_to. Will also put the initial text into Vim.
"""
all_tokens, seen_ts = tokenize_snippet_text(parent_to, text, indent,
__ALLOWED_TOKENS, __ALLOWED_TOKENS, _TOKEN_TO_TEXTOBJECT)
__ALLOWED_TOKENS, __ALLOWED_TOKENS, _TOKEN_TO_TEXTOBJECT)
_resolve_ambiguity(all_tokens, seen_ts)
_create_transformations(all_tokens, seen_ts)
finalize(all_tokens, seen_ts, parent_to)

View File

@ -7,7 +7,9 @@ from collections import defaultdict
from UltiSnips.snippet.source._snippet_dictionary import SnippetDictionary
class SnippetSource(object):
"""See module docstring."""
def __init__(self):
@ -15,25 +17,25 @@ class SnippetSource(object):
self._extends = defaultdict(set)
def ensure(self, filetypes):
"""Update/reload the snippets in the source when needed. It makes sure
that the snippets are not outdated.
"""Update/reload the snippets in the source when needed.
It makes sure that the snippets are not outdated.
"""
pass
def _get_existing_deep_extends(self, base_filetypes):
"""Helper for get all existing filetypes extended by base
filetypes.
"""
"""Helper for get all existing filetypes extended by base filetypes."""
deep_extends = self.get_deep_extends(base_filetypes)
return [ft for ft in deep_extends if ft in self._snippets]
def get_snippets(self, filetypes, before, possible):
"""Returns the snippets for all 'filetypes' (in order) and their parents
matching the text 'before'. If 'possible' is true, a partial match is
enough. Base classes can override this method to provide means of
creating snippets on the fly.
"""Returns the snippets for all 'filetypes' (in order) and their
parents matching the text 'before'. If 'possible' is true, a partial
match is enough. Base classes can override this method to provide means
of creating snippets on the fly.
Returns a list of SnippetDefinition s.
"""
result = []
for ft in self._get_existing_deep_extends(filetypes):
@ -43,7 +45,10 @@ class SnippetSource(object):
def get_clear_priority(self, filetypes):
"""Get maximum clearsnippets priority without arguments for specified
filetypes, if any. It returns None if there are no clearsnippets.
filetypes, if any.
It returns None if there are no clearsnippets.
"""
pri = None
for ft in self._get_existing_deep_extends(filetypes):
@ -54,8 +59,7 @@ class SnippetSource(object):
def get_cleared(self, filetypes):
"""Get a set of cleared snippets marked by clearsnippets with arguments
for specified filetypes.
"""
for specified filetypes."""
cleared = {}
for ft in self._get_existing_deep_extends(filetypes):
snippets = self._snippets[ft]
@ -65,21 +69,23 @@ class SnippetSource(object):
return cleared
def update_extends(self, child_ft, parent_fts):
"""Update the extending relation by given child filetype and
its parent filetypes.
"""
"""Update the extending relation by given child filetype and its parent
filetypes."""
self._extends[child_ft].update(parent_fts)
def get_deep_extends(self, base_filetypes):
"""Get a list of filetypes that is either directed or indirected
extended by given base filetypes. Note that the returned list
include the root filetype itself.
extended by given base filetypes.
Note that the returned list include the root filetype itself.
"""
seen = set(base_filetypes)
todo_fts = list(set(base_filetypes))
while todo_fts:
todo_ft = todo_fts.pop()
unseen_extends = set(ft for ft in self._extends[todo_ft] if ft not in seen)
unseen_extends = set(
ft for ft in self._extends[todo_ft] if ft not in seen)
seen.update(unseen_extends)
todo_fts.extend(unseen_extends)
return seen

View File

@ -3,7 +3,9 @@
"""Implements a container for parsed snippets."""
class SnippetDictionary(object):
"""See module docstring."""
def __init__(self):
@ -16,8 +18,11 @@ class SnippetDictionary(object):
self._snippets.append(snippet)
def get_matching_snippets(self, trigger, potentially):
"""Returns all snippets matching the given trigger. If 'potentially' is
true, returns all that could_match()."""
"""Returns all snippets matching the given trigger.
If 'potentially' is true, returns all that could_match().
"""
all_snippets = self._snippets
if not potentially:
return [s for s in all_snippets if s.matches(trigger)]
@ -25,8 +30,12 @@ class SnippetDictionary(object):
return [s for s in all_snippets if s.could_match(trigger)]
def clear_snippets(self, priority, triggers):
"""Clear the snippets by mark them as cleared. If trigger is
None, it updates the value of clear priority instead."""
"""Clear the snippets by mark them as cleared.
If trigger is None, it updates the value of clear priority
instead.
"""
if not triggers:
if self._clear_priority is None or priority > self._clear_priority:
self._clear_priority = priority

View File

@ -5,7 +5,9 @@
from UltiSnips.snippet.source._base import SnippetSource
class AddedSnippetsSource(SnippetSource):
"""See module docstring."""
def add_snippet(self, ft, snippet):

View File

@ -11,19 +11,25 @@ from UltiSnips import _vim
from UltiSnips import compatibility
from UltiSnips.snippet.source._base import SnippetSource
def _hash_file(path):
"""Returns a hashdigest of 'path'"""
"""Returns a hashdigest of 'path'."""
if not os.path.isfile(path):
return False
return hashlib.sha1(open(path, "rb").read()).hexdigest()
return hashlib.sha1(open(path, 'rb').read()).hexdigest()
class SnippetSyntaxError(RuntimeError):
"""Thrown when a syntax error is found in a file."""
def __init__(self, filename, line_index, msg):
RuntimeError.__init__(self, "%s in %s:%d" % (
RuntimeError.__init__(self, '%s in %s:%d' % (
msg, filename, line_index))
class SnippetFileSource(SnippetSource):
"""Base class that abstracts away 'extends' info and file hashes."""
def __init__(self):
@ -74,23 +80,23 @@ class SnippetFileSource(SnippetSource):
"""Parse the 'filename' for the given 'ft' and watch it for changes in
the future."""
self._file_hashes[filename] = _hash_file(filename)
file_data = compatibility.open_ascii_file(filename, "r").read()
file_data = compatibility.open_ascii_file(filename, 'r').read()
for event, data in self._parse_snippet_file(file_data, filename):
if event == "error":
if event == 'error':
msg, line_index = data
filename = _vim.eval("""fnamemodify(%s, ":~:.")""" %
_vim.escape(filename))
_vim.escape(filename))
raise SnippetSyntaxError(filename, line_index, msg)
elif event == "clearsnippets":
elif event == 'clearsnippets':
priority, triggers = data
self._snippets[ft].clear_snippets(priority, triggers)
elif event == "extends":
elif event == 'extends':
# TODO(sirver): extends information is more global
# than one snippet source.
filetypes, = data
self.update_extends(ft, filetypes)
elif event == "snippet":
elif event == 'snippet':
snippet, = data
self._snippets[ft].add_snippet(snippet)
else:
assert False, "Unhandled %s: %r" % (event, data)
assert False, 'Unhandled %s: %r' % (event, data)

View File

@ -3,9 +3,10 @@
"""Common code for snipMate and UltiSnips snippet files."""
def handle_extends(tail, line_index):
"""Handles an extends line in a snippet."""
if tail:
return "extends", ([p.strip() for p in tail.split(',')],)
return 'extends', ([p.strip() for p in tail.split(',')],)
else:
return "error", ("'extends' without file types", line_index)
return 'error', ("'extends' without file types", line_index)

View File

@ -12,17 +12,18 @@ from UltiSnips.snippet.source.file._base import SnippetFileSource
from UltiSnips.snippet.source.file._common import handle_extends
from UltiSnips.text import LineIterator, head_tail
def _splitall(path):
"""Split 'path' into all its components."""
# From http://my.safaribooksonline.com/book/programming/
# python/0596001673/files/pythoncook-chp-4-sect-16
allparts = []
while 1:
while True:
parts = os.path.split(path)
if parts[0] == path: # sentinel for absolute paths
allparts.insert(0, parts[0])
break
elif parts[1] == path: # sentinel for relative paths
elif parts[1] == path: # sentinel for relative paths
allparts.insert(0, parts[1])
break
else:
@ -30,46 +31,49 @@ def _splitall(path):
allparts.insert(0, parts[1])
return allparts
def snipmate_files_for(ft):
"""Returns all snipMate files we need to look at for 'ft'."""
if ft == "all":
ft = "_"
if ft == 'all':
ft = '_'
patterns = [
"%s.snippets" % ft,
os.path.join(ft, "*.snippets"),
os.path.join(ft, "*.snippet"),
os.path.join(ft, "*/*.snippet"),
'%s.snippets' % ft,
os.path.join(ft, '*.snippets'),
os.path.join(ft, '*.snippet'),
os.path.join(ft, '*/*.snippet'),
]
ret = set()
for rtp in _vim.eval("&runtimepath").split(','):
for rtp in _vim.eval('&runtimepath').split(','):
path = os.path.realpath(os.path.expanduser(
os.path.join(rtp, "snippets")))
os.path.join(rtp, 'snippets')))
for pattern in patterns:
for fn in glob.glob(os.path.join(path, pattern)):
ret.add(fn)
return ret
def _parse_snippet_file(content, full_filename):
"""Parses 'content' assuming it is a .snippet file and yields events."""
filename = full_filename[:-len(".snippet")] # strip extension
filename = full_filename[:-len('.snippet')] # strip extension
segments = _splitall(filename)
segments = segments[segments.index("snippets")+1:]
segments = segments[segments.index('snippets') + 1:]
assert len(segments) in (2, 3)
trigger = segments[1]
description = segments[2] if 2 < len(segments) else ""
description = segments[2] if 2 < len(segments) else ''
# Chomp \n if any.
if content and content.endswith(os.linesep):
content = content[:-len(os.linesep)]
yield "snippet", (SnipMateSnippetDefinition(trigger, content,
description, full_filename),)
yield 'snippet', (SnipMateSnippetDefinition(trigger, content,
description, full_filename),)
def _parse_snippet(line, lines, filename):
"""Parse a snippet defintions."""
start_line_index = lines.line_index
trigger, description = head_tail(line[len("snippet"):].lstrip())
content = ""
trigger, description = head_tail(line[len('snippet'):].lstrip())
content = ''
while True:
next_line = lines.peek()
if next_line is None:
@ -81,34 +85,41 @@ def _parse_snippet(line, lines, filename):
line = line[1:]
content += line
content = content[:-1] # Chomp the last newline
return "snippet", (SnipMateSnippetDefinition(
trigger, content, description, "%s:%i" % (filename, start_line_index)),)
return 'snippet', (SnipMateSnippetDefinition(
trigger, content, description, '%s:%i' % (filename, start_line_index)),)
def _parse_snippets_file(data, filename):
"""Parse 'data' assuming it is a .snippets file. Yields events in the
file."""
"""Parse 'data' assuming it is a .snippets file.
Yields events in the file.
"""
lines = LineIterator(data)
for line in lines:
if not line.strip():
continue
head, tail = head_tail(line)
if head == "extends":
if head == 'extends':
yield handle_extends(tail, lines.line_index)
elif head in "snippet":
elif head in 'snippet':
snippet = _parse_snippet(line, lines, filename)
if snippet is not None:
yield snippet
elif head and not head.startswith('#'):
yield "error", ("Invalid line %r" % line.rstrip(), lines.line_index)
yield 'error', ('Invalid line %r' % line.rstrip(), lines.line_index)
class SnipMateFileSource(SnippetFileSource):
"""Manages all snipMate snippet definitions found in rtp."""
def _get_all_snippet_files_for(self, ft):
return snipmate_files_for(ft)
def _parse_snippet_file(self, filedata, filename):
if filename.lower().endswith("snippet"):
if filename.lower().endswith('snippet'):
for event, data in _parse_snippet_file(filedata, filename):
yield event, data
else:

View File

@ -13,9 +13,10 @@ from UltiSnips.snippet.source.file._base import SnippetFileSource
from UltiSnips.snippet.source.file._common import handle_extends
from UltiSnips.text import LineIterator, head_tail
def find_snippet_files(ft, directory):
"""Returns all matching snippet files for 'ft' in 'directory'."""
patterns = ["%s.snippets", "%s_*.snippets", os.path.join("%s", "*")]
patterns = ['%s.snippets', '%s_*.snippets', os.path.join('%s', '*')]
ret = set()
directory = os.path.expanduser(directory)
for pattern in patterns:
@ -23,23 +24,24 @@ def find_snippet_files(ft, directory):
ret.add(os.path.realpath(fn))
return ret
def find_all_snippet_files(ft):
"""Returns all snippet files matching 'ft' in the given runtime path
directory."""
if _vim.eval("exists('b:UltiSnipsSnippetDirectories')") == "1":
snippet_dirs = _vim.eval("b:UltiSnipsSnippetDirectories")
if _vim.eval("exists('b:UltiSnipsSnippetDirectories')") == '1':
snippet_dirs = _vim.eval('b:UltiSnipsSnippetDirectories')
else:
snippet_dirs = _vim.eval("g:UltiSnipsSnippetDirectories")
snippet_dirs = _vim.eval('g:UltiSnipsSnippetDirectories')
patterns = ["%s.snippets", "%s_*.snippets", os.path.join("%s", "*")]
patterns = ['%s.snippets', '%s_*.snippets', os.path.join('%s', '*')]
ret = set()
for rtp in _vim.eval("&runtimepath").split(','):
for rtp in _vim.eval('&runtimepath').split(','):
for snippet_dir in snippet_dirs:
if snippet_dir == "snippets":
if snippet_dir == 'snippets':
raise RuntimeError(
"You have 'snippets' in UltiSnipsSnippetDirectories. This "
"directory is reserved for snipMate snippets. Use another "
"directory for UltiSnips snippets.")
'directory is reserved for snipMate snippets. Use another '
'directory for UltiSnips snippets.')
pth = os.path.realpath(os.path.expanduser(
os.path.join(rtp, snippet_dir)))
for pattern in patterns:
@ -47,11 +49,12 @@ def find_all_snippet_files(ft):
ret.add(fn)
return ret
def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
"""Parses the snippet that begins at the current line."""
start_line_index = lines.line_index
descr = ""
opts = ""
descr = ''
opts = ''
# Ensure this is a snippet
snip = line.split()[0]
@ -74,13 +77,13 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
# The rest is the trigger
trig = remain.strip()
if len(trig.split()) > 1 or "r" in opts:
if len(trig.split()) > 1 or 'r' in opts:
if trig[0] != trig[-1]:
return "error", ("Invalid multiword trigger: '%s'" % trig,
lines.line_index)
return 'error', ("Invalid multiword trigger: '%s'" % trig,
lines.line_index)
trig = trig[1:-1]
end = "end" + snip
content = ""
end = 'end' + snip
content = ''
found_end = False
for line in lines:
@ -91,20 +94,25 @@ def _handle_snippet_or_global(filename, line, lines, python_globals, priority):
content += line
if not found_end:
return "error", ("Missing 'endsnippet' for %r" % trig, lines.line_index)
return 'error', ("Missing 'endsnippet' for %r" %
trig, lines.line_index)
if snip == "global":
if snip == 'global':
python_globals[trig].append(content)
elif snip == "snippet":
return "snippet", (UltiSnipsSnippetDefinition(priority, trig, content,
descr, opts, python_globals,
"%s:%i" % (filename, start_line_index)),)
elif snip == 'snippet':
return 'snippet', (UltiSnipsSnippetDefinition(priority, trig, content,
descr, opts, python_globals,
'%s:%i' % (filename, start_line_index)),)
else:
return "error", ("Invalid snippet type: '%s'" % snip, lines.line_index)
return 'error', ("Invalid snippet type: '%s'" % snip, lines.line_index)
def _parse_snippets_file(data, filename):
"""Parse 'data' assuming it is a snippet file. Yields events in the
file."""
"""Parse 'data' assuming it is a snippet file.
Yields events in the file.
"""
python_globals = defaultdict(list)
lines = LineIterator(data)
@ -114,24 +122,26 @@ def _parse_snippets_file(data, filename):
continue
head, tail = head_tail(line)
if head in ("snippet", "global"):
if head in ('snippet', 'global'):
snippet = _handle_snippet_or_global(filename, line, lines,
python_globals, current_priority)
python_globals, current_priority)
if snippet is not None:
yield snippet
elif head == "extends":
elif head == 'extends':
yield handle_extends(tail, lines.line_index)
elif head == "clearsnippets":
yield "clearsnippets", (current_priority, tail.split())
elif head == "priority":
elif head == 'clearsnippets':
yield 'clearsnippets', (current_priority, tail.split())
elif head == 'priority':
try:
current_priority = int(tail.split()[0])
except (ValueError, IndexError):
yield "error", ("Invalid priority %r" % tail, lines.line_index)
yield 'error', ('Invalid priority %r' % tail, lines.line_index)
elif head and not head.startswith('#'):
yield "error", ("Invalid line %r" % line.rstrip(), lines.line_index)
yield 'error', ('Invalid line %r' % line.rstrip(), lines.line_index)
class UltiSnipsFileSource(SnippetFileSource):
"""Manages all snippets definitions found in rtp for ultisnips."""
def _get_all_snippet_files_for(self, ft):

View File

@ -15,21 +15,22 @@ from UltiSnips.compatibility import as_unicode
from UltiSnips.position import Position
from UltiSnips.snippet.definition import UltiSnipsSnippetDefinition
from UltiSnips.snippet.source import UltiSnipsFileSource, SnipMateFileSource, \
find_all_snippet_files, find_snippet_files, AddedSnippetsSource
find_all_snippet_files, find_snippet_files, AddedSnippetsSource
from UltiSnips.text import escape
from UltiSnips.vim_state import VimState, VisualContentPreserver
def _ask_user(a, formatted):
"""Asks the user using inputlist() and returns the selected element or
None."""
try:
rv = _vim.eval("inputlist(%s)" % _vim.escape(formatted))
rv = _vim.eval('inputlist(%s)' % _vim.escape(formatted))
if rv is None or rv == '0':
return None
rv = int(rv)
if rv > len(a):
rv = len(a)
return a[rv-1]
return a[rv - 1]
except _vim.error:
# Likely "invalid expression", but might be translated. We have no way
# of knowing the exact error, therefore, we ignore all errors silently.
@ -37,14 +38,15 @@ def _ask_user(a, formatted):
except KeyboardInterrupt:
return None
def _ask_snippets(snippets):
""" Given a list of snippets, ask the user which one they
want to use, and return it.
"""
display = [as_unicode("%i: %s (%s)") % (i+1, escape(s.description, '\\'),
escape(s.location, '\\')) for i, s in enumerate(snippets)]
"""Given a list of snippets, ask the user which one they want to use, and
return it."""
display = [as_unicode('%i: %s (%s)') % (i + 1, escape(s.description, '\\'),
escape(s.location, '\\')) for i, s in enumerate(snippets)]
return _ask_user(snippets, display)
def err_to_scratch_buffer(func):
"""Decorator that will catch any Exception that 'func' throws and displays
it in a new Vim scratch buffer."""
@ -52,9 +54,9 @@ def err_to_scratch_buffer(func):
def wrapper(self, *args, **kwds):
try:
return func(self, *args, **kwds)
except: # pylint: disable=bare-except
except: # pylint: disable=bare-except
msg = \
"""An error occured. This is either a bug in UltiSnips or a bug in a
"""An error occured. This is either a bug in UltiSnips or a bug in a
snippet definition. If you think this is a bug, please report it to
https://github.com/SirVer/ultisnips/issues/new.
@ -70,8 +72,12 @@ Following is the full stack trace:
# TODO(sirver): This class is still too long. It should only contain public
# facing methods, most of the private methods should be moved outside of it.
class SnippetManager(object):
"""The main entry point for all UltiSnips functionality. All Vim functions
call methods in this class."""
"""The main entry point for all UltiSnips functionality.
All Vim functions call methods in this class.
"""
def __init__(self, expand_trigger, forward_trigger, backward_trigger):
self.expand_trigger = expand_trigger
@ -89,48 +95,50 @@ class SnippetManager(object):
self._snippet_sources = []
self._added_snippets_source = AddedSnippetsSource()
self.register_snippet_source("ultisnips_files", UltiSnipsFileSource())
self.register_snippet_source("added", self._added_snippets_source)
self.register_snippet_source('ultisnips_files', UltiSnipsFileSource())
self.register_snippet_source('added', self._added_snippets_source)
enable_snipmate = True
if _vim.eval("exists('g:UltiSnipsEnableSnipMate')") == "1":
enable_snipmate = _vim.eval("g:UltiSnipsEnableSnipMate")
if enable_snipmate == "1":
self.register_snippet_source("snipmate_files",
SnipMateFileSource())
if _vim.eval("exists('g:UltiSnipsEnableSnipMate')") == '1':
enable_snipmate = _vim.eval('g:UltiSnipsEnableSnipMate')
if enable_snipmate == '1':
self.register_snippet_source('snipmate_files',
SnipMateFileSource())
self._reinit()
@err_to_scratch_buffer
def jump_forwards(self):
"""Jumps to the next tabstop."""
_vim.command("let g:ulti_jump_forwards_res = 1")
_vim.command('let g:ulti_jump_forwards_res = 1')
if not self._jump():
_vim.command("let g:ulti_jump_forwards_res = 0")
_vim.command('let g:ulti_jump_forwards_res = 0')
return self._handle_failure(self.forward_trigger)
@err_to_scratch_buffer
def jump_backwards(self):
"""Jumps to the previous tabstop."""
_vim.command("let g:ulti_jump_backwards_res = 1")
_vim.command('let g:ulti_jump_backwards_res = 1')
if not self._jump(True):
_vim.command("let g:ulti_jump_backwards_res = 0")
_vim.command('let g:ulti_jump_backwards_res = 0')
return self._handle_failure(self.backward_trigger)
@err_to_scratch_buffer
def expand(self):
"""Try to expand a snippet at the current position."""
_vim.command("let g:ulti_expand_res = 1")
_vim.command('let g:ulti_expand_res = 1')
if not self._try_expand():
_vim.command("let g:ulti_expand_res = 0")
_vim.command('let g:ulti_expand_res = 0')
self._handle_failure(self.expand_trigger)
@err_to_scratch_buffer
def expand_or_jump(self):
"""
This function is used for people who wants to have the same trigger for
expansion and forward jumping. It first tries to expand a snippet, if
this fails, it tries to jump forward.
"""This function is used for people who wants to have the same trigger
for expansion and forward jumping.
It first tries to expand a snippet, if this fails, it tries to
jump forward.
"""
_vim.command('let g:ulti_expand_or_jump_res = 1')
rv = self._try_expand()
@ -152,7 +160,7 @@ class SnippetManager(object):
snippets.sort(key=lambda x: x.trigger)
for snip in snippets:
description = snip.description[snip.description.find(snip.trigger) +
len(snip.trigger) + 2:]
len(snip.trigger) + 2:]
key = as_unicode(snip.trigger)
description = as_unicode(description)
@ -195,18 +203,18 @@ class SnippetManager(object):
@err_to_scratch_buffer
def add_snippet(self, trigger, value, description,
options, ft="all", priority=0):
options, ft='all', priority=0):
"""Add a snippet to the list of known snippets of the given 'ft'."""
self._added_snippets_source.add_snippet(ft,
UltiSnipsSnippetDefinition(priority, trigger, value,
description, options, {}, "added"))
UltiSnipsSnippetDefinition(priority, trigger, value,
description, options, {}, 'added'))
@err_to_scratch_buffer
def expand_anon(self, value, trigger="", description="", options=""):
def expand_anon(self, value, trigger='', description='', options=''):
"""Expand an anonymous snippet right here."""
before = _vim.buf.line_till_cursor
snip = UltiSnipsSnippetDefinition(0, trigger, value, description,
options, {}, "")
options, {}, '')
if not trigger or snip.matches(before):
self._do_snippet(snip, before)
@ -215,18 +223,24 @@ class SnippetManager(object):
return False
def register_snippet_source(self, name, snippet_source):
"""Registers a new 'snippet_source' with the given 'name'. The given
class must be an instance of SnippetSource. This source will be queried
for snippets."""
"""Registers a new 'snippet_source' with the given 'name'.
The given class must be an instance of SnippetSource. This
source will be queried for snippets.
"""
self._snippet_sources.append((name, snippet_source))
def unregister_snippet_source(self, name):
"""Unregister the source with the given 'name'. Does nothing if it is
not registered."""
"""Unregister the source with the given 'name'.
Does nothing if it is not registered.
"""
for index, (source_name, _) in enumerate(self._snippet_sources):
if name == source_name:
self._snippet_sources = self._snippet_sources[:index] + \
self._snippet_sources[index+1:]
self._snippet_sources[index + 1:]
break
def reset_buffer_filetypes(self):
@ -236,10 +250,10 @@ class SnippetManager(object):
def add_buffer_filetypes(self, ft):
"""Checks for changes in the list of snippet files or the contents of
the snippet files and reloads them if necessary. """
the snippet files and reloads them if necessary."""
buf_fts = self._buffer_filetypes[_vim.buf.number]
idx = -1
for ft in ft.split("."):
for ft in ft.split('.'):
ft = ft.strip()
if not ft:
continue
@ -255,7 +269,7 @@ class SnippetManager(object):
if not self._csnippets and self._inner_mappings_in_place:
self._unmap_inner_keys()
self._vstate.remember_position()
if _vim.eval("mode()") not in 'in':
if _vim.eval('mode()') not in 'in':
return
if self._ignore_movements:
@ -265,7 +279,7 @@ class SnippetManager(object):
if self._csnippets:
cstart = self._csnippets[0].start.line
cend = self._csnippets[0].end.line + \
self._vstate.diff_in_buffer_length
self._vstate.diff_in_buffer_length
ct = _vim.buf[cstart:cend + 1]
lt = self._vstate.remembered_buffer
pos = _vim.buf.cursor
@ -277,9 +291,9 @@ class SnippetManager(object):
# Cut down on lines searched for changes. Start from behind and
# remove all equal lines. Then do the same from the front.
if lt and ct:
while (lt[lt_span[1]-1] == ct[ct_span[1]-1] and
self._vstate.ppos.line < initial_line + lt_span[1]-1 and
pos.line < initial_line + ct_span[1]-1 and
while (lt[lt_span[1] - 1] == ct[ct_span[1] - 1] and
self._vstate.ppos.line < initial_line + lt_span[1] - 1 and
pos.line < initial_line + ct_span[1] - 1 and
(lt_span[0] < lt_span[1]) and
(ct_span[0] < ct_span[1])):
ct_span[1] -= 1
@ -319,14 +333,14 @@ class SnippetManager(object):
def _map_inner_keys(self):
"""Map keys that should only be defined when a snippet is active."""
if self.expand_trigger != self.forward_trigger:
_vim.command("inoremap <buffer> <silent> " + self.forward_trigger +
" <C-R>=UltiSnips#JumpForwards()<cr>")
_vim.command("snoremap <buffer> <silent> " + self.forward_trigger +
" <Esc>:call UltiSnips#JumpForwards()<cr>")
_vim.command("inoremap <buffer> <silent> " + self.backward_trigger +
" <C-R>=UltiSnips#JumpBackwards()<cr>")
_vim.command("snoremap <buffer> <silent> " + self.backward_trigger +
" <Esc>:call UltiSnips#JumpBackwards()<cr>")
_vim.command('inoremap <buffer> <silent> ' + self.forward_trigger +
' <C-R>=UltiSnips#JumpForwards()<cr>')
_vim.command('snoremap <buffer> <silent> ' + self.forward_trigger +
' <Esc>:call UltiSnips#JumpForwards()<cr>')
_vim.command('inoremap <buffer> <silent> ' + self.backward_trigger +
' <C-R>=UltiSnips#JumpBackwards()<cr>')
_vim.command('snoremap <buffer> <silent> ' + self.backward_trigger +
' <Esc>:call UltiSnips#JumpBackwards()<cr>')
self._inner_mappings_in_place = True
def _unmap_inner_keys(self):
@ -335,10 +349,10 @@ class SnippetManager(object):
return
try:
if self.expand_trigger != self.forward_trigger:
_vim.command("iunmap <buffer> %s" % self.forward_trigger)
_vim.command("sunmap <buffer> %s" % self.forward_trigger)
_vim.command("iunmap <buffer> %s" % self.backward_trigger)
_vim.command("sunmap <buffer> %s" % self.backward_trigger)
_vim.command('iunmap <buffer> %s' % self.forward_trigger)
_vim.command('sunmap <buffer> %s' % self.forward_trigger)
_vim.command('iunmap <buffer> %s' % self.backward_trigger)
_vim.command('sunmap <buffer> %s' % self.backward_trigger)
self._inner_mappings_in_place = False
except _vim.error:
# This happens when a preview window was opened. This issues
@ -348,16 +362,21 @@ class SnippetManager(object):
@err_to_scratch_buffer
def _save_last_visual_selection(self):
"""
This is called when the expand trigger is pressed in visual mode.
Our job is to remember everything between '< and '> and pass it on to
"""This is called when the expand trigger is pressed in visual mode.
Our job is to remember everything between '< and '> and pass it on to.
${VISUAL} in case it will be needed.
"""
self._visual_content.conserve()
def _leaving_buffer(self):
"""Called when the user switches tabs/windows/buffers. It basically
means that all snippets must be properly terminated."""
"""Called when the user switches tabs/windows/buffers.
It basically means that all snippets must be properly
terminated.
"""
while len(self._csnippets):
self._current_snippet_is_done()
self._reinit()
@ -392,7 +411,7 @@ class SnippetManager(object):
if self._cs:
ntab = self._cs.select_next_tab(backwards)
if ntab:
if self._cs.snippet.has_option("s"):
if self._cs.snippet.has_option('s'):
lineno = _vim.buf.cursor.line
_vim.buf[lineno] = _vim.buf[lineno].rstrip()
_vim.select(ntab.start, ntab.end)
@ -423,18 +442,18 @@ class SnippetManager(object):
def _handle_failure(self, trigger):
"""Mainly make sure that we play well with SuperTab."""
if trigger.lower() == "<tab>":
feedkey = "\\" + trigger
elif trigger.lower() == "<s-tab>":
feedkey = "\\" + trigger
if trigger.lower() == '<tab>':
feedkey = '\\' + trigger
elif trigger.lower() == '<s-tab>':
feedkey = '\\' + trigger
else:
feedkey = None
mode = "n"
mode = 'n'
if not self._supertab_keys:
if _vim.eval("exists('g:SuperTabMappingForward')") != "0":
if _vim.eval("exists('g:SuperTabMappingForward')") != '0':
self._supertab_keys = (
_vim.eval("g:SuperTabMappingForward"),
_vim.eval("g:SuperTabMappingBackward"),
_vim.eval('g:SuperTabMappingForward'),
_vim.eval('g:SuperTabMappingBackward'),
)
else:
self._supertab_keys = ['', '']
@ -443,22 +462,25 @@ class SnippetManager(object):
if trigger.lower() == sttrig.lower():
if idx == 0:
feedkey = r"\<Plug>SuperTabForward"
mode = "n"
mode = 'n'
elif idx == 1:
feedkey = r"\<Plug>SuperTabBackward"
mode = "p"
mode = 'p'
# Use remap mode so SuperTab mappings will be invoked.
break
if (feedkey == r"\<Plug>SuperTabForward" or
feedkey == r"\<Plug>SuperTabBackward"):
_vim.command("return SuperTab(%s)" % _vim.escape(mode))
_vim.command('return SuperTab(%s)' % _vim.escape(mode))
elif feedkey:
_vim.command("return %s" % _vim.escape(feedkey))
_vim.command('return %s' % _vim.escape(feedkey))
def _snips(self, before, partial):
"""Returns all the snippets for the given text before the cursor. If
partial is True, then get also return partial matches. """
"""Returns all the snippets for the given text before the cursor.
If partial is True, then get also return partial matches.
"""
filetypes = self._buffer_filetypes[_vim.buf.number][::-1]
matching_snippets = defaultdict(list)
clear_priority = None
@ -470,7 +492,7 @@ class SnippetManager(object):
for _, source in self._snippet_sources:
sclear_priority = source.get_clear_priority(filetypes)
if sclear_priority is not None and (clear_priority is None
or sclear_priority > clear_priority):
or sclear_priority > clear_priority):
clear_priority = sclear_priority
for key, value in source.get_cleared(filetypes).items():
if key not in cleared or value > cleared[key]:
@ -480,7 +502,7 @@ class SnippetManager(object):
for snippet in source.get_snippets(filetypes, before, partial):
if ((clear_priority is None or snippet.priority > clear_priority)
and (snippet.trigger not in cleared or
snippet.priority > cleared[snippet.trigger])):
snippet.priority > cleared[snippet.trigger])):
matching_snippets[snippet.trigger].append(snippet)
if not matching_snippets:
return []
@ -491,7 +513,7 @@ class SnippetManager(object):
for snippets_with_trigger in matching_snippets.values():
highest_priority = max(s.priority for s in snippets_with_trigger)
snippets.extend(s for s in snippets_with_trigger
if s.priority == highest_priority)
if s.priority == highest_priority)
# For partial matches we are done, but if we want to expand a snippet,
# we have to go over them again and only keep those with the maximum
@ -503,8 +525,8 @@ class SnippetManager(object):
return [s for s in snippets if s.priority == highest_priority]
def _do_snippet(self, snippet, before):
"""Expands the given snippet, and handles everything
that needs to be done with it."""
"""Expands the given snippet, and handles everything that needs to be
done with it."""
self._map_inner_keys()
# Adjust before, maybe the trigger is not the complete word
@ -522,13 +544,13 @@ class SnippetManager(object):
# pretending that the user deleted and retyped the text that our
# trigger matched.
edit_actions = [
("D", start.line, start.col, snippet.matched),
("I", start.line, start.col, snippet.matched),
('D', start.line, start.col, snippet.matched),
('I', start.line, start.col, snippet.matched),
]
self._csnippets[0].replay_user_edits(edit_actions)
si = snippet.launch(text_before, self._visual_content,
self._cs.find_parent_for_new_to(start), start, end)
self._cs.find_parent_for_new_to(start), start, end)
else:
start = Position(_vim.buf.cursor.line, len(text_before))
end = Position(_vim.buf.cursor.line, len(before))
@ -570,26 +592,29 @@ class SnippetManager(object):
return self._csnippets[-1]
def _file_to_edit(self, requested_ft, bang): # pylint: disable=no-self-use
"""Returns a file to be edited for the given requested_ft. If 'bang' is
"""Returns a file to be edited for the given requested_ft.
If 'bang' is
empty only private files in g:UltiSnipsSnippetsDir are considered,
otherwise all files are considered and the user gets to choose.
"""
# This method is not using self, but is called by UltiSnips.vim and is
# therefore in this class because it is the facade to Vim.
potentials = set()
if _vim.eval("exists('g:UltiSnipsSnippetsDir')") == "1":
snippet_dir = _vim.eval("g:UltiSnipsSnippetsDir")
if _vim.eval("exists('g:UltiSnipsSnippetsDir')") == '1':
snippet_dir = _vim.eval('g:UltiSnipsSnippetsDir')
else:
if platform.system() == "Windows":
snippet_dir = os.path.join(_vim.eval("$HOME"),
"vimfiles", "UltiSnips")
elif _vim.eval("has('nvim')") == "1":
snippet_dir = os.path.join(_vim.eval("$HOME"),
".nvim", "UltiSnips")
if platform.system() == 'Windows':
snippet_dir = os.path.join(_vim.eval('$HOME'),
'vimfiles', 'UltiSnips')
elif _vim.eval("has('nvim')") == '1':
snippet_dir = os.path.join(_vim.eval('$HOME'),
'.nvim', 'UltiSnips')
else:
snippet_dir = os.path.join(_vim.eval("$HOME"),
".vim", "UltiSnips")
snippet_dir = os.path.join(_vim.eval('$HOME'),
'.vim', 'UltiSnips')
filetypes = []
if requested_ft:
@ -603,20 +628,20 @@ class SnippetManager(object):
for ft in filetypes:
potentials.update(find_snippet_files(ft, snippet_dir))
potentials.add(os.path.join(snippet_dir,
ft + '.snippets'))
ft + '.snippets'))
if bang:
potentials.update(find_all_snippet_files(ft))
potentials = set(os.path.realpath(os.path.expanduser(p))
for p in potentials)
for p in potentials)
if len(potentials) > 1:
files = sorted(potentials)
formatted = [as_unicode('%i: %s') % (i, escape(fn, '\\')) for
i, fn in enumerate(files, 1)]
i, fn in enumerate(files, 1)]
file_to_edit = _ask_user(files, formatted)
if file_to_edit is None:
return ""
return ''
else:
file_to_edit = potentials.pop()

View File

@ -10,17 +10,17 @@ from position import Position
def transform(a, cmds):
buf = a.split("\n")
buf = a.split('\n')
for cmd in cmds:
ctype, line, col, char = cmd
if ctype == "D":
if ctype == 'D':
if char != '\n':
buf[line] = buf[line][:col] + buf[line][col+len(char):]
buf[line] = buf[line][:col] + buf[line][col + len(char):]
else:
buf[line] = buf[line] + buf[line+1]
del buf[line+1]
elif ctype == "I":
buf[line] = buf[line] + buf[line + 1]
del buf[line + 1]
elif ctype == 'I':
buf[line] = buf[line][:col] + char + buf[line][col:]
buf = '\n'.join(buf).split('\n')
return '\n'.join(buf)
@ -29,106 +29,127 @@ def transform(a, cmds):
import unittest
# Test Guessing {{{
class _BaseGuessing(object):
def runTest(self):
rv, es = guess_edit(self.initial_line, self.a, self.b, Position(*self.ppos), Position(*self.pos))
rv, es = guess_edit(
self.initial_line, self.a, self.b, Position(*self.ppos), Position(*self.pos))
self.assertEqual(rv, True)
self.assertEqual(self.wanted, es)
class TestGuessing_Noop0(_BaseGuessing, unittest.TestCase):
a, b = [], []
initial_line = 0
ppos, pos = (0, 6), (0, 7)
wanted = ()
class TestGuessing_InsertOneChar(_BaseGuessing, unittest.TestCase):
a, b = ["Hello World"], ["Hello World"]
a, b = ['Hello World'], ['Hello World']
initial_line = 0
ppos, pos = (0, 6), (0, 7)
wanted = (
("I", 0, 6, " "),
('I', 0, 6, ' '),
)
class TestGuessing_InsertOneChar1(_BaseGuessing, unittest.TestCase):
a, b = ["Hello World"], ["Hello World"]
a, b = ['Hello World'], ['Hello World']
initial_line = 0
ppos, pos = (0, 7), (0, 8)
wanted = (
("I", 0, 7, " "),
('I', 0, 7, ' '),
)
class TestGuessing_BackspaceOneChar(_BaseGuessing, unittest.TestCase):
a, b = ["Hello World"], ["Hello World"]
a, b = ['Hello World'], ['Hello World']
initial_line = 0
ppos, pos = (0, 7), (0, 6)
wanted = (
("D", 0, 6, " "),
('D', 0, 6, ' '),
)
class TestGuessing_DeleteOneChar(_BaseGuessing, unittest.TestCase):
a, b = ["Hello World"], ["Hello World"]
a, b = ['Hello World'], ['Hello World']
initial_line = 0
ppos, pos = (0, 5), (0, 5)
wanted = (
("D", 0, 5, " "),
('D', 0, 5, ' '),
)
# End: Test Guessing }}}
class _Base(object):
def runTest(self):
es = diff(self.a, self.b)
tr = transform(self.a, es)
self.assertEqual(self.b, tr)
self.assertEqual(self.wanted, es)
class TestEmptyString(_Base, unittest.TestCase):
a, b = "", ""
a, b = '', ''
wanted = ()
class TestAllMatch(_Base, unittest.TestCase):
a, b = "abcdef", "abcdef"
a, b = 'abcdef', 'abcdef'
wanted = ()
class TestLotsaNewlines(_Base, unittest.TestCase):
a, b = "Hello", "Hello\nWorld\nWorld\nWorld"
a, b = 'Hello', 'Hello\nWorld\nWorld\nWorld'
wanted = (
("I", 0, 5, "\n"),
("I", 1, 0, "World"),
("I", 1, 5, "\n"),
("I", 2, 0, "World"),
("I", 2, 5, "\n"),
("I", 3, 0, "World"),
('I', 0, 5, '\n'),
('I', 1, 0, 'World'),
('I', 1, 5, '\n'),
('I', 2, 0, 'World'),
('I', 2, 5, '\n'),
('I', 3, 0, 'World'),
)
class TestCrash(_Base, unittest.TestCase):
a = 'hallo Blah mitte=sdfdsfsd\nhallo kjsdhfjksdhfkjhsdfkh mittekjshdkfhkhsdfdsf'
b = 'hallo Blah mitte=sdfdsfsd\nhallo b mittekjshdkfhkhsdfdsf'
wanted = (
("D", 1, 6, "kjsdhfjksdhfkjhsdfkh"),
("I", 1, 6, "b"),
('D', 1, 6, 'kjsdhfjksdhfkjhsdfkh'),
('I', 1, 6, 'b'),
)
class TestRealLife(_Base, unittest.TestCase):
a = 'hallo End Beginning'
b = 'hallo End t'
wanted = (
("D", 0, 10, "Beginning"),
("I", 0, 10, "t"),
('D', 0, 10, 'Beginning'),
('I', 0, 10, 't'),
)
class TestRealLife1(_Base, unittest.TestCase):
a = 'Vorne hallo Hinten'
b = 'Vorne hallo Hinten'
wanted = (
("I", 0, 11, " "),
('I', 0, 11, ' '),
)
class TestWithNewline(_Base, unittest.TestCase):
a = 'First Line\nSecond Line'
b = 'n'
wanted = (
("D", 0, 0, "First Line"),
("D", 0, 0, "\n"),
("D", 0, 0, "Second Line"),
("I", 0, 0, "n"),
('D', 0, 0, 'First Line'),
('D', 0, 0, '\n'),
('D', 0, 0, 'Second Line'),
('I', 0, 0, 'n'),
)
@ -136,51 +157,56 @@ class TestCheapDelete(_Base, unittest.TestCase):
a = 'Vorne hallo Hinten'
b = 'Vorne Hinten'
wanted = (
("D", 0, 5, " hallo"),
('D', 0, 5, ' hallo'),
)
class TestNoSubstring(_Base, unittest.TestCase):
a,b = "abc", "def"
a, b = 'abc', 'def'
wanted = (
("D", 0, 0, "abc"),
("I", 0, 0, "def"),
('D', 0, 0, 'abc'),
('I', 0, 0, 'def'),
)
class TestCommonCharacters(_Base, unittest.TestCase):
a,b = "hasomelongertextbl", "hol"
a, b = 'hasomelongertextbl', 'hol'
wanted = (
("D", 0, 1, "asomelongertextb"),
("I", 0, 1, "o"),
('D', 0, 1, 'asomelongertextb'),
('I', 0, 1, 'o'),
)
class TestUltiSnipsProblem(_Base, unittest.TestCase):
a = "this is it this is it this is it"
b = "this is it a this is it"
a = 'this is it this is it this is it'
b = 'this is it a this is it'
wanted = (
("D", 0, 11, "this is it"),
("I", 0, 11, "a"),
('D', 0, 11, 'this is it'),
('I', 0, 11, 'a'),
)
class MatchIsTooCheap(_Base, unittest.TestCase):
a = "stdin.h"
b = "s"
a = 'stdin.h'
b = 's'
wanted = (
("D", 0, 1, "tdin.h"),
('D', 0, 1, 'tdin.h'),
)
class MultiLine(_Base, unittest.TestCase):
a = "hi first line\nsecond line first line\nsecond line world"
b = "hi first line\nsecond line k world"
a = 'hi first line\nsecond line first line\nsecond line world'
b = 'hi first line\nsecond line k world'
wanted = (
("D", 1, 12, "first line"),
("D", 1, 12, "\n"),
("D", 1, 12, "second line"),
("I", 1, 12, "k"),
('D', 1, 12, 'first line'),
('D', 1, 12, '\n'),
('D', 1, 12, 'second line'),
('I', 1, 12, 'k'),
)
if __name__ == '__main__':
unittest.main()
# k = TestEditScript()
# unittest.TextTestRunner().run(k)
unittest.main()
# k = TestEditScript()
# unittest.TextTestRunner().run(k)

View File

@ -7,13 +7,16 @@ import unittest
from position import Position
class _MPBase(object):
def runTest(self):
obj = Position(*self.obj)
for pivot, delta, wanted in self.steps:
obj.move(Position(*pivot), Position(*delta))
self.assertEqual(Position(*wanted), obj)
class MovePosition_DelSameLine(_MPBase, unittest.TestCase):
# hello wor*ld -> h*ld -> hl*ld
obj = (0, 9)
@ -21,13 +24,17 @@ class MovePosition_DelSameLine(_MPBase, unittest.TestCase):
((0, 1), (0, -8), (0, 1)),
((0, 1), (0, 1), (0, 2)),
)
class MovePosition_DelSameLine1(_MPBase, unittest.TestCase):
# hel*lo world -> hel*world -> hel*worl
obj = (0,3)
obj = (0, 3)
steps = (
((0, 4), (0, -3), (0,3)),
((0, 8), (0, -1), (0,3)),
((0, 4), (0, -3), (0, 3)),
((0, 8), (0, -1), (0, 3)),
)
class MovePosition_InsSameLine1(_MPBase, unittest.TestCase):
# hel*lo world -> hel*woresld
obj = (0, 3)
@ -36,6 +43,8 @@ class MovePosition_InsSameLine1(_MPBase, unittest.TestCase):
((0, 6), (0, 2), (0, 3)),
((0, 8), (0, -1), (0, 3))
)
class MovePosition_InsSameLine2(_MPBase, unittest.TestCase):
# hello wor*ld -> helesdlo wor*ld
obj = (0, 9)
@ -43,6 +52,7 @@ class MovePosition_InsSameLine2(_MPBase, unittest.TestCase):
((0, 3), (0, 3), (0, 12)),
)
class MovePosition_DelSecondLine(_MPBase, unittest.TestCase):
# hello world. sup hello world.*a, was
# *a, was ach nix
@ -52,6 +62,8 @@ class MovePosition_DelSecondLine(_MPBase, unittest.TestCase):
((0, 12), (0, -4), (1, 0)),
((0, 12), (-1, 0), (0, 12)),
)
class MovePosition_DelSecondLine1(_MPBase, unittest.TestCase):
# hello world. sup
# a, *was
@ -63,7 +75,7 @@ class MovePosition_DelSecondLine1(_MPBase, unittest.TestCase):
((0, 12), (0, -4), (1, 3)),
((0, 12), (-1, 0), (0, 15)),
((0, 12), (0, -3), (0, 12)),
((0, 12), (0, 1), (0, 13)),
((0, 12), (0, 1), (0, 13)),
)
if __name__ == '__main__':

View File

@ -3,22 +3,24 @@
"""Utilities to deal with text."""
def unescape(text):
"""Removes '\\' escaping from 'text'."""
rv = ""
rv = ''
i = 0
while i < len(text):
if i+1 < len(text) and text[i] == '\\':
rv += text[i+1]
if i + 1 < len(text) and text[i] == '\\':
rv += text[i + 1]
i += 1
else:
rv += text[i]
i += 1
return rv
def escape(text, chars):
"""Escapes all characters in 'chars' in text using backspaces."""
rv = ""
rv = ''
for char in text:
if char in chars:
rv += '\\'
@ -28,13 +30,14 @@ def escape(text, chars):
def fill_in_whitespace(text):
"""Returns 'text' with escaped whitespace replaced through whitespaces."""
text = text.replace(r"\n", "\n")
text = text.replace(r"\t", "\t")
text = text.replace(r"\r", "\r")
text = text.replace(r"\a", "\a")
text = text.replace(r"\b", "\b")
text = text.replace(r"\n", '\n')
text = text.replace(r"\t", '\t')
text = text.replace(r"\r", '\r')
text = text.replace(r"\a", '\a')
text = text.replace(r"\b", '\b')
return text
def head_tail(line):
"""Returns the first word in 'line' and the rest of 'line' or None if the
line is too short."""
@ -47,7 +50,9 @@ def head_tail(line):
pass
return head, tail
class LineIterator(object):
"""Convenience class that keeps track of line numbers in files."""
def __init__(self, text):

View File

@ -6,14 +6,16 @@
from UltiSnips import _vim
from UltiSnips.position import Position
def _calc_end(text, start):
"""Calculate the end position of the 'text' starting at 'start."""
if len(text) == 1:
new_end = start + Position(0, len(text[0]))
else:
new_end = Position(start.line + len(text)-1, len(text[-1]))
new_end = Position(start.line + len(text) - 1, len(text[-1]))
return new_end
def _text_to_vim(start, end, text):
"""Copy the given text to the current buffer, overwriting the span 'start'
to 'end'."""
@ -33,30 +35,33 @@ def _text_to_vim(start, end, text):
# Open any folds this might have created
_vim.buf.cursor = start
_vim.command("normal! zv")
_vim.command('normal! zv')
return new_end
# These classes use their subclasses a lot and we really do not want to expose
# their functions more globally.
# pylint: disable=protected-access
class TextObject(object):
"""Represents any object in the text that has a span in any ways."""
def __init__(self, parent, token, end=None,
initial_text="", tiebreaker=None):
initial_text='', tiebreaker=None):
self._parent = parent
if end is not None: # Took 4 arguments
if end is not None: # Took 4 arguments
self._start = token
self._end = end
self._initial_text = initial_text
else: # Initialize from token
else: # Initialize from token
self._start = token.start
self._end = token.end
self._initial_text = token.initial_text
self._tiebreaker = tiebreaker or Position(
self._start.line, self._end.line)
self._start.line, self._end.line)
if parent is not None:
parent._add_child(self)
@ -67,27 +72,27 @@ class TextObject(object):
def __lt__(self, other):
me_tuple = (self.start.line, self.start.col,
self._tiebreaker.line, self._tiebreaker.col)
self._tiebreaker.line, self._tiebreaker.col)
other_tuple = (other._start.line, other._start.col,
other._tiebreaker.line, other._tiebreaker.col)
other._tiebreaker.line, other._tiebreaker.col)
return me_tuple < other_tuple
def __le__(self, other):
me_tuple = (self._start.line, self._start.col,
self._tiebreaker.line, self._tiebreaker.col)
self._tiebreaker.line, self._tiebreaker.col)
other_tuple = (other._start.line, other._start.col,
other._tiebreaker.line, other._tiebreaker.col)
other._tiebreaker.line, other._tiebreaker.col)
return me_tuple <= other_tuple
def __repr__(self):
ct = ""
ct = ''
try:
ct = self.current_text
except IndexError:
ct = "<err>"
ct = '<err>'
return "%s(%r->%r,%r)" % (self.__class__.__name__,
self._start, self._end, ct)
return '%s(%r->%r,%r)' % (self.__class__.__name__,
self._start, self._end, ct)
@property
def current_text(self):
@ -96,7 +101,7 @@ class TextObject(object):
return _vim.buf[self._start.line][self._start.col:self._end.col]
else:
lines = [_vim.buf[self._start.line][self._start.col:]]
lines.extend(_vim.buf[self._start.line+1:self._end.line])
lines.extend(_vim.buf[self._start.line + 1:self._end.line])
lines.append(_vim.buf[self._end.line][:self._end.col])
return '\n'.join(lines)
@ -112,8 +117,10 @@ class TextObject(object):
def overwrite(self, gtext=None):
"""Overwrite the text of this object in the Vim Buffer and update its
length information. If 'gtext' is None use the initial text of this
object.
length information.
If 'gtext' is None use the initial text of this object.
"""
# We explicitly do not want to move our children around here as we
# either have non or we are replacing text initially which means we do
@ -122,7 +129,7 @@ class TextObject(object):
return
old_end = self._end
self._end = _text_to_vim(
self._start, self._end, gtext or self._initial_text)
self._start, self._end, gtext or self._initial_text)
if self._parent:
self._parent._child_has_moved(
self._parent._children.index(self), min(old_end, self._end),
@ -134,14 +141,16 @@ class TextObject(object):
Return False if you need to be called again for this edit cycle.
Otherwise return True.
"""
raise NotImplementedError("Must be implemented by subclasses.")
raise NotImplementedError('Must be implemented by subclasses.')
class EditableTextObject(TextObject):
"""
This base class represents any object in the text
that can be changed by the user
"""
"""This base class represents any object in the text that can be changed by
the user."""
def __init__(self, *args, **kwargs):
TextObject.__init__(self, *args, **kwargs)
self._children = []
@ -157,7 +166,7 @@ class EditableTextObject(TextObject):
@property
def _editable_children(self):
"""List of all children that are EditableTextObjects"""
"""List of all children that are EditableTextObjects."""
return [child for child in self._children if
isinstance(child, EditableTextObject)]
@ -177,13 +186,13 @@ class EditableTextObject(TextObject):
def _do_edit(self, cmd):
"""Apply the edit 'cmd' to this object."""
ctype, line, col, text = cmd
assert ('\n' not in text) or (text == "\n")
assert ('\n' not in text) or (text == '\n')
pos = Position(line, col)
to_kill = set()
new_cmds = []
for child in self._children:
if ctype == "I": # Insertion
if ctype == 'I': # Insertion
if (child._start < pos <
Position(child._end.line, child._end.col) and
isinstance(child, NoneditableTextObject)):
@ -194,9 +203,9 @@ class EditableTextObject(TextObject):
isinstance(child, EditableTextObject)):
child._do_edit(cmd)
return
else: # Deletion
delend = pos + Position(0, len(text)) if text != "\n" \
else Position(line + 1, 0)
else: # Deletion
delend = pos + Position(0, len(text)) if text != '\n' \
else Position(line + 1, 0)
if ((child._start <= pos < child._end) and
(child._start < delend <= child._end)):
# this edit command is completely for the child
@ -216,16 +225,16 @@ class EditableTextObject(TextObject):
elif (pos < child._start and
(child._start < delend <= child._end)):
# Case: partially for us, partially for the child
my_text = text[:(child._start-pos).col]
c_text = text[(child._start-pos).col:]
my_text = text[:(child._start - pos).col]
c_text = text[(child._start - pos).col:]
new_cmds.append((ctype, line, col, my_text))
new_cmds.append((ctype, line, col, c_text))
break
elif (delend >= child._end and (
child._start <= pos < child._end)):
# Case: partially for us, partially for the child
c_text = text[(child._end-pos).col:]
my_text = text[:(child._end-pos).col]
c_text = text[(child._end - pos).col:]
my_text = text[:(child._end - pos).col]
new_cmds.append((ctype, line, col, c_text))
new_cmds.append((ctype, line, col, my_text))
break
@ -238,8 +247,8 @@ class EditableTextObject(TextObject):
return
# We have to handle this ourselves
delta = Position(1, 0) if text == "\n" else Position(0, len(text))
if ctype == "D":
delta = Position(1, 0) if text == '\n' else Position(0, len(text))
if ctype == 'D':
# Makes no sense to delete in empty textobject
if self._start == self._end:
return
@ -263,7 +272,7 @@ class EditableTextObject(TextObject):
'diff'."""
self._end.move(pivot, diff)
for child in self._children[idx+1:]:
for child in self._children[idx + 1:]:
child._move(pivot, diff)
if self._parent:
@ -295,7 +304,6 @@ class EditableTextObject(TextObject):
return min(possible_sol)
def _get_prev_tab(self, number):
"""Returns the previous tabstop before 'number'."""
if not len(self._tabstops.keys()):
@ -321,8 +329,11 @@ class EditableTextObject(TextObject):
return max(possible_sol)
def _get_tabstop(self, requester, number):
"""Returns the tabstop 'number'. 'requester' is the class that is
interested in this."""
"""Returns the tabstop 'number'.
'requester' is the class that is interested in this.
"""
if number in self._tabstops:
return self._tabstops[number]
for child in self._editable_children:
@ -357,7 +368,10 @@ class EditableTextObject(TextObject):
except (AttributeError, KeyError):
pass
class NoneditableTextObject(TextObject):
"""All passive text objects that the user can't edit by hand."""
def _update(self, done):
return True

View File

@ -5,11 +5,12 @@
from UltiSnips.text_objects._base import NoneditableTextObject
class EscapedChar(NoneditableTextObject):
r"""
This class is a escape char like \$. It is handled in a text object to make
sure that siblings are correctly moved after replacing the text.
This is a base class without functionality just to mark it in the code.
"""
pass

View File

@ -5,7 +5,9 @@
from UltiSnips.text_objects._base import NoneditableTextObject
class Mirror(NoneditableTextObject):
"""See module docstring."""
def __init__(self, parent, tabstop, token):
@ -15,7 +17,7 @@ class Mirror(NoneditableTextObject):
def _update(self, done):
if self._ts.is_killed:
self.overwrite("")
self.overwrite('')
self._parent._del_child(self) # pylint:disable=protected-access
return True
@ -26,5 +28,9 @@ class Mirror(NoneditableTextObject):
return True
def _get_text(self):
"""Returns the text used for mirroring. Overwritten by base classes."""
"""Returns the text used for mirroring.
Overwritten by base classes.
"""
return self._ts.current_text

View File

@ -13,66 +13,78 @@ from UltiSnips.text_objects._base import NoneditableTextObject
class _Tabs(object):
"""Allows access to tabstop content via t[] inside of python code."""
def __init__(self, to):
self._to = to
def __getitem__(self, no):
ts = self._to._get_tabstop(self._to, int(no)) # pylint:disable=protected-access
ts = self._to._get_tabstop(
self._to,
int(no)) # pylint:disable=protected-access
if ts is None:
return ""
return ''
return ts.current_text
_VisualContent = namedtuple('_VisualContent', ['mode', 'text'])
class SnippetUtil(object):
"""Provides easy access to indentation, etc. This is the 'snip' object in
python code."""
"""Provides easy access to indentation, etc.
This is the 'snip' object in python code.
"""
def __init__(self, initial_indent, vmode, vtext):
self._ind = IndentUtil()
self._visual = _VisualContent(vmode, vtext)
self._initial_indent = self._ind.indent_to_spaces(initial_indent)
self._reset("")
self._reset('')
def _reset(self, cur):
"""Gets the snippet ready for another update.
:cur: the new value for c.
"""
self._ind.reset()
self._cur = cur
self._rv = ""
self._rv = ''
self._changed = False
self.reset_indent()
def shift(self, amount=1):
"""Shifts the indentation level.
Note that this uses the shiftwidth because thats what code
formatters use.
"""Shifts the indentation level. Note that this uses the shiftwidth
because thats what code formatters use.
:amount: the amount by which to shift.
"""
self.indent += " " * self._ind.shiftwidth * amount
self.indent += ' ' * self._ind.shiftwidth * amount
def unshift(self, amount=1):
"""Unshift the indentation level.
Note that this uses the shiftwidth because thats what code
formatters use.
"""Unshift the indentation level. Note that this uses the shiftwidth
because thats what code formatters use.
:amount: the amount by which to unshift.
"""
by = -self._ind.shiftwidth * amount
try:
self.indent = self.indent[:by]
except IndexError:
self.indent = ""
self.indent = ''
def mkline(self, line="", indent=None):
def mkline(self, line='', indent=None):
"""Creates 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 is None:
indent = self.indent
@ -82,7 +94,7 @@ class SnippetUtil(object):
try:
indent = indent[len(self._initial_indent):]
except IndexError:
indent = ""
indent = ''
indent = self._ind.spaces_to_indent(indent)
return indent + line
@ -95,22 +107,25 @@ class SnippetUtil(object):
@property
def fn(self): # pylint:disable=no-self-use,invalid-name
"""The filename."""
return _vim.eval('expand("%:t")') or ""
return _vim.eval('expand("%:t")') or ''
@property
def basename(self): # pylint:disable=no-self-use
"""The filename without extension."""
return _vim.eval('expand("%:t:r")') or ""
return _vim.eval('expand("%:t:r")') or ''
@property
def ft(self): # pylint:disable=invalid-name
"""The filetype."""
return self.opt("&filetype", "")
return self.opt('&filetype', '')
@property
def rv(self): # pylint:disable=invalid-name
"""The return value. The text to insert at the location of the
placeholder."""
"""The return value.
The text to insert at the location of the placeholder.
"""
return self._rv
@rv.setter
@ -131,12 +146,12 @@ class SnippetUtil(object):
@property
def v(self): # pylint:disable=invalid-name
"""Content of visual expansions"""
"""Content of visual expansions."""
return self._visual
def opt(self, option, default=None): # pylint:disable=no-self-use
"""Gets a Vim variable."""
if _vim.eval("exists('%s')" % option) == "1":
if _vim.eval("exists('%s')" % option) == '1':
try:
return _vim.eval(option)
except _vim.error:
@ -159,6 +174,7 @@ class SnippetUtil(object):
class PythonCode(NoneditableTextObject):
"""See module docstring."""
def __init__(self, parent, token):
@ -176,14 +192,14 @@ class PythonCode(NoneditableTextObject):
self._snip = SnippetUtil(token.indent, mode, text)
self._codes = ((
"import re, os, vim, string, random",
"\n".join(snippet.globals.get("!p", [])).replace("\r\n", "\n"),
token.code.replace("\\`", "`")
'import re, os, vim, string, random',
'\n'.join(snippet.globals.get('!p', [])).replace('\r\n', '\n'),
token.code.replace('\\`', '`')
))
NoneditableTextObject.__init__(self, parent, token)
def _update(self, done):
path = _vim.eval('expand("%")') or ""
path = _vim.eval('expand("%")') or ''
ct = self.current_text
self._locals.update({
't': _Tabs(self._parent),

View File

@ -12,6 +12,7 @@ import tempfile
from UltiSnips.compatibility import as_unicode
from UltiSnips.text_objects._base import NoneditableTextObject
def _chomp(string):
"""Rather than rstrip(), remove only the last newline and preserve
purposeful whitespace."""
@ -21,8 +22,9 @@ def _chomp(string):
string = string[:-1]
return string
def _run_shell_command(cmd, tmpdir):
"""Write the code to a temporary file"""
"""Write the code to a temporary file."""
cmdsuf = ''
if platform.system() == 'Windows':
# suffix required to run command on windows
@ -30,7 +32,7 @@ def _run_shell_command(cmd, tmpdir):
# turn echo off
cmd = '@echo off\r\n' + cmd
handle, path = tempfile.mkstemp(text=True, dir=tmpdir, suffix=cmdsuf)
os.write(handle, cmd.encode("utf-8"))
os.write(handle, cmd.encode('utf-8'))
os.close(handle)
os.chmod(path, stat.S_IRWXU)
@ -41,29 +43,32 @@ def _run_shell_command(cmd, tmpdir):
os.unlink(path)
return _chomp(as_unicode(stdout))
def _get_tmp():
"""Find an executable tmp directory."""
userdir = os.path.expanduser("~")
userdir = os.path.expanduser('~')
for testdir in [tempfile.gettempdir(), os.path.join(userdir, '.cache'),
os.path.join(userdir, '.tmp'), userdir]:
os.path.join(userdir, '.tmp'), userdir]:
if (not os.path.exists(testdir) or
not _run_shell_command('echo success', testdir) == 'success'):
continue
return testdir
return ''
class ShellCode(NoneditableTextObject):
"""See module docstring."""
def __init__(self, parent, token):
NoneditableTextObject.__init__(self, parent, token)
self._code = token.code.replace("\\`", "`")
self._code = token.code.replace('\\`', '`')
self._tmpdir = _get_tmp()
def _update(self, done):
if not self._tmpdir:
output = \
"Unable to find executable tmp directory, check noexec on /tmp"
'Unable to find executable tmp directory, check noexec on /tmp'
else:
output = _run_shell_command(self._code, self._tmpdir)
self.overwrite(output)

View File

@ -1,21 +1,27 @@
#!/usr/bin/env python
# encoding: utf-8
"""A Snippet instance is an instance of a Snippet Definition. That is, when the
user expands a snippet, a SnippetInstance is created to keep track of the
corresponding TextObjects. The Snippet itself is also a TextObject. """
"""A Snippet instance is an instance of a Snippet Definition.
That is, when the user expands a snippet, a SnippetInstance is created
to keep track of the corresponding TextObjects. The Snippet itself is
also a TextObject.
"""
from UltiSnips import _vim
from UltiSnips.position import Position
from UltiSnips.text_objects._base import EditableTextObject, \
NoneditableTextObject
NoneditableTextObject
class SnippetInstance(EditableTextObject):
"""See module docstring."""
# pylint:disable=protected-access
def __init__(self, snippet, parent, initial_text,
start, end, visual_content, last_re, globals):
start, end, visual_content, last_re, globals):
if start is None:
start = Position(0, 0)
if end is None:
@ -23,7 +29,7 @@ class SnippetInstance(EditableTextObject):
self.snippet = snippet
self._cts = 0
self.locals = {"match" : last_re}
self.locals = {'match': last_re}
self.globals = globals
self.visual_content = visual_content
@ -40,18 +46,22 @@ class SnippetInstance(EditableTextObject):
_place_initial_text(self)
def replay_user_edits(self, cmds):
"""Replay the edits the user has done to keep endings of our
Text objects in sync with reality"""
"""Replay the edits the user has done to keep endings of our Text
objects in sync with reality."""
for cmd in cmds:
self._do_edit(cmd)
def update_textobjects(self):
"""Update the text objects that should change automagically after
the users edits have been replayed. This might also move the Cursor
"""Update the text objects that should change automagically after the
users edits have been replayed.
This might also move the Cursor
"""
vc = _VimCursor(self)
done = set()
not_done = set()
def _find_recursive(obj):
"""Finds all text objects and puts them into 'not_done'."""
if isinstance(obj, EditableTextObject):
@ -69,10 +79,10 @@ class SnippetInstance(EditableTextObject):
counter -= 1
if not counter:
raise RuntimeError(
"The snippets content did not converge: Check for Cyclic "
"dependencies or random strings in your snippet. You can use "
'The snippets content did not converge: Check for Cyclic '
'dependencies or random strings in your snippet. You can use '
"'if not snip.c' to make sure to only expand random output "
"once.")
'once.')
vc.to_vim()
self._del_child(vc)
@ -112,6 +122,7 @@ class SnippetInstance(EditableTextObject):
class _VimCursor(NoneditableTextObject):
"""Helper class to keep track of the Vim Cursor when text objects expand
and move."""

View File

@ -1,12 +1,18 @@
#!/usr/bin/env python
# encoding: utf-8
"""This is the most important TextObject. A TabStop is were the cursor
comes to rest when the user taps through the Snippet."""
"""This is the most important TextObject.
A TabStop is were the cursor comes to rest when the user taps through
the Snippet.
"""
from UltiSnips.text_objects._base import EditableTextObject
class TabStop(EditableTextObject):
"""See module docstring."""
def __init__(self, parent, token, start=None, end=None):
@ -16,7 +22,8 @@ class TabStop(EditableTextObject):
else:
self._number = token.number
EditableTextObject.__init__(self, parent, token)
parent._tabstops[self._number] = self # pylint:disable=protected-access
parent._tabstops[
self._number] = self # pylint:disable=protected-access
@property
def number(self):
@ -30,5 +37,5 @@ class TabStop(EditableTextObject):
return self._parent is None
def __repr__(self):
return "TabStop(%s,%r->%r,%r)" % (self.number, self._start,
self._end, self.current_text)
return 'TabStop(%s,%r->%r,%r)' % (self.number, self._start,
self._end, self.current_text)

View File

@ -9,47 +9,50 @@ import sys
from UltiSnips.text import unescape, fill_in_whitespace
from UltiSnips.text_objects._mirror import Mirror
def _find_closing_brace(string, start_pos):
"""Finds the corresponding closing brace after start_pos."""
bracks_open = 1
for idx, char in enumerate(string[start_pos:]):
if char == '(':
if string[idx+start_pos-1] != '\\':
if string[idx + start_pos - 1] != '\\':
bracks_open += 1
elif char == ')':
if string[idx+start_pos-1] != '\\':
if string[idx + start_pos - 1] != '\\':
bracks_open -= 1
if not bracks_open:
return start_pos+idx+1
return start_pos + idx + 1
def _split_conditional(string):
"""Split the given conditional 'string' into its arguments."""
bracks_open = 0
args = []
carg = ""
carg = ''
for idx, char in enumerate(string):
if char == '(':
if string[idx-1] != '\\':
if string[idx - 1] != '\\':
bracks_open += 1
elif char == ')':
if string[idx-1] != '\\':
if string[idx - 1] != '\\':
bracks_open -= 1
elif char == ':' and not bracks_open and not string[idx-1] == '\\':
elif char == ':' and not bracks_open and not string[idx - 1] == '\\':
args.append(carg)
carg = ""
carg = ''
continue
carg += char
args.append(carg)
return args
def _replace_conditional(match, string):
"""Replaces a conditional match in a transformation."""
conditional_match = _CONDITIONAL.search(string)
while conditional_match:
start = conditional_match.start()
end = _find_closing_brace(string, start+4)
args = _split_conditional(string[start+4:end-1])
rv = ""
end = _find_closing_brace(string, start + 4)
args = _split_conditional(string[start + 4:end - 1])
rv = ''
if match.group(int(conditional_match.group(1))):
rv = unescape(_replace_conditional(match, args[0]))
elif len(args) > 1:
@ -62,7 +65,10 @@ _ONE_CHAR_CASE_SWITCH = re.compile(r"\\([ul].)", re.DOTALL)
_LONG_CASEFOLDINGS = re.compile(r"\\([UL].*?)\\E", re.DOTALL)
_DOLLAR = re.compile(r"\$(\d+)", re.DOTALL)
_CONDITIONAL = re.compile(r"\(\?(\d+):", re.DOTALL)
class _CleverReplace(object):
"""Mimics TextMates replace syntax."""
def __init__(self, expression):
@ -73,7 +79,7 @@ class _CleverReplace(object):
transformed = self._expression
# Replace all $? with capture groups
transformed = _DOLLAR.subn(
lambda m: match.group(int(m.group(1))), transformed)[0]
lambda m: match.group(int(m.group(1))), transformed)[0]
# Replace Case switches
def _one_char_case_change(match):
@ -83,7 +89,7 @@ class _CleverReplace(object):
else:
return match.group(1)[-1].lower()
transformed = _ONE_CHAR_CASE_SWITCH.subn(
_one_char_case_change, transformed)[0]
_one_char_case_change, transformed)[0]
def _multi_char_case_change(match):
"""Replaces multi character case changes."""
@ -92,13 +98,16 @@ class _CleverReplace(object):
else:
return match.group(1)[1:].lower()
transformed = _LONG_CASEFOLDINGS.subn(
_multi_char_case_change, transformed)[0]
_multi_char_case_change, transformed)[0]
transformed = _replace_conditional(match, transformed)
return unescape(fill_in_whitespace(transformed))
# flag used to display only one time the lack of unidecode
UNIDECODE_ALERT_RAISED = False
class TextObjectTransformation(object):
"""Base class for Transformations and ${VISUAL}."""
def __init__(self, token):
@ -111,11 +120,11 @@ class TextObjectTransformation(object):
flags = 0
self._match_this_many = 1
if token.options:
if "g" in token.options:
if 'g' in token.options:
self._match_this_many = 0
if "i" in token.options:
if 'i' in token.options:
flags |= re.IGNORECASE
if "a" in token.options:
if 'a' in token.options:
self._convert_to_ascii = True
self._find = re.compile(token.search, flags | re.DOTALL)
@ -132,14 +141,16 @@ class TextObjectTransformation(object):
if UNIDECODE_ALERT_RAISED == False:
UNIDECODE_ALERT_RAISED = True
sys.stderr.write(
"Please install unidecode python package in order to "
"be able to make ascii conversions.\n")
'Please install unidecode python package in order to '
'be able to make ascii conversions.\n')
if self._find is None:
return text
return self._find.subn(
self._replace.replace, text, self._match_this_many)[0]
self._replace.replace, text, self._match_this_many)[0]
class Transformation(Mirror, TextObjectTransformation):
"""See module docstring."""
def __init__(self, parent, ts, token):

View File

@ -6,10 +6,13 @@
from UltiSnips import _vim
from UltiSnips.text_objects._base import NoneditableTextObject
class VimLCode(NoneditableTextObject):
"""See module docstring."""
def __init__(self, parent, token):
self._code = token.code.replace("\\`", "`").strip()
self._code = token.code.replace('\\`', '`').strip()
NoneditableTextObject.__init__(self, parent, token)

View File

@ -2,8 +2,11 @@
# encoding: utf-8
"""A ${VISUAL} placeholder that will use the text that was last visually
selected and insert it here. If there was no text visually selected, this will
be the empty string. """
selected and insert it here.
If there was no text visually selected, this will be the empty string.
"""
import re
import textwrap
@ -14,7 +17,10 @@ from UltiSnips.text_objects._transformation import TextObjectTransformation
from UltiSnips.text_objects._base import NoneditableTextObject
_REPLACE_NON_WS = re.compile(r"[^ \t]")
class Visual(NoneditableTextObject, TextObjectTransformation):
"""See module docstring."""
def __init__(self, parent, token):
@ -29,27 +35,27 @@ class Visual(NoneditableTextObject, TextObjectTransformation):
snippet = snippet._parent # pylint:disable=protected-access
if not self._text:
self._text = token.alternative_text
self._mode = "v"
self._mode = 'v'
NoneditableTextObject.__init__(self, parent, token)
TextObjectTransformation.__init__(self, token)
def _update(self, done):
if self._mode == "v": # Normal selection.
if self._mode == 'v': # Normal selection.
text = self._text
else: # Block selection or line selection.
text_before = _vim.buf[self.start.line][:self.start.col]
indent = _REPLACE_NON_WS.sub(" ", text_before)
indent = _REPLACE_NON_WS.sub(' ', text_before)
iu = IndentUtil()
indent = iu.indent_to_spaces(indent)
indent = iu.spaces_to_indent(indent)
text = ""
text = ''
for idx, line in enumerate(textwrap.dedent(
self._text).splitlines(True)):
if idx != 0:
text += indent
text += line
text = text[:-1] # Strip final '\n'
text = text[:-1] # Strip final '\n'
text = self._transform(text)
self.overwrite(text)

View File

@ -9,13 +9,15 @@ from UltiSnips import _vim
from UltiSnips.compatibility import as_unicode, byte2col
from UltiSnips.position import Position
class VimPosition(Position):
"""Represents the current position in the buffer, together with some status
variables that might change our decisions down the line."""
def __init__(self):
pos = _vim.buf.cursor
self._mode = _vim.eval("mode()")
self._mode = _vim.eval('mode()')
Position.__init__(self, pos.line, pos.col)
@property
@ -23,7 +25,9 @@ class VimPosition(Position):
"""Returns the mode() this position was created."""
return self._mode
class VimState(object):
"""Caches some state information from Vim to better guess what editing
tasks the user might have done in the last step."""
@ -31,7 +35,7 @@ class VimState(object):
self._poss = deque(maxlen=5)
self._lvb = None
self._text_to_expect = ""
self._text_to_expect = ''
self._unnamed_reg_cached = False
# We store the cached value of the unnamed register in Vim directly to
@ -43,10 +47,14 @@ class VimState(object):
_vim.command('let g:_ultisnips_unnamed_reg_cache = ""')
def remember_unnamed_register(self, text_to_expect):
"""Save the unnamed register. 'text_to_expect' is text that we expect
"""Save the unnamed register.
'text_to_expect' is text that we expect
to be contained in the register the next time this method is called -
this could be text from the tabstop that was selected and might have
been overwritten. We will not cache that then."""
been overwritten. We will not cache that then.
"""
self._unnamed_reg_cached = True
escaped_text = self._text_to_expect.replace("'", "''")
res = int(_vim.eval('@" != ' + "'" + escaped_text + "'"))
@ -67,7 +75,7 @@ class VimState(object):
def remember_buffer(self, to):
"""Remember the content of the buffer and the position."""
self._lvb = _vim.buf[to.start.line:to.end.line+1]
self._lvb = _vim.buf[to.start.line:to.end.line + 1]
self._lvb_len = len(_vim.buf)
self.remember_position()
@ -92,7 +100,9 @@ class VimState(object):
"""The content of the remembered buffer."""
return self._lvb[:]
class VisualContentPreserver(object):
"""Saves the current visual selection and the selection mode it was done in
(e.g. line selection, block selection or regular selection.)"""
@ -101,28 +111,28 @@ class VisualContentPreserver(object):
def reset(self):
"""Forget the preserved state."""
self._mode = ""
self._text = as_unicode("")
self._mode = ''
self._text = as_unicode('')
def conserve(self):
"""Save the last visual selection ond the mode it was made in."""
sl, sbyte = map(int,
(_vim.eval("""line("'<")"""), _vim.eval("""col("'<")""")))
(_vim.eval("""line("'<")"""), _vim.eval("""col("'<")""")))
el, ebyte = map(int,
(_vim.eval("""line("'>")"""), _vim.eval("""col("'>")""")))
(_vim.eval("""line("'>")"""), _vim.eval("""col("'>")""")))
sc = byte2col(sl, sbyte - 1)
ec = byte2col(el, ebyte - 1)
self._mode = _vim.eval("visualmode()")
self._mode = _vim.eval('visualmode()')
_vim_line_with_eol = lambda ln: _vim.buf[ln] + '\n'
if sl == el:
text = _vim_line_with_eol(sl-1)[sc:ec+1]
text = _vim_line_with_eol(sl - 1)[sc:ec + 1]
else:
text = _vim_line_with_eol(sl-1)[sc:]
for cl in range(sl, el-1):
text = _vim_line_with_eol(sl - 1)[sc:]
for cl in range(sl, el - 1):
text += _vim_line_with_eol(cl)
text += _vim_line_with_eol(el-1)[:ec+1]
text += _vim_line_with_eol(el - 1)[:ec + 1]
self._text = text
@property

View File

@ -12,13 +12,13 @@ ARR_D = '\x1bOB'
SEQUENCES = [ARR_L, ARR_R, ARR_U, ARR_D]
# Defined Constants
JF = "?" # Jump forwards
JB = "+" # Jump backwards
LS = "@" # List snippets
EX = "\t" # EXPAND
EA = "#" # Expand anonymous
JF = '?' # Jump forwards
JB = '+' # Jump backwards
LS = '@' # List snippets
EX = '\t' # EXPAND
EA = '#' # Expand anonymous
COMPL_KW = chr(24) + chr(14)
COMPL_ACCEPT = chr(25)
PYTHON3 = sys.version_info >= (3,0)
PYTHON3 = sys.version_info >= (3, 0)

View File

@ -2,53 +2,66 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Anonymous Expansion {{{#
class _AnonBase(_VimTest):
args = ""
args = ''
def _extra_options_pre_init(self, vim_config):
vim_config.append("inoremap <silent> %s <C-R>=UltiSnips#Anon(%s)<cr>"
% (EA, self.args))
vim_config.append('inoremap <silent> %s <C-R>=UltiSnips#Anon(%s)<cr>'
% (EA, self.args))
class Anon_NoTrigger_Simple(_AnonBase):
args = '"simple expand"'
keys = "abc" + EA
wanted = "abcsimple expand"
keys = 'abc' + EA
wanted = 'abcsimple expand'
class Anon_NoTrigger_AfterSpace(_AnonBase):
args = '"simple expand"'
keys = "abc " + EA
wanted = "abc simple expand"
keys = 'abc ' + EA
wanted = 'abc simple expand'
class Anon_NoTrigger_BeginningOfLine(_AnonBase):
args = r"':latex:\`$1\`$0'"
keys = EA + "Hello" + JF + "World"
wanted = ":latex:`Hello`World"
keys = EA + 'Hello' + JF + 'World'
wanted = ':latex:`Hello`World'
class Anon_NoTrigger_FirstCharOfLine(_AnonBase):
args = r"':latex:\`$1\`$0'"
keys = " " + EA + "Hello" + JF + "World"
wanted = " :latex:`Hello`World"
keys = ' ' + EA + 'Hello' + JF + 'World'
wanted = ' :latex:`Hello`World'
class Anon_NoTrigger_Multi(_AnonBase):
args = '"simple $1 expand $1 $0"'
keys = "abc" + EA + "123" + JF + "456"
wanted = "abcsimple 123 expand 123 456"
keys = 'abc' + EA + '123' + JF + '456'
wanted = 'abcsimple 123 expand 123 456'
class Anon_Trigger_Multi(_AnonBase):
args = '"simple $1 expand $1 $0", "abc"'
keys = "123 abc" + EA + "123" + JF + "456"
wanted = "123 simple 123 expand 123 456"
keys = '123 abc' + EA + '123' + JF + '456'
wanted = '123 simple 123 expand 123 456'
class Anon_Trigger_Simple(_AnonBase):
args = '"simple expand", "abc"'
keys = "abc" + EA
wanted = "simple expand"
keys = 'abc' + EA
wanted = 'simple expand'
class Anon_Trigger_Twice(_AnonBase):
args = '"simple expand", "abc"'
keys = "abc" + EA + "\nabc" + EX
wanted = "simple expand\nabc" + EX
keys = 'abc' + EA + '\nabc' + EX
wanted = 'simple expand\nabc' + EX
class Anon_Trigger_Opts(_AnonBase):
args = '"simple expand", ".*abc", "desc", "r"'
keys = "blah blah abc" + EA
wanted = "simple expand"
keys = 'blah blah abc' + EA
wanted = 'simple expand'
# End: Anonymous Expansion #}}}

View File

@ -5,122 +5,141 @@ from test.util import running_on_windows
# Quotes in Snippets {{{#
# Test for Bug #774917
def _snip_quote(qt):
return (
("te" + qt + "st", "Expand me" + qt + "!", "test: "+qt),
("te", "Bad", ""),
)
('te' + qt + 'st', 'Expand me' + qt + '!', 'test: ' + qt),
('te', 'Bad', ''),
)
class Snippet_With_SingleQuote(_VimTest):
snippets = _snip_quote("'")
keys = "te'st" + EX
wanted = "Expand me'!"
class Snippet_With_SingleQuote_List(_VimTest):
snippets = _snip_quote("'")
keys = "te" + LS + "2\n"
keys = 'te' + LS + '2\n'
wanted = "Expand me'!"
class Snippet_With_DoubleQuote(_VimTest):
snippets = _snip_quote('"')
keys = 'te"st' + EX
wanted = "Expand me\"!"
class Snippet_With_DoubleQuote_List(_VimTest):
snippets = _snip_quote('"')
keys = "te" + LS + "2\n"
keys = 'te' + LS + '2\n'
wanted = "Expand me\"!"
# End: Quotes in Snippets #}}}
# Trailing whitespace {{{#
class RemoveTrailingWhitespace(_VimTest):
snippets = ("test", """Hello\t ${1:default}\n$2""", "", "s")
snippets = ('test', """Hello\t ${1:default}\n$2""", '', 's')
wanted = """Hello\nGoodbye"""
keys = "test" + EX + BS + JF + "Goodbye"
keys = 'test' + EX + BS + JF + 'Goodbye'
class LeaveTrailingWhitespace(_VimTest):
snippets = ("test", """Hello \t ${1:default}\n$2""")
snippets = ('test', """Hello \t ${1:default}\n$2""")
wanted = """Hello \t \nGoodbye"""
keys = "test" + EX + BS + JF + "Goodbye"
keys = 'test' + EX + BS + JF + 'Goodbye'
# End: Trailing whitespace #}}}
# Newline in default text {{{#
# Tests for bug 616315 #
class TrailingNewline_TabStop_NLInsideStuffBehind(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:
}<-behind1
$2<-behind2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj<-behind1
k<-behind2"""
class TrailingNewline_TabStop_JustNL(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:
}
$2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k"""
class TrailingNewline_TabStop_EndNL(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:a
}
$2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k"""
class TrailingNewline_TabStop_StartNL(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:
a}
$2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k"""
class TrailingNewline_TabStop_EndStartNL(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:
a
}
$2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k"""
class TrailingNewline_TabStop_NotEndStartNL(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:a
a}
$2""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k"""
class TrailingNewline_TabStop_ExtraNL_ECR(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:a
a}
$2
""")
keys = "test" + EX + "j" + JF + "k"
keys = 'test' + EX + 'j' + JF + 'k'
wanted = """
xj
k
"""
class _MultiLineDefault(_VimTest):
snippets = ("test", r"""
snippets = ('test', r"""
x${1:a
b
c
@ -129,8 +148,9 @@ e
f}
$2""")
class MultiLineDefault_Jump(_MultiLineDefault):
keys = "test" + EX + JF + "y"
keys = 'test' + EX + JF + 'y'
wanted = """
xa
b
@ -140,14 +160,16 @@ e
f
y"""
class MultiLineDefault_Type(_MultiLineDefault):
keys = "test" + EX + "z" + JF + "y"
keys = 'test' + EX + 'z' + JF + 'y'
wanted = """
xz
y"""
class MultiLineDefault_BS(_MultiLineDefault):
keys = "test" + EX + BS + JF + "y"
keys = 'test' + EX + BS + JF + 'y'
wanted = """
x
y"""
@ -155,42 +177,57 @@ y"""
# End: Newline in default text #}}}
# Umlauts and Special Chars {{{#
class _UmlautsBase(_VimTest):
skip_if = lambda self: running_on_windows() # SendKeys can't send UTF characters
# SendKeys can't send UTF characters
skip_if = lambda self: running_on_windows()
class Snippet_With_Umlauts_List(_UmlautsBase):
snippets = _snip_quote('ü')
keys = 'te' + LS + "2\n"
wanted = "Expand meü!"
keys = 'te' + LS + '2\n'
wanted = 'Expand meü!'
class Snippet_With_Umlauts(_UmlautsBase):
snippets = _snip_quote('ü')
keys = 'teüst' + EX
wanted = "Expand meü!"
wanted = 'Expand meü!'
class Snippet_With_Umlauts_TypeOn(_UmlautsBase):
snippets = ('ül', 'üüüüüßßßß')
keys = 'te ül' + EX + "more text"
wanted = "te üüüüüßßßßmore text"
keys = 'te ül' + EX + 'more text'
wanted = 'te üüüüüßßßßmore text'
class Snippet_With_Umlauts_OverwriteFirst(_UmlautsBase):
snippets = ('ül', 'üü ${1:world} üü ${2:hello}ßß\nüüüü')
keys = 'te ül' + EX + "more text" + JF + JF + "end"
wanted = "te üü more text üü helloßß\nüüüüend"
keys = 'te ül' + EX + 'more text' + JF + JF + 'end'
wanted = 'te üü more text üü helloßß\nüüüüend'
class Snippet_With_Umlauts_OverwriteSecond(_UmlautsBase):
snippets = ('ül', 'üü ${1:world} üü ${2:hello}ßß\nüüüü')
keys = 'te ül' + EX + JF + "more text" + JF + "end"
wanted = "te üü world üü more textßß\nüüüüend"
keys = 'te ül' + EX + JF + 'more text' + JF + 'end'
wanted = 'te üü world üü more textßß\nüüüüend'
class Snippet_With_Umlauts_OverwriteNone(_UmlautsBase):
snippets = ('ül', 'üü ${1:world} üü ${2:hello}ßß\nüüüü')
keys = 'te ül' + EX + JF + JF + "end"
wanted = "te üü world üü helloßß\nüüüüend"
keys = 'te ül' + EX + JF + JF + 'end'
wanted = 'te üü world üü helloßß\nüüüüend'
class Snippet_With_Umlauts_Mirrors(_UmlautsBase):
snippets = ('ül', 'üü ${1:world} üü $1')
keys = 'te ül' + EX + "hello"
wanted = "te üü hello üü hello"
keys = 'te ül' + EX + 'hello'
wanted = 'te üü hello üü hello'
class Snippet_With_Umlauts_Python(_UmlautsBase):
snippets = ('ül', 'üü ${1:world} üü `!p snip.rv = len(t[1])*"a"`')
keys = 'te ül' + EX + "hüüll"
wanted = "te üü hüüll üü aaaaa"
keys = 'te ül' + EX + 'hüüll'
wanted = 'te üü hüüll üü aaaaa'
# End: Umlauts and Special Chars #}}}

View File

@ -2,29 +2,33 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Tab Completion of Words {{{#
class Completion_SimpleExample_ECR(_VimTest):
snippets = ("test", "$1 ${1:blah}")
keys = "superkallifragilistik\ntest" + EX + "sup" + COMPL_KW + \
COMPL_ACCEPT + " some more"
wanted = "superkallifragilistik\nsuperkallifragilistik some more " \
"superkallifragilistik some more"
snippets = ('test', '$1 ${1:blah}')
keys = 'superkallifragilistik\ntest' + EX + 'sup' + COMPL_KW + \
COMPL_ACCEPT + ' some more'
wanted = 'superkallifragilistik\nsuperkallifragilistik some more ' \
'superkallifragilistik some more'
# We need >2 different words with identical starts to create the
# popup-menu:
COMPLETION_OPTIONS = "completion1\ncompletion2\n"
COMPLETION_OPTIONS = 'completion1\ncompletion2\n'
class Completion_ForwardsJumpWithoutCOMPL_ACCEPT(_VimTest):
# completions should not be truncated when JF is activated without having
# pressed COMPL_ACCEPT (Bug #598903)
snippets = ("test", "$1 $2")
keys = COMPLETION_OPTIONS + "test" + EX + "com" + COMPL_KW + JF + "foo"
wanted = COMPLETION_OPTIONS + "completion1 foo"
snippets = ('test', '$1 $2')
keys = COMPLETION_OPTIONS + 'test' + EX + 'com' + COMPL_KW + JF + 'foo'
wanted = COMPLETION_OPTIONS + 'completion1 foo'
class Completion_BackwardsJumpWithoutCOMPL_ACCEPT(_VimTest):
# completions should not be truncated when JB is activated without having
# pressed COMPL_ACCEPT (Bug #598903)
snippets = ("test", "$1 $2")
keys = COMPLETION_OPTIONS + "test" + EX + "foo" + JF + "com" + COMPL_KW + \
JB + "foo"
wanted = COMPLETION_OPTIONS + "foo completion1"
snippets = ('test', '$1 $2')
keys = COMPLETION_OPTIONS + 'test' + EX + 'foo' + JF + 'com' + COMPL_KW + \
JB + 'foo'
wanted = COMPLETION_OPTIONS + 'foo completion1'
# End: Tab Completion of Words #}}}

View File

@ -2,63 +2,88 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Undo of Snippet insertion {{{#
class Undo_RemoveMultilineSnippet(_VimTest):
snippets = ("test", "Hello\naaa ${1} bbb\nWorld")
keys = "test" + EX + ESC + "u" + "inothing"
wanted = "nothing"
snippets = ('test', 'Hello\naaa ${1} bbb\nWorld')
keys = 'test' + EX + ESC + 'u' + 'inothing'
wanted = 'nothing'
class Undo_RemoveEditInTabstop(_VimTest):
snippets = ("test", "$1 Hello\naaa ${1} bbb\nWorld")
keys = "hello test" + EX + "upsi" + ESC + "hh" + "iabcdef" + ESC + "u"
wanted = "hello upsi Hello\naaa upsi bbb\nWorld"
snippets = ('test', '$1 Hello\naaa ${1} bbb\nWorld')
keys = 'hello test' + EX + 'upsi' + ESC + 'hh' + 'iabcdef' + ESC + 'u'
wanted = 'hello upsi Hello\naaa upsi bbb\nWorld'
class Undo_RemoveWholeSnippet(_VimTest):
snippets = ("test", "Hello\n${1:Hello}World")
keys = "first line\n\n\n\n\n\nthird line" + \
ESC + "3k0itest" + EX + ESC + "uiupsy"
wanted = "first line\n\n\nupsy\n\n\nthird line"
snippets = ('test', 'Hello\n${1:Hello}World')
keys = 'first line\n\n\n\n\n\nthird line' + \
ESC + '3k0itest' + EX + ESC + 'uiupsy'
wanted = 'first line\n\n\nupsy\n\n\nthird line'
class JumpForward_DefSnippet(_VimTest):
snippets = ("test", "${1}\n`!p snip.rv = '\\n'.join(t[1].split())`\n\n${0:pass}")
keys = "test" + EX + "a b c" + JF + "shallnot"
wanted = "a b c\na\nb\nc\n\nshallnot"
snippets = (
'test',
"${1}\n`!p snip.rv = '\\n'.join(t[1].split())`\n\n${0:pass}")
keys = 'test' + EX + 'a b c' + JF + 'shallnot'
wanted = 'a b c\na\nb\nc\n\nshallnot'
class DeleteSnippetInsertion0(_VimTest):
snippets = ("test", "${1:hello} $1")
keys = "test" + EX + ESC + "Vkx" + "i\nworld\n"
wanted = "world"
snippets = ('test', '${1:hello} $1')
keys = 'test' + EX + ESC + 'Vkx' + 'i\nworld\n'
wanted = 'world'
class DeleteSnippetInsertion1(_VimTest):
snippets = ("test", r"$1${1/(.*)/(?0::.)/}")
keys = "test" + EX + ESC + "u" + "i" + JF + "\t"
wanted = "\t"
snippets = ('test', r"$1${1/(.*)/(?0::.)/}")
keys = 'test' + EX + ESC + 'u' + 'i' + JF + '\t'
wanted = '\t'
# End: Undo of Snippet insertion #}}}
# Normal mode editing {{{#
# Test for bug #927844
class DeleteLastTwoLinesInSnippet(_VimTest):
snippets = ("test", "$1hello\nnice\nworld")
keys = "test" + EX + ESC + "j2dd"
wanted = "hello"
snippets = ('test', '$1hello\nnice\nworld')
keys = 'test' + EX + ESC + 'j2dd'
wanted = 'hello'
class DeleteCurrentTabStop1_JumpBack(_VimTest):
snippets = ("test", "${1:hi}\nend")
keys = "test" + EX + ESC + "ddi" + JB
wanted = "end"
snippets = ('test', '${1:hi}\nend')
keys = 'test' + EX + ESC + 'ddi' + JB
wanted = 'end'
class DeleteCurrentTabStop2_JumpBack(_VimTest):
snippets = ("test", "${1:hi}\n${2:world}\nend")
keys = "test" + EX + JF + ESC + "ddi" + JB + "hello"
wanted = "hello\nend"
snippets = ('test', '${1:hi}\n${2:world}\nend')
keys = 'test' + EX + JF + ESC + 'ddi' + JB + 'hello'
wanted = 'hello\nend'
class DeleteCurrentTabStop3_JumpAround(_VimTest):
snippets = ("test", "${1:hi}\n${2:world}\nend")
keys = "test" + EX + JF + ESC + "ddkji" + JB + "hello" + JF + "world"
wanted = "hello\nendworld"
snippets = ('test', '${1:hi}\n${2:world}\nend')
keys = 'test' + EX + JF + ESC + 'ddkji' + JB + 'hello' + JF + 'world'
wanted = 'hello\nendworld'
# End: Normal mode editing #}}}
# Pressing BS in TabStop {{{#
# Test for Bug #774917
class Backspace_TabStop_Zero(_VimTest):
snippets = ("test", "A${1:C} ${0:DDD}", "This is Case 1")
keys = "test" + EX + "A" + JF + BS + "BBB"
wanted = "AA BBB"
snippets = ('test', 'A${1:C} ${0:DDD}', 'This is Case 1')
keys = 'test' + EX + 'A' + JF + BS + 'BBB'
wanted = 'AA BBB'
class Backspace_TabStop_NotZero(_VimTest):
snippets = ("test", "A${1:C} ${2:DDD}", "This is Case 1")
keys = "test" + EX + "A" + JF + BS + "BBB"
wanted = "AA BBB"
snippets = ('test', 'A${1:C} ${2:DDD}', 'This is Case 1')
keys = 'test' + EX + 'A' + JF + BS + 'BBB'
wanted = 'AA BBB'
# End: Pressing BS in TabStop #}}}

View File

@ -2,54 +2,72 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Simple Expands {{{#
class _SimpleExpands(_VimTest):
snippets = ("hallo", "Hallo Welt!")
snippets = ('hallo', 'Hallo Welt!')
class SimpleExpand_ExpectCorrectResult(_SimpleExpands):
keys = "hallo" + EX
wanted = "Hallo Welt!"
keys = 'hallo' + EX
wanted = 'Hallo Welt!'
class SimpleExpandTwice_ExpectCorrectResult(_SimpleExpands):
keys = "hallo" + EX + '\nhallo' + EX
wanted = "Hallo Welt!\nHallo Welt!"
keys = 'hallo' + EX + '\nhallo' + EX
wanted = 'Hallo Welt!\nHallo Welt!'
class SimpleExpandNewLineAndBackspae_ExpectCorrectResult(_SimpleExpands):
keys = "hallo" + EX + "\nHallo Welt!\n\n\b\b\b\b\b"
wanted = "Hallo Welt!\nHallo We"
keys = 'hallo' + EX + '\nHallo Welt!\n\n\b\b\b\b\b'
wanted = 'Hallo Welt!\nHallo We'
def _extra_options_pre_init(self, vim_config):
vim_config.append("set backspace=eol,start")
vim_config.append('set backspace=eol,start')
class SimpleExpandTypeAfterExpand_ExpectCorrectResult(_SimpleExpands):
keys = "hallo" + EX + "and again"
wanted = "Hallo Welt!and again"
keys = 'hallo' + EX + 'and again'
wanted = 'Hallo Welt!and again'
class SimpleExpandTypeAndDelete_ExpectCorrectResult(_SimpleExpands):
keys = "na du hallo" + EX + "and again\b\b\b\b\bblub"
wanted = "na du Hallo Welt!and blub"
keys = 'na du hallo' + EX + 'and again\b\b\b\b\bblub'
wanted = 'na du Hallo Welt!and blub'
class DoNotExpandAfterSpace_ExpectCorrectResult(_SimpleExpands):
keys = "hallo " + EX
wanted = "hallo " + EX
keys = 'hallo ' + EX
wanted = 'hallo ' + EX
class ExitSnippetModeAfterTabstopZero(_VimTest):
snippets = ("test", "SimpleText")
keys = "test" + EX + EX
wanted = "SimpleText" + EX
snippets = ('test', 'SimpleText')
keys = 'test' + EX + EX
wanted = 'SimpleText' + EX
class ExpandInTheMiddleOfLine_ExpectCorrectResult(_SimpleExpands):
keys = "Wie hallo gehts" + ESC + "bhi" + EX
wanted = "Wie Hallo Welt! gehts"
keys = 'Wie hallo gehts' + ESC + 'bhi' + EX
wanted = 'Wie Hallo Welt! gehts'
class MultilineExpand_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "Hallo Welt!\nUnd Wie gehts")
keys = "Wie hallo gehts" + ESC + "bhi" + EX
wanted = "Wie Hallo Welt!\nUnd Wie gehts gehts"
snippets = ('hallo', 'Hallo Welt!\nUnd Wie gehts')
keys = 'Wie hallo gehts' + ESC + 'bhi' + EX
wanted = 'Wie Hallo Welt!\nUnd Wie gehts gehts'
class MultilineExpandTestTyping_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "Hallo Welt!\nUnd Wie gehts")
wanted = "Wie Hallo Welt!\nUnd Wie gehtsHuiui! gehts"
keys = "Wie hallo gehts" + ESC + "bhi" + EX + "Huiui!"
snippets = ('hallo', 'Hallo Welt!\nUnd Wie gehts')
wanted = 'Wie Hallo Welt!\nUnd Wie gehtsHuiui! gehts'
keys = 'Wie hallo gehts' + ESC + 'bhi' + EX + 'Huiui!'
class SimpleExpandEndingWithNewline_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "Hallo Welt\n")
keys = "hallo" + EX + "\nAnd more"
wanted = "Hallo Welt\n\nAnd more"
snippets = ('hallo', 'Hallo Welt\n')
keys = 'hallo' + EX + '\nAnd more'
wanted = 'Hallo Welt\n\nAnd more'
# End: Simple Expands #}}}

View File

@ -2,17 +2,21 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Test for bug 1251994 {{{#
class Bug1251994(_VimTest):
snippets = ("test", "${2:#2} ${1:#1};$0")
keys = " test" + EX + "hello" + JF + "world" + JF + "blub"
wanted = " world hello;blub"
snippets = ('test', '${2:#2} ${1:#1};$0')
keys = ' test' + EX + 'hello' + JF + 'world' + JF + 'blub'
wanted = ' world hello;blub'
# End: 1251994 #}}}
# Test for https://github.com/SirVer/ultisnips/issues/157 (virtualedit) {{{#
class VirtualEdit(_VimTest):
snippets = ("pd", "padding: ${1:0}px")
keys = "\t\t\tpd" + EX + "2"
wanted = "\t\t\tpadding: 2px"
snippets = ('pd', 'padding: ${1:0}px')
keys = '\t\t\tpd' + EX + '2'
wanted = '\t\t\tpadding: 2px'
def _extra_options_pre_init(self, vim_config):
vim_config.append('set virtualedit=all')
@ -20,51 +24,61 @@ class VirtualEdit(_VimTest):
# End: 1251994 #}}}
# Test for Github Pull Request #134 - Retain unnamed register {{{#
class RetainsTheUnnamedRegister(_VimTest):
snippets = ("test", "${1:hello} ${2:world} ${0}")
keys = "yank" + ESC + "by4lea test" + EX + "HELLO" + JF + JF + ESC + "p"
wanted = "yank HELLO world yank"
snippets = ('test', '${1:hello} ${2:world} ${0}')
keys = 'yank' + ESC + 'by4lea test' + EX + 'HELLO' + JF + JF + ESC + 'p'
wanted = 'yank HELLO world yank'
class RetainsTheUnnamedRegister_ButOnlyOnce(_VimTest):
snippets = ("test", "${1:hello} ${2:world} ${0}")
keys = "blahfasel" + ESC + "v" + 4*ARR_L + "xotest" + EX + ESC + ARR_U + "v0xo" + ESC + "p"
wanted = "\nblah\nhello world "
snippets = ('test', '${1:hello} ${2:world} ${0}')
keys = 'blahfasel' + ESC + 'v' + 4 * ARR_L + \
'xotest' + EX + ESC + ARR_U + 'v0xo' + ESC + 'p'
wanted = '\nblah\nhello world '
# End: Github Pull Request # 134 #}}}
# Test to ensure that shiftwidth follows tabstop when it's set to zero post
# version 7.3.693. Prior to that version a shiftwidth of zero effectively
# removes tabs.
class ShiftWidthZero(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config += [
"if exists('*shiftwidth')",
" set shiftwidth=0",
"endif",
]
snippets = ("test", "\t${1}${0}")
keys = "test" + EX + "foo"
wanted = "\tfoo"
def _extra_options_pre_init(self, vim_config):
vim_config += [
"if exists('*shiftwidth')",
' set shiftwidth=0',
'endif',
]
snippets = ('test', '\t${1}${0}')
keys = 'test' + EX + 'foo'
wanted = '\tfoo'
# Test for https://github.com/SirVer/ultisnips/issues/171 {{{#
# Make sure that we don't crash when trying to save and restore the clipboard
# when it contains data that we can't coerce into Unicode.
class NonUnicodeDataInUnnamedRegister(_VimTest):
snippets = ("test", "hello")
keys = "test" + EX + ESC + \
"\n".join([":redir @a",
":messages",
":redir END",
(":if match(@a, 'Error') != -1 | " +
"call setline('.', 'error detected') | " +
"3put a | " +
"endif"),
""])
wanted = "hello"
snippets = ('test', 'hello')
keys = 'test' + EX + ESC + \
'\n'.join([':redir @a',
':messages',
':redir END',
(":if match(@a, 'Error') != -1 | " +
"call setline('.', 'error detected') | " +
'3put a | ' +
'endif'),
''])
wanted = 'hello'
def _before_test(self):
# The string below was the one a user had on their clipboard when
# encountering the UnicodeDecodeError and could not be coerced into
# unicode.
self.vim.send(
':let @" = "\\x80kdI{\\x80@7 1},' +
'\\x80kh\\x80kh\\x80kd\\x80kdq\\x80kb\\x1b"\n')
':let @" = "\\x80kdI{\\x80@7 1},' +
'\\x80kh\\x80kh\\x80kd\\x80kdq\\x80kb\\x1b"\n')
# End: #171 #}}}

View File

@ -2,41 +2,50 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Folding Interaction {{{#
class FoldingEnabled_SnippetWithFold_ExpectNoFolding(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set foldlevel=0")
vim_config.append("set foldmethod=marker")
snippets = ("test", r"""Hello {{{
vim_config.append('set foldlevel=0')
vim_config.append('set foldmethod=marker')
snippets = ('test', r"""Hello {{{
${1:Welt} }}}""")
keys = "test" + EX + "Ball"
keys = 'test' + EX + 'Ball'
wanted = """Hello {{{
Ball }}}"""
class FoldOverwrite_Simple_ECR(_VimTest):
snippets = ("fold",
"""# ${1:Description} `!p snip.rv = vim.eval("&foldmarker").split(",")[0]`
snippets = ('fold',
"""# ${1:Description} `!p snip.rv = vim.eval("&foldmarker").split(",")[0]`
# End: $1 `!p snip.rv = vim.eval("&foldmarker").split(",")[1]`""")
keys = "fold" + EX + "hi"
wanted = "# hi {{{\n\n# End: hi }}}"
keys = 'fold' + EX + 'hi'
wanted = '# hi {{{\n\n# End: hi }}}'
class Fold_DeleteMiddleLine_ECR(_VimTest):
snippets = ("fold",
"""# ${1:Description} `!p snip.rv = vim.eval("&foldmarker").split(",")[0]`
snippets = ('fold',
"""# ${1:Description} `!p snip.rv = vim.eval("&foldmarker").split(",")[0]`
# End: $1 `!p snip.rv = vim.eval("&foldmarker").split(",")[1]`""")
keys = "fold" + EX + "hi" + ESC + "jdd"
wanted = "# hi {{{\n\n# End: hi }}}"
keys = 'fold' + EX + 'hi' + ESC + 'jdd'
wanted = '# hi {{{\n\n# End: hi }}}'
class PerlSyntaxFold(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set foldlevel=0")
vim_config.append("syntax enable")
vim_config.append("set foldmethod=syntax")
vim_config.append("let g:perl_fold = 1")
vim_config.append("so $VIMRUNTIME/syntax/perl.vim")
snippets = ("test", r"""package ${1:`!v printf('c%02d', 3)`};
vim_config.append('set foldlevel=0')
vim_config.append('syntax enable')
vim_config.append('set foldmethod=syntax')
vim_config.append('let g:perl_fold = 1')
vim_config.append('so $VIMRUNTIME/syntax/perl.vim')
snippets = ('test', r"""package ${1:`!v printf('c%02d', 3)`};
${0}
1;""")
keys = "test" + EX + JF + "sub junk {}"
wanted = "package c03;\nsub junk {}\n1;"
keys = 'test' + EX + JF + 'sub junk {}'
wanted = 'package c03;\nsub junk {}\n1;'
# End: Folding Interaction #}}}

View File

@ -3,15 +3,20 @@ from test.constant import *
from test.util import running_on_windows
# ExpandTab {{{#
class _ExpandTabs(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set expandtab")
vim_config.append('set sw=3')
vim_config.append('set expandtab')
class RecTabStopsWithExpandtab_SimpleExample_ECR(_ExpandTabs):
snippets = ("m", "\tBlaahblah \t\t ")
keys = "m" + EX
wanted = " Blaahblah \t\t "
snippets = ('m', '\tBlaahblah \t\t ')
keys = 'm' + EX
wanted = ' Blaahblah \t\t '
class RecTabStopsWithExpandtab_SpecialIndentProblem_ECR(_ExpandTabs):
# Windows indents the Something line after pressing return, though it
@ -22,37 +27,47 @@ class RecTabStopsWithExpandtab_SpecialIndentProblem_ECR(_ExpandTabs):
# completely.
skip_if = lambda self: running_on_windows()
snippets = (
("m1", "Something"),
("m", "\t$0"),
('m1', 'Something'),
('m', '\t$0'),
)
keys = "m" + EX + "m1" + EX + '\nHallo'
wanted = " Something\n Hallo"
keys = 'm' + EX + 'm1' + EX + '\nHallo'
wanted = ' Something\n Hallo'
def _extra_options_pre_init(self, vim_config):
_ExpandTabs._extra_options_pre_init(self, vim_config)
vim_config.append("set indentkeys=o,O,*<Return>,<>>,{,}")
vim_config.append("set indentexpr=8")
vim_config.append('set indentkeys=o,O,*<Return>,<>>,{,}')
vim_config.append('set indentexpr=8')
# End: ExpandTab #}}}
# Proper Indenting {{{#
class ProperIndenting_SimpleCase_ECR(_VimTest):
snippets = ("test", "for\n blah")
keys = " test" + EX + "Hui"
wanted = " for\n blahHui"
snippets = ('test', 'for\n blah')
keys = ' test' + EX + 'Hui'
wanted = ' for\n blahHui'
class ProperIndenting_SingleLineNoReindenting_ECR(_VimTest):
snippets = ("test", "hui")
keys = " test" + EX + "blah"
wanted = " huiblah"
snippets = ('test', 'hui')
keys = ' test' + EX + 'blah'
wanted = ' huiblah'
class ProperIndenting_AutoIndentAndNewline_ECR(_VimTest):
snippets = ("test", "hui")
keys = " test" + EX + "\n"+ "blah"
wanted = " hui\n blah"
snippets = ('test', 'hui')
keys = ' test' + EX + '\n' + 'blah'
wanted = ' hui\n blah'
def _extra_options_pre_init(self, vim_config):
vim_config.append("set autoindent")
vim_config.append('set autoindent')
# Test for bug 1073816
class ProperIndenting_FirstLineInFile_ECR(_VimTest):
text_before = ""
text_after = ""
files = { "us/all.snippets": r"""
text_before = ''
text_after = ''
files = { 'us/all.snippets': r"""
global !p
def complete(t, opts):
if t:
@ -69,31 +84,41 @@ snippet '^#?inc' "#include <>" !r
#include <$1`!p snip.rv = complete(t[1], ['cassert', 'cstdio', 'cstdlib', 'cstring', 'fstream', 'iostream', 'sstream'])`>
endsnippet
"""}
keys = "inc" + EX + "foo"
wanted = "#include <foo>"
class ProperIndenting_FirstLineInFileComplete_ECR(ProperIndenting_FirstLineInFile_ECR):
keys = "inc" + EX + "cstdl"
wanted = "#include <cstdlib>"
keys = 'inc' + EX + 'foo'
wanted = '#include <foo>'
class ProperIndenting_FirstLineInFileComplete_ECR(
ProperIndenting_FirstLineInFile_ECR):
keys = 'inc' + EX + 'cstdl'
wanted = '#include <cstdlib>'
# End: Proper Indenting #}}}
# Format options tests {{{#
class _FormatoptionsBase(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set tw=20")
vim_config.append("set fo=lrqntc")
vim_config.append('set tw=20')
vim_config.append('set fo=lrqntc')
class FOSimple_Break_ExpectCorrectResult(_FormatoptionsBase):
snippets = ("test", "${1:longer expand}\n$1\n$0", "", "f")
keys = "test" + EX + "This is a longer text that should wrap as formatoptions are enabled" + JF + "end"
wanted = "This is a longer\ntext that should\nwrap as\nformatoptions are\nenabled\n" + \
"This is a longer\ntext that should\nwrap as\nformatoptions are\nenabled\n" + "end"
snippets = ('test', '${1:longer expand}\n$1\n$0', '', 'f')
keys = 'test' + EX + \
'This is a longer text that should wrap as formatoptions are enabled' + \
JF + 'end'
wanted = 'This is a longer\ntext that should\nwrap as\nformatoptions are\nenabled\n' + \
'This is a longer\ntext that should\nwrap as\nformatoptions are\nenabled\n' + \
'end'
class FOTextBeforeAndAfter_ExpectCorrectResult(_FormatoptionsBase):
snippets = ("test", "Before${1:longer expand}After\nstart$1end")
keys = "test" + EX + "This is a longer text that should wrap"
snippets = ('test', 'Before${1:longer expand}After\nstart$1end')
keys = 'test' + EX + 'This is a longer text that should wrap'
wanted = \
"""BeforeThis is a
"""BeforeThis is a
longer text that
should wrapAfter
startThis is a
@ -103,11 +128,11 @@ should wrapend"""
# Tests for https://bugs.launchpad.net/bugs/719998
class FOTextAfter_ExpectCorrectResult(_FormatoptionsBase):
snippets = ("test", "${1:longer expand}after\nstart$1end")
keys = ("test" + EX + "This is a longer snippet that should wrap properly "
"and the mirror below should work as well")
snippets = ('test', '${1:longer expand}after\nstart$1end')
keys = ('test' + EX + 'This is a longer snippet that should wrap properly '
'and the mirror below should work as well')
wanted = \
"""This is a longer
"""This is a longer
snippet that should
wrap properly and
the mirror below
@ -118,11 +143,12 @@ wrap properly and
the mirror below
should work as wellend"""
class FOWrapOnLongWord_ExpectCorrectResult(_FormatoptionsBase):
snippets = ("test", "${1:longer expand}after\nstart$1end")
keys = ("test" + EX + "This is a longersnippet that should wrap properly")
snippets = ('test', '${1:longer expand}after\nstart$1end')
keys = ('test' + EX + 'This is a longersnippet that should wrap properly')
wanted = \
"""This is a
"""This is a
longersnippet that
should wrap properlyafter
startThis is a

View File

@ -4,141 +4,181 @@ from test.constant import *
from test.util import running_on_windows
# ShellCode Interpolation {{{#
class TabStop_Shell_SimpleExample(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", "hi `echo hallo` you!")
keys = "test" + EX + "and more"
wanted = "hi hallo you!and more"
snippets = ('test', 'hi `echo hallo` you!')
keys = 'test' + EX + 'and more'
wanted = 'hi hallo you!and more'
class TabStop_Shell_WithUmlauts(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", "hi `echo höüäh` you!")
keys = "test" + EX + "and more"
wanted = "hi höüäh you!and more"
snippets = ('test', 'hi `echo höüäh` you!')
keys = 'test' + EX + 'and more'
wanted = 'hi höüäh you!and more'
class TabStop_Shell_TextInNextLine(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", "hi `echo hallo`\nWeiter")
keys = "test" + EX + "and more"
wanted = "hi hallo\nWeiterand more"
snippets = ('test', 'hi `echo hallo`\nWeiter')
keys = 'test' + EX + 'and more'
wanted = 'hi hallo\nWeiterand more'
class TabStop_Shell_InDefValue_Leave(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", "Hallo ${1:now `echo fromecho`} end")
keys = "test" + EX + JF + "and more"
wanted = "Hallo now fromecho endand more"
snippets = ('test', 'Hallo ${1:now `echo fromecho`} end')
keys = 'test' + EX + JF + 'and more'
wanted = 'Hallo now fromecho endand more'
class TabStop_Shell_InDefValue_Overwrite(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", "Hallo ${1:now `echo fromecho`} end")
keys = "test" + EX + "overwrite" + JF + "and more"
wanted = "Hallo overwrite endand more"
snippets = ('test', 'Hallo ${1:now `echo fromecho`} end')
keys = 'test' + EX + 'overwrite' + JF + 'and more'
wanted = 'Hallo overwrite endand more'
class TabStop_Shell_TestEscapedChars_Overwrite(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", r"""`echo \`echo "\\$hi"\``""")
keys = "test" + EX
wanted = "$hi"
snippets = ('test', r"""`echo \`echo "\\$hi"\``""")
keys = 'test' + EX
wanted = '$hi'
class TabStop_Shell_TestEscapedCharsAndShellVars_Overwrite(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", r"""`hi="blah"; echo \`echo "$hi"\``""")
keys = "test" + EX
wanted = "blah"
snippets = ('test', r"""`hi="blah"; echo \`echo "$hi"\``""")
keys = 'test' + EX
wanted = 'blah'
class TabStop_Shell_ShebangPython(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = ("test", """Hallo ${1:now `#!/usr/bin/env python
snippets = ('test', """Hallo ${1:now `#!/usr/bin/env python
print "Hallo Welt"
`} end""")
keys = "test" + EX + JF + "and more"
wanted = "Hallo now Hallo Welt endand more"
keys = 'test' + EX + JF + 'and more'
wanted = 'Hallo now Hallo Welt endand more'
# End: ShellCode Interpolation #}}}
# VimScript Interpolation {{{#
class TabStop_VimScriptInterpolation_SimpleExample(_VimTest):
snippets = ("test", """hi `!v indent(".")` End""")
keys = " test" + EX
wanted = " hi 4 End"
snippets = ('test', """hi `!v indent(".")` End""")
keys = ' test' + EX
wanted = ' hi 4 End'
# End: VimScript Interpolation #}}}
# PythonCode Interpolation {{{#
# Deprecated Implementation {{{#
class PythonCodeOld_SimpleExample(_VimTest):
snippets = ("test", """hi `!p res = "Hallo"` End""")
keys = "test" + EX
wanted = "hi Hallo End"
snippets = ('test', """hi `!p res = "Hallo"` End""")
keys = 'test' + EX
wanted = 'hi Hallo End'
class PythonCodeOld_ReferencePlaceholderAfter(_VimTest):
snippets = ("test", """${1:hi} `!p res = t[1]+".blah"` End""")
keys = "test" + EX + "ho"
wanted = "ho ho.blah End"
snippets = ('test', """${1:hi} `!p res = t[1]+".blah"` End""")
keys = 'test' + EX + 'ho'
wanted = 'ho ho.blah End'
class PythonCodeOld_ReferencePlaceholderBefore(_VimTest):
snippets = ("test", """`!p res = len(t[1])*"#"`\n${1:some text}""")
keys = "test" + EX + "Hallo Welt"
wanted = "##########\nHallo Welt"
snippets = ('test', """`!p res = len(t[1])*"#"`\n${1:some text}""")
keys = 'test' + EX + 'Hallo Welt'
wanted = '##########\nHallo Welt'
class PythonCodeOld_TransformedBeforeMultiLine(_VimTest):
snippets = ("test", """${1/.+/egal/m} ${1:`!p
snippets = ('test', """${1/.+/egal/m} ${1:`!p
res = "Hallo"`} End""")
keys = "test" + EX
wanted = "egal Hallo End"
keys = 'test' + EX
wanted = 'egal Hallo End'
class PythonCodeOld_IndentedMultiline(_VimTest):
snippets = ("test", """start `!p a = 1
snippets = ('test', """start `!p a = 1
b = 2
if b > a:
res = "b isbigger a"
else:
res = "a isbigger b"` end""")
keys = " test" + EX
wanted = " start b isbigger a end"
keys = ' test' + EX
wanted = ' start b isbigger a end'
# End: Deprecated Implementation #}}}
# New Implementation {{{#
class PythonCode_UseNewOverOld(_VimTest):
snippets = ("test", """hi `!p res = "Old"
snippets = ('test', """hi `!p res = "Old"
snip.rv = "New"` End""")
keys = "test" + EX
wanted = "hi New End"
keys = 'test' + EX
wanted = 'hi New End'
class PythonCode_SimpleExample(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo"` End""")
keys = "test" + EX
wanted = "hi Hallo End"
snippets = ('test', """hi `!p snip.rv = "Hallo"` End""")
keys = 'test' + EX
wanted = 'hi Hallo End'
class PythonCode_SimpleExample_ReturnValueIsEmptyString(_VimTest):
snippets = ("test", """hi`!p snip.rv = ""`End""")
keys = "test" + EX
wanted = "hiEnd"
snippets = ('test', """hi`!p snip.rv = ""`End""")
keys = 'test' + EX
wanted = 'hiEnd'
class PythonCode_ReferencePlaceholder(_VimTest):
snippets = ("test", """${1:hi} `!p snip.rv = t[1]+".blah"` End""")
keys = "test" + EX + "ho"
wanted = "ho ho.blah End"
snippets = ('test', """${1:hi} `!p snip.rv = t[1]+".blah"` End""")
keys = 'test' + EX + 'ho'
wanted = 'ho ho.blah End'
class PythonCode_ReferencePlaceholderBefore(_VimTest):
snippets = ("test", """`!p snip.rv = len(t[1])*"#"`\n${1:some text}""")
keys = "test" + EX + "Hallo Welt"
wanted = "##########\nHallo Welt"
snippets = ('test', """`!p snip.rv = len(t[1])*"#"`\n${1:some text}""")
keys = 'test' + EX + 'Hallo Welt'
wanted = '##########\nHallo Welt'
class PythonCode_TransformedBeforeMultiLine(_VimTest):
snippets = ("test", """${1/.+/egal/m} ${1:`!p
snippets = ('test', """${1/.+/egal/m} ${1:`!p
snip.rv = "Hallo"`} End""")
keys = "test" + EX
wanted = "egal Hallo End"
keys = 'test' + EX
wanted = 'egal Hallo End'
class PythonCode_MultilineIndented(_VimTest):
snippets = ("test", """start `!p a = 1
snippets = ('test', """start `!p a = 1
b = 2
if b > a:
snip.rv = "b isbigger a"
else:
snip.rv = "a isbigger b"` end""")
keys = " test" + EX
wanted = " start b isbigger a end"
keys = ' test' + EX
wanted = ' start b isbigger a end'
class PythonCode_SimpleAppend(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo1"
snippets = ('test', """hi `!p snip.rv = "Hallo1"
snip += "Hallo2"` End""")
keys = "test" + EX
wanted = "hi Hallo1\nHallo2 End"
keys = 'test' + EX
wanted = 'hi Hallo1\nHallo2 End'
class PythonCode_MultiAppend(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo1"
snippets = ('test', """hi `!p snip.rv = "Hallo1"
snip += "Hallo2"
snip += "Hallo3"` End""")
keys = "test" + EX
wanted = "hi Hallo1\nHallo2\nHallo3 End"
keys = 'test' + EX
wanted = 'hi Hallo1\nHallo2\nHallo3 End'
class PythonCode_MultiAppendSimpleIndent(_VimTest):
snippets = ("test", """hi
snippets = ('test', """hi
`!p snip.rv="Hallo1"
snip += "Hallo2"
snip += "Hallo3"`
@ -152,8 +192,9 @@ End""")
Hallo3
End"""
class PythonCode_SimpleMkline(_VimTest):
snippets = ("test", r"""hi
snippets = ('test', r"""hi
`!p snip.rv="Hallo1\n"
snip.rv += snip.mkline("Hallo2") + "\n"
snip.rv += snip.mkline("Hallo3")`
@ -167,8 +208,9 @@ End""")
Hallo3
End"""
class PythonCode_MultiAppendShift(_VimTest):
snippets = ("test", r"""hi
snippets = ('test', r"""hi
`!p snip.rv="i1"
snip += "i1"
snip >> 1
@ -189,8 +231,9 @@ i0
i3
End"""
class PythonCode_MultiAppendShiftMethods(_VimTest):
snippets = ("test", r"""hi
snippets = ('test', r"""hi
`!p snip.rv="i1\n"
snip.rv += snip.mkline("i1\n")
snip.shift(1)
@ -213,7 +256,7 @@ i0
class PythonCode_ResetIndent(_VimTest):
snippets = ("test", r"""hi
snippets = ('test', r"""hi
`!p snip.rv="i1"
snip >> 1
snip += "i2"
@ -235,11 +278,13 @@ i0
i1
End"""
class PythonCode_IndentEtSw(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set expandtab")
snippets = ("test", r"""hi
vim_config.append('set sw=3')
vim_config.append('set expandtab')
snippets = ('test', r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
@ -257,11 +302,13 @@ i0
i1
End"""
class PythonCode_IndentEtSwOffset(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set expandtab")
snippets = ("test", r"""hi
vim_config.append('set sw=3')
vim_config.append('set expandtab')
snippets = ('test', r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
@ -279,11 +326,13 @@ End""")
i1
End"""
class PythonCode_IndentNoetSwTs(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set ts=4")
snippets = ("test", r"""hi
vim_config.append('set sw=3')
vim_config.append('set ts=4')
snippets = ('test', r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
@ -302,74 +351,108 @@ i0
End"""
# Test using 'opt'
class PythonCode_OptExists(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append('let g:UStest="yes"')
snippets = ("test", r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
snippets = (
'test',
r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
keys = """test""" + EX
wanted = """hi yes End"""
class PythonCode_OptNoExists(_VimTest):
snippets = ("test", r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
snippets = (
'test',
r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
keys = """test""" + EX
wanted = """hi no End"""
class PythonCode_IndentProblem(_VimTest):
# A test case which is likely related to bug 719649
snippets = ("test", r"""hi `!p
snippets = ('test', r"""hi `!p
snip.rv = "World"
` End""")
keys = " " * 8 + "test" + EX # < 8 works.
keys = ' ' * 8 + 'test' + EX # < 8 works.
wanted = """ hi World End"""
class PythonCode_TrickyReferences(_VimTest):
snippets = ("test", r"""${2:${1/.+/egal/}} ${1:$3} ${3:`!p snip.rv = "hi"`}""")
keys = "ups test" + EX
wanted = "ups egal hi hi"
snippets = (
'test',
r"""${2:${1/.+/egal/}} ${1:$3} ${3:`!p snip.rv = "hi"`}""")
keys = 'ups test' + EX
wanted = 'ups egal hi hi'
# locals
class PythonCode_Locals(_VimTest):
snippets = ("test", r"""hi `!p a = "test"
snippets = ('test', r"""hi `!p a = "test"
snip.rv = "nothing"` `!p snip.rv = a
` End""")
keys = """test""" + EX
wanted = """hi nothing test End"""
class PythonCode_LongerTextThanSource_Chars(_VimTest):
snippets = ("test", r"""hi`!p snip.rv = "a" * 100`end""")
keys = """test""" + EX + "ups"
wanted = "hi" + 100*"a" + "endups"
snippets = ('test', r"""hi`!p snip.rv = "a" * 100`end""")
keys = """test""" + EX + 'ups'
wanted = 'hi' + 100 * 'a' + 'endups'
class PythonCode_LongerTextThanSource_MultiLine(_VimTest):
snippets = ("test", r"""hi`!p snip.rv = "a" * 100 + '\n'*100 + "a"*100`end""")
keys = """test""" + EX + "ups"
wanted = "hi" + 100*"a" + 100*"\n" + 100*"a" + "endups"
snippets = (
'test',
r"""hi`!p snip.rv = "a" * 100 + '\n'*100 + "a"*100`end""")
keys = """test""" + EX + 'ups'
wanted = 'hi' + 100 * 'a' + 100 * '\n' + 100 * 'a' + 'endups'
class PythonCode_AccessKilledTabstop_OverwriteSecond(_VimTest):
snippets = ("test", r"`!p snip.rv = t[2].upper()`${1:h${2:welt}o}`!p snip.rv = t[2].upper()`")
keys = "test" + EX + JF + "okay"
wanted = "OKAYhokayoOKAY"
snippets = (
'test',
r"`!p snip.rv = t[2].upper()`${1:h${2:welt}o}`!p snip.rv = t[2].upper()`")
keys = 'test' + EX + JF + 'okay'
wanted = 'OKAYhokayoOKAY'
class PythonCode_AccessKilledTabstop_OverwriteFirst(_VimTest):
snippets = ("test", r"`!p snip.rv = t[2].upper()`${1:h${2:welt}o}`!p snip.rv = t[2].upper()`")
keys = "test" + EX + "aaa"
wanted = "aaa"
snippets = (
'test',
r"`!p snip.rv = t[2].upper()`${1:h${2:welt}o}`!p snip.rv = t[2].upper()`")
keys = 'test' + EX + 'aaa'
wanted = 'aaa'
class PythonVisual_NoVisualSelection_Ignore(_VimTest):
snippets = ("test", "h`!p snip.rv = snip.v.mode + snip.v.text`b")
keys = "test" + EX + "abc"
wanted = "hbabc"
snippets = ('test', 'h`!p snip.rv = snip.v.mode + snip.v.text`b')
keys = 'test' + EX + 'abc'
wanted = 'hbabc'
class PythonVisual_SelectOneWord(_VimTest):
snippets = ("test", "h`!p snip.rv = snip.v.mode + snip.v.text`b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hvblablubb"
snippets = ('test', 'h`!p snip.rv = snip.v.mode + snip.v.text`b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hvblablubb'
class PythonVisual_LineSelect_Simple(_VimTest):
snippets = ("test", "h`!p snip.rv = snip.v.mode + snip.v.text`b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "hVhello\nnice\nworld\nb"
snippets = ('test', 'h`!p snip.rv = snip.v.mode + snip.v.text`b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'hVhello\nnice\nworld\nb'
# Tests for https://bugs.launchpad.net/bugs/1259349
class Python_WeirdScoping_Error(_VimTest):
snippets = ("test", "h`!p import re; snip.rv = '%i' % len([re.search for i in 'aiiia'])`b")
keys = "test" + EX
wanted = "h5b"
snippets = (
'test',
"h`!p import re; snip.rv = '%i' % len([re.search for i in 'aiiia'])`b")
keys = 'test' + EX
wanted = 'h5b'
# End: New Implementation #}}}
# End: PythonCode Interpolation #}}}

View File

@ -2,29 +2,42 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# List Snippets {{{#
class _ListAllSnippets(_VimTest):
snippets = ( ("testblah", "BLAAH", "Say BLAH"),
("test", "TEST ONE", "Say tst one"),
("aloha", "OHEEEE", "Say OHEE"),
)
snippets = (('testblah', 'BLAAH', 'Say BLAH'),
('test', 'TEST ONE', 'Say tst one'),
('aloha', 'OHEEEE', 'Say OHEE'),
)
class ListAllAvailable_NothingTyped_ExpectCorrectResult(_ListAllSnippets):
keys = "" + LS + "3\n"
wanted = "BLAAH"
keys = '' + LS + '3\n'
wanted = 'BLAAH'
class ListAllAvailable_SpaceInFront_ExpectCorrectResult(_ListAllSnippets):
keys = " " + LS + "3\n"
wanted = " BLAAH"
keys = ' ' + LS + '3\n'
wanted = ' BLAAH'
class ListAllAvailable_BraceInFront_ExpectCorrectResult(_ListAllSnippets):
keys = "} " + LS + "3\n"
wanted = "} BLAAH"
keys = '} ' + LS + '3\n'
wanted = '} BLAAH'
class ListAllAvailable_testtyped_ExpectCorrectResult(_ListAllSnippets):
keys = "hallo test" + LS + "2\n"
wanted = "hallo BLAAH"
class ListAllAvailable_testtypedSecondOpt_ExpectCorrectResult(_ListAllSnippets):
keys = "hallo test" + LS + "1\n"
wanted = "hallo TEST ONE"
keys = 'hallo test' + LS + '2\n'
wanted = 'hallo BLAAH'
class ListAllAvailable_testtypedSecondOpt_ExpectCorrectResult(
_ListAllSnippets):
keys = 'hallo test' + LS + '1\n'
wanted = 'hallo TEST ONE'
class ListAllAvailable_NonDefined_NoExpectionShouldBeRaised(_ListAllSnippets):
keys = "hallo qualle" + LS + "Hi"
wanted = "hallo qualleHi"
keys = 'hallo qualle' + LS + 'Hi'
wanted = 'hallo qualleHi'
# End: List Snippets #}}}

View File

@ -2,192 +2,271 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Mirrors {{{#
class TextTabStopTextAfterTab_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 Hinten\n$1")
keys = "test" + EX + "hallo"
wanted = "hallo Hinten\nhallo"
snippets = ('test', '$1 Hinten\n$1')
keys = 'test' + EX + 'hallo'
wanted = 'hallo Hinten\nhallo'
class TextTabStopTextBeforeTab_ExpectCorrectResult(_VimTest):
snippets = ("test", "Vorne $1\n$1")
keys = "test" + EX + "hallo"
wanted = "Vorne hallo\nhallo"
snippets = ('test', 'Vorne $1\n$1')
keys = 'test' + EX + 'hallo'
wanted = 'Vorne hallo\nhallo'
class TextTabStopTextSurroundedTab_ExpectCorrectResult(_VimTest):
snippets = ("test", "Vorne $1 Hinten\n$1")
keys = "test" + EX + "hallo test"
wanted = "Vorne hallo test Hinten\nhallo test"
snippets = ('test', 'Vorne $1 Hinten\n$1')
keys = 'test' + EX + 'hallo test'
wanted = 'Vorne hallo test Hinten\nhallo test'
class TextTabStopTextBeforeMirror_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\nVorne $1")
keys = "test" + EX + "hallo"
wanted = "hallo\nVorne hallo"
snippets = ('test', '$1\nVorne $1')
keys = 'test' + EX + 'hallo'
wanted = 'hallo\nVorne hallo'
class TextTabStopAfterMirror_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1 Hinten")
keys = "test" + EX + "hallo"
wanted = "hallo\nhallo Hinten"
snippets = ('test', '$1\n$1 Hinten')
keys = 'test' + EX + 'hallo'
wanted = 'hallo\nhallo Hinten'
class TextTabStopSurroundMirror_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\nVorne $1 Hinten")
keys = "test" + EX + "hallo welt"
wanted = "hallo welt\nVorne hallo welt Hinten"
snippets = ('test', '$1\nVorne $1 Hinten')
keys = 'test' + EX + 'hallo welt'
wanted = 'hallo welt\nVorne hallo welt Hinten'
class TextTabStopAllSurrounded_ExpectCorrectResult(_VimTest):
snippets = ("test", "ObenVorne $1 ObenHinten\nVorne $1 Hinten")
keys = "test" + EX + "hallo welt"
wanted = "ObenVorne hallo welt ObenHinten\nVorne hallo welt Hinten"
snippets = ('test', 'ObenVorne $1 ObenHinten\nVorne $1 Hinten')
keys = 'test' + EX + 'hallo welt'
wanted = 'ObenVorne hallo welt ObenHinten\nVorne hallo welt Hinten'
class MirrorBeforeTabstopLeave_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1:this is it} $1")
keys = "test" + EX
wanted = "this is it this is it this is it"
snippets = ('test', '$1 ${1:this is it} $1')
keys = 'test' + EX
wanted = 'this is it this is it this is it'
class MirrorBeforeTabstopOverwrite_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1:this is it} $1")
keys = "test" + EX + "a"
wanted = "a a a"
snippets = ('test', '$1 ${1:this is it} $1')
keys = 'test' + EX + 'a'
wanted = 'a a a'
class TextTabStopSimpleMirrorMultiline_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1")
keys = "test" + EX + "hallo"
wanted = "hallo\nhallo"
snippets = ('test', '$1\n$1')
keys = 'test' + EX + 'hallo'
wanted = 'hallo\nhallo'
class SimpleMirrorMultilineMany_ExpectCorrectResult(_VimTest):
snippets = ("test", " $1\n$1\na$1b\n$1\ntest $1 mich")
keys = "test" + EX + "hallo"
wanted = " hallo\nhallo\nahallob\nhallo\ntest hallo mich"
snippets = ('test', ' $1\n$1\na$1b\n$1\ntest $1 mich')
keys = 'test' + EX + 'hallo'
wanted = ' hallo\nhallo\nahallob\nhallo\ntest hallo mich'
class MultilineTabStopSimpleMirrorMultiline_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n\n$1\n\n$1")
keys = "test" + EX + "hallo Du\nHi"
wanted = "hallo Du\nHi\n\nhallo Du\nHi\n\nhallo Du\nHi"
snippets = ('test', '$1\n\n$1\n\n$1')
keys = 'test' + EX + 'hallo Du\nHi'
wanted = 'hallo Du\nHi\n\nhallo Du\nHi\n\nhallo Du\nHi'
class MultilineTabStopSimpleMirrorMultiline1_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1\n$1")
keys = "test" + EX + "hallo Du\nHi"
wanted = "hallo Du\nHi\nhallo Du\nHi\nhallo Du\nHi"
snippets = ('test', '$1\n$1\n$1')
keys = 'test' + EX + 'hallo Du\nHi'
wanted = 'hallo Du\nHi\nhallo Du\nHi\nhallo Du\nHi'
class MultilineTabStopSimpleMirrorDeleteInLine_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1\n$1")
keys = "test" + EX + "hallo Du\nHi\b\bAch Blah"
wanted = "hallo Du\nAch Blah\nhallo Du\nAch Blah\nhallo Du\nAch Blah"
snippets = ('test', '$1\n$1\n$1')
keys = 'test' + EX + 'hallo Du\nHi\b\bAch Blah'
wanted = 'hallo Du\nAch Blah\nhallo Du\nAch Blah\nhallo Du\nAch Blah'
class TextTabStopSimpleMirrorMultilineMirrorInFront_ECR(_VimTest):
snippets = ("test", "$1\n${1:sometext}")
keys = "test" + EX + "hallo\nagain"
wanted = "hallo\nagain\nhallo\nagain"
snippets = ('test', '$1\n${1:sometext}')
keys = 'test' + EX + 'hallo\nagain'
wanted = 'hallo\nagain\nhallo\nagain'
class SimpleMirrorDelete_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1")
keys = "test" + EX + "hallo\b\b"
wanted = "hal\nhal"
snippets = ('test', '$1\n$1')
keys = 'test' + EX + 'hallo\b\b'
wanted = 'hal\nhal'
class SimpleMirrorSameLine_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 $1")
keys = "test" + EX + "hallo"
wanted = "hallo hallo"
snippets = ('test', '$1 $1')
keys = 'test' + EX + 'hallo'
wanted = 'hallo hallo'
class SimpleMirrorSameLine_InText_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 $1")
keys = "ups test blah" + ESC + "02f i" + EX + "hallo"
wanted = "ups hallo hallo blah"
snippets = ('test', '$1 $1')
keys = 'ups test blah' + ESC + '02f i' + EX + 'hallo'
wanted = 'ups hallo hallo blah'
class SimpleMirrorSameLineBeforeTabDefVal_ECR(_VimTest):
snippets = ("test", "$1 ${1:replace me}")
keys = "test" + EX + "hallo foo"
wanted = "hallo foo hallo foo"
snippets = ('test', '$1 ${1:replace me}')
keys = 'test' + EX + 'hallo foo'
wanted = 'hallo foo hallo foo'
class SimpleMirrorSameLineBeforeTabDefVal_DelB4Typing_ECR(_VimTest):
snippets = ("test", "$1 ${1:replace me}")
keys = "test" + EX + BS + "hallo foo"
wanted = "hallo foo hallo foo"
snippets = ('test', '$1 ${1:replace me}')
keys = 'test' + EX + BS + 'hallo foo'
wanted = 'hallo foo hallo foo'
class SimpleMirrorSameLineMany_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 $1 $1 $1")
keys = "test" + EX + "hallo du"
wanted = "hallo du hallo du hallo du hallo du"
snippets = ('test', '$1 $1 $1 $1')
keys = 'test' + EX + 'hallo du'
wanted = 'hallo du hallo du hallo du hallo du'
class SimpleMirrorSameLineManyMultiline_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 $1 $1 $1")
keys = "test" + EX + "hallo du\nwie gehts"
wanted = "hallo du\nwie gehts hallo du\nwie gehts hallo du\nwie gehts" \
" hallo du\nwie gehts"
snippets = ('test', '$1 $1 $1 $1')
keys = 'test' + EX + 'hallo du\nwie gehts'
wanted = 'hallo du\nwie gehts hallo du\nwie gehts hallo du\nwie gehts' \
' hallo du\nwie gehts'
class SimpleMirrorDeleteSomeEnterSome_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1\n$1")
keys = "test" + EX + "hallo\b\bhups"
wanted = "halhups\nhalhups"
snippets = ('test', '$1\n$1')
keys = 'test' + EX + 'hallo\b\bhups'
wanted = 'halhups\nhalhups'
class SimpleTabstopWithDefaultSimpelType_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:defa}\n$1")
keys = "test" + EX + "world"
wanted = "ha world\nworld"
snippets = ('test', 'ha ${1:defa}\n$1')
keys = 'test' + EX + 'world'
wanted = 'ha world\nworld'
class SimpleTabstopWithDefaultComplexType_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:default value} $1\nanother: $1 mirror")
keys = "test" + EX + "world"
wanted = "ha world world\nanother: world mirror"
snippets = ('test', 'ha ${1:default value} $1\nanother: $1 mirror')
keys = 'test' + EX + 'world'
wanted = 'ha world world\nanother: world mirror'
class SimpleTabstopWithDefaultSimpelKeep_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:defa}\n$1")
keys = "test" + EX
wanted = "ha defa\ndefa"
snippets = ('test', 'ha ${1:defa}\n$1')
keys = 'test' + EX
wanted = 'ha defa\ndefa'
class SimpleTabstopWithDefaultComplexKeep_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:default value} $1\nanother: $1 mirror")
keys = "test" + EX
wanted = "ha default value default value\nanother: default value mirror"
snippets = ('test', 'ha ${1:default value} $1\nanother: $1 mirror')
keys = 'test' + EX
wanted = 'ha default value default value\nanother: default value mirror'
class TabstopWithMirrorManyFromAll_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $5 ${1:blub} $4 $0 ${2:$1.h} $1 $3 ${4:More}")
keys = "test" + EX + "hi" + JF + "hu" + JF + "hub" + JF + "hulla" + \
JF + "blah" + JF + "end"
wanted = "ha blah hi hulla end hu hi hub hulla"
snippets = ('test', 'ha $5 ${1:blub} $4 $0 ${2:$1.h} $1 $3 ${4:More}')
keys = 'test' + EX + 'hi' + JF + 'hu' + JF + 'hub' + JF + 'hulla' + \
JF + 'blah' + JF + 'end'
wanted = 'ha blah hi hulla end hu hi hub hulla'
class TabstopWithMirrorInDefaultNoType_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:blub} ${2:$1.h}")
keys = "test" + EX
wanted = "ha blub blub.h"
snippets = ('test', 'ha ${1:blub} ${2:$1.h}')
keys = 'test' + EX
wanted = 'ha blub blub.h'
class TabstopWithMirrorInDefaultNoType1_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha ${1:blub} ${2:$1}")
keys = "test" + EX
wanted = "ha blub blub"
snippets = ('test', 'ha ${1:blub} ${2:$1}')
keys = 'test' + EX
wanted = 'ha blub blub'
class TabstopWithMirrorInDefaultTwiceAndExtra_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:$1.h $1.c}\ntest $1")
keys = "test" + EX + "stdin"
wanted = "ha stdin stdin.h stdin.c\ntest stdin"
snippets = ('test', 'ha $1 ${2:$1.h $1.c}\ntest $1')
keys = 'test' + EX + 'stdin'
wanted = 'ha stdin stdin.h stdin.c\ntest stdin'
class TabstopWithMirrorInDefaultMultipleLeave_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:snip} ${3:$1.h $2}")
keys = "test" + EX + "stdin"
wanted = "ha stdin snip stdin.h snip"
class TabstopWithMirrorInDefaultMultipleOverwrite_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:snip} ${3:$1.h $2}")
keys = "test" + EX + "stdin" + JF + "do snap"
wanted = "ha stdin do snap stdin.h do snap"
snippets = ('test', 'ha $1 ${2:snip} ${3:$1.h $2}')
keys = 'test' + EX + 'stdin'
wanted = 'ha stdin snip stdin.h snip'
class TabstopWithMirrorInDefaultMultipleOverwrite_ExpectCorrectResult(
_VimTest):
snippets = ('test', 'ha $1 ${2:snip} ${3:$1.h $2}')
keys = 'test' + EX + 'stdin' + JF + 'do snap'
wanted = 'ha stdin do snap stdin.h do snap'
class TabstopWithMirrorInDefaultOverwrite_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:$1.h}")
keys = "test" + EX + "stdin" + JF + "overwritten"
wanted = "ha stdin overwritten"
snippets = ('test', 'ha $1 ${2:$1.h}')
keys = 'test' + EX + 'stdin' + JF + 'overwritten'
wanted = 'ha stdin overwritten'
class TabstopWithMirrorInDefaultOverwrite1_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:$1}")
keys = "test" + EX + "stdin" + JF + "overwritten"
wanted = "ha stdin overwritten"
snippets = ('test', 'ha $1 ${2:$1}')
keys = 'test' + EX + 'stdin' + JF + 'overwritten'
wanted = 'ha stdin overwritten'
class TabstopWithMirrorInDefaultNoOverwrite1_ExpectCorrectResult(_VimTest):
snippets = ("test", "ha $1 ${2:$1}")
keys = "test" + EX + "stdin" + JF + JF + "end"
wanted = "ha stdin stdinend"
snippets = ('test', 'ha $1 ${2:$1}')
keys = 'test' + EX + 'stdin' + JF + JF + 'end'
wanted = 'ha stdin stdinend'
class MirrorRealLifeExample_ExpectCorrectResult(_VimTest):
snippets = (
("for", "for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})" \
"\n{\n\t${0:/* code */}\n}"),
('for', 'for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})'
'\n{\n\t${0:/* code */}\n}'),
)
keys ="for" + EX + "100" + JF + "avar\b\b\b\ba_variable" + JF + \
"a_variable *= 2" + JF + "// do nothing"
keys = 'for' + EX + '100' + JF + 'avar\b\b\b\ba_variable' + JF + \
'a_variable *= 2' + JF + '// do nothing'
wanted = """for(size_t a_variable = 0; a_variable < 100; a_variable *= 2)
{
\t// do nothing
}"""
class Mirror_TestKill_InsertBefore_NoKill(_VimTest):
snippets = "test", "$1 $1_"
keys = "hallo test" + EX + "auch" + ESC + "wihi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noauch hinoauch_end"
snippets = 'test', '$1 $1_'
keys = 'hallo test' + EX + 'auch' + ESC + \
'wihi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noauch hinoauch_end'
class Mirror_TestKill_InsertAfter_NoKill(_VimTest):
snippets = "test", "$1 $1_"
keys = "hallo test" + EX + "auch" + ESC + "eiab" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noauch noauchab_end"
snippets = 'test', '$1 $1_'
keys = 'hallo test' + EX + 'auch' + ESC + \
'eiab' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noauch noauchab_end'
class Mirror_TestKill_InsertBeginning_Kill(_VimTest):
snippets = "test", "$1 $1_"
keys = "hallo test" + EX + "auch" + ESC + "wahi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noauch ahiuch_end"
snippets = 'test', '$1 $1_'
keys = 'hallo test' + EX + 'auch' + ESC + \
'wahi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noauch ahiuch_end'
class Mirror_TestKill_InsertEnd_Kill(_VimTest):
snippets = "test", "$1 $1_"
keys = "hallo test" + EX + "auch" + ESC + "ehihi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noauch auchih_end"
snippets = 'test', '$1 $1_'
keys = 'hallo test' + EX + 'auch' + ESC + \
'ehihi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noauch auchih_end'
class Mirror_TestKillTabstop_Kill(_VimTest):
snippets = "test", "welt${1:welt${2:welt}welt} $2"
keys = "hallo test" + EX + "elt"
wanted = "hallo weltelt "
snippets = 'test', 'welt${1:welt${2:welt}welt} $2'
keys = 'hallo test' + EX + 'elt'
wanted = 'hallo weltelt '
# End: Mirrors #}}}

View File

@ -2,59 +2,82 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Cursor Movement {{{#
class CursorMovement_Multiline_ECR(_VimTest):
snippets = ("test", r"$1 ${1:a tab}")
keys = "test" + EX + "this is something\nvery nice\nnot" + JF + "more text"
wanted = "this is something\nvery nice\nnot " \
"this is something\nvery nice\nnotmore text"
snippets = ('test', r"$1 ${1:a tab}")
keys = 'test' + EX + 'this is something\nvery nice\nnot' + JF + 'more text'
wanted = 'this is something\nvery nice\nnot ' \
'this is something\nvery nice\nnotmore text'
class CursorMovement_BS_InEditMode(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set backspace=eol,indent,start")
snippets = ("<trh", "<tr>\n\t<th>$1</th>\n\t$2\n</tr>\n$3")
keys = "<trh" + EX + "blah" + JF + BS + BS + JF + "end"
wanted = "<tr>\n\t<th>blah</th>\n</tr>\nend"
vim_config.append('set backspace=eol,indent,start')
snippets = ('<trh', '<tr>\n\t<th>$1</th>\n\t$2\n</tr>\n$3')
keys = '<trh' + EX + 'blah' + JF + BS + BS + JF + 'end'
wanted = '<tr>\n\t<th>blah</th>\n</tr>\nend'
# End: Cursor Movement #}}}
# Insert Mode Moving {{{#
class IMMoving_CursorsKeys_ECR(_VimTest):
snippets = ("test", "${1:Some}")
keys = "test" + EX + "text" + 3*ARR_U + 6*ARR_D
wanted = "text"
class IMMoving_AcceptInputWhenMoved_ECR(_VimTest):
snippets = ("test", r"$1 ${1:a tab}")
keys = "test" + EX + "this" + 2*ARR_L + "hallo\nwelt"
wanted = "thhallo\nweltis thhallo\nweltis"
class IMMoving_NoExiting_ECR(_VimTest):
snippets = ("test", r"$1 ${2:a tab} ${1:Tab}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + 7*ARR_L + \
JF + "hallo"
wanted = "hello tab hallo tab this"
class IMMoving_NoExitingEventAtEnd_ECR(_VimTest):
snippets = ("test", r"$1 ${2:a tab} ${1:Tab}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + JF + "hallo"
wanted = "hello tab hallo tab this"
class IMMoving_ExitWhenOutsideRight_ECR(_VimTest):
snippets = ("test", r"$1 ${2:blub} ${1:Tab}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + ARR_R + JF + "hallo"
wanted = "hello tab blub tab " + JF + "hallothis"
class IMMoving_NotExitingWhenBarelyOutsideLeft_ECR(_VimTest):
snippets = ("test", r"${1:Hi} ${2:blub}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + 3*ARR_L + \
JF + "hallo"
wanted = "hello tab hallo this"
class IMMoving_ExitWhenOutsideLeft_ECR(_VimTest):
snippets = ("test", r"${1:Hi} ${2:blub}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + 4*ARR_L + \
JF + "hallo"
wanted = "hello" + JF + "hallo tab blub this"
class IMMoving_ExitWhenOutsideAbove_ECR(_VimTest):
snippets = ("test", "${1:Hi}\n${2:blub}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + 1*ARR_U + "\n" + JF + \
"hallo"
wanted = JF + "hallo\nhello tab\nblub this"
class IMMoving_ExitWhenOutsideBelow_ECR(_VimTest):
snippets = ("test", "${1:Hi}\n${2:blub}")
keys = "hello test this" + ESC + "02f i" + EX + "tab" + 2*ARR_D + JF + \
"testhallo\n"
wanted = "hello tab\nblub this\n" + JF + "testhallo"
# End: Insert Mode Moving #}}}
class IMMoving_CursorsKeys_ECR(_VimTest):
snippets = ('test', '${1:Some}')
keys = 'test' + EX + 'text' + 3 * ARR_U + 6 * ARR_D
wanted = 'text'
class IMMoving_AcceptInputWhenMoved_ECR(_VimTest):
snippets = ('test', r"$1 ${1:a tab}")
keys = 'test' + EX + 'this' + 2 * ARR_L + 'hallo\nwelt'
wanted = 'thhallo\nweltis thhallo\nweltis'
class IMMoving_NoExiting_ECR(_VimTest):
snippets = ('test', r"$1 ${2:a tab} ${1:Tab}")
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + 7 * ARR_L + \
JF + 'hallo'
wanted = 'hello tab hallo tab this'
class IMMoving_NoExitingEventAtEnd_ECR(_VimTest):
snippets = ('test', r"$1 ${2:a tab} ${1:Tab}")
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + JF + 'hallo'
wanted = 'hello tab hallo tab this'
class IMMoving_ExitWhenOutsideRight_ECR(_VimTest):
snippets = ('test', r"$1 ${2:blub} ${1:Tab}")
keys = 'hello test this' + ESC + '02f i' + \
EX + 'tab' + ARR_R + JF + 'hallo'
wanted = 'hello tab blub tab ' + JF + 'hallothis'
class IMMoving_NotExitingWhenBarelyOutsideLeft_ECR(_VimTest):
snippets = ('test', r"${1:Hi} ${2:blub}")
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + 3 * ARR_L + \
JF + 'hallo'
wanted = 'hello tab hallo this'
class IMMoving_ExitWhenOutsideLeft_ECR(_VimTest):
snippets = ('test', r"${1:Hi} ${2:blub}")
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + 4 * ARR_L + \
JF + 'hallo'
wanted = 'hello' + JF + 'hallo tab blub this'
class IMMoving_ExitWhenOutsideAbove_ECR(_VimTest):
snippets = ('test', '${1:Hi}\n${2:blub}')
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + 1 * ARR_U + '\n' + JF + \
'hallo'
wanted = JF + 'hallo\nhello tab\nblub this'
class IMMoving_ExitWhenOutsideBelow_ECR(_VimTest):
snippets = ('test', '${1:Hi}\n${2:blub}')
keys = 'hello test this' + ESC + '02f i' + EX + 'tab' + 2 * ARR_D + JF + \
'testhallo\n'
wanted = 'hello tab\nblub this\n' + JF + 'testhallo'
# End: Insert Mode Moving #}}}

View File

@ -2,58 +2,71 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Selecting Between Same Triggers {{{#
class _MultipleMatches(_VimTest):
snippets = ( ("test", "Case1", "This is Case 1"),
("test", "Case2", "This is Case 2") )
snippets = (('test', 'Case1', 'This is Case 1'),
('test', 'Case2', 'This is Case 2'))
class Multiple_SimpleCaseSelectFirst_ECR(_MultipleMatches):
keys = "test" + EX + "1\n"
wanted = "Case1"
keys = 'test' + EX + '1\n'
wanted = 'Case1'
class Multiple_SimpleCaseSelectSecond_ECR(_MultipleMatches):
keys = "test" + EX + "2\n"
wanted = "Case2"
keys = 'test' + EX + '2\n'
wanted = 'Case2'
class Multiple_SimpleCaseSelectTooHigh_ESelectLast(_MultipleMatches):
keys = "test" + EX + "5\n"
wanted = "Case2"
keys = 'test' + EX + '5\n'
wanted = 'Case2'
class Multiple_SimpleCaseSelectZero_EEscape(_MultipleMatches):
keys = "test" + EX + "0\n" + "hi"
wanted = "testhi"
keys = 'test' + EX + '0\n' + 'hi'
wanted = 'testhi'
class Multiple_SimpleCaseEscapeOut_ECR(_MultipleMatches):
keys = "test" + EX + ESC + "hi"
wanted = "testhi"
keys = 'test' + EX + ESC + 'hi'
wanted = 'testhi'
class Multiple_ManySnippetsOneTrigger_ECR(_VimTest):
# Snippet definition {{{#
snippets = (
("test", "Case1", "This is Case 1"),
("test", "Case2", "This is Case 2"),
("test", "Case3", "This is Case 3"),
("test", "Case4", "This is Case 4"),
("test", "Case5", "This is Case 5"),
("test", "Case6", "This is Case 6"),
("test", "Case7", "This is Case 7"),
("test", "Case8", "This is Case 8"),
("test", "Case9", "This is Case 9"),
("test", "Case10", "This is Case 10"),
("test", "Case11", "This is Case 11"),
("test", "Case12", "This is Case 12"),
("test", "Case13", "This is Case 13"),
("test", "Case14", "This is Case 14"),
("test", "Case15", "This is Case 15"),
("test", "Case16", "This is Case 16"),
("test", "Case17", "This is Case 17"),
("test", "Case18", "This is Case 18"),
("test", "Case19", "This is Case 19"),
("test", "Case20", "This is Case 20"),
("test", "Case21", "This is Case 21"),
("test", "Case22", "This is Case 22"),
("test", "Case23", "This is Case 23"),
("test", "Case24", "This is Case 24"),
("test", "Case25", "This is Case 25"),
("test", "Case26", "This is Case 26"),
("test", "Case27", "This is Case 27"),
("test", "Case28", "This is Case 28"),
("test", "Case29", "This is Case 29"),
) #}}}
keys = "test" + EX + " " + ESC + ESC + "ahi"
wanted = "testhi"
('test', 'Case1', 'This is Case 1'),
('test', 'Case2', 'This is Case 2'),
('test', 'Case3', 'This is Case 3'),
('test', 'Case4', 'This is Case 4'),
('test', 'Case5', 'This is Case 5'),
('test', 'Case6', 'This is Case 6'),
('test', 'Case7', 'This is Case 7'),
('test', 'Case8', 'This is Case 8'),
('test', 'Case9', 'This is Case 9'),
('test', 'Case10', 'This is Case 10'),
('test', 'Case11', 'This is Case 11'),
('test', 'Case12', 'This is Case 12'),
('test', 'Case13', 'This is Case 13'),
('test', 'Case14', 'This is Case 14'),
('test', 'Case15', 'This is Case 15'),
('test', 'Case16', 'This is Case 16'),
('test', 'Case17', 'This is Case 17'),
('test', 'Case18', 'This is Case 18'),
('test', 'Case19', 'This is Case 19'),
('test', 'Case20', 'This is Case 20'),
('test', 'Case21', 'This is Case 21'),
('test', 'Case22', 'This is Case 22'),
('test', 'Case23', 'This is Case 23'),
('test', 'Case24', 'This is Case 24'),
('test', 'Case25', 'This is Case 25'),
('test', 'Case26', 'This is Case 26'),
('test', 'Case27', 'This is Case 27'),
('test', 'Case28', 'This is Case 28'),
('test', 'Case29', 'This is Case 29'),
) # }}}
keys = 'test' + EX + ' ' + ESC + ESC + 'ahi'
wanted = 'testhi'
# End: Selecting Between Same Triggers #}}}

View File

@ -1,69 +1,77 @@
from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
class ParseSnippets_SimpleSnippet(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet testsnip "Test Snippet" b!
This is a test snippet!
endsnippet
"""}
keys = "testsnip" + EX
wanted = "This is a test snippet!"
keys = 'testsnip' + EX
wanted = 'This is a test snippet!'
class ParseSnippets_MissingEndSnippet(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet testsnip "Test Snippet" b!
This is a test snippet!
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
expected_error = r"Missing 'endsnippet' for 'testsnip' in \S+:4"
class ParseSnippets_UnknownDirective(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
unknown directive
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
expected_error = r"Invalid line 'unknown directive' in \S+:2"
class ParseSnippets_InvalidPriorityLine(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
priority - 50
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
expected_error = r"Invalid priority '- 50' in \S+:2"
class ParseSnippets_InvalidPriorityLine1(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
priority
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
expected_error = r"Invalid priority '' in \S+:2"
class ParseSnippets_ExtendsWithoutFiletype(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
extends
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
expected_error = r"'extends' without file types in \S+:2"
class ParseSnippets_ClearAll(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet testsnip "Test snippet"
This is a test.
endsnippet
clearsnippets
"""}
keys = "testsnip" + EX
wanted = "testsnip" + EX
keys = 'testsnip' + EX
wanted = 'testsnip' + EX
class ParseSnippets_ClearOne(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
clearsnippets toclear
snippet testsnip "Test snippet"
@ -74,11 +82,12 @@ class ParseSnippets_ClearOne(_VimTest):
Do not expand.
endsnippet
"""}
keys = "toclear" + EX + "\n" + "testsnip" + EX
wanted = "toclear" + EX + "\n" + "This is a test."
keys = 'toclear' + EX + '\n' + 'testsnip' + EX
wanted = 'toclear' + EX + '\n' + 'This is a test.'
class ParseSnippets_ClearTwo(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
clearsnippets testsnip toclear
snippet testsnip "Test snippet"
@ -89,12 +98,12 @@ class ParseSnippets_ClearTwo(_VimTest):
Do not expand.
endsnippet
"""}
keys = "toclear" + EX + "\n" + "testsnip" + EX
wanted = "toclear" + EX + "\n" + "testsnip" + EX
keys = 'toclear' + EX + '\n' + 'testsnip' + EX
wanted = 'toclear' + EX + '\n' + 'testsnip' + EX
class _ParseSnippets_MultiWord(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet /test snip/
This is a test.
endsnippet
@ -107,18 +116,25 @@ class _ParseSnippets_MultiWord(_VimTest):
This is yet another test.
endsnippet
"""}
class ParseSnippets_MultiWord_Simple(_ParseSnippets_MultiWord):
keys = "test snip" + EX
wanted = "This is a test."
keys = 'test snip' + EX
wanted = 'This is a test.'
class ParseSnippets_MultiWord_Description(_ParseSnippets_MultiWord):
keys = "snip test" + EX
wanted = "This is another test."
keys = 'snip test' + EX
wanted = 'This is another test.'
class ParseSnippets_MultiWord_Description_Option(_ParseSnippets_MultiWord):
keys = "snippet test" + EX
wanted = "This is yet another test."
keys = 'snippet test' + EX
wanted = 'This is yet another test.'
class _ParseSnippets_MultiWord_RE(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet /[d-f]+/ "" r
az test
endsnippet
@ -131,55 +147,67 @@ class _ParseSnippets_MultiWord_RE(_VimTest):
re-test
endsnippet
"""}
class ParseSnippets_MultiWord_RE1(_ParseSnippets_MultiWord_RE):
keys = "abc def" + EX
wanted = "abc az test"
keys = 'abc def' + EX
wanted = 'abc az test'
class ParseSnippets_MultiWord_RE2(_ParseSnippets_MultiWord_RE):
keys = "foo" + EX + " bar" + EX + "\nbar" + EX
wanted = "foo-bar test bar\t\nfoo-bar test"
keys = 'foo' + EX + ' bar' + EX + '\nbar' + EX
wanted = 'foo-bar test bar\t\nfoo-bar test'
class ParseSnippets_MultiWord_RE3(_ParseSnippets_MultiWord_RE):
keys = "test test test" + EX
wanted = "re-test"
keys = 'test test test' + EX
wanted = 're-test'
class ParseSnippets_MultiWord_Quotes(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet "test snip"
This is a test.
endsnippet
"""}
keys = "test snip" + EX
wanted = "This is a test."
keys = 'test snip' + EX
wanted = 'This is a test.'
class ParseSnippets_MultiWord_WithQuotes(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet !"test snip"!
This is a test.
endsnippet
"""}
keys = '"test snip"' + EX
wanted = "This is a test."
wanted = 'This is a test.'
class ParseSnippets_MultiWord_NoContainer(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet test snip
This is a test.
endsnippet
"""}
keys = "test snip" + EX
keys = 'test snip' + EX
wanted = keys
expected_error = "Invalid multiword trigger: 'test snip' in \S+:2"
class ParseSnippets_MultiWord_UnmatchedContainer(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet !inv snip/
This is a test.
endsnippet
"""}
keys = "inv snip" + EX
keys = 'inv snip' + EX
wanted = keys
expected_error = "Invalid multiword trigger: '!inv snip/' in \S+:2"
class ParseSnippets_Global_Python(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
global !p
def tex(ins):
return "a " + ins + " b"
@ -193,11 +221,12 @@ class ParseSnippets_Global_Python(_VimTest):
x `!p snip.rv = tex("jon")` y
endsnippet
"""}
keys = "ab" + EX + "\nac" + EX
wanted = "x a bob b y\nx a jon b y"
keys = 'ab' + EX + '\nac' + EX
wanted = 'x a bob b y\nx a jon b y'
class ParseSnippets_Global_Local_Python(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
global !p
def tex(ins):
return "a " + ins + " b"
@ -208,5 +237,5 @@ x `!p first = tex("bob")
snip.rv = "first"` `!p snip.rv = first` y
endsnippet
"""}
keys = "ab" + EX
wanted = "x first a bob b y"
keys = 'ab' + EX
wanted = 'x first a bob b y'

View File

@ -3,11 +3,12 @@ import sys
from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
PYTHON3 = sys.version_info >= (3,0)
PYTHON3 = sys.version_info >= (3, 0)
def python3():
if PYTHON3:
return "Test does not work on python3."
return 'Test does not work on python3.'
# Plugin: YouCompleteMe {{{#
# TODO(sirver): disabled because it fails right now.
@ -15,9 +16,9 @@ def python3():
# def skip_if(self):
# r = python3()
# if r:
# return r
# return r
# if "7.4" not in self.version:
# return "Needs Vim 7.4."
# return "Needs Vim 7.4."
# plugins = ["Valloric/YouCompleteMe"]
# snippets = ("superlongtrigger", "Hello")
# keys = "superlo\ty"
@ -34,15 +35,18 @@ def python3():
# time.sleep(1)
# End: Plugin: YouCompleteMe #}}}
# Plugin: Neocomplete {{{#
class Plugin_Neocomplete_BugTest(_VimTest):
# Test for https://github.com/SirVer/ultisnips/issues/228
def skip_if(self):
if "+lua" not in self.version:
return "Needs +lua"
plugins = ["Shougo/neocomplete.vim"]
snippets = ("t", "Hello", "", "w")
keys = "iab\\ t" + EX
wanted = "iab\\ Hello"
if '+lua' not in self.version:
return 'Needs +lua'
plugins = ['Shougo/neocomplete.vim']
snippets = ('t', 'Hello', '', 'w')
keys = 'iab\\ t' + EX
wanted = 'iab\\ Hello'
def _extra_options_pre_init(self, vim_config):
vim_config.append(r'set iskeyword+=\\ ')
@ -53,34 +57,39 @@ class Plugin_Neocomplete_BugTest(_VimTest):
vim_config.append('let g:neocomplete#enable_refresh_always = 1')
# End: Plugin: Neocomplete #}}}
# Plugin: unite {{{#
class Plugin_unite_BugTest(_VimTest):
plugins = ["Shougo/unite.vim"]
snippets = ("t", "Hello", "", "w")
keys = "iab\\ t=UltiSnipsCallUnite()\n"
wanted = "iab\\ Hello "
plugins = ['Shougo/unite.vim']
snippets = ('t', 'Hello', '', 'w')
keys = 'iab\\ t=UltiSnipsCallUnite()\n'
wanted = 'iab\\ Hello '
def _extra_options_pre_init(self, vim_config):
vim_config.append(r'set iskeyword+=\\ ')
vim_config.append('function! UltiSnipsCallUnite()')
vim_config.append(' Unite -start-insert -winheight=100 -immediately -no-empty ultisnips')
vim_config.append(
' Unite -start-insert -winheight=100 -immediately -no-empty ultisnips')
vim_config.append(' return ""')
vim_config.append('endfunction')
# End: Plugin: unite #}}}
# Plugin: Supertab {{{#
class Plugin_SuperTab_SimpleTest(_VimTest):
plugins = ["ervandew/supertab"]
snippets = ("long", "Hello", "", "w")
keys = ( "longtextlongtext\n" +
"longt" + EX + "\n" + # Should complete word
"long" + EX ) # Should expand
wanted = "longtextlongtext\nlongtextlongtext\nHello"
plugins = ['ervandew/supertab']
snippets = ('long', 'Hello', '', 'w')
keys = ('longtextlongtext\n' +
'longt' + EX + '\n' + # Should complete word
'long' + EX) # Should expand
wanted = 'longtextlongtext\nlongtextlongtext\nHello'
def _before_test(self):
# Make sure that UltiSnips has the keymap
self.vim.send(":call UltiSnips#map_keys#MapKeys()\n")
self.vim.send(':call UltiSnips#map_keys#MapKeys()\n')
def _extra_options_post_init(self, vim_config):
assert EX == "\t" # Otherwise this test needs changing.
assert EX == '\t' # Otherwise this test needs changing.
vim_config.append('let g:SuperTabDefaultCompletionType = "<c-p>"')
vim_config.append('let g:SuperTabRetainCompletionDuration = "insert"')
vim_config.append('let g:SuperTabLongestHighlight = 1')

View File

@ -2,193 +2,248 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Recursive (Nested) Snippets {{{#
class RecTabStops_SimpleCase_ExpectCorrectResult(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "m" + EX + "hello" + JF + "world" + JF + "ups" + JF + "end"
wanted = "[ [ hello world ]ups end ]"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'm' + EX + 'hello' + \
JF + 'world' + JF + 'ups' + JF + 'end'
wanted = '[ [ hello world ]ups end ]'
class RecTabStops_SimpleCaseLeaveSecondSecond_ExpectCorrectResult(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "m" + EX + "hello" + JF + "world" + JF + JF + JF + "end"
wanted = "[ [ hello world ] sec ]end"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'm' + EX + 'hello' + JF + 'world' + JF + JF + JF + 'end'
wanted = '[ [ hello world ] sec ]end'
class RecTabStops_SimpleCaseLeaveFirstSecond_ExpectCorrectResult(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "m" + EX + "hello" + JF + JF + JF + "world" + JF + "end"
wanted = "[ [ hello sec ] world ]end"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'm' + EX + 'hello' + JF + JF + JF + 'world' + JF + 'end'
wanted = '[ [ hello sec ] world ]end'
class RecTabStops_InnerWOTabStop_ECR(_VimTest):
snippets = (
("m1", "Just some Text"),
("m", "[ ${1:first} ${2:sec} ]"),
('m1', 'Just some Text'),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m1" + EX + "hi" + JF + "two" + JF + "end"
wanted = "[ Just some Texthi two ]end"
keys = 'm' + EX + 'm1' + EX + 'hi' + JF + 'two' + JF + 'end'
wanted = '[ Just some Texthi two ]end'
class RecTabStops_InnerWOTabStopTwiceDirectly_ECR(_VimTest):
snippets = (
("m1", "JST"),
("m", "[ ${1:first} ${2:sec} ]"),
('m1', 'JST'),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m1" + EX + " m1" + EX + "hi" + JF + "two" + JF + "end"
wanted = "[ JST JSThi two ]end"
keys = 'm' + EX + 'm1' + EX + ' m1' + EX + 'hi' + JF + 'two' + JF + 'end'
wanted = '[ JST JSThi two ]end'
class RecTabStops_InnerWOTabStopTwice_ECR(_VimTest):
snippets = (
("m1", "JST"),
("m", "[ ${1:first} ${2:sec} ]"),
('m1', 'JST'),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m1" + EX + JF + "m1" + EX + "hi" + JF + "end"
wanted = "[ JST JSThi ]end"
keys = 'm' + EX + 'm1' + EX + JF + 'm1' + EX + 'hi' + JF + 'end'
wanted = '[ JST JSThi ]end'
class RecTabStops_OuterOnlyWithZeroTS_ECR(_VimTest):
snippets = (
("m", "A $0 B"),
("m1", "C $1 D $0 E"),
('m', 'A $0 B'),
('m1', 'C $1 D $0 E'),
)
keys = "m" + EX + "m1" + EX + "CD" + JF + "DE"
wanted = "A C CD D DE E B"
keys = 'm' + EX + 'm1' + EX + 'CD' + JF + 'DE'
wanted = 'A C CD D DE E B'
class RecTabStops_OuterOnlyWithZero_ECR(_VimTest):
snippets = (
("m", "A $0 B"),
("m1", "C $1 D $0 E"),
('m', 'A $0 B'),
('m1', 'C $1 D $0 E'),
)
keys = "m" + EX + "m1" + EX + "CD" + JF + "DE"
wanted = "A C CD D DE E B"
keys = 'm' + EX + 'm1' + EX + 'CD' + JF + 'DE'
wanted = 'A C CD D DE E B'
class RecTabStops_ExpandedInZeroTS_ECR(_VimTest):
snippets = (
("m", "A $0 B $1"),
("m1", "C $1 D $0 E"),
('m', 'A $0 B $1'),
('m1', 'C $1 D $0 E'),
)
keys = "m" + EX + "hi" + JF + "m1" + EX + "CD" + JF + "DE"
wanted = "A C CD D DE E B hi"
keys = 'm' + EX + 'hi' + JF + 'm1' + EX + 'CD' + JF + 'DE'
wanted = 'A C CD D DE E B hi'
class RecTabStops_ExpandedInZeroTSTwice_ECR(_VimTest):
snippets = (
("m", "A $0 B $1"),
("m1", "C $1 D $0 E"),
('m', 'A $0 B $1'),
('m1', 'C $1 D $0 E'),
)
keys = "m" + EX + "hi" + JF + "m" + EX + "again" + JF + "m1" + \
EX + "CD" + JF + "DE"
wanted = "A A C CD D DE E B again B hi"
keys = 'm' + EX + 'hi' + JF + 'm' + EX + 'again' + JF + 'm1' + \
EX + 'CD' + JF + 'DE'
wanted = 'A A C CD D DE E B again B hi'
class RecTabStops_ExpandedInZeroTSSecondTime_ECR(_VimTest):
snippets = (
("m", "A $0 B $1"),
("m1", "C $1 D $0 E"),
('m', 'A $0 B $1'),
('m1', 'C $1 D $0 E'),
)
keys = "m" + EX + "hi" + JF + "m" + EX + "m1" + EX + "CD" + JF + "DE" + JF + "AB"
wanted = "A A AB B C CD D DE E B hi"
keys = 'm' + EX + 'hi' + JF + 'm' + EX + \
'm1' + EX + 'CD' + JF + 'DE' + JF + 'AB'
wanted = 'A A AB B C CD D DE E B hi'
class RecTabsStops_TypeInZero_ECR(_VimTest):
snippets = (
("v", r"\vec{$1}", "Vector", "w"),
("frac", r"\frac{${1:one}}${0:zero}{${2:two}}", "Fractio", "w"),
('v', r"\vec{$1}", 'Vector', 'w'),
('frac', r"\frac{${1:one}}${0:zero}{${2:two}}", 'Fractio', 'w'),
)
keys = "v" + EX + "frac" + EX + "a" + JF + "b" + JF + "frac" + EX + "aa" + JF + JF + "cc" + JF + \
"hello frac" + EX + JF + JF + "world"
keys = 'v' + EX + 'frac' + EX + 'a' + JF + 'b' + JF + 'frac' + EX + 'aa' + JF + JF + 'cc' + JF + \
'hello frac' + EX + JF + JF + 'world'
wanted = r"\vec{\frac{a}\frac{aa}cc{two}{b}}hello \frac{one}world{two}"
class RecTabsStops_TypeInZero2_ECR(_VimTest):
snippets = (
("m", r"_${0:explicit zero}", "snip", "i"),
('m', r"_${0:explicit zero}", 'snip', 'i'),
)
keys = "m" + EX + "hello m" + EX + "world m" + EX + "end"
keys = 'm' + EX + 'hello m' + EX + 'world m' + EX + 'end'
wanted = r"_hello _world _end"
class RecTabsStops_BackspaceZero_ECR(_VimTest):
snippets = (
("m", r"${1:one}${0:explicit zero}${2:two}", "snip", "i"),
('m', r"${1:one}${0:explicit zero}${2:two}", 'snip', 'i'),
)
keys = "m" + EX + JF + JF + BS + "m" + EX
keys = 'm' + EX + JF + JF + BS + 'm' + EX
wanted = r"oneoneexplicit zerotwotwo"
class RecTabStops_MirrorInnerSnippet_ECR(_VimTest):
snippets = (
("m", "[ $1 $2 ] $1"),
("m1", "ASnip $1 ASnip $2 ASnip"),
('m', '[ $1 $2 ] $1'),
('m1', 'ASnip $1 ASnip $2 ASnip'),
)
keys = "m" + EX + "m1" + EX + "Hallo" + JF + "Hi" + JF + "endone" + JF + "two" + JF + "totalend"
wanted = "[ ASnip Hallo ASnip Hi ASnipendone two ] ASnip Hallo ASnip Hi ASnipendonetotalend"
keys = 'm' + EX + 'm1' + EX + 'Hallo' + JF + 'Hi' + \
JF + 'endone' + JF + 'two' + JF + 'totalend'
wanted = '[ ASnip Hallo ASnip Hi ASnipendone two ] ASnip Hallo ASnip Hi ASnipendonetotalend'
class RecTabStops_NotAtBeginningOfTS_ExpectCorrectResult(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "hello m" + EX + "hi" + JF + "two" + JF + "ups" + JF + "three" + \
JF + "end"
wanted = "[ hello [ hi two ]ups three ]end"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'hello m' + EX + 'hi' + JF + 'two' + JF + 'ups' + JF + 'three' + \
JF + 'end'
wanted = '[ hello [ hi two ]ups three ]end'
class RecTabStops_InNewlineInTabstop_ExpectCorrectResult(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "hello\nm" + EX + "hi" + JF + "two" + JF + "ups" + JF + "three" + \
JF + "end"
wanted = "[ hello\n[ hi two ]ups three ]end"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'hello\nm' + EX + 'hi' + JF + 'two' + JF + 'ups' + JF + 'three' + \
JF + 'end'
wanted = '[ hello\n[ hi two ]ups three ]end'
class RecTabStops_InNewlineInTabstopNotAtBeginOfLine_ECR(_VimTest):
snippets = ("m", "[ ${1:first} ${2:sec} ]")
keys = "m" + EX + "hello\nhello again m" + EX + "hi" + JF + "two" + \
JF + "ups" + JF + "three" + JF + "end"
wanted = "[ hello\nhello again [ hi two ]ups three ]end"
snippets = ('m', '[ ${1:first} ${2:sec} ]')
keys = 'm' + EX + 'hello\nhello again m' + EX + 'hi' + JF + 'two' + \
JF + 'ups' + JF + 'three' + JF + 'end'
wanted = '[ hello\nhello again [ hi two ]ups three ]end'
class RecTabStops_InNewlineMultiline_ECR(_VimTest):
snippets = ("m", "M START\n$0\nM END")
keys = "m" + EX + "m" + EX
wanted = "M START\nM START\n\nM END\nM END"
snippets = ('m', 'M START\n$0\nM END')
keys = 'm' + EX + 'm' + EX
wanted = 'M START\nM START\n\nM END\nM END'
class RecTabStops_InNewlineManualIndent_ECR(_VimTest):
snippets = ("m", "M START\n$0\nM END")
keys = "m" + EX + " m" + EX + "hi"
wanted = "M START\n M START\n hi\n M END\nM END"
snippets = ('m', 'M START\n$0\nM END')
keys = 'm' + EX + ' m' + EX + 'hi'
wanted = 'M START\n M START\n hi\n M END\nM END'
class RecTabStops_InNewlineManualIndentTextInFront_ECR(_VimTest):
snippets = ("m", "M START\n$0\nM END")
keys = "m" + EX + " hallo m" + EX + "hi"
wanted = "M START\n hallo M START\n hi\n M END\nM END"
snippets = ('m', 'M START\n$0\nM END')
keys = 'm' + EX + ' hallo m' + EX + 'hi'
wanted = 'M START\n hallo M START\n hi\n M END\nM END'
class RecTabStops_InNewlineMultilineWithIndent_ECR(_VimTest):
snippets = ("m", "M START\n $0\nM END")
keys = "m" + EX + "m" + EX + "hi"
wanted = "M START\n M START\n hi\n M END\nM END"
snippets = ('m', 'M START\n $0\nM END')
keys = 'm' + EX + 'm' + EX + 'hi'
wanted = 'M START\n M START\n hi\n M END\nM END'
class RecTabStops_InNewlineMultilineWithNonZeroTS_ECR(_VimTest):
snippets = ("m", "M START\n $1\nM END -> $0")
keys = "m" + EX + "m" + EX + "hi" + JF + "hallo" + JF + "end"
wanted = "M START\n M START\n hi\n M END -> hallo\n" \
"M END -> end"
snippets = ('m', 'M START\n $1\nM END -> $0')
keys = 'm' + EX + 'm' + EX + 'hi' + JF + 'hallo' + JF + 'end'
wanted = 'M START\n M START\n hi\n M END -> hallo\n' \
'M END -> end'
class RecTabStops_BarelyNotLeavingInner_ECR(_VimTest):
snippets = (
("m", "[ ${1:first} ${2:sec} ]"),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m" + EX + "a" + 3*ARR_L + JF + "hallo" + \
JF + "ups" + JF + "world" + JF + "end"
wanted = "[ [ a hallo ]ups world ]end"
keys = 'm' + EX + 'm' + EX + 'a' + 3 * ARR_L + JF + 'hallo' + \
JF + 'ups' + JF + 'world' + JF + 'end'
wanted = '[ [ a hallo ]ups world ]end'
class RecTabStops_LeavingInner_ECR(_VimTest):
snippets = (
("m", "[ ${1:first} ${2:sec} ]"),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m" + EX + "a" + 4*ARR_L + JF + "hallo" + \
JF + "world"
wanted = "[ [ a sec ] hallo ]world"
keys = 'm' + EX + 'm' + EX + 'a' + 4 * ARR_L + JF + 'hallo' + \
JF + 'world'
wanted = '[ [ a sec ] hallo ]world'
class RecTabStops_LeavingInnerInner_ECR(_VimTest):
snippets = (
("m", "[ ${1:first} ${2:sec} ]"),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m" + EX + "m" + EX + "a" + 4*ARR_L + JF + "hallo" + \
JF + "ups" + JF + "world" + JF + "end"
wanted = "[ [ [ a sec ] hallo ]ups world ]end"
keys = 'm' + EX + 'm' + EX + 'm' + EX + 'a' + 4 * ARR_L + JF + 'hallo' + \
JF + 'ups' + JF + 'world' + JF + 'end'
wanted = '[ [ [ a sec ] hallo ]ups world ]end'
class RecTabStops_LeavingInnerInnerTwo_ECR(_VimTest):
snippets = (
("m", "[ ${1:first} ${2:sec} ]"),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m" + EX + "m" + EX + "a" + 6*ARR_L + JF + "hallo" + \
JF + "end"
wanted = "[ [ [ a sec ] sec ] hallo ]end"
keys = 'm' + EX + 'm' + EX + 'm' + EX + 'a' + 6 * ARR_L + JF + 'hallo' + \
JF + 'end'
wanted = '[ [ [ a sec ] sec ] hallo ]end'
class RecTabStops_ZeroTSisNothingSpecial_ECR(_VimTest):
snippets = (
("m1", "[ ${1:first} $0 ${2:sec} ]"),
("m", "[ ${1:first} ${2:sec} ]"),
('m1', '[ ${1:first} $0 ${2:sec} ]'),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m1" + EX + "one" + JF + "two" + \
JF + "three" + JF + "four" + JF + "end"
wanted = "[ [ one three two ] four ]end"
keys = 'm' + EX + 'm1' + EX + 'one' + JF + 'two' + \
JF + 'three' + JF + 'four' + JF + 'end'
wanted = '[ [ one three two ] four ]end'
class RecTabStops_MirroredZeroTS_ECR(_VimTest):
snippets = (
("m1", "[ ${1:first} ${0:Year, some default text} $0 ${2:sec} ]"),
("m", "[ ${1:first} ${2:sec} ]"),
('m1', '[ ${1:first} ${0:Year, some default text} $0 ${2:sec} ]'),
('m', '[ ${1:first} ${2:sec} ]'),
)
keys = "m" + EX + "m1" + EX + "one" + JF + "two" + \
JF + "three" + JF + "four" + JF + "end"
wanted = "[ [ one three three two ] four ]end"
keys = 'm' + EX + 'm1' + EX + 'one' + JF + 'two' + \
JF + 'three' + JF + 'four' + JF + 'end'
wanted = '[ [ one three three two ] four ]end'
class RecTabStops_ChildTriggerContainsParentTextObjects(_VimTest):
# https://bugs.launchpad.net/bugs/1191617
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
global !p
def complete(t, opts):
if t:
@ -205,7 +260,6 @@ auto = autocomplete_options(t, match.group(2), attr=["id: ", "class: ", "title:
snip.rv = "form_for" + match.group(1) + "{"`$1`!p if (snip.c != auto) : snip.rv=auto`
endsnippet
"""}
keys = "form_for user, namespace: some_namespace, html: {i" + EX + "i" + EX
wanted = "form_for user, namespace: some_namespace, html: {(id: |class: |title: )d: "
keys = 'form_for user, namespace: some_namespace, html: {i' + EX + 'i' + EX
wanted = 'form_for user, namespace: some_namespace, html: {(id: |class: |title: )d: '
# End: Recursive (Nested) Snippets #}}}

View File

@ -3,18 +3,25 @@ from test.constant import *
# Unmap SelectMode Mappings {{{#
# Test for bug 427298 #
class _SelectModeMappings(_VimTest):
snippets = ("test", "${1:World}")
keys = "test" + EX + "Hello"
wanted = "Hello"
maps = ("", "")
buffer_maps = ("", "")
snippets = ('test', '${1:World}')
keys = 'test' + EX + 'Hello'
wanted = 'Hello'
maps = ('', '')
buffer_maps = ('', '')
do_unmapping = True
ignores = []
def _extra_options_pre_init(self, vim_config):
vim_config.append(":let g:UltiSnipsRemoveSelectModeMappings=%i" % int(self.do_unmapping))
vim_config.append(":let g:UltiSnipsMappingsToIgnore=%s" % repr(self.ignores))
vim_config.append(
':let g:UltiSnipsRemoveSelectModeMappings=%i' % int(
self.do_unmapping))
vim_config.append(
':let g:UltiSnipsMappingsToIgnore=%s' %
repr(
self.ignores))
if not isinstance(self.maps[0], tuple):
self.maps = (self.maps,)
@ -22,71 +29,96 @@ class _SelectModeMappings(_VimTest):
self.buffer_maps = (self.buffer_maps,)
for key, m in self.maps:
if not len(key): continue
vim_config.append(":smap %s %s" % (key,m))
if not len(key):
continue
vim_config.append(':smap %s %s' % (key, m))
for key, m in self.buffer_maps:
if not len(key): continue
vim_config.append(":smap <buffer> %s %s" % (key,m))
if not len(key):
continue
vim_config.append(':smap <buffer> %s %s' % (key, m))
class SelectModeMappings_RemoveBeforeSelecting_ECR(_SelectModeMappings):
maps = ("H", "x")
wanted = "Hello"
maps = ('H', 'x')
wanted = 'Hello'
class SelectModeMappings_DisableRemoveBeforeSelecting_ECR(_SelectModeMappings):
do_unmapping = False
maps = ("H", "x")
wanted = "xello"
maps = ('H', 'x')
wanted = 'xello'
class SelectModeMappings_IgnoreMappings_ECR(_SelectModeMappings):
ignores = ["e"]
maps = ("H", "x"), ("e", "l")
wanted = "Hello"
ignores = ['e']
maps = ('H', 'x'), ('e', 'l')
wanted = 'Hello'
class SelectModeMappings_IgnoreMappings1_ECR(_SelectModeMappings):
ignores = ["H"]
maps = ("H", "x"), ("e", "l")
wanted = "xello"
ignores = ['H']
maps = ('H', 'x'), ('e', 'l')
wanted = 'xello'
class SelectModeMappings_IgnoreMappings2_ECR(_SelectModeMappings):
ignores = ["e", "H"]
maps = ("e", "l"), ("H", "x")
wanted = "xello"
ignores = ['e', 'H']
maps = ('e', 'l'), ('H', 'x')
wanted = 'xello'
class SelectModeMappings_BufferLocalMappings_ECR(_SelectModeMappings):
buffer_maps = ("H", "blah")
wanted = "Hello"
buffer_maps = ('H', 'blah')
wanted = 'Hello'
# End: Unmap SelectMode Mappings #}}}
# Exclusive Selection {{{#
class _ES_Base(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set selection=exclusive")
vim_config.append('set selection=exclusive')
class ExclusiveSelection_SimpleTabstop_Test(_ES_Base):
snippets = ("test", "h${1:blah}w $1")
keys = "test" + EX + "ui" + JF
wanted = "huiw ui"
snippets = ('test', 'h${1:blah}w $1')
keys = 'test' + EX + 'ui' + JF
wanted = 'huiw ui'
class ExclusiveSelection_RealWorldCase_Test(_ES_Base):
snippets = ("for",
"""for ($${1:i} = ${2:0}; $$1 < ${3:count}; $$1${4:++}) {
snippets = ('for',
"""for ($${1:i} = ${2:0}; $$1 < ${3:count}; $$1${4:++}) {
${5:// code}
}""")
keys = "for" + EX + "k" + JF
keys = 'for' + EX + 'k' + JF
wanted = """for ($k = 0; $k < count; $k++) {
// code
}"""
# End: Exclusive Selection #}}}
# Old Selection {{{#
class _OS_Base(_VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set selection=old")
vim_config.append('set selection=old')
class OldSelection_SimpleTabstop_Test(_OS_Base):
snippets =("test", "h${1:blah}w $1")
keys = "test" + EX + "ui" + JF
wanted = "huiw ui"
snippets = ('test', 'h${1:blah}w $1')
keys = 'test' + EX + 'ui' + JF
wanted = 'huiw ui'
class OldSelection_RealWorldCase_Test(_OS_Base):
snippets = ("for",
"""for ($${1:i} = ${2:0}; $$1 < ${3:count}; $$1${4:++}) {
snippets = ('for',
"""for ($${1:i} = ${2:0}; $$1 < ${3:count}; $$1${4:++}) {
${5:// code}
}""")
keys = "for" + EX + "k" + JF
keys = 'for' + EX + 'k' + JF
wanted = """for ($k = 0; $k < count; $k++) {
// code
}"""

View File

@ -3,97 +3,125 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# snipMate support {{{#
class snipMate_SimpleSnippet(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet hello
\tThis is a test snippet
\t# With a comment"""}
keys = "hello" + EX
wanted = "This is a test snippet\n# With a comment"
keys = 'hello' + EX
wanted = 'This is a test snippet\n# With a comment'
class snipMate_OtherFiletype(_VimTest):
files = { "snippets/blubi.snippets": """
files = { 'snippets/blubi.snippets': """
snippet hello
\tworked"""}
keys = "hello" + EX + ESC + ":set ft=blubi\nohello" + EX
wanted = "hello" + EX + "\nworked"
keys = 'hello' + EX + ESC + ':set ft=blubi\nohello' + EX
wanted = 'hello' + EX + '\nworked'
class snipMate_MultiMatches(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet hello The first snippet."
\tone
snippet hello The second snippet.
\ttwo"""}
keys = "hello" + EX + "2\n"
wanted = "two"
keys = 'hello' + EX + '2\n'
wanted = 'two'
class snipMate_SimpleSnippetSubDirectory(_VimTest):
files = { "snippets/_/blub.snippets": """
files = { 'snippets/_/blub.snippets': """
snippet hello
\tThis is a test snippet"""}
keys = "hello" + EX
wanted = "This is a test snippet"
keys = 'hello' + EX
wanted = 'This is a test snippet'
class snipMate_SimpleSnippetInSnippetFile(_VimTest):
files = {
"snippets/_/hello.snippet": """This is a stand alone snippet""",
"snippets/_/hello1.snippet": """This is two stand alone snippet""",
"snippets/_/hello2/this_is_my_cool_snippet.snippet": """Three""",
'snippets/_/hello.snippet': """This is a stand alone snippet""",
'snippets/_/hello1.snippet': """This is two stand alone snippet""",
'snippets/_/hello2/this_is_my_cool_snippet.snippet': """Three""",
}
keys = "hello" + EX + "\nhello1" + EX + "\nhello2" + EX
wanted = "This is a stand alone snippet\nThis is two stand alone snippet\nThree"
keys = 'hello' + EX + '\nhello1' + EX + '\nhello2' + EX
wanted = 'This is a stand alone snippet\nThis is two stand alone snippet\nThree'
class snipMate_Interpolation(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet test
\tla`printf('c%02d', 3)`lu"""}
keys = "test" + EX
wanted = "lac03lu"
keys = 'test' + EX
wanted = 'lac03lu'
class snipMate_InterpolationWithSystem(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet test
\tla`system('echo -ne öäü')`lu"""}
keys = "test" + EX
wanted = "laöäülu"
keys = 'test' + EX
wanted = 'laöäülu'
class snipMate_TestMirrors(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet for
\tfor (${2:i}; $2 < ${1:count}; $1++) {
\t\t${4}
\t}"""}
keys = "for" + EX + "blub" + JF + "j" + JF + "hi"
wanted = "for (j; j < blub; blub++) {\n\thi\n}"
keys = 'for' + EX + 'blub' + JF + 'j' + JF + 'hi'
wanted = 'for (j; j < blub; blub++) {\n\thi\n}'
class snipMate_TestMirrorsInPlaceholders(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet opt
\t<option value="${1:option}">${2:$1}</option>"""}
keys = "opt" + EX + "some" + JF + JF + "ende"
keys = 'opt' + EX + 'some' + JF + JF + 'ende'
wanted = """<option value="some">some</option>ende"""
class snipMate_TestMirrorsInPlaceholders_Overwrite(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet opt
\t<option value="${1:option}">${2:$1}</option>"""}
keys = "opt" + EX + "some" + JF + "not" + JF + "ende"
keys = 'opt' + EX + 'some' + JF + 'not' + JF + 'ende'
wanted = """<option value="some">not</option>ende"""
class snipMate_Visual_Simple(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet v
\th${VISUAL}b"""}
keys = "blablub" + ESC + "0v6l" + EX + "v" + EX
wanted = "hblablubb"
keys = 'blablub' + ESC + '0v6l' + EX + 'v' + EX
wanted = 'hblablubb'
class snipMate_NoNestedTabstops(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet test
\th$${1:${2:blub}}$$"""}
keys = "test" + EX + JF + "hi"
wanted = "h$${2:blub}$$hi"
keys = 'test' + EX + JF + 'hi'
wanted = 'h$${2:blub}$$hi'
class snipMate_Extends(_VimTest):
files = { "snippets/a.snippets": """
files = { 'snippets/a.snippets': """
extends b
snippet test
\tblub""", "snippets/b.snippets": """
\tblub""", 'snippets/b.snippets': """
snippet test1
\tblah"""
}
keys = ESC + ":set ft=a\n" + "itest1" + EX
wanted = "blah"
}
keys = ESC + ':set ft=a\n' + 'itest1' + EX
wanted = 'blah'
class snipMate_EmptyLinesContinueSnippets(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet test
\tblub
@ -101,20 +129,21 @@ snippet test
snippet test1
\ta"""
}
keys = "test" + EX
wanted = "blub\n\nblah\n"
}
keys = 'test' + EX
wanted = 'blub\n\nblah\n'
class snipMate_OverwrittenByRegExpTrigger(_VimTest):
files = { "snippets/_.snippets": """
files = { 'snippets/_.snippets': """
snippet def
\tsnipmate
""",
"us/all.snippets": r"""
'us/all.snippets': r"""
snippet "(de)?f" "blub" r
ultisnips
endsnippet
""" }
keys = "def" + EX
wanted = "ultisnips"
keys = 'def' + EX
wanted = 'ultisnips'
# End: snipMate support #}}}

View File

@ -4,126 +4,178 @@ from test.constant import *
from test.util import running_on_windows
# Snippet Options {{{#
class SnippetOptions_OnlyExpandWhenWSInFront_Expand(_VimTest):
snippets = ("test", "Expand me!", "", "b")
keys = "test" + EX
wanted = "Expand me!"
snippets = ('test', 'Expand me!', '', 'b')
keys = 'test' + EX
wanted = 'Expand me!'
class SnippetOptions_OnlyExpandWhenWSInFront_Expand2(_VimTest):
snippets = ("test", "Expand me!", "", "b")
keys = " test" + EX
wanted = " Expand me!"
snippets = ('test', 'Expand me!', '', 'b')
keys = ' test' + EX
wanted = ' Expand me!'
class SnippetOptions_OnlyExpandWhenWSInFront_DontExpand(_VimTest):
snippets = ("test", "Expand me!", "", "b")
keys = "a test" + EX
wanted = "a test" + EX
snippets = ('test', 'Expand me!', '', 'b')
keys = 'a test' + EX
wanted = 'a test' + EX
class SnippetOptions_OnlyExpandWhenWSInFront_OneWithOneWO(_VimTest):
snippets = (
("test", "Expand me!", "", "b"),
("test", "not at beginning", "", ""),
('test', 'Expand me!', '', 'b'),
('test', 'not at beginning', '', ''),
)
keys = "a test" + EX
wanted = "a not at beginning"
keys = 'a test' + EX
wanted = 'a not at beginning'
class SnippetOptions_OnlyExpandWhenWSInFront_OneWithOneWOChoose(_VimTest):
snippets = (
("test", "Expand me!", "", "b"),
("test", "not at beginning", "", ""),
('test', 'Expand me!', '', 'b'),
('test', 'not at beginning', '', ''),
)
keys = " test" + EX + "1\n"
wanted = " Expand me!"
keys = ' test' + EX + '1\n'
wanted = ' Expand me!'
class SnippetOptions_ExpandInwordSnippets_SimpleExpand(_VimTest):
snippets = (("test", "Expand me!", "", "i"), )
keys = "atest" + EX
wanted = "aExpand me!"
snippets = (('test', 'Expand me!', '', 'i'), )
keys = 'atest' + EX
wanted = 'aExpand me!'
class SnippetOptions_ExpandInwordSnippets_ExpandSingle(_VimTest):
snippets = (("test", "Expand me!", "", "i"), )
keys = "test" + EX
wanted = "Expand me!"
snippets = (('test', 'Expand me!', '', 'i'), )
keys = 'test' + EX
wanted = 'Expand me!'
class SnippetOptions_ExpandInwordSnippetsWithOtherChars_Expand(_VimTest):
snippets = (("test", "Expand me!", "", "i"), )
keys = "$test" + EX
wanted = "$Expand me!"
snippets = (('test', 'Expand me!', '', 'i'), )
keys = '$test' + EX
wanted = '$Expand me!'
class SnippetOptions_ExpandInwordSnippetsWithOtherChars_Expand2(_VimTest):
snippets = (("test", "Expand me!", "", "i"), )
keys = "-test" + EX
wanted = "-Expand me!"
snippets = (('test', 'Expand me!', '', 'i'), )
keys = '-test' + EX
wanted = '-Expand me!'
class SnippetOptions_ExpandInwordSnippetsWithOtherChars_Expand3(_VimTest):
skip_if = lambda self: running_on_windows()
snippets = (("test", "Expand me!", "", "i"), )
keys = "ßßtest" + EX
wanted = "ßßExpand me!"
snippets = (('test', 'Expand me!', '', 'i'), )
keys = 'ßßtest' + EX
wanted = 'ßßExpand me!'
class _SnippetOptions_ExpandWordSnippets(_VimTest):
snippets = (("test", "Expand me!", "", "w"), )
snippets = (('test', 'Expand me!', '', 'w'), )
class SnippetOptions_ExpandWordSnippets_NormalExpand(
_SnippetOptions_ExpandWordSnippets):
keys = "test" + EX
wanted = "Expand me!"
keys = 'test' + EX
wanted = 'Expand me!'
class SnippetOptions_ExpandWordSnippets_NoExpand(
_SnippetOptions_ExpandWordSnippets):
keys = "atest" + EX
wanted = "atest" + EX
_SnippetOptions_ExpandWordSnippets):
keys = 'atest' + EX
wanted = 'atest' + EX
class SnippetOptions_ExpandWordSnippets_ExpandSuffix(
_SnippetOptions_ExpandWordSnippets):
keys = "a-test" + EX
wanted = "a-Expand me!"
_SnippetOptions_ExpandWordSnippets):
keys = 'a-test' + EX
wanted = 'a-Expand me!'
class SnippetOptions_ExpandWordSnippets_ExpandSuffix2(
_SnippetOptions_ExpandWordSnippets):
keys = "a(test" + EX
wanted = "a(Expand me!"
_SnippetOptions_ExpandWordSnippets):
keys = 'a(test' + EX
wanted = 'a(Expand me!'
class SnippetOptions_ExpandWordSnippets_ExpandSuffix3(
_SnippetOptions_ExpandWordSnippets):
keys = "[[test" + EX
wanted = "[[Expand me!"
_SnippetOptions_ExpandWordSnippets):
keys = '[[test' + EX
wanted = '[[Expand me!'
class _No_Tab_Expand(_VimTest):
snippets = ("test", "\t\tExpand\tme!\t", "", "t")
snippets = ('test', '\t\tExpand\tme!\t', '', 't')
class No_Tab_Expand_Simple(_No_Tab_Expand):
keys = "test" + EX
wanted = "\t\tExpand\tme!\t"
keys = 'test' + EX
wanted = '\t\tExpand\tme!\t'
class No_Tab_Expand_Leading_Spaces(_No_Tab_Expand):
keys = " test" + EX
wanted = " \t\tExpand\tme!\t"
keys = ' test' + EX
wanted = ' \t\tExpand\tme!\t'
class No_Tab_Expand_Leading_Tabs(_No_Tab_Expand):
keys = "\ttest" + EX
wanted = "\t\t\tExpand\tme!\t"
keys = '\ttest' + EX
wanted = '\t\t\tExpand\tme!\t'
class No_Tab_Expand_No_TS(_No_Tab_Expand):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set sts=3")
keys = "test" + EX
wanted = "\t\tExpand\tme!\t"
vim_config.append('set sw=3')
vim_config.append('set sts=3')
keys = 'test' + EX
wanted = '\t\tExpand\tme!\t'
class No_Tab_Expand_ET(_No_Tab_Expand):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set expandtab")
keys = "test" + EX
wanted = "\t\tExpand\tme!\t"
vim_config.append('set sw=3')
vim_config.append('set expandtab')
keys = 'test' + EX
wanted = '\t\tExpand\tme!\t'
class No_Tab_Expand_ET_Leading_Spaces(_No_Tab_Expand):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set expandtab")
keys = " test" + EX
wanted = " \t\tExpand\tme!\t"
vim_config.append('set sw=3')
vim_config.append('set expandtab')
keys = ' test' + EX
wanted = ' \t\tExpand\tme!\t'
class No_Tab_Expand_ET_SW(_No_Tab_Expand):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=8")
vim_config.append("set expandtab")
keys = "test" + EX
wanted = "\t\tExpand\tme!\t"
vim_config.append('set sw=8')
vim_config.append('set expandtab')
keys = 'test' + EX
wanted = '\t\tExpand\tme!\t'
class No_Tab_Expand_ET_SW_TS(_No_Tab_Expand):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set sw=3")
vim_config.append("set sts=3")
vim_config.append("set ts=3")
vim_config.append("set expandtab")
keys = "test" + EX
wanted = "\t\tExpand\tme!\t"
vim_config.append('set sw=3')
vim_config.append('set sts=3')
vim_config.append('set ts=3')
vim_config.append('set expandtab')
keys = 'test' + EX
wanted = '\t\tExpand\tme!\t'
class _TabExpand_RealWorld(object):
snippets = ("hi",
r"""hi
snippets = ('hi',
r"""hi
`!p snip.rv="i1\n"
snip.rv += snip.mkline("i1\n")
snip.shift(1)
@ -135,10 +187,12 @@ snip.rv += snip.mkline("i3")`
snip.rv = repr(snip.rv)
End""")
class No_Tab_Expand_RealWorld(_TabExpand_RealWorld,_VimTest):
class No_Tab_Expand_RealWorld(_TabExpand_RealWorld, _VimTest):
def _extra_options_pre_init(self, vim_config):
vim_config.append("set noexpandtab")
keys = "\t\thi" + EX
vim_config.append('set noexpandtab')
keys = '\t\thi' + EX
wanted = """\t\thi
\t\ti1
\t\ti1
@ -150,106 +204,148 @@ class No_Tab_Expand_RealWorld(_TabExpand_RealWorld,_VimTest):
class SnippetOptions_Regex_Expand(_VimTest):
snippets = ("(test)", "Expand me!", "", "r")
keys = "test" + EX
wanted = "Expand me!"
snippets = ('(test)', 'Expand me!', '', 'r')
keys = 'test' + EX
wanted = 'Expand me!'
class SnippetOptions_Regex_Multiple(_VimTest):
snippets = ("(test *)+", "Expand me!", "", "r")
keys = "test test test" + EX
wanted = "Expand me!"
snippets = ('(test *)+', 'Expand me!', '', 'r')
keys = 'test test test' + EX
wanted = 'Expand me!'
class _Regex_Self(_VimTest):
snippets = ("((?<=\W)|^)(\.)", "self.", "", "r")
snippets = ('((?<=\W)|^)(\.)', 'self.', '', 'r')
class SnippetOptions_Regex_Self_Start(_Regex_Self):
keys = "." + EX
wanted = "self."
keys = '.' + EX
wanted = 'self.'
class SnippetOptions_Regex_Self_Space(_Regex_Self):
keys = " ." + EX
wanted = " self."
keys = ' .' + EX
wanted = ' self.'
class SnippetOptions_Regex_Self_TextAfter(_Regex_Self):
keys = " .a" + EX
wanted = " .a" + EX
keys = ' .a' + EX
wanted = ' .a' + EX
class SnippetOptions_Regex_Self_TextBefore(_Regex_Self):
keys = "a." + EX
wanted = "a." + EX
keys = 'a.' + EX
wanted = 'a.' + EX
class SnippetOptions_Regex_PythonBlockMatch(_VimTest):
snippets = (r"([abc]+)([def]+)", r"""`!p m = match
snip.rv += m.group(2)
snip.rv += m.group(1)
`""", "", "r")
keys = "test cabfed" + EX
wanted = "test fedcab"
`""", '', 'r')
keys = 'test cabfed' + EX
wanted = 'test fedcab'
class SnippetOptions_Regex_PythonBlockNoMatch(_VimTest):
snippets = (r"cabfed", r"""`!p snip.rv = match or "No match"`""")
keys = "test cabfed" + EX
wanted = "test No match"
keys = 'test cabfed' + EX
wanted = 'test No match'
# Tests for Bug #691575
class SnippetOptions_Regex_SameLine_Long_End(_VimTest):
snippets = ("(test.*)", "Expand me!", "", "r")
keys = "test test abc" + EX
wanted = "Expand me!"
snippets = ('(test.*)', 'Expand me!', '', 'r')
keys = 'test test abc' + EX
wanted = 'Expand me!'
class SnippetOptions_Regex_SameLine_Long_Start(_VimTest):
snippets = ("(.*test)", "Expand me!", "", "r")
keys = "abc test test" + EX
wanted = "Expand me!"
snippets = ('(.*test)', 'Expand me!', '', 'r')
keys = 'abc test test' + EX
wanted = 'Expand me!'
class SnippetOptions_Regex_SameLine_Simple(_VimTest):
snippets = ("(test)", "Expand me!", "", "r")
keys = "abc test test" + EX
wanted = "abc test Expand me!"
snippets = ('(test)', 'Expand me!', '', 'r')
keys = 'abc test test' + EX
wanted = 'abc test Expand me!'
class MultiWordSnippet_Simple(_VimTest):
snippets = ("test me", "Expand me!")
keys = "test me" + EX
wanted = "Expand me!"
snippets = ('test me', 'Expand me!')
keys = 'test me' + EX
wanted = 'Expand me!'
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_Expand(_VimTest):
snippets = ("test it", "Expand me!", "", "b")
keys = "test it" + EX
wanted = "Expand me!"
snippets = ('test it', 'Expand me!', '', 'b')
keys = 'test it' + EX
wanted = 'Expand me!'
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_Expand2(_VimTest):
snippets = ("test it", "Expand me!", "", "b")
keys = " test it" + EX
wanted = " Expand me!"
snippets = ('test it', 'Expand me!', '', 'b')
keys = ' test it' + EX
wanted = ' Expand me!'
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_DontExpand(_VimTest):
snippets = ("test it", "Expand me!", "", "b")
keys = "a test it" + EX
wanted = "a test it" + EX
snippets = ('test it', 'Expand me!', '', 'b')
keys = 'a test it' + EX
wanted = 'a test it' + EX
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_OneWithOneWO(_VimTest):
snippets = (
("test it", "Expand me!", "", "b"),
("test it", "not at beginning", "", ""),
('test it', 'Expand me!', '', 'b'),
('test it', 'not at beginning', '', ''),
)
keys = "a test it" + EX
wanted = "a not at beginning"
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_OneWithOneWOChoose(_VimTest):
keys = 'a test it' + EX
wanted = 'a not at beginning'
class MultiWord_SnippetOptions_OnlyExpandWhenWSInFront_OneWithOneWOChoose(
_VimTest):
snippets = (
("test it", "Expand me!", "", "b"),
("test it", "not at beginning", "", ""),
('test it', 'Expand me!', '', 'b'),
('test it', 'not at beginning', '', ''),
)
keys = " test it" + EX + "1\n"
wanted = " Expand me!"
keys = ' test it' + EX + '1\n'
wanted = ' Expand me!'
class MultiWord_SnippetOptions_ExpandInwordSnippets_SimpleExpand(_VimTest):
snippets = (("test it", "Expand me!", "", "i"), )
keys = "atest it" + EX
wanted = "aExpand me!"
snippets = (('test it', 'Expand me!', '', 'i'), )
keys = 'atest it' + EX
wanted = 'aExpand me!'
class MultiWord_SnippetOptions_ExpandInwordSnippets_ExpandSingle(_VimTest):
snippets = (("test it", "Expand me!", "", "i"), )
keys = "test it" + EX
wanted = "Expand me!"
snippets = (('test it', 'Expand me!', '', 'i'), )
keys = 'test it' + EX
wanted = 'Expand me!'
class _MultiWord_SnippetOptions_ExpandWordSnippets(_VimTest):
snippets = (("test it", "Expand me!", "", "w"), )
snippets = (('test it', 'Expand me!', '', 'w'), )
class MultiWord_SnippetOptions_ExpandWordSnippets_NormalExpand(
_MultiWord_SnippetOptions_ExpandWordSnippets):
keys = "test it" + EX
wanted = "Expand me!"
keys = 'test it' + EX
wanted = 'Expand me!'
class MultiWord_SnippetOptions_ExpandWordSnippets_NoExpand(
_MultiWord_SnippetOptions_ExpandWordSnippets):
keys = "atest it" + EX
wanted = "atest it" + EX
_MultiWord_SnippetOptions_ExpandWordSnippets):
keys = 'atest it' + EX
wanted = 'atest it' + EX
class MultiWord_SnippetOptions_ExpandWordSnippets_ExpandSuffix(
_MultiWord_SnippetOptions_ExpandWordSnippets):
keys = "a-test it" + EX
wanted = "a-Expand me!"
_MultiWord_SnippetOptions_ExpandWordSnippets):
keys = 'a-test it' + EX
wanted = 'a-Expand me!'
# Snippet Options #}}}

View File

@ -2,92 +2,102 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# Snippet Priority {{{#
class SnippetPriorities_MultiWordTriggerOverwriteExisting(_VimTest):
snippets = (
("test me", "${1:Hallo}", "Types Hallo"),
("test me", "${1:World}", "Types World"),
("test me", "We overwrite", "Overwrite the two", "", 1),
('test me', '${1:Hallo}', 'Types Hallo'),
('test me', '${1:World}', 'Types World'),
('test me', 'We overwrite', 'Overwrite the two', '', 1),
)
keys = "test me" + EX
wanted = "We overwrite"
keys = 'test me' + EX
wanted = 'We overwrite'
class SnippetPriorities_DoNotCareAboutNonMatchings(_VimTest):
snippets = (
("test1", "Hallo", "Types Hallo"),
("test2", "We overwrite", "Overwrite the two", "", 1),
('test1', 'Hallo', 'Types Hallo'),
('test2', 'We overwrite', 'Overwrite the two', '', 1),
)
keys = "test1" + EX
wanted = "Hallo"
keys = 'test1' + EX
wanted = 'Hallo'
class SnippetPriorities_OverwriteExisting(_VimTest):
snippets = (
("test", "${1:Hallo}", "Types Hallo"),
("test", "${1:World}", "Types World"),
("test", "We overwrite", "Overwrite the two", "", 1),
('test', '${1:Hallo}', 'Types Hallo'),
('test', '${1:World}', 'Types World'),
('test', 'We overwrite', 'Overwrite the two', '', 1),
)
keys = "test" + EX
wanted = "We overwrite"
keys = 'test' + EX
wanted = 'We overwrite'
class SnippetPriorities_OverwriteTwice_ECR(_VimTest):
snippets = (
("test", "${1:Hallo}", "Types Hallo"),
("test", "${1:World}", "Types World"),
("test", "We overwrite", "Overwrite the two", "", 1),
("test", "again", "Overwrite again", "", 2),
('test', '${1:Hallo}', 'Types Hallo'),
('test', '${1:World}', 'Types World'),
('test', 'We overwrite', 'Overwrite the two', '', 1),
('test', 'again', 'Overwrite again', '', 2),
)
keys = "test" + EX
wanted = "again"
keys = 'test' + EX
wanted = 'again'
class SnippetPriorities_OverwriteThenChoose_ECR(_VimTest):
snippets = (
("test", "${1:Hallo}", "Types Hallo"),
("test", "${1:World}", "Types World"),
("test", "We overwrite", "Overwrite the two", "", 1),
("test", "No overwrite", "Not overwritten", "", 1),
('test', '${1:Hallo}', 'Types Hallo'),
('test', '${1:World}', 'Types World'),
('test', 'We overwrite', 'Overwrite the two', '', 1),
('test', 'No overwrite', 'Not overwritten', '', 1),
)
keys = "test" + EX + "1\n\n" + "test" + EX + "2\n"
wanted = "We overwrite\nNo overwrite"
keys = 'test' + EX + '1\n\n' + 'test' + EX + '2\n'
wanted = 'We overwrite\nNo overwrite'
class SnippetPriorities_AddedHasHigherThanFile(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet test "Test Snippet" b
This is a test snippet
endsnippet
"""}
snippets = (
("test", "We overwrite", "Overwrite the two", "", 1),
('test', 'We overwrite', 'Overwrite the two', '', 1),
)
keys = "test" + EX
wanted = "We overwrite"
keys = 'test' + EX
wanted = 'We overwrite'
class SnippetPriorities_FileHasHigherThanAdded(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
snippet test "Test Snippet" b
This is a test snippet
endsnippet
"""}
snippets = (
("test", "We do not overwrite", "Overwrite the two", "", -1),
('test', 'We do not overwrite', 'Overwrite the two', '', -1),
)
keys = "test" + EX
wanted = "This is a test snippet"
keys = 'test' + EX
wanted = 'This is a test snippet'
class SnippetPriorities_FileHasHigherThanAdded(_VimTest):
files = { "us/all.snippets": r"""
files = { 'us/all.snippets': r"""
priority -3
snippet test "Test Snippet" b
This is a test snippet
endsnippet
"""}
snippets = (
("test", "We overwrite", "Overwrite the two", "", -5),
('test', 'We overwrite', 'Overwrite the two', '', -5),
)
keys = "test" + EX
wanted = "This is a test snippet"
keys = 'test' + EX
wanted = 'This is a test snippet'
class SnippetPriorities_SimpleClear(_VimTest):
files = {
"us/all.snippets": r"""
'us/all.snippets': r"""
priority 1
clearsnippets
priority -1
@ -96,50 +106,53 @@ class SnippetPriorities_SimpleClear(_VimTest):
endsnippet
"""
}
keys = "test" + EX
wanted = "test" + EX
keys = 'test' + EX
wanted = 'test' + EX
class SnippetPriorities_SimpleClear2(_VimTest):
files = {
"us/all.snippets": r"""
'us/all.snippets': r"""
clearsnippets
snippet test "Test snippet"
Should not expand to this.
endsnippet
"""
}
keys = "test" + EX
wanted = "test" + EX
keys = 'test' + EX
wanted = 'test' + EX
class SnippetPriorities_ClearedByParent(_VimTest):
files = {
"us/p.snippets": r"""
'us/p.snippets': r"""
clearsnippets
""",
"us/c.snippets": r"""
'us/c.snippets': r"""
extends p
snippet test "Test snippets"
Should not expand to this.
endsnippet
"""
}
keys = ESC + ":set ft=c\n" + "itest" + EX
wanted = "test" + EX
keys = ESC + ':set ft=c\n' + 'itest' + EX
wanted = 'test' + EX
class SnippetPriorities_ClearedByChild(_VimTest):
files = {
"us/p.snippets": r"""
'us/p.snippets': r"""
snippet test "Test snippets"
Should only expand in p.
endsnippet
""",
"us/c.snippets": r"""
'us/c.snippets': r"""
extends p
clearsnippets
"""
}
keys = (ESC + ":set ft=p\n" + "itest" + EX + "\n" +
ESC + ":set ft=c\n" + "itest" + EX + ESC + ":set ft=p")
wanted = "Should only expand in p.\ntest" + EX
keys = (ESC + ':set ft=p\n' + 'itest' + EX + '\n' +
ESC + ':set ft=c\n' + 'itest' + EX + ESC + ':set ft=p')
wanted = 'Should only expand in p.\ntest' + EX
# End: Snippet Priority #}}}

View File

@ -1,258 +1,366 @@
from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
class TabStopSimpleReplace_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${0:End} ${1:Beginning}")
keys = "hallo" + EX + "na" + JF + "Du Nase"
wanted = "hallo Du Nase na"
snippets = ('hallo', 'hallo ${0:End} ${1:Beginning}')
keys = 'hallo' + EX + 'na' + JF + 'Du Nase'
wanted = 'hallo Du Nase na'
class TabStopSimpleReplaceZeroLengthTabstops_ExpectCorrectResult(_VimTest):
snippets = ("test", r":latex:\`$1\`$0")
keys = "test" + EX + "Hello" + JF + "World"
wanted = ":latex:`Hello`World"
snippets = ('test', r":latex:\`$1\`$0")
keys = 'test' + EX + 'Hello' + JF + 'World'
wanted = ':latex:`Hello`World'
class TabStopSimpleReplaceReversed_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${1:End} ${0:Beginning}")
keys = "hallo" + EX + "na" + JF + "Du Nase"
wanted = "hallo na Du Nase"
snippets = ('hallo', 'hallo ${1:End} ${0:Beginning}')
keys = 'hallo' + EX + 'na' + JF + 'Du Nase'
wanted = 'hallo na Du Nase'
class TabStopSimpleReplaceSurrounded_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${0:End} a small feed")
keys = "hallo" + EX + "Nase"
wanted = "hallo Nase a small feed"
snippets = ('hallo', 'hallo ${0:End} a small feed')
keys = 'hallo' + EX + 'Nase'
wanted = 'hallo Nase a small feed'
class TabStopSimpleReplaceSurrounded1_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo $0 a small feed")
keys = "hallo" + EX + "Nase"
wanted = "hallo Nase a small feed"
snippets = ('hallo', 'hallo $0 a small feed')
keys = 'hallo' + EX + 'Nase'
wanted = 'hallo Nase a small feed'
class TabStop_Exit_ExpectCorrectResult(_VimTest):
snippets = ("echo", "$0 run")
keys = "echo" + EX + "test"
wanted = "test run"
snippets = ('echo', '$0 run')
keys = 'echo' + EX + 'test'
wanted = 'test run'
class TabStopNoReplace_ExpectCorrectResult(_VimTest):
snippets = ("echo", "echo ${1:Hallo}")
keys = "echo" + EX
wanted = "echo Hallo"
snippets = ('echo', 'echo ${1:Hallo}')
keys = 'echo' + EX
wanted = 'echo Hallo'
class TabStop_EscapingCharsBackticks(_VimTest):
snippets = ("test", r"snip \` literal")
keys = "test" + EX
wanted = "snip ` literal"
snippets = ('test', r"snip \` literal")
keys = 'test' + EX
wanted = 'snip ` literal'
class TabStop_EscapingCharsDollars(_VimTest):
snippets = ("test", r"snip \$0 $$0 end")
keys = "test" + EX + "hi"
wanted = "snip $0 $hi end"
snippets = ('test', r"snip \$0 $$0 end")
keys = 'test' + EX + 'hi'
wanted = 'snip $0 $hi end'
class TabStop_EscapingCharsDollars1(_VimTest):
snippets = ("test", r"a\${1:literal}")
keys = "test" + EX
wanted = "a${1:literal}"
snippets = ('test', r"a\${1:literal}")
keys = 'test' + EX
wanted = 'a${1:literal}'
class TabStop_EscapingCharsDollars_BeginningOfLine(_VimTest):
snippets = ("test", "\n\\${1:literal}")
keys = "test" + EX
wanted = "\n${1:literal}"
snippets = ('test', '\n\\${1:literal}')
keys = 'test' + EX
wanted = '\n${1:literal}'
class TabStop_EscapingCharsDollars_BeginningOfDefinitionText(_VimTest):
snippets = ("test", "\\${1:literal}")
keys = "test" + EX
wanted = "${1:literal}"
snippets = ('test', '\\${1:literal}')
keys = 'test' + EX
wanted = '${1:literal}'
class TabStop_EscapingChars_Backslash(_VimTest):
snippets = ("test", r"This \ is a backslash!")
keys = "test" + EX
wanted = "This \\ is a backslash!"
snippets = ('test', r"This \ is a backslash!")
keys = 'test' + EX
wanted = 'This \\ is a backslash!'
class TabStop_EscapingChars_Backslash2(_VimTest):
snippets = ("test", r"This is a backslash \\ done")
keys = "test" + EX
snippets = ('test', r"This is a backslash \\ done")
keys = 'test' + EX
wanted = r"This is a backslash \ done"
class TabStop_EscapingChars_Backslash3(_VimTest):
snippets = ("test", r"These are two backslashes \\\\ done")
keys = "test" + EX
snippets = ('test', r"These are two backslashes \\\\ done")
keys = 'test' + EX
wanted = r"These are two backslashes \\ done"
class TabStop_EscapingChars_Backslash4(_VimTest):
# Test for bug 746446
snippets = ("test", r"\\$1{$2}")
keys = "test" + EX + "hello" + JF + "world"
snippets = ('test', r"\\$1{$2}")
keys = 'test' + EX + 'hello' + JF + 'world'
wanted = r"\hello{world}"
class TabStop_EscapingChars_RealLife(_VimTest):
snippets = ("test", r"usage: \`basename \$0\` ${1:args}")
keys = "test" + EX + "[ -u -v -d ]"
wanted = "usage: `basename $0` [ -u -v -d ]"
snippets = ('test', r"usage: \`basename \$0\` ${1:args}")
keys = 'test' + EX + '[ -u -v -d ]'
wanted = 'usage: `basename $0` [ -u -v -d ]'
class TabStopEscapingWhenSelected_ECR(_VimTest):
snippets = ("test", "snip ${1:default}")
keys = "test" + EX + ESC + "0ihi"
wanted = "hisnip default"
snippets = ('test', 'snip ${1:default}')
keys = 'test' + EX + ESC + '0ihi'
wanted = 'hisnip default'
class TabStopEscapingWhenSelectedSingleCharTS_ECR(_VimTest):
snippets = ("test", "snip ${1:i}")
keys = "test" + EX + ESC + "0ihi"
wanted = "hisnip i"
snippets = ('test', 'snip ${1:i}')
keys = 'test' + EX + ESC + '0ihi'
wanted = 'hisnip i'
class TabStopEscapingWhenSelectedNoCharTS_ECR(_VimTest):
snippets = ("test", "snip $1")
keys = "test" + EX + ESC + "0ihi"
wanted = "hisnip "
snippets = ('test', 'snip $1')
keys = 'test' + EX + ESC + '0ihi'
wanted = 'hisnip '
class TabStopWithOneChar_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "nothing ${1:i} hups")
keys = "hallo" + EX + "ship"
wanted = "nothing ship hups"
snippets = ('hallo', 'nothing ${1:i} hups')
keys = 'hallo' + EX + 'ship'
wanted = 'nothing ship hups'
class TabStopTestJumping_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${2:End} mitte ${1:Beginning}")
keys = "hallo" + EX + JF + "Test" + JF + "Hi"
wanted = "hallo Test mitte BeginningHi"
class TabStopTestJumping2_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo $2 $1")
keys = "hallo" + EX + JF + "Test" + JF + "Hi"
wanted = "hallo Test Hi"
class TabStopTestJumpingRLExampleWithZeroTab_ExpectCorrectResult(_VimTest):
snippets = ("test", "each_byte { |${1:byte}| $0 }")
keys = "test" + EX + JF + "Blah"
wanted = "each_byte { |byte| Blah }"
snippets = ('hallo', 'hallo ${2:End} mitte ${1:Beginning}')
keys = 'hallo' + EX + JF + 'Test' + JF + 'Hi'
wanted = 'hallo Test mitte BeginningHi'
class TabStopTestJumping2_ExpectCorrectResult(_VimTest):
snippets = ('hallo', 'hallo $2 $1')
keys = 'hallo' + EX + JF + 'Test' + JF + 'Hi'
wanted = 'hallo Test Hi'
class TabStopTestJumpingRLExampleWithZeroTab_ExpectCorrectResult(_VimTest):
snippets = ('test', 'each_byte { |${1:byte}| $0 }')
keys = 'test' + EX + JF + 'Blah'
wanted = 'each_byte { |byte| Blah }'
class TabStopTestJumpingDontJumpToEndIfThereIsTabZero_ExpectCorrectResult(
_VimTest):
snippets = ('hallo', 'hallo $0 $1')
keys = 'hallo' + EX + 'Test' + JF + 'Hi' + JF + JF + 'du'
wanted = 'hallo Hi' + 2 * JF + 'du Test'
class TabStopTestJumpingDontJumpToEndIfThereIsTabZero_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo $0 $1")
keys = "hallo" + EX + "Test" + JF + "Hi" + JF + JF + "du"
wanted = "hallo Hi" + 2*JF + "du Test"
class TabStopTestBackwardJumping_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${2:End} mitte${1:Beginning}")
keys = "hallo" + EX + "Somelengthy Text" + JF + "Hi" + JB + \
"Lets replace it again" + JF + "Blah" + JF + JB*2 + JF
wanted = "hallo Blah mitteLets replace it again" + JB*2 + JF
snippets = ('hallo', 'hallo ${2:End} mitte${1:Beginning}')
keys = 'hallo' + EX + 'Somelengthy Text' + JF + 'Hi' + JB + \
'Lets replace it again' + JF + 'Blah' + JF + JB * 2 + JF
wanted = 'hallo Blah mitteLets replace it again' + JB * 2 + JF
class TabStopTestBackwardJumping2_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo $2 $1")
keys = "hallo" + EX + "Somelengthy Text" + JF + "Hi" + JB + \
"Lets replace it again" + JF + "Blah" + JF + JB*2 + JF
wanted = "hallo Blah Lets replace it again" + JB*2 + JF
snippets = ('hallo', 'hallo $2 $1')
keys = 'hallo' + EX + 'Somelengthy Text' + JF + 'Hi' + JB + \
'Lets replace it again' + JF + 'Blah' + JF + JB * 2 + JF
wanted = 'hallo Blah Lets replace it again' + JB * 2 + JF
class TabStopTestMultilineExpand_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo $0\nnice $1 work\n$3 $2\nSeem to work")
keys ="test hallo World" + ESC + "02f i" + EX + "world" + JF + "try" + \
JF + "test" + JF + "one more" + JF
wanted = "test hallo one more" + JF + "\nnice world work\n" \
"test try\nSeem to work World"
snippets = ('hallo', 'hallo $0\nnice $1 work\n$3 $2\nSeem to work')
keys = 'test hallo World' + ESC + '02f i' + EX + 'world' + JF + 'try' + \
JF + 'test' + JF + 'one more' + JF
wanted = 'test hallo one more' + JF + '\nnice world work\n' \
'test try\nSeem to work World'
class TabStop_TSInDefaultTextRLExample_OverwriteNone_ECR(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = "test" + EX
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = 'test' + EX
wanted = """<div id="some_id">\n \n</div>"""
class TabStop_TSInDefaultTextRLExample_OverwriteFirst_NoJumpBack(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = "test" + EX + " blah" + JF + "Hallo"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = 'test' + EX + ' blah' + JF + 'Hallo'
wanted = """<div blah>\n Hallo\n</div>"""
class TabStop_TSInDefaultTextRLExample_DeleteFirst(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = "test" + EX + BS + JF + "Hallo"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = 'test' + EX + BS + JF + 'Hallo'
wanted = """<div>\n Hallo\n</div>"""
class TabStop_TSInDefaultTextRLExample_OverwriteFirstJumpBack(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = "test" + EX + "Hi" + JF + "Hallo" + JB + "SomethingElse" + JF + \
"Nupl" + JF + "Nox"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = 'test' + EX + 'Hi' + JF + 'Hallo' + JB + 'SomethingElse' + JF + \
'Nupl' + JF + 'Nox'
wanted = """<divSomethingElse>\n Nupl Nox\n</div>"""
class TabStop_TSInDefaultTextRLExample_OverwriteSecond(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = "test" + EX + JF + "no" + JF + "End"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $0\n</div>""")
keys = 'test' + EX + JF + 'no' + JF + 'End'
wanted = """<div id="no">\n End\n</div>"""
class TabStop_TSInDefaultTextRLExample_OverwriteSecondTabBack(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = "test" + EX + JF + "no" + JF + "End" + JB + "yes" + JF + "Begin" \
+ JF + "Hi"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = 'test' + EX + JF + 'no' + JF + 'End' + JB + 'yes' + JF + 'Begin' \
+ JF + 'Hi'
wanted = """<div id="yes">\n Begin Hi\n</div>"""
class TabStop_TSInDefaultTextRLExample_OverwriteSecondTabBackTwice(_VimTest):
snippets = ("test", """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = "test" + EX + JF + "no" + JF + "End" + JB + "yes" + JB + \
" allaway" + JF + "Third" + JF + "Last"
snippets = ('test', """<div${1: id="${2:some_id}"}>\n $3 $0\n</div>""")
keys = 'test' + EX + JF + 'no' + JF + 'End' + JB + 'yes' + JB + \
' allaway' + JF + 'Third' + JF + 'Last'
wanted = """<div allaway>\n Third Last\n</div>"""
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecond(_VimTest):
snippets = ("test", """h${1:a$2b}l""")
keys = "test" + EX + JF + "ups" + JF + "End"
snippets = ('test', """h${1:a$2b}l""")
keys = 'test' + EX + JF + 'ups' + JF + 'End'
wanted = """haupsblEnd"""
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteFirst(_VimTest):
snippets = ("test", """h${1:a$2b}l""")
keys = "test" + EX + "ups" + JF + "End"
snippets = ('test', """h${1:a$2b}l""")
keys = 'test' + EX + 'ups' + JF + 'End'
wanted = """hupslEnd"""
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackOverwrite(_VimTest):
snippets = ("test", """h${1:a$2b}l""")
keys = "test" + EX + JF + "longertext" + JB + "overwrite" + JF + "End"
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackOverwrite(
_VimTest):
snippets = ('test', """h${1:a$2b}l""")
keys = 'test' + EX + JF + 'longertext' + JB + 'overwrite' + JF + 'End'
wanted = """hoverwritelEnd"""
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackAndForward0(_VimTest):
snippets = ("test", """h${1:a$2b}l""")
keys = "test" + EX + JF + "longertext" + JB + JF + "overwrite" + JF + "End"
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackAndForward0(
_VimTest):
snippets = ('test', """h${1:a$2b}l""")
keys = 'test' + EX + JF + 'longertext' + JB + JF + 'overwrite' + JF + 'End'
wanted = """haoverwriteblEnd"""
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackAndForward1(_VimTest):
snippets = ("test", """h${1:a$2b}l""")
keys = "test" + EX + JF + "longertext" + JB + JF + JF + "End"
class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackAndForward1(
_VimTest):
snippets = ('test', """h${1:a$2b}l""")
keys = 'test' + EX + JF + 'longertext' + JB + JF + JF + 'End'
wanted = """halongertextblEnd"""
class TabStop_TSInDefaultNested_OverwriteOneJumpBackToOther(_VimTest):
snippets = ("test", "hi ${1:this ${2:second ${3:third}}} $4")
keys = "test" + EX + JF + "Hallo" + JF + "Ende"
wanted = "hi this Hallo Ende"
snippets = ('test', 'hi ${1:this ${2:second ${3:third}}} $4')
keys = 'test' + EX + JF + 'Hallo' + JF + 'Ende'
wanted = 'hi this Hallo Ende'
class TabStop_TSInDefaultNested_OverwriteOneJumpToThird(_VimTest):
snippets = ("test", "hi ${1:this ${2:second ${3:third}}} $4")
keys = "test" + EX + JF + JF + "Hallo" + JF + "Ende"
wanted = "hi this second Hallo Ende"
snippets = ('test', 'hi ${1:this ${2:second ${3:third}}} $4')
keys = 'test' + EX + JF + JF + 'Hallo' + JF + 'Ende'
wanted = 'hi this second Hallo Ende'
class TabStop_TSInDefaultNested_OverwriteOneJumpAround(_VimTest):
snippets = ("test", "hi ${1:this ${2:second ${3:third}}} $4")
keys = "test" + EX + JF + JF + "Hallo" + JB+JB + "Blah" + JF + "Ende"
wanted = "hi Blah Ende"
snippets = ('test', 'hi ${1:this ${2:second ${3:third}}} $4')
keys = 'test' + EX + JF + JF + 'Hallo' + JB + JB + 'Blah' + JF + 'Ende'
wanted = 'hi Blah Ende'
class TabStop_TSInDefault_MirrorsOutside_DoNothing(_VimTest):
snippets = ("test", "hi ${1:this ${2:second}} $2")
keys = "test" + EX
wanted = "hi this second second"
snippets = ('test', 'hi ${1:this ${2:second}} $2')
keys = 'test' + EX
wanted = 'hi this second second'
class TabStop_TSInDefault_MirrorsOutside_OverwriteSecond(_VimTest):
snippets = ("test", "hi ${1:this ${2:second}} $2")
keys = "test" + EX + JF + "Hallo"
wanted = "hi this Hallo Hallo"
snippets = ('test', 'hi ${1:this ${2:second}} $2')
keys = 'test' + EX + JF + 'Hallo'
wanted = 'hi this Hallo Hallo'
class TabStop_TSInDefault_MirrorsOutside_Overwrite0(_VimTest):
snippets = ("test", "hi ${1:this ${2:second}} $2")
keys = "test" + EX + "Hallo"
wanted = "hi Hallo "
snippets = ('test', 'hi ${1:this ${2:second}} $2')
keys = 'test' + EX + 'Hallo'
wanted = 'hi Hallo '
class TabStop_TSInDefault_MirrorsOutside_Overwrite1(_VimTest):
snippets = ("test", "$1: ${1:'${2:second}'} $2")
keys = "test" + EX + "Hallo"
wanted = "Hallo: Hallo "
snippets = ('test', "$1: ${1:'${2:second}'} $2")
keys = 'test' + EX + 'Hallo'
wanted = 'Hallo: Hallo '
class TabStop_TSInDefault_MirrorsOutside_OverwriteSecond1(_VimTest):
snippets = ("test", "$1: ${1:'${2:second}'} $2")
keys = "test" + EX + JF + "Hallo"
snippets = ('test', "$1: ${1:'${2:second}'} $2")
keys = 'test' + EX + JF + 'Hallo'
wanted = "'Hallo': 'Hallo' Hallo"
class TabStop_TSInDefault_MirrorsOutside_OverwriteFirstSwitchNumbers(_VimTest):
snippets = ("test", "$2: ${2:'${1:second}'} $1")
keys = "test" + EX + "Hallo"
snippets = ('test', "$2: ${2:'${1:second}'} $1")
keys = 'test' + EX + 'Hallo'
wanted = "'Hallo': 'Hallo' Hallo"
class TabStop_TSInDefault_MirrorsOutside_OverwriteFirst_RLExample(_VimTest):
snippets = ("test", """`!p snip.rv = t[1].split('/')[-1].lower().strip("'")` = require(${1:'${2:sys}'})""")
keys = "test" + EX + "WORLD" + JF + "End"
wanted = "world = require(WORLD)End"
snippets = (
'test',
"""`!p snip.rv = t[1].split('/')[-1].lower().strip("'")` = require(${1:'${2:sys}'})""")
keys = 'test' + EX + 'WORLD' + JF + 'End'
wanted = 'world = require(WORLD)End'
class TabStop_TSInDefault_MirrorsOutside_OverwriteSecond_RLExample(_VimTest):
snippets = ("test", """`!p snip.rv = t[1].split('/')[-1].lower().strip("'")` = require(${1:'${2:sys}'})""")
keys = "test" + EX + JF + "WORLD" + JF + "End"
snippets = (
'test',
"""`!p snip.rv = t[1].split('/')[-1].lower().strip("'")` = require(${1:'${2:sys}'})""")
keys = 'test' + EX + JF + 'WORLD' + JF + 'End'
wanted = "world = require('WORLD')End"
class TabStop_Multiline_Leave(_VimTest):
snippets = ("test", "hi ${1:first line\nsecond line} world" )
keys = "test" + EX
wanted = "hi first line\nsecond line world"
snippets = ('test', 'hi ${1:first line\nsecond line} world')
keys = 'test' + EX
wanted = 'hi first line\nsecond line world'
class TabStop_Multiline_Overwrite(_VimTest):
snippets = ("test", "hi ${1:first line\nsecond line} world" )
keys = "test" + EX + "Nothing"
wanted = "hi Nothing world"
snippets = ('test', 'hi ${1:first line\nsecond line} world')
keys = 'test' + EX + 'Nothing'
wanted = 'hi Nothing world'
class TabStop_Multiline_MirrorInFront_Leave(_VimTest):
snippets = ("test", "hi $1 ${1:first line\nsecond line} world" )
keys = "test" + EX
wanted = "hi first line\nsecond line first line\nsecond line world"
snippets = ('test', 'hi $1 ${1:first line\nsecond line} world')
keys = 'test' + EX
wanted = 'hi first line\nsecond line first line\nsecond line world'
class TabStop_Multiline_MirrorInFront_Overwrite(_VimTest):
snippets = ("test", "hi $1 ${1:first line\nsecond line} world" )
keys = "test" + EX + "Nothing"
wanted = "hi Nothing Nothing world"
snippets = ('test', 'hi $1 ${1:first line\nsecond line} world')
keys = 'test' + EX + 'Nothing'
wanted = 'hi Nothing Nothing world'
class TabStop_Multiline_DelFirstOverwriteSecond_Overwrite(_VimTest):
snippets = ("test", "hi $1 $2 ${1:first line\nsecond line} ${2:Hi} world" )
keys = "test" + EX + BS + JF + "Nothing"
wanted = "hi Nothing Nothing world"
snippets = ('test', 'hi $1 $2 ${1:first line\nsecond line} ${2:Hi} world')
keys = 'test' + EX + BS + JF + 'Nothing'
wanted = 'hi Nothing Nothing world'
class TabStopNavigatingInInsertModeSimple_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "Hallo ${1:WELT} ups")
keys = "hallo" + EX + "haselnut" + 2*ARR_L + "hips" + JF + "end"
wanted = "Hallo haselnhipsut upsend"
snippets = ('hallo', 'Hallo ${1:WELT} ups')
keys = 'hallo' + EX + 'haselnut' + 2 * ARR_L + 'hips' + JF + 'end'
wanted = 'Hallo haselnhipsut upsend'
class TabStop_CROnlyOnSelectedNear(_VimTest):
snippets = ("test", "t$1t${2: }t{\n\t$0\n}")
keys = "test" + EX + JF + "\n" + JF + "t"
wanted = "tt\nt{\n\tt\n}"
snippets = ('test', 't$1t${2: }t{\n\t$0\n}')
keys = 'test' + EX + JF + '\n' + JF + 't'
wanted = 'tt\nt{\n\tt\n}'

View File

@ -4,169 +4,245 @@ from test.constant import *
from test.util import no_unidecode_available
# Transformations {{{#
class Transformation_SimpleCase_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/foo/batzl/}")
keys = "test" + EX + "hallo foo boy"
wanted = "hallo foo boy hallo batzl boy"
snippets = ('test', '$1 ${1/foo/batzl/}')
keys = 'test' + EX + 'hallo foo boy'
wanted = 'hallo foo boy hallo batzl boy'
class Transformation_SimpleCaseNoTransform_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/foo/batzl/}")
keys = "test" + EX + "hallo"
wanted = "hallo hallo"
snippets = ('test', '$1 ${1/foo/batzl/}')
keys = 'test' + EX + 'hallo'
wanted = 'hallo hallo'
class Transformation_SimpleCaseTransformInFront_ExpectCorrectResult(_VimTest):
snippets = ("test", "${1/foo/batzl/} $1")
keys = "test" + EX + "hallo foo"
wanted = "hallo batzl hallo foo"
snippets = ('test', '${1/foo/batzl/} $1')
keys = 'test' + EX + 'hallo foo'
wanted = 'hallo batzl hallo foo'
class Transformation_SimpleCaseTransformInFrontDefVal_ECR(_VimTest):
snippets = ("test", "${1/foo/batzl/} ${1:replace me}")
keys = "test" + EX + "hallo foo"
wanted = "hallo batzl hallo foo"
snippets = ('test', '${1/foo/batzl/} ${1:replace me}')
keys = 'test' + EX + 'hallo foo'
wanted = 'hallo batzl hallo foo'
class Transformation_MultipleTransformations_ECR(_VimTest):
snippets = ("test", "${1:Some Text}${1/.+/\\U$0\E/}\n${1/.+/\L$0\E/}")
keys = "test" + EX + "SomE tExt "
wanted = "SomE tExt SOME TEXT \nsome text "
snippets = ('test', '${1:Some Text}${1/.+/\\U$0\E/}\n${1/.+/\L$0\E/}')
keys = 'test' + EX + 'SomE tExt '
wanted = 'SomE tExt SOME TEXT \nsome text '
class Transformation_TabIsAtEndAndDeleted_ECR(_VimTest):
snippets = ("test", "${1/.+/is something/}${1:some}")
keys = "hallo test" + EX + "some\b\b\b\b\b"
wanted = "hallo "
snippets = ('test', '${1/.+/is something/}${1:some}')
keys = 'hallo test' + EX + 'some\b\b\b\b\b'
wanted = 'hallo '
class Transformation_TabIsAtEndAndDeleted1_ECR(_VimTest):
snippets = ("test", "${1/.+/is something/}${1:some}")
keys = "hallo test" + EX + "some\b\b\b\bmore"
wanted = "hallo is somethingmore"
snippets = ('test', '${1/.+/is something/}${1:some}')
keys = 'hallo test' + EX + 'some\b\b\b\bmore'
wanted = 'hallo is somethingmore'
class Transformation_TabIsAtEndNoTextLeave_ECR(_VimTest):
snippets = ("test", "${1/.+/is something/}${1}")
keys = "hallo test" + EX
wanted = "hallo "
snippets = ('test', '${1/.+/is something/}${1}')
keys = 'hallo test' + EX
wanted = 'hallo '
class Transformation_TabIsAtEndNoTextType_ECR(_VimTest):
snippets = ("test", "${1/.+/is something/}${1}")
keys = "hallo test" + EX + "b"
wanted = "hallo is somethingb"
snippets = ('test', '${1/.+/is something/}${1}')
keys = 'hallo test' + EX + 'b'
wanted = 'hallo is somethingb'
class Transformation_InsideTabLeaveAtDefault_ECR(_VimTest):
snippets = ("test", r"$1 ${2:${1/.+/(?0:defined $0)/}}")
keys = "test" + EX + "sometext" + JF
wanted = "sometext defined sometext"
snippets = ('test', r"$1 ${2:${1/.+/(?0:defined $0)/}}")
keys = 'test' + EX + 'sometext' + JF
wanted = 'sometext defined sometext'
class Transformation_InsideTabOvertype_ECR(_VimTest):
snippets = ("test", r"$1 ${2:${1/.+/(?0:defined $0)/}}")
keys = "test" + EX + "sometext" + JF + "overwrite"
wanted = "sometext overwrite"
snippets = ('test', r"$1 ${2:${1/.+/(?0:defined $0)/}}")
keys = 'test' + EX + 'sometext' + JF + 'overwrite'
wanted = 'sometext overwrite'
class Transformation_Backreference_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/([ab])oo/$1ull/}")
keys = "test" + EX + "foo boo aoo"
wanted = "foo boo aoo foo bull aoo"
snippets = ('test', '$1 ${1/([ab])oo/$1ull/}')
keys = 'test' + EX + 'foo boo aoo'
wanted = 'foo boo aoo foo bull aoo'
class Transformation_BackreferenceTwice_ExpectCorrectResult(_VimTest):
snippets = ("test", r"$1 ${1/(dead) (par[^ ]*)/this $2 is a bit $1/}")
keys = "test" + EX + "dead parrot"
wanted = "dead parrot this parrot is a bit dead"
snippets = ('test', r"$1 ${1/(dead) (par[^ ]*)/this $2 is a bit $1/}")
keys = 'test' + EX + 'dead parrot'
wanted = 'dead parrot this parrot is a bit dead'
class Transformation_CleverTransformUpercaseChar_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(.)/\\u$1/}")
keys = "test" + EX + "hallo"
wanted = "hallo Hallo"
class Transformation_CleverTransformLowercaseChar_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(.*)/\l$1/}")
keys = "test" + EX + "Hallo"
wanted = "Hallo hallo"
snippets = ('test', '$1 ${1/(.)/\\u$1/}')
keys = 'test' + EX + 'hallo'
wanted = 'hallo Hallo'
class Transformation_CleverTransformLowercaseChar_ExpectCorrectResult(
_VimTest):
snippets = ('test', '$1 ${1/(.*)/\l$1/}')
keys = 'test' + EX + 'Hallo'
wanted = 'Hallo hallo'
class Transformation_CleverTransformLongUpper_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(.*)/\\U$1\E/}")
keys = "test" + EX + "hallo"
wanted = "hallo HALLO"
snippets = ('test', '$1 ${1/(.*)/\\U$1\E/}')
keys = 'test' + EX + 'hallo'
wanted = 'hallo HALLO'
class Transformation_CleverTransformLongLower_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(.*)/\L$1\E/}")
keys = "test" + EX + "HALLO"
wanted = "HALLO hallo"
snippets = ('test', '$1 ${1/(.*)/\L$1\E/}')
keys = 'test' + EX + 'HALLO'
wanted = 'HALLO hallo'
class Transformation_SimpleCaseAsciiResult(_VimTest):
skip_if = lambda self: no_unidecode_available()
snippets = ("ascii", "$1 ${1/(.*)/$1/a}")
keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€"
wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoiEEACOIEU"
snippets = ('ascii', '$1 ${1/(.*)/$1/a}')
keys = 'ascii' + EX + 'éèàçôïÉÈÀÇÔÏ€'
wanted = 'éèàçôïÉÈÀÇÔÏ€ eeacoiEEACOIEU'
class Transformation_LowerCaseAsciiResult(_VimTest):
skip_if = lambda self: no_unidecode_available()
snippets = ("ascii", "$1 ${1/(.*)/\L$1\E/a}")
keys = "ascii" + EX + "éèàçôïÉÈÀÇÔÏ€"
wanted = "éèàçôïÉÈÀÇÔÏ€ eeacoieeacoieu"
snippets = ('ascii', '$1 ${1/(.*)/\L$1\E/a}')
keys = 'ascii' + EX + 'éèàçôïÉÈÀÇÔÏ€'
wanted = 'éèàçôïÉÈÀÇÔÏ€ eeacoieeacoieu'
class Transformation_ConditionalInsertionSimple_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(^a).*/(?0:began with an a)/}")
keys = "test" + EX + "a some more text"
wanted = "a some more text began with an a"
snippets = ('test', '$1 ${1/(^a).*/(?0:began with an a)/}')
keys = 'test' + EX + 'a some more text'
wanted = 'a some more text began with an a'
class Transformation_CIBothDefinedNegative_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(?:(^a)|(^b)).*/(?1:yes:no)/}")
keys = "test" + EX + "b some"
wanted = "b some no"
snippets = ('test', '$1 ${1/(?:(^a)|(^b)).*/(?1:yes:no)/}')
keys = 'test' + EX + 'b some'
wanted = 'b some no'
class Transformation_CIBothDefinedPositive_ExpectCorrectResult(_VimTest):
snippets = ("test", "$1 ${1/(?:(^a)|(^b)).*/(?1:yes:no)/}")
keys = "test" + EX + "a some"
wanted = "a some yes"
snippets = ('test', '$1 ${1/(?:(^a)|(^b)).*/(?1:yes:no)/}')
keys = 'test' + EX + 'a some'
wanted = 'a some yes'
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..."
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):
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-> "
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/}")
keys = "test" + EX + "test, hallo"
wanted = "test, hallo test\nhallo"
snippets = ('test', r"$1 ${1/, */\n/}")
keys = 'test' + EX + 'test, hallo'
wanted = 'test, hallo test\nhallo'
class Transformation_CITabstop_ECR(_VimTest):
snippets = ("test", r"$1 ${1/, */\t/}")
keys = "test" + EX + "test, hallo"
wanted = "test, hallo test\thallo"
snippets = ('test', r"$1 ${1/, */\t/}")
keys = 'test' + EX + 'test, hallo'
wanted = 'test, hallo test\thallo'
class Transformation_CIEscapedParensinReplace_ECR(_VimTest):
snippets = ("test", r"$1 ${1/hal((?:lo)|(?:ul))/(?1:ha\($1\))/}")
keys = "test" + EX + "test, halul"
wanted = "test, halul test, ha(ul)"
snippets = ('test', r"$1 ${1/hal((?:lo)|(?:ul))/(?1:ha\($1\))/}")
keys = 'test' + EX + 'test, halul'
wanted = 'test, halul test, ha(ul)'
class Transformation_OptionIgnoreCase_ECR(_VimTest):
snippets = ("test", r"$1 ${1/test/blah/i}")
keys = "test" + EX + "TEST"
wanted = "TEST blah"
snippets = ('test', r"$1 ${1/test/blah/i}")
keys = 'test' + EX + 'TEST'
wanted = 'TEST blah'
class Transformation_OptionReplaceGlobal_ECR(_VimTest):
snippets = ("test", r"$1 ${1/, */-/g}")
keys = "test" + EX + "a, nice, building"
wanted = "a, nice, building a-nice-building"
snippets = ('test', r"$1 ${1/, */-/g}")
keys = 'test' + EX + 'a, nice, building'
wanted = 'a, nice, building a-nice-building'
class Transformation_OptionReplaceGlobalMatchInReplace_ECR(_VimTest):
snippets = ("test", r"$1 ${1/, */, /g}")
keys = "test" + EX + "a, nice, building"
wanted = "a, nice, building a, nice, building"
snippets = ('test', r"$1 ${1/, */, /g}")
keys = 'test' + EX + 'a, nice, building'
wanted = 'a, nice, building a, nice, building'
class TransformationUsingBackspaceToDeleteDefaultValueInFirstTab_ECR(_VimTest):
snippets = ("test", "snip ${1/.+/(?0:m1)/} ${2/.+/(?0:m2)/} "
"${1:default} ${2:def}")
keys = "test" + EX + BS + JF + "hi"
wanted = "snip m2 hi"
class TransformationUsingBackspaceToDeleteDefaultValueInSecondTab_ECR(_VimTest):
snippets = ("test", "snip ${1/.+/(?0:m1)/} ${2/.+/(?0:m2)/} "
"${1:default} ${2:def}")
keys = "test" + EX + "hi" + JF + BS
wanted = "snip m1 hi "
class TransformationUsingBackspaceToDeleteDefaultValueTypeSomethingThen_ECR(_VimTest):
snippets = ("test", "snip ${1/.+/(?0:matched)/} ${1:default}")
keys = "test" + EX + BS + "hallo"
wanted = "snip matched hallo"
snippets = ('test', 'snip ${1/.+/(?0:m1)/} ${2/.+/(?0:m2)/} '
'${1:default} ${2:def}')
keys = 'test' + EX + BS + JF + 'hi'
wanted = 'snip m2 hi'
class TransformationUsingBackspaceToDeleteDefaultValueInSecondTab_ECR(
_VimTest):
snippets = ('test', 'snip ${1/.+/(?0:m1)/} ${2/.+/(?0:m2)/} '
'${1:default} ${2:def}')
keys = 'test' + EX + 'hi' + JF + BS
wanted = 'snip m1 hi '
class TransformationUsingBackspaceToDeleteDefaultValueTypeSomethingThen_ECR(
_VimTest):
snippets = ('test', 'snip ${1/.+/(?0:matched)/} ${1:default}')
keys = 'test' + EX + BS + 'hallo'
wanted = 'snip matched hallo'
class TransformationUsingBackspaceToDeleteDefaultValue_ECR(_VimTest):
snippets = ("test", "snip ${1/.+/(?0:matched)/} ${1:default}")
keys = "test" + EX + BS
wanted = "snip "
snippets = ('test', 'snip ${1/.+/(?0:matched)/} ${1:default}')
keys = 'test' + EX + BS
wanted = 'snip '
class Transformation_TestKill_InsertBefore_NoKill(_VimTest):
snippets = "test", r"$1 ${1/.*/\L$0$0\E/}_"
keys = "hallo test" + EX + "AUCH" + ESC + "wihi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noAUCH hinoauchnoauch_end"
snippets = 'test', r"$1 ${1/.*/\L$0$0\E/}_"
keys = 'hallo test' + EX + 'AUCH' + ESC + \
'wihi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noAUCH hinoauchnoauch_end'
class Transformation_TestKill_InsertAfter_NoKill(_VimTest):
snippets = "test", r"$1 ${1/.*/\L$0$0\E/}_"
keys = "hallo test" + EX + "AUCH" + ESC + "eiab" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noAUCH noauchnoauchab_end"
snippets = 'test', r"$1 ${1/.*/\L$0$0\E/}_"
keys = 'hallo test' + EX + 'AUCH' + ESC + \
'eiab' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noAUCH noauchnoauchab_end'
class Transformation_TestKill_InsertBeginning_Kill(_VimTest):
snippets = "test", r"$1 ${1/.*/\L$0$0\E/}_"
keys = "hallo test" + EX + "AUCH" + ESC + "wahi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noAUCH ahiuchauch_end"
snippets = 'test', r"$1 ${1/.*/\L$0$0\E/}_"
keys = 'hallo test' + EX + 'AUCH' + ESC + \
'wahi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noAUCH ahiuchauch_end'
class Transformation_TestKill_InsertEnd_Kill(_VimTest):
snippets = "test", r"$1 ${1/.*/\L$0$0\E/}_"
keys = "hallo test" + EX + "AUCH" + ESC + "ehihi" + ESC + "bb" + "ino" + JF + "end"
wanted = "hallo noAUCH auchauchih_end"
snippets = 'test', r"$1 ${1/.*/\L$0$0\E/}_"
keys = 'hallo test' + EX + 'AUCH' + ESC + \
'ehihi' + ESC + 'bb' + 'ino' + JF + 'end'
wanted = 'hallo noAUCH auchauchih_end'
# End: Transformations #}}}

View File

@ -4,76 +4,94 @@ from test.constant import *
from test.util import running_on_windows
# AddSnippet Function {{{#
class _AddFuncBase(_VimTest):
args = ""
args = ''
def _extra_options_pre_init(self, vim_config):
vim_config.append(":call UltiSnips#AddSnippetWithPriority(%s)" %
self.args)
vim_config.append(':call UltiSnips#AddSnippetWithPriority(%s)' %
self.args)
class AddFunc_Simple(_AddFuncBase):
args = '"test", "simple expand", "desc", "", "all", 0'
keys = "abc test" + EX
wanted = "abc simple expand"
keys = 'abc test' + EX
wanted = 'abc simple expand'
class AddFunc_Opt(_AddFuncBase):
args = '".*test", "simple expand", "desc", "r", "all", 0'
keys = "abc test" + EX
wanted = "simple expand"
keys = 'abc test' + EX
wanted = 'simple expand'
# End: AddSnippet Function #}}}
# Langmap Handling {{{#
# Test for bug 501727 #
class TestNonEmptyLangmap_ExpectCorrectResult(_VimTest):
snippets = ("testme",
"""my snipped ${1:some_default}
snippets = ('testme',
"""my snipped ${1:some_default}
and a mirror: $1
$2...$3
$0""")
keys = "testme" + EX + "hi1" + JF + "hi2" + JF + "hi3" + JF + "hi4"
wanted ="""my snipped hi1
keys = 'testme' + EX + 'hi1' + JF + 'hi2' + JF + 'hi3' + JF + 'hi4'
wanted = """my snipped hi1
and a mirror: hi1
hi2...hi3
hi4"""
def _extra_options_pre_init(self, vim_config):
vim_config.append("set langmap=dj,rk,nl,ln,jd,kr,DJ,RK,NL,LN,JD,KR")
vim_config.append('set langmap=dj,rk,nl,ln,jd,kr,DJ,RK,NL,LN,JD,KR')
# Test for https://bugs.launchpad.net/bugs/501727 #
class TestNonEmptyLangmapWithSemi_ExpectCorrectResult(_VimTest):
snippets = ("testme",
"""my snipped ${1:some_default}
snippets = ('testme',
"""my snipped ${1:some_default}
and a mirror: $1
$2...$3
$0""")
keys = "testme" + EX + "hi;" + JF + "hi2" + JF + "hi3" + JF + "hi4" + ESC + ";Hello"
wanted ="""my snipped hi;
keys = 'testme' + EX + 'hi;' + JF + 'hi2' + \
JF + 'hi3' + JF + 'hi4' + ESC + ';Hello'
wanted = """my snipped hi;
and a mirror: hi;
hi2...hi3
hi4Hello"""
def _before_test(self):
self.vim.send(":set langmap=\\\\;;A\n")
self.vim.send(':set langmap=\\\\;;A\n')
# Test for bug 871357 #
class TestLangmapWithUtf8_ExpectCorrectResult(_VimTest):
skip_if = lambda self: running_on_windows() # SendKeys can't send UTF characters
snippets = ("testme",
"""my snipped ${1:some_default}
# SendKeys can't send UTF characters
skip_if = lambda self: running_on_windows()
snippets = ('testme',
"""my snipped ${1:some_default}
and a mirror: $1
$2...$3
$0""")
keys = "testme" + EX + "hi1" + JF + "hi2" + JF + "hi3" + JF + "hi4"
wanted ="""my snipped hi1
keys = 'testme' + EX + 'hi1' + JF + 'hi2' + JF + 'hi3' + JF + 'hi4'
wanted = """my snipped hi1
and a mirror: hi1
hi2...hi3
hi4"""
def _before_test(self):
self.vim.send(":set langmap=йq,цw,уe,кr,еt,нy,гu,шi,щo,зp,х[,ъ],фa,ыs,вd,аf,пg,рh,оj,лk,дl,ж\\;,э',яz,чx,сc,мv,иb,тn,ьm,ю.,ё',ЙQ,ЦW,УE,КR,ЕT,НY,ГU,ШI,ЩO,ЗP,Х\{\},ФA,ЫS,ВD,АF,ПG,РH,ОJ,ЛK,ДL,Ж\:,Э\",ЯZ,ЧX,СC,МV,ИB,ТN,ЬM,Б\<,Ю\>\n")
self.vim.send(
":set langmap=йq,цw,уe,кr,еt,нy,гu,шi,щo,зp,х[,ъ],фa,ыs,вd,аf,пg,рh,оj,лk,дl,ж\\;,э',яz,чx,сc,мv,иb,тn,ьm,ю.,ё',ЙQ,ЦW,УE,КR,ЕT,НY,ГU,ШI,ЩO,ЗP,Х\{\},ФA,ЫS,ВD,АF,ПG,РH,ОJ,ЛK,ДL,Ж\:,Э\",ЯZ,ЧX,СC,МV,ИB,ТN,ЬM,Б\<,Ю\>\n")
# End: Langmap Handling #}}}
# SnippetsInCurrentScope {{{#
class VerifyVimDict1(_VimTest):
"""check:
correct type (4 means vim dictionary)
correct length of dictionary (in this case we have on element if the use same prefix, dictionary should have 1 element)
@ -83,48 +101,56 @@ class VerifyVimDict1(_VimTest):
snippets = ('testâ', 'abc123ά', '123\'êabc')
keys = ('test=(type(UltiSnips#SnippetsInCurrentScope()) . len(UltiSnips#SnippetsInCurrentScope()) . ' +
'UltiSnips#SnippetsInCurrentScope()["testâ"]' + ')\n' +
'=len(UltiSnips#SnippetsInCurrentScope())\n')
'UltiSnips#SnippetsInCurrentScope()["testâ"]' + ')\n' +
'=len(UltiSnips#SnippetsInCurrentScope())\n')
wanted = 'test41123\'êabc0'
class VerifyVimDict2(_VimTest):
"""check:
can use " in trigger
"""
snippets = ('te"stâ', 'abc123ά', '123êabc')
akey = "'te{}stâ'".format('"')
keys = ('te"=(UltiSnips#SnippetsInCurrentScope()[{}]'.format(akey) + ')\n')
keys = (
'te"=(UltiSnips#SnippetsInCurrentScope()[{}]'.format(akey) + ')\n')
wanted = 'te"123êabc'
class VerifyVimDict3(_VimTest):
"""check:
can use ' in trigger
"""
snippets = ("te'stâ", 'abc123ά', '123êabc')
akey = '"te{}stâ"'.format("'")
keys = ("te'=(UltiSnips#SnippetsInCurrentScope()[{}]".format(akey) + ')\n')
keys = (
"te'=(UltiSnips#SnippetsInCurrentScope()[{}]".format(akey) + ')\n')
wanted = "te'123êabc"
# End: SnippetsInCurrentScope #}}}
# Snippet Source {{{#
class AddNewSnippetSource(_VimTest):
keys = ( "blumba" + EX + ESC +
":%(python)s UltiSnips_Manager.register_snippet_source(" +
"'temp', MySnippetSource())\n" +
"oblumba" + EX + ESC +
":%(python)s UltiSnips_Manager.unregister_snippet_source('temp')\n" +
"oblumba" + EX ) % { 'python': 'py3' if PYTHON3 else 'py' }
keys = ('blumba' + EX + ESC +
':%(python)s UltiSnips_Manager.register_snippet_source(' +
"'temp', MySnippetSource())\n" +
'oblumba' + EX + ESC +
":%(python)s UltiSnips_Manager.unregister_snippet_source('temp')\n" +
'oblumba' + EX) % {'python': 'py3' if PYTHON3 else 'py'}
wanted = (
"blumba" + EX + "\n" +
"this is a dynamic snippet" + "\n" +
"blumba" + EX
'blumba' + EX + '\n' +
'this is a dynamic snippet' + '\n' +
'blumba' + EX
)
def _extra_options_post_init(self, vim_config):
self._create_file("snippet_source.py","""
self._create_file('snippet_source.py', """
from UltiSnips.snippet.source import SnippetSource
from UltiSnips.snippet.definition import UltiSnipsSnippetDefinition
@ -138,5 +164,7 @@ class MySnippetSource(SnippetSource):
return []
""")
pyfile = 'py3file' if PYTHON3 else 'pyfile'
vim_config.append("%s %s" % (pyfile, self.name_temp("snippet_source.py")))
vim_config.append(
'%s %s' %
(pyfile, self.name_temp('snippet_source.py')))
# End: Snippet Source #}}}

View File

@ -2,140 +2,203 @@ from test.vim_test_case import VimTestCase as _VimTest
from test.constant import *
# ${VISUAL} {{{#
class Visual_NoVisualSelection_Ignore(_VimTest):
snippets = ("test", "h${VISUAL}b")
keys = "test" + EX + "abc"
wanted = "hbabc"
snippets = ('test', 'h${VISUAL}b')
keys = 'test' + EX + 'abc'
wanted = 'hbabc'
class Visual_SelectOneWord(_VimTest):
snippets = ("test", "h${VISUAL}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hblablubb"
snippets = ('test', 'h${VISUAL}b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hblablubb'
class Visual_SelectOneWord_ProblemAfterTab(_VimTest):
snippets = ("test", "h${VISUAL}b", "", "i")
keys = "\tblablub" + ESC + "5hv3l" + EX + "test" + EX
wanted = "\tbhlablbub"
snippets = ('test', 'h${VISUAL}b', '', 'i')
keys = '\tblablub' + ESC + '5hv3l' + EX + 'test' + EX
wanted = '\tbhlablbub'
class VisualWithDefault_ExpandWithoutVisual(_VimTest):
snippets = ("test", "h${VISUAL:world}b")
keys = "test" + EX + "hi"
wanted = "hworldbhi"
snippets = ('test', 'h${VISUAL:world}b')
keys = 'test' + EX + 'hi'
wanted = 'hworldbhi'
class VisualWithDefaultWithSlashes_ExpandWithoutVisual(_VimTest):
snippets = ("test", r"h${VISUAL:\/\/ body}b")
keys = "test" + EX + "hi"
wanted = "h// bodybhi"
snippets = ('test', r"h${VISUAL:\/\/ body}b")
keys = 'test' + EX + 'hi'
wanted = 'h// bodybhi'
class VisualWithDefault_ExpandWithVisual(_VimTest):
snippets = ("test", "h${VISUAL:world}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hblablubb"
snippets = ('test', 'h${VISUAL:world}b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hblablubb'
class Visual_ExpandTwice(_VimTest):
snippets = ("test", "h${VISUAL}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX + "\ntest" + EX
wanted = "hblablubb\nhb"
snippets = ('test', 'h${VISUAL}b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX + '\ntest' + EX
wanted = 'hblablubb\nhb'
class Visual_SelectOneWord_TwiceVisual(_VimTest):
snippets = ("test", "h${VISUAL}b${VISUAL}a")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hblablubbblabluba"
snippets = ('test', 'h${VISUAL}b${VISUAL}a')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hblablubbblabluba'
class Visual_SelectOneWord_Inword(_VimTest):
snippets = ("test", "h${VISUAL}b", "Description", "i")
keys = "blablub" + ESC + "0lv4l" + EX + "test" + EX
wanted = "bhlablubb"
snippets = ('test', 'h${VISUAL}b', 'Description', 'i')
keys = 'blablub' + ESC + '0lv4l' + EX + 'test' + EX
wanted = 'bhlablubb'
class Visual_SelectOneWord_TillEndOfLine(_VimTest):
snippets = ("test", "h${VISUAL}b", "Description", "i")
keys = "blablub" + ESC + "0v$" + EX + "test" + EX + ESC + "o"
wanted = "hblablub\nb"
snippets = ('test', 'h${VISUAL}b', 'Description', 'i')
keys = 'blablub' + ESC + '0v$' + EX + 'test' + EX + ESC + 'o'
wanted = 'hblablub\nb'
class Visual_SelectOneWordWithTabstop_TillEndOfLine(_VimTest):
snippets = ("test", "h${2:ahh}${VISUAL}${1:ups}b", "Description", "i")
keys = "blablub" + ESC + "0v$" + EX + "test" + EX + "mmm" + JF + "n" + JF + "done" + ESC + "o"
wanted = "hnblablub\nmmmbdone"
snippets = ('test', 'h${2:ahh}${VISUAL}${1:ups}b', 'Description', 'i')
keys = 'blablub' + ESC + '0v$' + EX + 'test' + \
EX + 'mmm' + JF + 'n' + JF + 'done' + ESC + 'o'
wanted = 'hnblablub\nmmmbdone'
class Visual_InDefaultText_SelectOneWord_NoOverwrite(_VimTest):
snippets = ("test", "h${1:${VISUAL}}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX + JF + "hello"
wanted = "hblablubbhello"
snippets = ('test', 'h${1:${VISUAL}}b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX + JF + 'hello'
wanted = 'hblablubbhello'
class Visual_InDefaultText_SelectOneWord(_VimTest):
snippets = ("test", "h${1:${VISUAL}}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX + "hello"
wanted = "hhellob"
snippets = ('test', 'h${1:${VISUAL}}b')
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX + 'hello'
wanted = 'hhellob'
class Visual_CrossOneLine(_VimTest):
snippets = ("test", "h${VISUAL}b")
keys = "bla blub\n helloi" + ESC + "0k4lvjll" + EX + "test" + EX
wanted = "bla hblub\n hellobi"
snippets = ('test', 'h${VISUAL}b')
keys = 'bla blub\n helloi' + ESC + '0k4lvjll' + EX + 'test' + EX
wanted = 'bla hblub\n hellobi'
class Visual_LineSelect_Simple(_VimTest):
snippets = ("test", "h${VISUAL}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "hhello\n nice\n worldb"
snippets = ('test', 'h${VISUAL}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'hhello\n nice\n worldb'
class Visual_InDefaultText_LineSelect_NoOverwrite(_VimTest):
snippets = ("test", "h${1:bef${VISUAL}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + JF + "hi"
wanted = "hbefhello\n nice\n worldaftbhi"
snippets = ('test', 'h${1:bef${VISUAL}aft}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX + JF + 'hi'
wanted = 'hbefhello\n nice\n worldaftbhi'
class Visual_InDefaultText_LineSelect_Overwrite(_VimTest):
snippets = ("test", "h${1:bef${VISUAL}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + "jup" + JF + "hi"
wanted = "hjupbhi"
snippets = ('test', 'h${1:bef${VISUAL}aft}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + \
EX + 'test' + EX + 'jup' + JF + 'hi'
wanted = 'hjupbhi'
class Visual_LineSelect_CheckIndentSimple(_VimTest):
snippets = ("test", "beg\n\t${VISUAL}\nend")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "beg\n\thello\n\tnice\n\tworld\nend"
snippets = ('test', 'beg\n\t${VISUAL}\nend')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'beg\n\thello\n\tnice\n\tworld\nend'
class Visual_LineSelect_CheckIndentTwice(_VimTest):
snippets = ("test", "beg\n\t${VISUAL}\nend")
keys = " hello\n nice\n\tworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "beg\n\t hello\n\t nice\n\t\tworld\nend"
snippets = ('test', 'beg\n\t${VISUAL}\nend')
keys = ' hello\n nice\n\tworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'beg\n\t hello\n\t nice\n\t\tworld\nend'
class Visual_InDefaultText_IndentSpacesToTabstop_NoOverwrite(_VimTest):
snippets = ("test", "h${1:beforea${VISUAL}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + JF + "hi"
wanted = "hbeforeahello\n\tnice\n\tworldaftbhi"
snippets = ('test', 'h${1:beforea${VISUAL}aft}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX + JF + 'hi'
wanted = 'hbeforeahello\n\tnice\n\tworldaftbhi'
class Visual_InDefaultText_IndentSpacesToTabstop_Overwrite(_VimTest):
snippets = ("test", "h${1:beforea${VISUAL}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + "ups" + JF + "hi"
wanted = "hupsbhi"
snippets = ('test', 'h${1:beforea${VISUAL}aft}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + \
EX + 'test' + EX + 'ups' + JF + 'hi'
wanted = 'hupsbhi'
class Visual_InDefaultText_IndentSpacesToTabstop_NoOverwrite1(_VimTest):
snippets = ("test", "h${1:beforeaaa${VISUAL}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + JF + "hi"
wanted = "hbeforeaaahello\n\t nice\n\t worldaftbhi"
snippets = ('test', 'h${1:beforeaaa${VISUAL}aft}b')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX + JF + 'hi'
wanted = 'hbeforeaaahello\n\t nice\n\t worldaftbhi'
class Visual_InDefaultText_IndentBeforeTabstop_NoOverwrite(_VimTest):
snippets = ("test", "hello\n\t ${1:${VISUAL}}\nend")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + JF + "hi"
wanted = "hello\n\t hello\n\t nice\n\t world\nendhi"
snippets = ('test', 'hello\n\t ${1:${VISUAL}}\nend')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX + JF + 'hi'
wanted = 'hello\n\t hello\n\t nice\n\t world\nendhi'
class Visual_LineSelect_WithTabStop(_VimTest):
snippets = ("test", "beg\n\t${VISUAL}\n\t${1:here_we_go}\nend")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + "super" + JF + "done"
wanted = "beg\n\thello\n\tnice\n\tworld\n\tsuper\nenddone"
snippets = ('test', 'beg\n\t${VISUAL}\n\t${1:here_we_go}\nend')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + \
EX + 'test' + EX + 'super' + JF + 'done'
wanted = 'beg\n\thello\n\tnice\n\tworld\n\tsuper\nenddone'
class Visual_LineSelect_CheckIndentWithTS_NoOverwrite(_VimTest):
snippets = ("test", "beg\n\t${0:${VISUAL}}\nend")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "beg\n\thello\n\tnice\n\tworld\nend"
snippets = ('test', 'beg\n\t${0:${VISUAL}}\nend')
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'beg\n\thello\n\tnice\n\tworld\nend'
class Visual_LineSelect_DedentLine(_VimTest):
snippets = ("if", "if {\n\t${VISUAL}$0\n}")
keys = "if" + EX + "one\n\ttwo\n\tthree" + ESC + ARR_U*2 + "V" + ARR_D + EX + "\tif" + EX
wanted = "if {\n\tif {\n\t\tone\n\t\ttwo\n\t}\n\tthree\n}"
snippets = ('if', 'if {\n\t${VISUAL}$0\n}')
keys = 'if' + EX + 'one\n\ttwo\n\tthree' + ESC + \
ARR_U * 2 + 'V' + ARR_D + EX + '\tif' + EX
wanted = 'if {\n\tif {\n\t\tone\n\t\ttwo\n\t}\n\tthree\n}'
class VisualTransformation_SelectOneWord(_VimTest):
snippets = ("test", r"h${VISUAL/./\U$0\E/g}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hBLABLUBb"
snippets = ('test', r"h${VISUAL/./\U$0\E/g}b")
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hBLABLUBb'
class VisualTransformationWithDefault_ExpandWithoutVisual(_VimTest):
snippets = ("test", r"h${VISUAL:world/./\U$0\E/g}b")
keys = "test" + EX + "hi"
wanted = "hWORLDbhi"
snippets = ('test', r"h${VISUAL:world/./\U$0\E/g}b")
keys = 'test' + EX + 'hi'
wanted = 'hWORLDbhi'
class VisualTransformationWithDefault_ExpandWithVisual(_VimTest):
snippets = ("test", r"h${VISUAL:world/./\U$0\E/g}b")
keys = "blablub" + ESC + "0v6l" + EX + "test" + EX
wanted = "hBLABLUBb"
snippets = ('test', r"h${VISUAL:world/./\U$0\E/g}b")
keys = 'blablub' + ESC + '0v6l' + EX + 'test' + EX
wanted = 'hBLABLUBb'
class VisualTransformation_LineSelect_Simple(_VimTest):
snippets = ("test", r"h${VISUAL/./\U$0\E/g}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX
wanted = "hHELLO\n NICE\n WORLDb"
snippets = ('test', r"h${VISUAL/./\U$0\E/g}b")
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX
wanted = 'hHELLO\n NICE\n WORLDb'
class VisualTransformation_InDefaultText_LineSelect_NoOverwrite(_VimTest):
snippets = ("test", r"h${1:bef${VISUAL/./\U$0\E/g}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + JF + "hi"
wanted = "hbefHELLO\n NICE\n WORLDaftbhi"
snippets = ('test', r"h${1:bef${VISUAL/./\U$0\E/g}aft}b")
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + EX + 'test' + EX + JF + 'hi'
wanted = 'hbefHELLO\n NICE\n WORLDaftbhi'
class VisualTransformation_InDefaultText_LineSelect_Overwrite(_VimTest):
snippets = ("test", r"h${1:bef${VISUAL/./\U$0\E/g}aft}b")
keys = "hello\nnice\nworld" + ESC + "Vkk" + EX + "test" + EX + "jup" + JF + "hi"
wanted = "hjupbhi"
snippets = ('test', r"h${1:bef${VISUAL/./\U$0\E/g}aft}b")
keys = 'hello\nnice\nworld' + ESC + 'Vkk' + \
EX + 'test' + EX + 'jup' + JF + 'hi'
wanted = 'hjupbhi'
# End: ${VISUAL} #}}}

View File

@ -6,10 +6,12 @@ try:
except ImportError:
UNIDECODE_IMPORTED = False
def running_on_windows():
if platform.system() == "Windows":
return "Does not work on Windows."
if platform.system() == 'Windows':
return 'Does not work on Windows.'
def no_unidecode_available():
if not UNIDECODE_IMPORTED:
return "unidecode is not available."
return 'unidecode is not available.'

View File

@ -9,6 +9,7 @@ import time
from test.constant import *
def wait_until_file_exists(file_path, times=None, interval=0.01):
while times is None or times:
if os.path.exists(file_path):
@ -18,17 +19,19 @@ def wait_until_file_exists(file_path, times=None, interval=0.01):
times -= 1
return False
def read_text_file(filename):
"""Reads the contens of a text file."""
if PYTHON3:
return open(filename,"r", encoding="utf-8").read()
return open(filename, 'r', encoding='utf-8').read()
else:
return open(filename,"r").read()
return open(filename, 'r').read()
def is_process_running(pid):
"""Returns true if a process with pid is running, false otherwise."""
# from http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid
# from
# http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid
try:
os.kill(pid, 0)
except OSError:
@ -36,10 +39,12 @@ def is_process_running(pid):
else:
return True
def silent_call(cmd):
"""Calls 'cmd' and returns the exit value."""
return subprocess.call(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
def create_directory(dirname):
"""Creates 'dirname' and its parents if it does not exist."""
try:
@ -49,8 +54,9 @@ def create_directory(dirname):
class TempFileManager(object):
def __init__(self, name=""):
self._temp_dir = tempfile.mkdtemp(prefix="UltiSnipsTest_" + name)
def __init__(self, name=''):
self._temp_dir = tempfile.mkdtemp(prefix='UltiSnipsTest_' + name)
def name_temp(self, file_path):
return os.path.join(self._temp_dir, file_path)
@ -59,15 +65,16 @@ class TempFileManager(object):
abs_path = self.name_temp(file_path)
create_directory(os.path.dirname(abs_path))
if PYTHON3:
with open(abs_path, "w", encoding="utf-8") as f:
with open(abs_path, 'w', encoding='utf-8') as f:
f.write(content)
else:
with open(abs_path, "w") as f:
with open(abs_path, 'w') as f:
f.write(content)
return abs_path
def unique_name_temp(self, suffix="", prefix=""):
file_handler, abspath = tempfile.mkstemp(suffix, prefix, self._temp_dir)
def unique_name_temp(self, suffix='', prefix=''):
file_handler, abspath = tempfile.mkstemp(
suffix, prefix, self._temp_dir)
os.close(file_handler)
os.remove(abspath)
return abspath
@ -78,12 +85,13 @@ class TempFileManager(object):
class VimInterface(TempFileManager):
def __init__(self, name=""):
def __init__(self, name=''):
TempFileManager.__init__(self, name)
def get_buffer_data(self):
buffer_path = self.unique_name_temp(prefix="buffer_")
self.send(ESC + ":w! %s\n" % buffer_path)
buffer_path = self.unique_name_temp(prefix='buffer_')
self.send(ESC + ':w! %s\n' % buffer_path)
if wait_until_file_exists(buffer_path, 50):
return read_text_file(buffer_path)[:-1]
@ -91,35 +99,40 @@ class VimInterface(TempFileManager):
raise NotImplementedError()
def launch(self, config=[]):
pid_file = self.name_temp("vim.pid")
done_file = self.name_temp("loading_done")
pid_file = self.name_temp('vim.pid')
done_file = self.name_temp('loading_done')
if os.path.exists(done_file):
os.remove(done_file)
post_config = []
post_config.append("%s << EOF" % ("py3" if PYTHON3 else "py"))
post_config.append("import vim")
post_config.append("with open('%s', 'w') as pid_file: pid_file.write(vim.eval('getpid()'))" % pid_file)
post_config.append("with open('%s', 'w') as done_file: pass" % done_file)
post_config.append("EOF")
post_config.append('%s << EOF' % ('py3' if PYTHON3 else 'py'))
post_config.append('import vim')
post_config.append(
"with open('%s', 'w') as pid_file: pid_file.write(vim.eval('getpid()'))" %
pid_file)
post_config.append(
"with open('%s', 'w') as done_file: pass" %
done_file)
post_config.append('EOF')
config_path = self.write_temp("vim_config.vim",
textwrap.dedent(os.linesep.join(config + post_config) + "\n"))
config_path = self.write_temp('vim_config.vim',
textwrap.dedent(os.linesep.join(config + post_config) + '\n'))
# Note the space to exclude it from shell history.
self.send(""" vim -u %s\r\n""" % config_path)
wait_until_file_exists(done_file)
self._vim_pid = int(open(pid_file, "r").read())
self._vim_pid = int(open(pid_file, 'r').read())
def leave_with_wait(self):
self.send(3*ESC + ":qa!\n")
self.send(3 * ESC + ':qa!\n')
while is_process_running(self._vim_pid):
time.sleep(.05)
class VimInterfaceScreen(VimInterface):
def __init__(self, session):
VimInterface.__init__(self, "Screen")
VimInterface.__init__(self, 'Screen')
self.session = session
self.need_screen_escapes = 0
self.detect_parsing()
@ -128,35 +141,42 @@ class VimInterfaceScreen(VimInterface):
if self.need_screen_escapes:
# escape characters that are special to some versions of screen
repl = lambda m: '\\' + m.group(0)
s = re.sub( r"[$^#\\']", repl, s )
s = re.sub(r"[$^#\\']", repl, s)
if PYTHON3:
s = s.encode("utf-8")
s = s.encode('utf-8')
while True:
rv = 0
if len(s) > 30:
rv |= silent_call(["screen", "-x", self.session, "-X", "register", "S", s])
rv |= silent_call(["screen", "-x", self.session, "-X", "paste", "S"])
rv |= silent_call(
['screen', '-x', self.session, '-X', 'register', 'S', s])
rv |= silent_call(
['screen', '-x', self.session, '-X', 'paste', 'S'])
else:
rv |= silent_call(["screen", "-x", self.session, "-X", "stuff", s])
if not rv: break
rv |= silent_call(
['screen', '-x', self.session, '-X', 'stuff', s])
if not rv:
break
time.sleep(.2)
def detect_parsing(self):
self.launch()
# Send a string where the interpretation will depend on version of screen
string = "$TERM"
self.send("i" + string + ESC)
# Send a string where the interpretation will depend on version of
# screen
string = '$TERM'
self.send('i' + string + ESC)
output = self.get_buffer_data()
# If the output doesn't match the input, need to do additional escaping
if output != string:
self.need_screen_escapes = 1
self.leave_with_wait()
class VimInterfaceTmux(VimInterface):
def __init__(self, session):
VimInterface.__init__(self, "Tmux")
VimInterface.__init__(self, 'Tmux')
self.session = session
self._check_version()
@ -166,68 +186,73 @@ class VimInterfaceTmux(VimInterface):
s = s.replace(';', r'\;')
if PYTHON3:
s = s.encode("utf-8")
silent_call(["tmux", "send-keys", "-t", self.session, "-l", s])
s = s.encode('utf-8')
silent_call(['tmux', 'send-keys', '-t', self.session, '-l', s])
def _check_version(self):
stdout, _ = subprocess.Popen(["tmux", "-V"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
stdout, _ = subprocess.Popen(['tmux', '-V'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
if PYTHON3:
stdout = stdout.decode("utf-8")
stdout = stdout.decode('utf-8')
m = re.match(r"tmux (\d+).(\d+)", stdout)
if not m or not (int(m.group(1)), int(m.group(2))) >= (1, 8):
raise RuntimeError("Need at least tmux 1.8, you have %s." % stdout.strip())
raise RuntimeError(
'Need at least tmux 1.8, you have %s.' %
stdout.strip())
class VimInterfaceWindows(VimInterface):
BRACES = re.compile("([}{])")
WIN_ESCAPES = ["+", "^", "%", "~", "[", "]", "<", ">", "(", ")"]
BRACES = re.compile('([}{])')
WIN_ESCAPES = ['+', '^', '%', '~', '[', ']', '<', '>', '(', ')']
WIN_REPLACES = [
(BS, "{BS}"),
(ARR_L, "{LEFT}"),
(ARR_R, "{RIGHT}"),
(ARR_U, "{UP}"),
(ARR_D, "{DOWN}"),
("\t", "{TAB}"),
("\n", "~"),
(ESC, "{ESC}"),
(BS, '{BS}'),
(ARR_L, '{LEFT}'),
(ARR_R, '{RIGHT}'),
(ARR_U, '{UP}'),
(ARR_D, '{DOWN}'),
('\t', '{TAB}'),
('\n', '~'),
(ESC, '{ESC}'),
# On my system ` waits for a second keystroke, so `+SPACE = "`". On
# most systems, `+Space = "` ". I work around this, by sending the host
# ` as `+_+BS. Awkward, but the only way I found to get this working.
("`", "`_{BS}"),
("´", "´_{BS}"),
("{^}", "{^}_{BS}"),
# On my system ` waits for a second keystroke, so `+SPACE = "`". On
# most systems, `+Space = "` ". I work around this, by sending the host
# ` as `+_+BS. Awkward, but the only way I found to get this working.
('`', '`_{BS}'),
('´', '´_{BS}'),
('{^}', '{^}_{BS}'),
]
def __init__(self):
self.seq_buf = []
# import windows specific modules
import win32com.client, win32gui
import win32com.client
import win32gui
self.win32gui = win32gui
self.shell = win32com.client.Dispatch("WScript.Shell")
self.shell = win32com.client.Dispatch('WScript.Shell')
def is_focused(self, title=None):
cur_title = self.win32gui.GetWindowText(self.win32gui.GetForegroundWindow())
if (title or "- GVIM") in cur_title:
cur_title = self.win32gui.GetWindowText(
self.win32gui.GetForegroundWindow())
if (title or '- GVIM') in cur_title:
return True
return False
def focus(self, title=None):
if not self.shell.AppActivate(title or "- GVIM"):
raise Exception("Failed to switch to GVim window")
if not self.shell.AppActivate(title or '- GVIM'):
raise Exception('Failed to switch to GVim window')
time.sleep(1)
def convert_keys(self, keys):
keys = self.BRACES.sub(r"{\1}", keys)
for k in self.WIN_ESCAPES:
keys = keys.replace(k, "{%s}" % k)
keys = keys.replace(k, '{%s}' % k)
for f, r in self.WIN_REPLACES:
keys = keys.replace(f, r)
return keys
def send(self, keys):
self.seq_buf.append(keys)
seq = "".join(self.seq_buf)
seq = ''.join(self.seq_buf)
for f in SEQUENCES:
if f.startswith(seq) and f != seq:
@ -241,7 +266,6 @@ class VimInterfaceWindows(VimInterface):
self.focus()
if not self.is_focused():
# This is the only way I can find to stop test execution
raise KeyboardInterrupt("Failed to focus GVIM")
raise KeyboardInterrupt('Failed to focus GVIM')
self.shell.SendKeys(seq)

View File

@ -6,7 +6,6 @@ import os
import re
import shutil
import subprocess
import sys
import tempfile
import textwrap
import time
@ -14,9 +13,11 @@ import unittest
from constant import *
def is_process_running(pid):
"""Returns true if a process with pid is running, false otherwise."""
# from http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid
# from
# http://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid
try:
os.kill(pid, 0)
except OSError:
@ -24,10 +25,12 @@ def is_process_running(pid):
else:
return True
def silent_call(cmd):
"""Calls 'cmd' and returns the exit value."""
return subprocess.call(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
def create_directory(dirname):
"""Creates 'dirname' and its parents if it does not exist."""
try:
@ -35,16 +38,19 @@ def create_directory(dirname):
except OSError:
pass
def plugin_cache_dir():
"""The directory that we check out our bundles to."""
return os.path.join(tempfile.gettempdir(), "UltiSnips_test_vim_plugins")
return os.path.join(tempfile.gettempdir(), 'UltiSnips_test_vim_plugins')
def read_text_file(filename):
"""Reads the contens of a text file."""
if PYTHON3:
return open(filename,"r", encoding="utf-8").read()
return open(filename, 'r', encoding='utf-8').read()
else:
return open(filename,"r").read()
return open(filename, 'r').read()
def wait_until_file_exists(file_path, times=None, interval=0.01):
while times is None or times:
@ -55,59 +61,61 @@ def wait_until_file_exists(file_path, times=None, interval=0.01):
times -= 1
return False
class TempFileManager(object):
"""A TempFileManager keeps a unique prefix path for temp
files. A temp file, or a name for a temp file generate by a
TempFileManager always belongs to the same directory.
"""A TempFileManager keeps a unique prefix path for temp files.
A temp file, or a name for a temp file generate by a TempFileManager
always belongs to the same directory.
"""
def __init__(self, name=""):
"""The unique prefix path is UltiSnipsTest_{name}XXXXXX.
"""
self._temp_dir = tempfile.mkdtemp(prefix="UltiSnipsTest_" + name)
def __init__(self, name=''):
"""The unique prefix path is UltiSnipsTest_{name}XXXXXX."""
self._temp_dir = tempfile.mkdtemp(prefix='UltiSnipsTest_' + name)
def name_temp(self, file_path):
"""Get the absolute path of a temp file by given file path.
"""
"""Get the absolute path of a temp file by given file path."""
return os.path.join(self._temp_dir, file_path)
def write_temp(self, file_path, content):
"""Write the content to a temp file by given file path inside
the _temp_dir, and return the absolute path of that file.
"""
"""Write the content to a temp file by given file path inside the
_temp_dir, and return the absolute path of that file."""
abs_path = self.name_temp(file_path)
create_directory(os.path.dirname(abs_path))
if PYTHON3:
with open(abs_path, "w", encoding="utf-8") as f:
with open(abs_path, 'w', encoding='utf-8') as f:
f.write(content)
else:
with open(abs_path, "w") as f:
with open(abs_path, 'w') as f:
f.write(content)
return abs_path
def unique_name_temp(self, suffix="", prefix=""):
"""Generate a unique name for a temp file with given suffix and
prefix, and return full absolute path.
"""
file_handler, abspath = tempfile.mkstemp(suffix, prefix, self._temp_dir)
def unique_name_temp(self, suffix='', prefix=''):
"""Generate a unique name for a temp file with given suffix and prefix,
and return full absolute path."""
file_handler, abspath = tempfile.mkstemp(
suffix, prefix, self._temp_dir)
os.close(file_handler)
os.remove(abspath)
return abspath
def clear_temp(self):
"""Clear the temp file directory, but the directory itself is
not removed.
"""
"""Clear the temp file directory, but the directory itself is not
removed."""
shutil.rmtree(self._temp_dir)
create_directory(self._temp_dir)
class VimInterface(TempFileManager):
def __init__(self, name=""):
def __init__(self, name=''):
TempFileManager.__init__(self, name)
def get_buffer_data(self):
buffer_path = self.unique_name_temp(prefix="buffer_")
self.send(ESC + ":w! %s\n" % buffer_path)
buffer_path = self.unique_name_temp(prefix='buffer_')
self.send(ESC + ':w! %s\n' % buffer_path)
if wait_until_file_exists(buffer_path, 50):
return read_text_file(buffer_path)[:-1]
@ -115,35 +123,40 @@ class VimInterface(TempFileManager):
raise NotImplementedError()
def launch(self, config=[]):
pid_file = self.name_temp("vim.pid")
done_file = self.name_temp("loading_done")
pid_file = self.name_temp('vim.pid')
done_file = self.name_temp('loading_done')
if os.path.exists(done_file):
os.remove(done_file)
post_config = []
post_config.append("%s << EOF" % ("py3" if PYTHON3 else "py"))
post_config.append("import vim")
post_config.append("with open('%s', 'w') as pid_file: pid_file.write(vim.eval('getpid()'))" % pid_file)
post_config.append("with open('%s', 'w') as done_file: pass" % done_file)
post_config.append("EOF")
post_config.append('%s << EOF' % ('py3' if PYTHON3 else 'py'))
post_config.append('import vim')
post_config.append(
"with open('%s', 'w') as pid_file: pid_file.write(vim.eval('getpid()'))" %
pid_file)
post_config.append(
"with open('%s', 'w') as done_file: pass" %
done_file)
post_config.append('EOF')
config_path = self.write_temp("vim_config.vim",
textwrap.dedent(os.linesep.join(config + post_config) + "\n"))
config_path = self.write_temp('vim_config.vim',
textwrap.dedent(os.linesep.join(config + post_config) + '\n'))
# Note the space to exclude it from shell history.
self.send(""" vim -u %s\r\n""" % config_path)
wait_until_file_exists(done_file)
self._vim_pid = int(open(pid_file, "r").read())
self._vim_pid = int(open(pid_file, 'r').read())
def leave_with_wait(self):
self.send(3*ESC + ":qa!\n")
self.send(3 * ESC + ':qa!\n')
while is_process_running(self._vim_pid):
time.sleep(.05)
class VimInterfaceScreen(VimInterface):
def __init__(self, session):
VimInterface.__init__(self, "Screen")
VimInterface.__init__(self, 'Screen')
self.session = session
self.need_screen_escapes = 0
self.detect_parsing()
@ -152,33 +165,40 @@ class VimInterfaceScreen(VimInterface):
if self.need_screen_escapes:
# escape characters that are special to some versions of screen
repl = lambda m: '\\' + m.group(0)
s = re.sub( r"[$^#\\']", repl, s )
s = re.sub(r"[$^#\\']", repl, s)
if PYTHON3:
s = s.encode("utf-8")
s = s.encode('utf-8')
while True:
rv = 0
if len(s) > 30:
rv |= silent_call(["screen", "-x", self.session, "-X", "register", "S", s])
rv |= silent_call(["screen", "-x", self.session, "-X", "paste", "S"])
rv |= silent_call(
['screen', '-x', self.session, '-X', 'register', 'S', s])
rv |= silent_call(
['screen', '-x', self.session, '-X', 'paste', 'S'])
else:
rv |= silent_call(["screen", "-x", self.session, "-X", "stuff", s])
if not rv: break
rv |= silent_call(
['screen', '-x', self.session, '-X', 'stuff', s])
if not rv:
break
time.sleep(.2)
def detect_parsing(self):
self.launch()
# Send a string where the interpretation will depend on version of screen
string = "$TERM"
self.send("i" + string + ESC)
# Send a string where the interpretation will depend on version of
# screen
string = '$TERM'
self.send('i' + string + ESC)
output = self.get_buffer_data()
# If the output doesn't match the input, need to do additional escaping
if output != string:
self.need_screen_escapes = 1
self.leave_with_wait()
class VimInterfaceTmux(VimInterface):
def __init__(self, session):
self.session = session
self._check_version()
@ -189,68 +209,73 @@ class VimInterfaceTmux(VimInterface):
s = s.replace(';', r'\;')
if PYTHON3:
s = s.encode("utf-8")
silent_call(["tmux", "send-keys", "-t", self.session, "-l", s])
s = s.encode('utf-8')
silent_call(['tmux', 'send-keys', '-t', self.session, '-l', s])
def _check_version(self):
stdout, _ = subprocess.Popen(["tmux", "-V"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
stdout, _ = subprocess.Popen(['tmux', '-V'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
if PYTHON3:
stdout = stdout.decode("utf-8")
stdout = stdout.decode('utf-8')
m = re.match(r"tmux (\d+).(\d+)", stdout)
if not m or not (int(m.group(1)), int(m.group(2))) >= (1, 9):
raise RuntimeError("Need at least tmux 1.9, you have %s." % stdout.strip())
raise RuntimeError(
'Need at least tmux 1.9, you have %s.' %
stdout.strip())
class VimInterfaceWindows(VimInterface):
BRACES = re.compile("([}{])")
WIN_ESCAPES = ["+", "^", "%", "~", "[", "]", "<", ">", "(", ")"]
BRACES = re.compile('([}{])')
WIN_ESCAPES = ['+', '^', '%', '~', '[', ']', '<', '>', '(', ')']
WIN_REPLACES = [
(BS, "{BS}"),
(ARR_L, "{LEFT}"),
(ARR_R, "{RIGHT}"),
(ARR_U, "{UP}"),
(ARR_D, "{DOWN}"),
("\t", "{TAB}"),
("\n", "~"),
(ESC, "{ESC}"),
(BS, '{BS}'),
(ARR_L, '{LEFT}'),
(ARR_R, '{RIGHT}'),
(ARR_U, '{UP}'),
(ARR_D, '{DOWN}'),
('\t', '{TAB}'),
('\n', '~'),
(ESC, '{ESC}'),
# On my system ` waits for a second keystroke, so `+SPACE = "`". On
# most systems, `+Space = "` ". I work around this, by sending the host
# ` as `+_+BS. Awkward, but the only way I found to get this working.
("`", "`_{BS}"),
("´", "´_{BS}"),
("{^}", "{^}_{BS}"),
# On my system ` waits for a second keystroke, so `+SPACE = "`". On
# most systems, `+Space = "` ". I work around this, by sending the host
# ` as `+_+BS. Awkward, but the only way I found to get this working.
('`', '`_{BS}'),
('´', '´_{BS}'),
('{^}', '{^}_{BS}'),
]
def __init__(self):
self.seq_buf = []
# import windows specific modules
import win32com.client, win32gui
import win32com.client
import win32gui
self.win32gui = win32gui
self.shell = win32com.client.Dispatch("WScript.Shell")
self.shell = win32com.client.Dispatch('WScript.Shell')
def is_focused(self, title=None):
cur_title = self.win32gui.GetWindowText(self.win32gui.GetForegroundWindow())
if (title or "- GVIM") in cur_title:
cur_title = self.win32gui.GetWindowText(
self.win32gui.GetForegroundWindow())
if (title or '- GVIM') in cur_title:
return True
return False
def focus(self, title=None):
if not self.shell.AppActivate(title or "- GVIM"):
raise Exception("Failed to switch to GVim window")
if not self.shell.AppActivate(title or '- GVIM'):
raise Exception('Failed to switch to GVim window')
time.sleep(1)
def convert_keys(self, keys):
keys = self.BRACES.sub(r"{\1}", keys)
for k in self.WIN_ESCAPES:
keys = keys.replace(k, "{%s}" % k)
keys = keys.replace(k, '{%s}' % k)
for f, r in self.WIN_REPLACES:
keys = keys.replace(f, r)
return keys
def send(self, keys):
self.seq_buf.append(keys)
seq = "".join(self.seq_buf)
seq = ''.join(self.seq_buf)
for f in SEQUENCES:
if f.startswith(seq) and f != seq:
@ -264,7 +289,7 @@ class VimInterfaceWindows(VimInterface):
self.focus()
if not self.is_focused():
# This is the only way I can find to stop test execution
raise KeyboardInterrupt("Failed to focus GVIM")
raise KeyboardInterrupt('Failed to focus GVIM')
self.shell.SendKeys(seq)
@ -272,13 +297,13 @@ class VimInterfaceWindows(VimInterface):
class VimTestCase(unittest.TestCase, TempFileManager):
snippets = ()
files = {}
text_before = " --- some text before --- \n\n"
text_after = "\n\n --- some text after --- "
expected_error = ""
wanted = ""
keys = ""
text_before = ' --- some text before --- \n\n'
text_after = '\n\n --- some text after --- '
expected_error = ''
wanted = ''
keys = ''
sleeptime = 0.00
output = ""
output = ''
plugins = []
# Skip this test for the given reason or None for not skipping it.
skip_if = lambda self: None
@ -286,7 +311,7 @@ class VimTestCase(unittest.TestCase, TempFileManager):
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
TempFileManager.__init__(self, "Case")
TempFileManager.__init__(self, 'Case')
def runTest(self):
# Only checks the output. All work is done in setUp().
@ -304,37 +329,41 @@ class VimTestCase(unittest.TestCase, TempFileManager):
def _extra_options_pre_init(self, vim_config):
"""Adds extra lines to the vim_config list."""
pass
def _extra_options_post_init(self, vim_config):
"""Adds extra lines to the vim_config list."""
pass
def _before_test(self):
"""Send these keys before the test runs. Used for buffer local
variables and other options."""
pass
"""Send these keys before the test runs.
Used for buffer local variables and other options.
"""
def _create_file(self, file_path, content):
"""Creates a file in the runtimepath that is created for this test.
Returns the absolute path to the file."""
return self.write_temp(file_path, textwrap.dedent(content + "\n"))
Returns the absolute path to the file.
"""
return self.write_temp(file_path, textwrap.dedent(content + '\n'))
def _link_file(self, source, relative_destination):
"""Creates a link from 'source' to the 'relative_destination' in our temp dir."""
"""Creates a link from 'source' to the 'relative_destination' in our
temp dir."""
absdir = self.name_temp(relative_destination)
create_directory(absdir)
os.symlink(source, os.path.join(absdir, os.path.basename(source)))
def setUp(self):
if not VimTestCase.version:
VimTestCase.version, _ = subprocess.Popen(["vim", "--version"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
VimTestCase.version, _ = subprocess.Popen(['vim', '--version'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
if PYTHON3:
VimTestCase.version = VimTestCase.version.decode("utf-8")
VimTestCase.version = VimTestCase.version.decode('utf-8')
if self.plugins and not self.test_plugins:
return self.skipTest("Not testing integration with other plugins.")
return self.skipTest('Not testing integration with other plugins.')
reason_for_skipping = self.skip_if()
if reason_for_skipping is not None:
return self.skipTest(reason_for_skipping)
@ -345,10 +374,19 @@ class VimTestCase(unittest.TestCase, TempFileManager):
os.path.dirname(os.path.dirname(__file__)), self._temp_dir))
if self.plugins:
self._link_file(os.path.join(plugin_cache_dir(), "vim-pathogen", "autoload"), ".")
self._link_file(
os.path.join(
plugin_cache_dir(),
'vim-pathogen',
'autoload'),
'.')
for plugin in self.plugins:
self._link_file(os.path.join(plugin_cache_dir(), os.path.basename(plugin)), "bundle")
vim_config.append("execute pathogen#infect()")
self._link_file(
os.path.join(
plugin_cache_dir(),
os.path.basename(plugin)),
'bundle')
vim_config.append('execute pathogen#infect()')
# Vim parameters.
vim_config.append('syntax on')
@ -363,7 +401,9 @@ class VimTestCase(unittest.TestCase, TempFileManager):
vim_config.append('let g:UltiSnipsJumpForwardTrigger="?"')
vim_config.append('let g:UltiSnipsJumpBackwardTrigger="+"')
vim_config.append('let g:UltiSnipsListSnippets="@"')
vim_config.append('let g:UltiSnipsUsePythonVersion="%i"' % (3 if PYTHON3 else 2))
vim_config.append(
'let g:UltiSnipsUsePythonVersion="%i"' %
(3 if PYTHON3 else 2))
vim_config.append('let g:UltiSnipsSnippetDirectories=["us"]')
self._extra_options_pre_init(vim_config)
@ -374,14 +414,14 @@ class VimTestCase(unittest.TestCase, TempFileManager):
self._extra_options_post_init(vim_config)
# Finally, add the snippets and some configuration for the test.
vim_config.append("%s << EOF" % ("py3" if PYTHON3 else "py"))
vim_config.append('%s << EOF' % ('py3' if PYTHON3 else 'py'))
if len(self.snippets) and not isinstance(self.snippets[0],tuple):
self.snippets = ( self.snippets, )
if len(self.snippets) and not isinstance(self.snippets[0], tuple):
self.snippets = (self.snippets, )
for s in self.snippets:
sv, content = s[:2]
description = ""
options = ""
description = ''
options = ''
priority = 0
if len(s) > 2:
description = s[2]
@ -389,16 +429,17 @@ class VimTestCase(unittest.TestCase, TempFileManager):
options = s[3]
if len(s) > 4:
priority = s[4]
vim_config.append("UltiSnips_Manager.add_snippet(%r, %r, %r, %r, priority=%i)" % (
sv, content, description, options, priority))
vim_config.append('UltiSnips_Manager.add_snippet(%r, %r, %r, %r, priority=%i)' % (
sv, content, description, options, priority))
# fill buffer with default text and place cursor in between.
prefilled_text = (self.text_before + self.text_after).splitlines()
vim_config.append("vim.current.buffer[:] = %r\n" % prefilled_text)
vim_config.append("vim.current.window.cursor = (max(len(vim.current.buffer)//2, 1), 0)")
vim_config.append('vim.current.buffer[:] = %r\n' % prefilled_text)
vim_config.append(
'vim.current.window.cursor = (max(len(vim.current.buffer)//2, 1), 0)')
# End of python stuff.
vim_config.append("EOF")
vim_config.append('EOF')
for name, content in self.files.items():
self._create_file(name, content)
@ -417,7 +458,7 @@ class VimTestCase(unittest.TestCase, TempFileManager):
def tearDown(self):
if self.interrupt:
print("Working directory: %s" % (self._temp_dir))
print('Working directory: %s' % (self._temp_dir))
return
self.vim.leave_with_wait()
self.clear_temp()

View File

@ -47,28 +47,32 @@ import unittest
from test.constant import *
from test.vim_interface import *
def plugin_cache_dir():
"""The directory that we check out our bundles to."""
return os.path.join(tempfile.gettempdir(), "UltiSnips_test_vim_plugins")
return os.path.join(tempfile.gettempdir(), 'UltiSnips_test_vim_plugins')
def clone_plugin(plugin):
"""Clone the given plugin into our plugin directory."""
dirname = os.path.join(plugin_cache_dir(), os.path.basename(plugin))
print("Cloning %s -> %s" % (plugin, dirname))
print('Cloning %s -> %s' % (plugin, dirname))
if os.path.exists(dirname):
print("Skip cloning of %s. Already there." % plugin)
print('Skip cloning of %s. Already there.' % plugin)
return
create_directory(dirname)
subprocess.call(["git", "clone", "--recursive",
"--depth", "1", "https://github.com/%s" % plugin, dirname])
subprocess.call(['git', 'clone', '--recursive',
'--depth', '1', 'https://github.com/%s' % plugin, dirname])
if plugin == 'Valloric/YouCompleteMe':
# CLUTCH: this plugin needs something extra.
subprocess.call(os.path.join(dirname, './install.sh'), cwd=dirname)
if plugin == "Valloric/YouCompleteMe":
## CLUTCH: this plugin needs something extra.
subprocess.call(os.path.join(dirname, "./install.sh"), cwd=dirname)
def setup_other_plugins(all_plugins):
"""Creates /tmp/UltiSnips_test_vim_plugins and clones all plugins into this."""
clone_plugin("tpope/vim-pathogen")
"""Creates /tmp/UltiSnips_test_vim_plugins and clones all plugins into
this."""
clone_plugin('tpope/vim-pathogen')
for plugin in all_plugins:
clone_plugin(plugin)
@ -76,35 +80,35 @@ if __name__ == '__main__':
import optparse
def parse_args():
p = optparse.OptionParser("%prog [OPTIONS] <test case names to run>")
p = optparse.OptionParser('%prog [OPTIONS] <test case names to run>')
p.set_defaults(session="vim", interrupt=False,
verbose=False, interface="screen", retries=4, plugins=False)
p.set_defaults(session='vim', interrupt=False,
verbose=False, interface='screen', retries=4, plugins=False)
p.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="print name of tests as they are executed")
p.add_option("--clone-plugins", action="store_true",
help="Only clones dependant plugins and exits the test runner.")
p.add_option("--plugins", action="store_true",
help="Run integration tests with other Vim plugins.")
p.add_option("--interface", type=str,
help="interface to vim to use on Mac and or Linux [screen|tmux].")
p.add_option("-s", "--session", dest="session", metavar="SESSION",
help="session parameters for the terminal multiplexer SESSION [%default]")
p.add_option("-i", "--interrupt", dest="interrupt",
action="store_true",
help="Stop after defining the snippet. This allows the user " \
"to interactively test the snippet in vim. You must give " \
"exactly one test case on the cmdline. The test will always fail."
)
p.add_option("-r", "--retries", dest="retries", type=int,
help="How often should each test be retried before it is "
"considered failed. Works around flakyness in the terminal "
"multiplexer and race conditions in writing to the file system.")
p.add_option('-v', '--verbose', dest='verbose', action='store_true',
help='print name of tests as they are executed')
p.add_option('--clone-plugins', action='store_true',
help='Only clones dependant plugins and exits the test runner.')
p.add_option('--plugins', action='store_true',
help='Run integration tests with other Vim plugins.')
p.add_option('--interface', type=str,
help='interface to vim to use on Mac and or Linux [screen|tmux].')
p.add_option('-s', '--session', dest='session', metavar='SESSION',
help='session parameters for the terminal multiplexer SESSION [%default]')
p.add_option('-i', '--interrupt', dest='interrupt',
action='store_true',
help='Stop after defining the snippet. This allows the user '
'to interactively test the snippet in vim. You must give '
'exactly one test case on the cmdline. The test will always fail.'
)
p.add_option('-r', '--retries', dest='retries', type=int,
help='How often should each test be retried before it is '
'considered failed. Works around flakyness in the terminal '
'multiplexer and race conditions in writing to the file system.')
o, args = p.parse_args()
if o.interface not in ("screen", "tmux"):
p.error("--interface must be [screen|tmux].")
if o.interface not in ('screen', 'tmux'):
p.error('--interface must be [screen|tmux].')
return o, args
@ -118,20 +122,21 @@ if __name__ == '__main__':
return flatten
def main():
options,selected_tests = parse_args()
options, selected_tests = parse_args()
all_test_suites = unittest.defaultTestLoader.discover(start_dir="test")
all_test_suites = unittest.defaultTestLoader.discover(start_dir='test')
vim = None
if not options.clone_plugins:
if platform.system() == "Windows":
raise RuntimeError("TODO: TestSuite is broken under windows. Volunteers wanted!.")
if platform.system() == 'Windows':
raise RuntimeError(
'TODO: TestSuite is broken under windows. Volunteers wanted!.')
# vim = VimInterfaceWindows()
vim.focus()
else:
if options.interface == "screen":
if options.interface == 'screen':
vim = VimInterfaceScreen(options.session)
elif options.interface == "tmux":
elif options.interface == 'tmux':
vim = VimInterfaceTmux(options.session)
all_other_plugins = set()
@ -148,7 +153,7 @@ if __name__ == '__main__':
if len(selected_tests):
id = test.id().split('.')[1]
if not any([ id.startswith(t) for t in selected_tests ]):
if not any([id.startswith(t) for t in selected_tests]):
continue
tests.add(test)
suite.addTests(tests)

View File

@ -11,28 +11,37 @@ import glob
_UNESCAPE = re.compile(ur'&\w+?;', re.UNICODE)
def unescape(s):
if s is None:
return ""
return ''
def fixup(m):
ent = m.group(0)[1:-1]
return unichr(htmlentitydefs.name2codepoint[ent])
try:
return _UNESCAPE.sub(fixup,s)
return _UNESCAPE.sub(fixup, s)
except:
print "unescape failed: %s" % repr(s)
print 'unescape failed: %s' % repr(s)
raise
class UnknownVariable(Exception):
pass
class UnsupportedVariableExpression(Exception):
pass
def replace_vars(m):
""" Replace vars in 'content' portion.
"""Replace vars in 'content' portion.
:m: match object
:returns: string"""
:returns: string
"""
var = m.group(1)
default = m.group(2)
@ -40,10 +49,10 @@ def replace_vars(m):
raise UnsupportedVariableExpression(var)
translate_vars = {
'TM_PHP_OPEN_TAG_WITH_ECHO': 'g:UltiSnipsOpenTagWithEcho',
'TM_PHP_OPEN_TAG': 'g:UltiSnipsOpenTag',
'PHPDOC_AUTHOR': 'g:snips_author',
}
'TM_PHP_OPEN_TAG_WITH_ECHO': 'g:UltiSnipsOpenTagWithEcho',
'TM_PHP_OPEN_TAG': 'g:UltiSnipsOpenTag',
'PHPDOC_AUTHOR': 'g:snips_author',
}
# TODO: TM_SELECTED_TEXT/([\t ]*).*/$1/m
if var in translate_vars:
@ -54,44 +63,48 @@ def replace_vars(m):
return "`!v exists('%s') ? %s : '%s'`" % (newvar, newvar, default)
def parse_content(c):
try:
data = ElementTree.fromstring(c)[0]
rv = {}
for k,v in zip(data[::2], data[1::2]):
for k, v in zip(data[::2], data[1::2]):
rv[k.text] = unescape(v.text)
if re.search( r'\$\{\D', rv["content"] ):
rv["content"] = re.sub(r'\$\{([^\d}][^}:]*)(?::([^}]*))?\}', replace_vars, rv["content"])
if re.search(r'\$\{\D', rv['content']):
rv['content'] = re.sub(
r'\$\{([^\d}][^}:]*)(?::([^}]*))?\}',
replace_vars,
rv['content'])
return rv
except (ExpatError, ElementTree.ParseError) as detail:
print " Syntax Error: %s" % (detail,)
print ' Syntax Error: %s' % (detail,)
print c
return None
except UnknownVariable as detail:
print " Unknown variable: %s" % (detail,)
print ' Unknown variable: %s' % (detail,)
return None
except UnsupportedVariableExpression as detail:
print " Unsupported variable expression: %s" % (detail,)
print ' Unsupported variable expression: %s' % (detail,)
return None
def fetch_snippets_from_svn(name):
base_url = "http://svn.textmate.org/trunk/Bundles/" + name + ".tmbundle/"
snippet_idx = base_url + "Snippets/"
base_url = 'http://svn.textmate.org/trunk/Bundles/' + name + '.tmbundle/'
snippet_idx = base_url + 'Snippets/'
idx_list = urllib.urlopen(snippet_idx).read()
rv = []
for link in re.findall("<li>(.*?)</li>", idx_list):
for link in re.findall('<li>(.*?)</li>', idx_list):
m = re.match(r'<a\s*href="(.*)"\s*>(.*)</a>', link)
link, name = m.groups()
if name == "..":
if name == '..':
continue
name = unescape(name.rsplit('.', 1)[0]) # remove Extension
name = unescape(name.rsplit('.', 1)[0]) # remove Extension
print "Fetching data for Snippet '%s'" % name
content = urllib.urlopen(snippet_idx + link).read()
@ -101,12 +114,13 @@ def fetch_snippets_from_svn(name):
return rv
def fetch_snippets_from_dir(path):
""" Fetch snippets from a given path"""
"""Fetch snippets from a given path."""
rv = []
for filename in glob.glob(os.path.join(path, '*.tmSnippet')):
print "Reading file %s" % filename
print 'Reading file %s' % filename
f = open(filename)
content = f.read()
@ -116,20 +130,20 @@ def fetch_snippets_from_dir(path):
rv.append((name, cont))
return rv
def write_snippets(snip_descr, f):
for name, d in snip_descr:
if "tabTrigger" not in d:
if 'tabTrigger' not in d:
continue
if "content" not in d or d["content"] is None:
print "SKIP: %s (no content)" % (d,)
if 'content' not in d or d['content'] is None:
print 'SKIP: %s (no content)' % (d,)
continue
f.write('snippet %s "%s"\n' % (d["tabTrigger"], name))
f.write(d["content"].encode("utf-8") + "\n")
f.write("endsnippet\n\n")
f.write('snippet %s "%s"\n' % (d['tabTrigger'], name))
f.write(d['content'].encode('utf-8') + '\n')
f.write('endsnippet\n\n')
if __name__ == '__main__':
@ -144,5 +158,4 @@ if __name__ == '__main__':
rv = fetch_snippets_from_svn(bundle)
name = bundle.lower()
write_snippets(rv, open("tm_" + name + ".snippets","w"))
write_snippets(rv, open('tm_' + name + '.snippets', 'w'))