TabStops and Mirror Tests now all pass again

This commit is contained in:
Holger Rapp 2012-01-17 20:46:42 +01:00
parent f1f6e9abff
commit 9044a955ce
6 changed files with 202 additions and 162 deletions

View File

@ -27,6 +27,9 @@ class Position(object):
return locals() return locals()
line = property(**line()) line = property(**line())
def copy(self):
return Position(self._line, self._col)
def __add__(self,pos): def __add__(self,pos):
if not isinstance(pos,Position): if not isinstance(pos,Position):
raise TypeError("unsupported operand type(s) for +: " \ raise TypeError("unsupported operand type(s) for +: " \
@ -34,6 +37,12 @@ class Position(object):
return Position(self.line + pos.line, self.col + pos.col) return Position(self.line + pos.line, self.col + pos.col)
# def geometric_add(self, delta): # TODO
# assert(delta.line >= 0 and delta.col >= 0)
# if delta.line == 0:
# return Position(self.line, self.col + other.col)
# return Position(self.line + delta.line,
def __sub__(self,pos): # TODO: is this really true? def __sub__(self,pos): # TODO: is this really true?
if not isinstance(pos,Position): if not isinstance(pos,Position):
raise TypeError("unsupported operand type(s) for +: " \ raise TypeError("unsupported operand type(s) for +: " \

View File

@ -6,6 +6,8 @@ Not really a Lexer in the classical sense, but code to hack Snippet Definitions
into Logical Units called Tokens. into Logical Units called Tokens.
""" """
from debug import debug
import string import string
import re import re
@ -18,10 +20,10 @@ __all__ = [
# Helper Classes {{{ # Helper Classes {{{
class _TextIterator(object): class _TextIterator(object):
def __init__(self, text): def __init__(self, text, offset):
self._text = text self._text = text
self._line = 0 self._line = offset.line
self._col = 0 self._col = offset.col
self._idx = 0 self._idx = 0
@ -291,8 +293,9 @@ __ALLOWED_TOKENS = [
EscapeCharToken, VisualToken, TransformationToken, TabStopToken, MirrorToken, EscapeCharToken, VisualToken, TransformationToken, TabStopToken, MirrorToken,
PythonCodeToken, VimLCodeToken, ShellCodeToken PythonCodeToken, VimLCodeToken, ShellCodeToken
] ]
def tokenize(text, indent): def tokenize(text, indent, offset):
stream = _TextIterator(text) debug("tokenize: offset: %r" % (offset))
stream = _TextIterator(text, offset)
try: try:
while True: while True:

View File

@ -19,6 +19,11 @@ from UltiSnips.Util import IndentUtil
__all__ = [ "Mirror", "Transformation", "SnippetInstance" ] __all__ = [ "Mirror", "Transformation", "SnippetInstance" ]
from debug import debug from debug import debug
def _do_print(obj, indent =""): # TODO: remote again
debug("%s %r" % (indent, obj))
for c in obj._childs:
_do_print(c, indent + " ")
########################################################################### ###########################################################################
# Helper class # # Helper class #
@ -163,9 +168,13 @@ class _TOParser(object):
def _replace_initital_texts(self, seen_ts): def _replace_initital_texts(self, seen_ts):
def _place_initial_text(obj): def _place_initial_text(obj):
debug("In _place_initial_text: obj: %r" % (obj)) debug("#### Initial Text: %r" % obj)
obj.initial_replace() obj.initial_replace()
par = obj
while par._parent: par = par._parent
_do_print(par)
for c in obj._childs: # TODO: private parts! for c in obj._childs: # TODO: private parts!
_place_initial_text(c) _place_initial_text(c)
@ -179,8 +188,12 @@ class _TOParser(object):
_update_non_tabstops(self._parent_to) _update_non_tabstops(self._parent_to)
def _do_parse(self, all_tokens, seen_ts): # TODO: offset is no longer used
tokens = list(tokenize(self._text, self._indent)) def _do_parse(self, all_tokens, seen_ts, offset = None):
if offset is None:
offset = self._parent_to._start
tokens = list(tokenize(self._text, self._indent, offset))
debug("tokens: %r" % (tokens))
for token in tokens: for token in tokens:
all_tokens.append((self._parent_to, token)) all_tokens.append((self._parent_to, token))
@ -206,6 +219,35 @@ class _TOParser(object):
########################################################################### ###########################################################################
# Public classes # # Public classes #
########################################################################### ###########################################################################
# TODO: this function is related to text object and should maybe be private
def _move_nocheck(obj, old_end, new_end, diff):
assert(diff == (new_end - old_end)) # TODO: argument has no sense
if obj < old_end: return
debug("obj: %r, new_end: %r, diff: %r" % (obj, new_end, diff))
if diff.line >= 0:
obj.line += diff.line
if obj.line == new_end.line:
obj.col += diff.col
else:
debug("diff: %r" % (diff))
obj.line += diff.line
if obj.line == new_end.line:
obj.col += diff.col
def _move(obj, sp, diff):
if obj < sp: return
debug("obj: %r, sp: %r, diff: %r" % (obj, sp, diff))
if diff.line >= 0:
if obj.line == sp.line:
obj.col += diff.col
obj.line += diff.line
else:
debug("diff: %r" % (diff))
obj.line += diff.line
if obj.line == sp.line:
obj.col += sp.col
class TextObject(object): class TextObject(object):
""" """
This base class represents any object in the text This base class represents any object in the text
@ -233,20 +275,22 @@ class TextObject(object):
self._cts = 0 self._cts = 0
self._is_killed = False # TODO: not often needed self._is_killed = False # TODO: not often needed
def initial_replace(self, gtc = None): def initial_replace(self):
ct = gtc or self._initial_text # TODO: Initial Text is nearly unused. ct = self._initial_text # TODO: Initial Text is nearly unused.
debug("self._start: %r, self._end: %r" % (self._start, self._end))
debug("self._start: %r, self._end: %r" % (self._start, self._end)) debug("self._start: %r, self._end: %r" % (self._start, self._end))
debug("self.abs_start: %r, self.abs_end: %r" % (self.abs_start, self.abs_end))
debug("ct: %r" % (ct)) debug("ct: %r" % (ct))
old_end = self.abs_end old_end = self._end
ct.to_vim(self.abs_start, self.abs_end) # TODO: to vim returns something unused ct.to_vim(self._start, self._end) # TODO: to vim returns something unused
debug("self.abs_end: %r" % (self.abs_end)) debug("self._end: %r" % (self._end))
self._end = ct.calc_end(self._start) self._end = ct.calc_end(self._start)
debug("self.abs_start: %r, self.abs_end: %r" % (self.abs_start, self.abs_end)) debug("self._start: %r, self._end: %r" % (self._start, self._end))
if self.abs_end != old_end: if self._end != old_end:
exclude = set()
exclude = set(c for c in self._childs) exclude = set(c for c in self._childs)
exclude.add(self) exclude.add(self)
self.child_end_moved(old_end, self.abs_end - old_end, exclude) # TODO: maybe get rid of this function as well?
self.child_end_moved(min(old_end, self._end), self._end - old_end, exclude)
def __lt__(self, other): def __lt__(self, other):
return self._start < other._start return self._start < other._start
@ -258,16 +302,16 @@ class TextObject(object):
############## ##############
@property @property
def current_text(self): def current_text(self):
abs_span = self.abs_span _span = self.span
buf = vim.current.buffer buf = vim.current.buffer
if abs_span.start.line == abs_span.end.line: if _span.start.line == _span.end.line:
return as_unicode(buf[abs_span.start.line][abs_span.start.col:abs_span.end.col]) return as_unicode(buf[_span.start.line][_span.start.col:_span.end.col])
else: else:
lines = [] lines = []
lines.append(buf[abs_span.start.line][abs_span.start.col:]) lines.append(buf[_span.start.line][_span.start.col:])
lines.extend(buf[abs_span.start.line+1:abs_span.end.line]) lines.extend(buf[_span.start.line+1:_span.end.line])
lines.append(buf[abs_span.end.line][:abs_span.end.col]) lines.append(buf[_span.end.line][:_span.end.col])
return as_unicode('\n'.join(lines)) return as_unicode('\n'.join(lines))
@property @property
@ -276,27 +320,6 @@ class TextObject(object):
return None return None
return self._tabstops[self._cts] return self._tabstops[self._cts]
def abs_start(self):
if self._parent:
ps = self._parent.abs_start
if self._start.line == 0:
return ps + self._start
else:
return Position(ps.line + self._start.line, self._start.col)
return self._start
abs_start = property(abs_start)
def abs_end(self):
if self._parent:
ps = self._parent.abs_start
if self._end.line == 0:
return ps + self._end
else:
return Position(ps.line + self._end.line, self._end.col)
return self._end
abs_end = property(abs_end)
def span(self): def span(self):
return Span(self._start, self._end) return Span(self._start, self._end)
span = property(span) span = property(span)
@ -309,57 +332,72 @@ class TextObject(object):
return self._end return self._end
end = property(end) end = property(end)
def abs_span(self):
return Span(self.abs_start, self.abs_end)
abs_span = property(abs_span)
#################### ####################
# Public functions # # Public functions #
#################### ####################
def child_end_moved(self, sp, diff, skip): # TODO: pretty wasteful, give index # TODO: This really only is called when a child has shortened
def child_end_moved2(self, old_end, new_end): # TODO: pretty wasteful, give index
if not (self._parent) or old_end == new_end:
return
debug("###*** ")
assert(self._parent)
_do_print(self._parent)
pold_end = self._parent._end.copy()
_move_nocheck(self._parent._end, old_end, new_end, new_end - old_end)
def _move_all(o):
_move_nocheck(o._start, old_end, new_end, new_end - old_end)
_move_nocheck(o._end, old_end, new_end, new_end - old_end)
for oc in o._childs:
_move_all(oc)
for c in self._parent._childs:
if c is self: continue
_move_all(c)
_do_print(self._parent)
debug("***### ")
debug("pold_end: %r, self._parent._end: %r" % (pold_end, self._parent._end))
self._parent.child_end_moved2(pold_end, self._parent._end)
def child_end_moved(self, sp, diff, skip = set()): # TODO: pretty wasteful, give index
debug("self: %r, skip: %r, diff: %r" % (self, skip, diff)) debug("self: %r, skip: %r, diff: %r" % (self, skip, diff))
def _move_start(obj):
if obj.abs_start.line == sp.line and obj.abs_start.col >= sp.col:
obj._start.line += diff.line
obj._start.col += diff.col
elif obj.abs_start.line > sp.line:
obj._start.line += diff.line
def _move_end(obj):
if obj.abs_end.line == sp.line and obj.abs_end.col >= sp.col:
obj._end.line += diff.line
obj._end.col += diff.col
elif obj.abs_end.line > sp.line:
obj._end.line += diff.line
if self not in skip: if self not in skip:
_move_end(self) _move(self._end, sp, diff)
for c in self._childs: for c in self._childs:
if c in skip: continue if c in skip: continue
debug(" c: %r" % (c)) def _move_all(o):
debug(" b4: c.abs_span: %r" % (c.abs_span)) _move(o._start, sp, diff)
_move_start(c) _move(o._end, sp, diff)
_move_end(c)
debug(" a4: c.abs_span: %r" % (c.abs_span))
for oc in o._childs:
_move_all(oc)
_move_all(c)
debug("self._parent: %r" % (self._parent))
if self._parent and self._parent not in skip: if self._parent and self._parent not in skip:
debug("b4 parent sp: %r, diff: %r" % (sp, diff))
self._parent.child_end_moved(sp, diff, set((self,))) self._parent.child_end_moved(sp, diff, set((self,)))
debug("after parent sp: %r, diff: %r" % (sp, diff))
def _do_edit(self, cmd): def _do_edit(self, cmd):
debug("self: %r, cmd: %r" % (self, cmd)) debug("self: %r, cmd: %r" % (self, cmd))
debug("self._childs: %r" % (self._childs))
ctype, line, col, char = cmd ctype, line, col, char = cmd
debug("char: %r" % (char))
assert( ('\n' not in char) or (char == "\n")) assert( ('\n' not in char) or (char == "\n"))
pos = Position(line, col) pos = Position(line, col)
to_kill = set() to_kill = set()
for c in self._childs: for c in self._childs:
abs_start = c.abs_start start = c._start
abs_end = c.abs_end end = c._end
if ctype == "D": if ctype == "D":
if char == "\n": if char == "\n":
@ -368,31 +406,31 @@ class TextObject(object):
end_pos = pos + Position(0, len(char)) end_pos = pos + Position(0, len(char))
# TODO: char is no longer true -> Text # TODO: char is no longer true -> Text
# Case: this deletion removes the child # Case: this deletion removes the child
if (pos < abs_start and end_pos >= abs_end): if (pos < start and end_pos >= end):
debug("Case 1") debug(" Case 1")
to_kill.add(c) to_kill.add(c)
# Case: this edit command is completely for the child # Case: this edit command is completely for the child
elif (abs_start <= pos <= abs_end) and (abs_start <= end_pos <= abs_end): elif (start <= pos <= end) and (start <= end_pos <= end):
debug("Case 2") debug(" Case 2")
if not isinstance(c, TabStop): # Erasing inside NonTabstop -> Kill element if not isinstance(c, TabStop): # Erasing inside NonTabstop -> Kill element
to_kill.add(c) to_kill.add(c)
continue continue
c._do_edit(cmd) c._do_edit(cmd)
return return
# Case: partially for us, partially for the child # Case: partially for us, partially for the child
elif (pos < abs_start and (abs_start < end_pos <= abs_end)): elif (pos < start and (start < end_pos <= end)):
debug("Case 3") debug(" Case 3")
my_text = char[:(abs_start-pos).col] my_text = char[:(start-pos).col]
c_text = char[(abs_start-pos).col:] c_text = char[(start-pos).col:]
debug(" my_text: %r" % (my_text)) debug(" my_text: %r" % (my_text))
debug(" c_text: %r" % (c_text)) debug(" c_text: %r" % (c_text))
self._do_edit((ctype, line, col, my_text)) self._do_edit((ctype, line, col, my_text))
self._do_edit((ctype, line, col, c_text)) self._do_edit((ctype, line, col, c_text))
return return
elif (end_pos >= abs_end and (abs_start <= pos < abs_end)): elif (end_pos >= end and (start <= pos < end)):
debug("Case 4") debug(" Case 4")
c_text = char[(abs_end-pos).col:] c_text = char[(end-pos).col:]
my_text = char[:(abs_end-pos).col] my_text = char[:(end-pos).col]
debug(" c_text: %r" % (c_text)) debug(" c_text: %r" % (c_text))
debug(" my_text: %r" % (my_text)) debug(" my_text: %r" % (my_text))
self._do_edit((ctype, line, col, c_text)) self._do_edit((ctype, line, col, c_text))
@ -403,57 +441,43 @@ class TextObject(object):
if ctype == "I": if ctype == "I":
if not isinstance(c, TabStop): # TODO: make this nicer if not isinstance(c, TabStop): # TODO: make this nicer
continue continue
if (abs_start <= pos <= abs_end): if (start <= pos <= end):
c._do_edit(cmd) c._do_edit(cmd)
return return
for c in to_kill: for c in to_kill:
debug("Kill c: %r" % (c)) debug(" Kill c: %r" % (c))
self._del_child(c) self._del_child(c)
# We have to handle this ourselves # We have to handle this ourselves
sp = self.abs_start # TODO
def _move_end(obj, diff): # TODO: this is code duplication, the other one is buggy!
if obj.abs_end < sp: return
if delta.line >= 0:
if obj.abs_end.line == sp.line:
obj._end.col += diff.col
obj._end.line += diff.line
else:
obj._end.line += diff.line
if obj.abs_end.line == sp.line:
obj._end.col += diff.col
if ctype == "D": # TODO: code duplication if ctype == "D": # TODO: code duplication
assert(self.abs_start != self.abs_end) # Makes no sense to delete in empty textobject assert(self._start != self._end) # Makes no sense to delete in empty textobject
if char == "\n": if char == "\n":
delta = Position(-1, col) # TODO: this feels somehow incorrect: delta = Position(-1, col) # TODO: this feels somehow incorrect:
else: else:
delta = Position(0, -len(char)) delta = Position(0, -len(char))
_move_end(self, delta)
self.child_end_moved(self.abs_end, delta, set((self,)))
else: else:
old_end = self.abs_end
if char == "\n": if char == "\n":
delta = Position(1, -col) # TODO: this feels somehow incorrect delta = Position(1, -col) # TODO: this feels somehow incorrect
else: else:
delta = Position(0, len(char)) delta = Position(0, len(char))
_move_end(self, delta) old_end = self._end.copy()
_move(self._end, Position(line, col), delta)
#self.child_end_moved(Position(line, col), self._end - old_end, set((self,)))
self.child_end_moved2(old_end, self._end)
self.child_end_moved(old_end, delta, set((self,))) def edited(self, cmds): # TODO: Only in SnippetInstance
def edited(self, cmds):
assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0) assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0)
debug("begin: self.current_text: %r" % (self.current_text)) debug("begin: self.current_text: %r" % (self.current_text))
debug("self.abs_start: %r, self.abs_end: %r" % (self.abs_start, self.abs_end)) debug("self._start: %r, self._end: %r" % (self._start, self._end))
# Replay User Edits to update end of our current texts # Replay User Edits to update end of our current texts
for cmd in cmds: for cmd in cmds:
self._do_edit(cmd) self._do_edit(cmd)
def do_edits(self): _do_print(self)
def do_edits(self): # TODO: only in snippets instance
debug("In do_edits") debug("In do_edits")
# Do our own edits; keep track of the Cursor # Do our own edits; keep track of the Cursor
vc = VimCursor(self) vc = VimCursor(self)
@ -473,9 +497,7 @@ class TextObject(object):
assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0) assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0)
debug("self._childs: %r" % (self._childs)) debug("self._childs: %r" % (self._childs))
debug("end: self.current_text: %r" % (self.current_text)) _do_print(self)
debug("self.abs_start: %r, self.abs_end: %r" % (self.abs_start, self.abs_end))
debug("self._childs: %r" % (self._childs))
def update(self): def update(self):
@ -635,14 +657,6 @@ class VimCursor(TextObject):
def __repr__(self): def __repr__(self):
return "VimCursor(%r)" % (self._start) return "VimCursor(%r)" % (self._start)
@property # TODO: remove those again
def abs_start(self):
return self._start
@property
def abs_end(self):
return self._end
# TODO: Maybe DependantTextObject which can't be edited and can be killed # TODO: Maybe DependantTextObject which can't be edited and can be killed
class Mirror(TextObject): class Mirror(TextObject):
""" """
@ -664,22 +678,22 @@ class Mirror(TextObject):
tb = TextBuffer(self._ts.current_text) tb = TextBuffer(self._ts.current_text)
debug("new_text, self: %r" % (self)) debug("new_text, self: %r" % (self))
debug("self.abs_start: %r, self.abs_end: %r, self.current_text: %r" % (self.abs_start, self.abs_end, self.current_text)) debug("tb: %r" % (tb))
debug("self._start: %r, self._end: %r, self.current_text: %r" % (self._start, self._end, self.current_text))
# TODO: initial replace does not need to take an argument # TODO: initial replace does not need to take an argument
old_end = self.abs_end old_end = self._end
tb.to_vim(self.abs_start, self.abs_end) # TODO: to vim returns something unused tb.to_vim(self._start, self._end) # TODO: to vim returns something unused
debug("self.abs_end: %r" % (self.abs_end)) new_end = tb.calc_end(self._start)
self._end = tb.calc_end(self._start) self._end = new_end
debug("self.abs_start: %r, self.abs_end: %r" % (self.abs_start, self.abs_end)) if new_end != old_end:
if self.abs_end != old_end:
# TODO: child_end_moved is a stupid name for this function # TODO: child_end_moved is a stupid name for this function
self.child_end_moved(old_end, self.abs_end - old_end, set((self,))) self.child_end_moved2(old_end, new_end)
if self._ts._is_killed: if self._ts._is_killed:
self._parent._del_child(self) self._parent._del_child(self)
def __repr__(self): def __repr__(self):
return "Mirror(%s -> %s)" % (self.abs_start, self.abs_end) return "Mirror(%s -> %s, %r)" % (self._start, self._end, self.current_text)
class Visual(TextObject): class Visual(TextObject):
""" """
@ -994,7 +1008,7 @@ class TabStop(TextObject):
# TODO: none of the _repr_ must access _current_text # TODO: none of the _repr_ must access _current_text
def __repr__(self): def __repr__(self):
return "TabStop(%i, %s -> %s, %s)" % (self._no, self.abs_start, self.abs_end, return "TabStop(%i, %s -> %s, %s)" % (self._no, self._start, self._end,
repr(self.current_text)) repr(self.current_text))
class SnippetInstance(TextObject): class SnippetInstance(TextObject):
@ -1019,8 +1033,10 @@ class SnippetInstance(TextObject):
_TOParser(self, initial_text, indent).parse(True) _TOParser(self, initial_text, indent).parse(True)
_do_print(self)
def __repr__(self): def __repr__(self):
return "SnippetInstance(%s -> %s)" % (self._start, self._end) return "SnippetInstance(%s -> %s, %r)" % (self._start, self._end, self.current_text)
def _get_tabstop(self, requester, no): def _get_tabstop(self, requester, no):
# SnippetInstances are completely self contained, therefore, we do not # SnippetInstances are completely self contained, therefore, we do not

