More mirror tests

This commit is contained in:
Holger Rapp 2012-01-17 13:48:01 +01:00
parent 994074d920
commit b057d6332e
3 changed files with 116 additions and 94 deletions

View File

@ -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

View File

@ -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
View File

@ -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