More mirror tests
This commit is contained in:
parent
994074d920
commit
b057d6332e
@ -152,8 +152,7 @@ class _TOParser(object):
|
||||
seen_ts[token.no] = ts
|
||||
parent._add_tabstop(ts)
|
||||
else:
|
||||
m = Mirror(parent, token)
|
||||
seen_ts[token.no].add_referencer(m)
|
||||
Mirror(parent, seen_ts[token.no], token)
|
||||
|
||||
def _create_objects_with_links_to_tabs(self, all_tokens, seen_ts):
|
||||
for parent, token in all_tokens:
|
||||
@ -163,17 +162,22 @@ class _TOParser(object):
|
||||
Transformation(parent, seen_ts[token.no], token)
|
||||
|
||||
def _replace_initital_texts(self, seen_ts):
|
||||
def _do_it(obj):
|
||||
debug("In _do_it: obj: %r" % (obj))
|
||||
def _place_initial_text(obj):
|
||||
debug("In _place_initial_text: obj: %r" % (obj))
|
||||
obj.initial_replace()
|
||||
|
||||
for c in obj._childs: # TODO: private parts!
|
||||
_do_it(c)
|
||||
_place_initial_text(c)
|
||||
|
||||
_do_it(self._parent_to)
|
||||
_place_initial_text(self._parent_to)
|
||||
|
||||
for ts in seen_ts.values():
|
||||
ts.update_referencers()
|
||||
def _update_non_tabstops(obj): # TODO: Stupid function name
|
||||
obj._really_updateman()
|
||||
|
||||
for c in obj._childs:
|
||||
_update_non_tabstops(c)
|
||||
|
||||
_update_non_tabstops(self._parent_to)
|
||||
|
||||
def _do_parse(self, all_tokens, seen_ts):
|
||||
tokens = list(tokenize(self._text, self._indent))
|
||||
@ -364,7 +368,7 @@ class TextObject(object):
|
||||
end_pos = pos + Position(0, len(char))
|
||||
# TODO: char is no longer true -> Text
|
||||
# Case: this deletion removes the child
|
||||
if (pos <= abs_start and end_pos > abs_end):
|
||||
if (pos < abs_start and end_pos >= abs_end):
|
||||
debug("Case 1")
|
||||
to_kill.add(c)
|
||||
# Case: this edit command is completely for the child
|
||||
@ -443,14 +447,13 @@ class TextObject(object):
|
||||
vc = VimCursor(self)
|
||||
assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 1)
|
||||
# Update all referers # TODO: maybe in a function of its own
|
||||
def _do_it(obj):
|
||||
if isinstance(obj, TabStop):
|
||||
obj.update_referencers()
|
||||
def _update_non_tabstops(obj): # TODO: stupid functon name
|
||||
obj._really_updateman()
|
||||
|
||||
for c in obj._childs:
|
||||
_do_it(c)
|
||||
_update_non_tabstops(c)
|
||||
|
||||
_do_it(self)
|
||||
_update_non_tabstops(self)
|
||||
|
||||
#debug("self._childs: %r, vc: %r" % (self._childs, vc))
|
||||
vc.update_position()
|
||||
@ -491,6 +494,7 @@ class TextObject(object):
|
||||
# return new_end
|
||||
|
||||
def _get_next_tab(self, no):
|
||||
debug("_get_next_tab: self: %r, no: %r" % (self, no))
|
||||
if not len(self._tabstops.keys()):
|
||||
return
|
||||
tno_max = max(self._tabstops.keys())
|
||||
@ -540,7 +544,7 @@ class TextObject(object):
|
||||
###############################
|
||||
# Private/Protected functions #
|
||||
###############################
|
||||
def _do_update(self):
|
||||
def _really_updateman(self): # TODO:
|
||||
pass
|
||||
|
||||
# def _move_textobjects_behind(self, start, end, lines, cols, obj_idx):
|
||||
@ -632,10 +636,21 @@ class Mirror(TextObject):
|
||||
"""
|
||||
A Mirror object mirrors a TabStop that is, text is repeated here
|
||||
"""
|
||||
def new_text(self, tb): # TODO: function has a stupid name
|
||||
if self._is_killed:
|
||||
return
|
||||
def __init__(self, parent, tabstop, token):
|
||||
TextObject.__init__(self, parent, token)
|
||||
|
||||
self._ts = tabstop
|
||||
|
||||
def _really_updateman(self): # TODO: function has a stupid name
|
||||
# TODO: this function will get called to often. It should
|
||||
# check if a replacement is really needed
|
||||
assert(not self._is_killed)
|
||||
|
||||
if self._ts._is_killed:
|
||||
tb = TextBuffer("")
|
||||
else:
|
||||
|
||||
tb = TextBuffer(self._ts.current_text)
|
||||
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))
|
||||
# TODO: initial replace does not need to take an argument
|
||||
@ -648,6 +663,9 @@ class Mirror(TextObject):
|
||||
# TODO: child_end_moved is a stupid name for this function
|
||||
self.child_end_moved(old_end, self.abs_end - old_end, set((self,)))
|
||||
|
||||
if self._ts._is_killed:
|
||||
self._parent._del_child(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "Mirror(%s -> %s)" % (self.abs_start, self.abs_end)
|
||||
|
||||
@ -951,8 +969,6 @@ class TabStop(TextObject):
|
||||
comes to rest when the user taps through the Snippet.
|
||||
"""
|
||||
def __init__(self, parent, token, start = None, end = None):
|
||||
self._referencer = []
|
||||
|
||||
if start is not None:
|
||||
self._no = token
|
||||
TextObject.__init__(self, parent, start, end)
|
||||
@ -960,16 +976,6 @@ class TabStop(TextObject):
|
||||
TextObject.__init__(self, parent, token)
|
||||
self._no = token.no
|
||||
|
||||
def update_referencers(self):
|
||||
for r in self._referencer:
|
||||
debug("r: %r" % (r))
|
||||
debug("self.current_text: %r" % (self.current_text))
|
||||
r.new_text(TextBuffer(self.current_text))
|
||||
|
||||
def add_referencer(self, r):
|
||||
self._referencer.append(r)
|
||||
self._referencer.sort()
|
||||
|
||||
def no(self):
|
||||
return self._no
|
||||
no = property(no)
|
||||
@ -1015,6 +1021,7 @@ class SnippetInstance(TextObject):
|
||||
return rv
|
||||
|
||||
def select_next_tab(self, backwards = False):
|
||||
debug("select_next_tab: self: %r, self._cts: %r" % (self, self._cts))
|
||||
if self._cts is None:
|
||||
return
|
||||
|
||||
|
@ -5,6 +5,8 @@ import heapq # TODO: overkill. Bucketing is better
|
||||
from collections import defaultdict
|
||||
import sys
|
||||
|
||||
# TODO: check test cases here. They are not up to date
|
||||
|
||||
def edit_script(a, b, sline = 0, scol = 0):
|
||||
d = defaultdict(list)
|
||||
seen = defaultdict(lambda: sys.maxint)
|
||||
@ -13,7 +15,8 @@ def edit_script(a, b, sline = 0, scol = 0):
|
||||
|
||||
# TODO: needs some doku
|
||||
cost = 0
|
||||
DI_COST = len(a)+len(b)
|
||||
D_COST = len(a)+len(b)
|
||||
I_COST = len(a)+len(b)
|
||||
while True:
|
||||
while len(d[cost]):
|
||||
#sumarized = [ compactify(what) for c, x, line, col, what in d[cost] ] # TODO: not needed
|
||||
@ -30,9 +33,14 @@ def edit_script(a, b, sline = 0, scol = 0):
|
||||
if a[x] == '\n':
|
||||
ncol = 0
|
||||
nline +=1
|
||||
if seen[x+1,y+1] > cost + 1:
|
||||
d[cost+1].append((x+1,y+1, nline, ncol, what)) # TODO: slow!
|
||||
seen[x+1,y+1] = cost + 1
|
||||
lcost = cost + 1
|
||||
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 = (D_COST + I_COST)*1.5
|
||||
if seen[x+1,y+1] > lcost:
|
||||
d[lcost].append((x+1,y+1, nline, ncol, what)) # TODO: slow!
|
||||
seen[x+1,y+1] = lcost
|
||||
|
||||
if y < len(b): # INSERT
|
||||
ncol = col + 1
|
||||
@ -42,24 +50,24 @@ def edit_script(a, b, sline = 0, scol = 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 + (DI_COST + ncol) // 2
|
||||
seen[x,y+1] > cost + (I_COST + ncol) // 2
|
||||
):
|
||||
seen[x,y+1] = cost + (DI_COST + ncol) // 2
|
||||
d[cost + (DI_COST + ncol) // 2].append((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 + DI_COST + ncol:
|
||||
seen[x,y+1] = cost + DI_COST + ncol
|
||||
d[cost + ncol + DI_COST].append((x,y+1, nline, ncol, what + (("I", line, col,b[y]),)))
|
||||
seen[x,y+1] = cost + (I_COST + ncol) // 2
|
||||
d[cost + (I_COST + ncol) // 2].append((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 + I_COST + ncol:
|
||||
seen[x,y+1] = cost + I_COST + ncol
|
||||
d[cost + ncol + I_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
|
||||
seen[x+1,y] > cost + DI_COST // 2
|
||||
seen[x+1,y] > cost + D_COST // 2
|
||||
):
|
||||
seen[x+1,y] = cost + DI_COST // 2
|
||||
d[cost + DI_COST // 2].append((x+1,y, line, col, what[:-1] + (("D",line, col, what[-1][-1] + a[x]),) ))
|
||||
elif seen[x+1,y] > cost + DI_COST:
|
||||
seen[x+1,y] = cost + DI_COST
|
||||
d[cost + DI_COST].append((x+1,y, line, col, what + (("D",line, col, a[x]),) ))
|
||||
seen[x+1,y] = cost + D_COST // 2
|
||||
d[cost + D_COST // 2].append((x+1,y, line, col, what[:-1] + (("D",line, col, what[-1][-1] + a[x]),) ))
|
||||
elif seen[x+1,y] > cost + D_COST:
|
||||
seen[x+1,y] = cost + D_COST
|
||||
d[cost + D_COST].append((x+1,y, line, col, what + (("D",line, col, a[x]),) ))
|
||||
cost += 1
|
||||
|
||||
def transform(a, cmds):
|
||||
@ -150,6 +158,13 @@ class TestPaperExample(_Base, unittest.TestCase):
|
||||
("I", 0, 5, "c"),
|
||||
)
|
||||
|
||||
class TestCommonCharacters(_Base, unittest.TestCase):
|
||||
a,b = "hasomelongertextbl", "hol"
|
||||
wanted = (
|
||||
("D", 0, 1, "asomelongertextb"),
|
||||
("I", 0, 1, "o"),
|
||||
)
|
||||
|
||||
class TestSKienaExample(_Base, unittest.TestCase):
|
||||
a, b = "thou shalt not", "you should not"
|
||||
wanted = (
|
||||
@ -173,8 +188,7 @@ class MatchIsTooCheap(_Base, unittest.TestCase):
|
||||
a = "stdin.h"
|
||||
b = "s"
|
||||
wanted = (
|
||||
("D", 0, 0, "stdin.h"),
|
||||
("I", 0, 0, "s"),
|
||||
("D", 0, 1, "tdin.h"),
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
93
test.py
93
test.py
@ -735,52 +735,53 @@ class TabStop_TSInDefaultText_ZeroLengthNested_OverwriteSecondJumpBackAndForward
|
||||
wanted = """halongertextblEnd"""
|
||||
|
||||
# TODO: Test for Python where initial text is longer than python code. Might lead to problems
|
||||
##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"
|
||||
##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"
|
||||
##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"
|
||||
##
|
||||
##class TabStop_TSInDefault_MirrorsOutside_DoNothing(_VimTest):
|
||||
## 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"
|
||||
##class TabStop_TSInDefault_MirrorsOutside_Overwrite(_VimTest):
|
||||
## 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 "
|
||||
##class TabStop_TSInDefault_MirrorsOutside_OverwriteSecond1(_VimTest):
|
||||
## 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"
|
||||
## 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"
|
||||
##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"
|
||||
## wanted = "world = require('WORLD')End"
|
||||
##
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
|
||||
class TabStop_TSInDefault_MirrorsOutside_DoNothing(_VimTest):
|
||||
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"
|
||||
class TabStop_TSInDefault_MirrorsOutside_Overwrite0(_VimTest):
|
||||
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 "
|
||||
class TabStop_TSInDefault_MirrorsOutside_OverwriteSecond1(_VimTest):
|
||||
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"
|
||||
wanted = "'Hallo': 'Hallo' Hallo"
|
||||
# TODO: these tests have python in them
|
||||
# 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"
|
||||
# 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"
|
||||
# wanted = "world = require('WORLD')End"
|
||||
|
||||
##class TabStop_Multiline_Leave(_VimTest):
|
||||
## snippets = ("test", "hi ${1:first line\nsecond line} world" )
|
||||
## keys = "test" + EX
|
||||
|
Loading…
x
Reference in New Issue
Block a user