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()
|
||||
|
||||
if self._csnippets:
|
||||
abs_end = self._vstate.pos
|
||||
abs_start = self._vstate.ppos
|
||||
if abs_end < abs_start:
|
||||
abs_start, abs_end = abs_end, abs_start
|
||||
abs_start = Position(0,0) # TODO
|
||||
abs_end = Position(len(vim.current.buffer)-1, 10000)
|
||||
span = Span(abs_start, abs_end)
|
||||
ct = map(as_unicode, vim.current.buffer)
|
||||
lt = map(as_unicode, self._lvb[:])
|
||||
lt_span, ct_span = edit_distance.line_diffs(lt, ct)
|
||||
debug("lt: %r" % (lt))
|
||||
debug("ct: %r" % (ct))
|
||||
debug("lt_span: %r, ct_span: %r" % (lt_span, ct_span))
|
||||
|
||||
# TODO
|
||||
# ct = TextBuffer('\n'.join(vim.current.buffer))[span]
|
||||
# lt = self._lvb[span]
|
||||
ct = as_unicode('\n').join(map(as_unicode, vim.current.buffer))
|
||||
lt = as_unicode(self._lvb)
|
||||
# start_line = min(self._vstate.pos.line, self._vstate.ppos.line)
|
||||
# ct = as_unicode('\n').join(map(as_unicode, vim.current.buffer[start_line:]))
|
||||
# lt = as_unicode('\n').join(self._lvb[start_line:])
|
||||
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._check_if_still_inside_snippet()
|
||||
|
@ -7,11 +7,66 @@ import sys
|
||||
|
||||
# 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)
|
||||
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
|
||||
cost = 0
|
||||
@ -23,7 +78,7 @@ def edit_script(a, b, sline = 0, scol = 0):
|
||||
#print "%r: %r" % (cost, sumarized)
|
||||
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)
|
||||
return what
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user