View File

@ -805,7 +805,7 @@ class SnippetManager(object):
debug("lt: %r, ct: %r" % (lt, ct)) debug("lt: %r, ct: %r" % (lt, ct))
rv = edit_distance.edit_script(lt, ct, abs_start.line, abs_start.col) rv = edit_distance.edit_script(lt, ct, abs_start.line, abs_start.col)
debug("rv: %r" % (rv,)) debug("edit_script: %r" % (rv,))
self._csnippets[0].edited(rv) self._csnippets[0].edited(rv)
self._check_if_still_inside_snippet() self._check_if_still_inside_snippet()
@ -866,8 +866,8 @@ class SnippetManager(object):
# Did we leave the snippet with this movement? # Did we leave the snippet with this movement?
if self._cs: if self._cs:
debug("self._vstate.pos: %r, self._cs.abs_span: %r" % (self._vstate.pos, self._cs.abs_span)) debug("self._vstate.pos: %r, self._cs.span: %r" % (self._vstate.pos, self._cs.span))
if self._cs and not (self._vstate.pos in self._cs.abs_span): if self._cs and not (self._vstate.pos in self._cs.span):
self._current_snippet_is_done() self._current_snippet_is_done()
self._reinit() self._reinit()
@ -887,9 +887,9 @@ class SnippetManager(object):
if self._cs: if self._cs:
self._ctab = self._cs.select_next_tab(backwards) self._ctab = self._cs.select_next_tab(backwards)
debug("self._ctab: %r" % (self._ctab)) debug("self._ctab: %r" % (self._ctab))
debug("self._ctab.abs_span: %r" % (self._ctab.abs_span)) debug("self._ctab.span: %r" % (self._ctab.span))
if self._ctab: if self._ctab:
self._vstate.select_span(self._ctab.abs_span) self._vstate.select_span(self._ctab.span)
jumped = True jumped = True
if self._ctab.no == 0: if self._ctab.no == 0:
self._current_snippet_is_done() self._current_snippet_is_done()

