Become a little smarter about the area that actually changed in an edit
This commit is contained in:
parent
7e05d49bce
commit
a483218f70
@ -794,21 +794,23 @@ class SnippetManager(object):
|
|||||||
self._vstate.update()
|
self._vstate.update()
|
||||||
|
|
||||||
if self._csnippets:
|
if self._csnippets:
|
||||||
abs_end = self._vstate.pos
|
ct = map(as_unicode, vim.current.buffer)
|
||||||
abs_start = self._vstate.ppos
|
lt = map(as_unicode, self._lvb[:])
|
||||||
if abs_end < abs_start:
|
lt_span, ct_span = edit_distance.line_diffs(lt, ct)
|
||||||
abs_start, abs_end = abs_end, abs_start
|
debug("lt: %r" % (lt))
|
||||||
abs_start = Position(0,0) # TODO
|
debug("ct: %r" % (ct))
|
||||||
abs_end = Position(len(vim.current.buffer)-1, 10000)
|
debug("lt_span: %r, ct_span: %r" % (lt_span, ct_span))
|
||||||
span = Span(abs_start, abs_end)
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# ct = TextBuffer('\n'.join(vim.current.buffer))[span]
|
# start_line = min(self._vstate.pos.line, self._vstate.ppos.line)
|
||||||
# lt = self._lvb[span]
|
# ct = as_unicode('\n').join(map(as_unicode, vim.current.buffer[start_line:]))
|
||||||
ct = as_unicode('\n').join(map(as_unicode, vim.current.buffer))
|
# lt = as_unicode('\n').join(self._lvb[start_line:])
|
||||||
lt = as_unicode(self._lvb)
|
lt = '\n'.join(lt[lt_span[0]:lt_span[1]+1])
|
||||||
|
ct = '\n'.join(ct[ct_span[0]:ct_span[1]+1])
|
||||||
|
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, min(lt_span[0], ct_span[0]))
|
||||||
|
debug("rv: %r" % (rv,))
|
||||||
self._csnippets[0].edited(rv)
|
self._csnippets[0].edited(rv)
|
||||||
|
|
||||||
self._check_if_still_inside_snippet()
|
self._check_if_still_inside_snippet()
|
||||||
|
@ -7,11 +7,66 @@ import sys
|
|||||||
|
|
||||||
# TODO: check test cases here. They are not up to date
|
# TODO: check test cases here. They are not up to date
|
||||||
|
|
||||||
def edit_script(a, b, sline = 0, scol = 0):
|
from .debug import debug
|
||||||
|
|
||||||
|
def line_diffs(a, b, sline = 0):
|
||||||
d = defaultdict(list)
|
d = defaultdict(list)
|
||||||
seen = defaultdict(lambda: sys.maxint)
|
seen = defaultdict(lambda: sys.maxint)
|
||||||
|
|
||||||
d[0] = [ (0,0,sline,scol, ()) ]
|
d[0] = [ (0,0,sline, ()) ]
|
||||||
|
cost = 0
|
||||||
|
while True:
|
||||||
|
while len(d[cost]):
|
||||||
|
x, y, line, what = d[cost].pop()
|
||||||
|
|
||||||
|
if x == len(a) and y == len(b):
|
||||||
|
# Find first span of changes in both buffers
|
||||||
|
x_min, x_max = sys.maxint, -sys.maxint
|
||||||
|
y_min, y_max = sys.maxint, -sys.maxint
|
||||||
|
debug("what: %r" % (what,))
|
||||||
|
for cmd,x,y in what:
|
||||||
|
if cmd == 'D':
|
||||||
|
x_min = min(x_min, x)
|
||||||
|
x_max = max(x_max, x)
|
||||||
|
elif cmd == 'I':
|
||||||
|
x_max = max(x_max, x-1 if x > 0 else 0)
|
||||||
|
x_min = min(x_min, x-1 if x > 0 else 0)
|
||||||
|
# y_min = min(y_min, line)
|
||||||
|
y_min = min(y_min, y-1 if y > 0 else 0)
|
||||||
|
y_max = max(y_max, y)
|
||||||
|
elif cmd == "M":
|
||||||
|
x_min = min(x_min, x)
|
||||||
|
x_max = max(x_max, x)
|
||||||
|
y_min = min(y_min, y)
|
||||||
|
y_max = max(y_max, y)
|
||||||
|
|
||||||
|
return (x_min, x_max), (y_min, y_max)
|
||||||
|
|
||||||
|
# TODO: line == y
|
||||||
|
if x < len(a) and y < len(b) and len(a[x]) == len(b[y]) and \
|
||||||
|
a[x] == b[y]: # Equal lines
|
||||||
|
if seen[x+1,y+1] > cost:
|
||||||
|
seen[x+1,y+1] = cost
|
||||||
|
if x != y:
|
||||||
|
d[cost].append((x+1,y+1,line+1, what + (('M', x,y),))) # TODO: match only debug
|
||||||
|
else:
|
||||||
|
d[cost].append((x+1,y+1,line+1, what)) # TODO: match only debug
|
||||||
|
if x < len(a): # Delete
|
||||||
|
if seen[x+1,y] > cost + 1 + x:
|
||||||
|
seen[x+1,y] = cost + 1 + x
|
||||||
|
d[cost+1+x].append((x+1,y, line, what + (('D', x, y),)))
|
||||||
|
if y < len(b): # Insert
|
||||||
|
if seen[x,y+1] > cost + 1 + y:
|
||||||
|
seen[x,y+1] = cost + 1 + y
|
||||||
|
d[cost+1+y].append((x,y+1,line+1, what + (('I', x, y),)))
|
||||||
|
cost += 1
|
||||||
|
|
||||||
|
|
||||||
|
def edit_script(a, b, sline = 0):
|
||||||
|
d = defaultdict(list)
|
||||||
|
seen = defaultdict(lambda: sys.maxint)
|
||||||
|
|
||||||
|
d[0] = [ (0,0,sline, 0, ()) ]
|
||||||
|
|
||||||
# TODO: needs some doku
|
# TODO: needs some doku
|
||||||
cost = 0
|
cost = 0
|
||||||
@ -23,7 +78,7 @@ def edit_script(a, b, sline = 0, scol = 0):
|
|||||||
#print "%r: %r" % (cost, sumarized)
|
#print "%r: %r" % (cost, sumarized)
|
||||||
x, y, line, col, what = d[cost].pop()
|
x, y, line, col, what = d[cost].pop()
|
||||||
|
|
||||||
if a[x:] == b[y:]: ## TODO: try out is
|
if a[x:] == b[y:]:
|
||||||
#print "cost: %r" % (cost)
|
#print "cost: %r" % (cost)
|
||||||
return what
|
return what
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user