View File

@ -164,14 +164,14 @@ class TestNoSubstring(_Base, unittest.TestCase):
) )
# TODO: quote the correct paper # TODO: quote the correct paper
# #
class TestPaperExample(_Base, unittest.TestCase): # class TestPaperExample(_Base, unittest.TestCase):
a,b = "abcabba", "cbabac" # a,b = "abcabba", "cbabac"
wanted = ( # wanted = (
("D", 0, 0, "ab"), # ("D", 0, 0, "ab"),
("I", 0, 1, "b"), # ("I", 0, 1, "b"),
("D", 0, 4, "b"), # ("D", 0, 4, "b"),
("I", 0, 5, "c"), # ("I", 0, 5, "c"),
) # )
class TestCommonCharacters(_Base, unittest.TestCase): class TestCommonCharacters(_Base, unittest.TestCase):
a,b = "hasomelongertextbl", "hol" a,b = "hasomelongertextbl", "hol"
@ -206,6 +206,18 @@ class MatchIsTooCheap(_Base, unittest.TestCase):
("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"
wanted = (
("D", 1, 12, "first line"),
("D", 1, 12, "\n"),
("D", 1, 12, "second line"),
("I", 1, 12, "k"),
)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# k = TestEditScript() # k = TestEditScript()

22
test.py
View File

@ -1305,17 +1305,17 @@ class TabstopWithMirrorInDefaultNoOverwrite1_ExceptCorrectResult(_VimTest):
keys = "test" + EX + "stdin" + JF + JF + "end" keys = "test" + EX + "stdin" + JF + JF + "end"
wanted = "ha stdin stdinend" wanted = "ha stdin stdinend"
##class MirrorRealLifeExample_ExceptCorrectResult(_VimTest): class MirrorRealLifeExample_ExceptCorrectResult(_VimTest):
## snippets = ( snippets = (
## ("for", "for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})" \ ("for", "for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})" \
## "\n{\n\t${0:/* code */}\n}"), "\n{\n\t${0:/* code */}\n}"),
## ) )
## keys ="for" + EX + "100" + JF + "avar\b\b\b\ba_variable" + JF + \ keys ="for" + EX + "100" + JF + "avar\b\b\b\ba_variable" + JF + \
## "a_variable *= 2" + JF + "// do nothing" "a_variable *= 2" + JF + "// do nothing"
## wanted = """for(size_t a_variable = 0; a_variable < 100; a_variable *= 2) wanted = """for(size_t a_variable = 0; a_variable < 100; a_variable *= 2)
##{ {
##\t// do nothing \t// do nothing
##}""" }"""
### End: Mirrors #}}} ### End: Mirrors #}}}
### Transformations {{{# ### Transformations {{{#
##class Transformation_SimpleCase_ExceptCorrectResult(_VimTest): ##class Transformation_SimpleCase_ExceptCorrectResult(_VimTest):