First hooks into vim. Very slow atm

This commit is contained in:
Holger Rapp 2012-01-15 17:36:39 +01:00
parent 96f4068329
commit 3a7674bca0
4 changed files with 115 additions and 72 deletions

View File

@ -1,70 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
import heapq # TODO: overkill. Bucketing is better
from collections import defaultdict
class GridPoint(object):
"""Docstring for GridPoint """
__slots__ = ("parent", "cost",)
def __init__(self, parent, cost):
"""@todo: to be defined
:parent: @todo
:cost: @todo
"""
self._parent = parent
self._cost = cost
def edit_script(a, b):
heap = [ (0,0,0,"") ]
while True:
cost, y, x,what = heapq.heappop(heap)
if x == len(a) and y == len(b):
return what
if x < len(a) and y < len(b) and a[x] == b[y]:
heapq.heappush(heap, (cost, y+1,x+1, what + "M"))
else:
if x < len(a) and y < len(b):
heapq.heappush(heap, (cost + 1, y+1, x+1, what + "S"))
if x < len(a):
heapq.heappush(heap, (cost + 1, y, x+1, what + "D"))
if y < len(b):
heapq.heappush(heap, (cost + 1, y+1, x, what + "I"))
import unittest
class TestEditScript(unittest.TestCase):
def test_empty_string(self):
rv = edit_script("","")
self.assertEqual(rv, "")
def test_all_match(self):
rv = edit_script("abcdef", "abcdef")
self.assertEqual("MMMMMM", rv)
def test_no_substr(self):
rv = edit_script("abc", "def")
self.assertEqual("SSS", rv)
def test_paper_example(self):
rv = edit_script("abcabba","cbabac")
self.assertEqual(rv, "SMDMMDMI")
def test_skiena_example(self):
rv = edit_script("thou shalt not", "you should not")
self.assertEqual(rv, "DSMMMMMISMSMMMM")
if __name__ == '__main__':
unittest.main()
# k = TestEditScript()
# unittest.TextTestRunner().run(k)

View File

@ -200,8 +200,8 @@ exec g:_uspy "UltiSnips_Manager.forward_trigger = vim.eval('g:UltiSnipsJumpForwa
exec g:_uspy "UltiSnips_Manager.backward_trigger = vim.eval('g:UltiSnipsJumpBackwardTrigger')"
au CursorMovedI * call UltiSnips_CursorMoved()
au InsertEnter * call UltiSnips_EnteredInsertMode()
au WinLeave * call UltiSnips_LeavingWindow()
"au InsertEnter * call UltiSnips_EnteredInsertMode()
"au WinLeave * call UltiSnips_LeavingWindow()
call UltiSnips_MapKeys()

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python
# encoding: utf-8
import edit_distance
from debug import debug
from functools import wraps
import glob
import hashlib
@ -650,6 +653,7 @@ class SnippetManager(object):
@err_to_scratch_buffer
def reset(self, test_error=False):
self._lvb = ""
self._test_error = test_error
self._snippets = {}
self._visual_content = as_unicode("")
@ -795,6 +799,11 @@ class SnippetManager(object):
@err_to_scratch_buffer
def cursor_moved(self):
cb = as_unicode('\n'.join(vim.current.buffer))
rv = edit_distance.edit_script(self._lvb, cb)
# debug("rv: %r" % (rv,))
self._lvb = cb
return
self._vstate.update()
if not self._vstate.buf_changed and not self._expect_move_wo_change:

104
plugin/UltiSnips/edit_distance.py Executable file
View File

@ -0,0 +1,104 @@
#!/usr/bin/env python
# encoding: utf-8
import heapq # TODO: overkill. Bucketing is better
from collections import defaultdict
class GridPoint(object):
"""Docstring for GridPoint """
__slots__ = ("parent", "cost",)
def __init__(self, parent, cost):
"""@todo: to be defined
:parent: @todo
:cost: @todo
"""
self._parent = parent
self._cost = cost
def edit_script(a, b):
d = defaultdict(list)
d[0] = [ (0,0,0,0, ()) ]
cost = 0
while True:
while len(d[cost]):
y, x, nline, ncol, what = d[cost].pop()
if x == len(a) and y == len(b):
return what
if x < len(a) and y < len(b) and a[x] == b[y]:
ncol += 1
if a[x] == '\n':
ncol = 0
nline += 1
d[cost].append((y+1,x+1, nline, ncol, what))
else:
if x < len(a):
d[cost + 1].append((y,x+1, nline, ncol, what + (("D",nline, ncol),) ))
if y < len(b):
oline, ocol = nline, ncol
ncol += 1
if b[y] == '\n':
ncol = 0
nline += 1
d[cost + 1].append((y+1,x, nline, ncol, what + (("I", oline, ocol,b[y]),)))
cost += 1
def transform(a, cmds):
buf = a.split("\n")
for cmd in cmds:
if cmd[0] == "D":
line, col = cmd[1:]
buf[line] = buf[line][:col] + buf[line][col+1:]
elif cmd[0] == "I":
line, col, char = cmd[1:]
buf[line] = buf[line][:col] + char + buf[line][col:]
buf = '\n'.join(buf).split('\n')
return '\n'.join(buf)
import unittest
class _Base(object):
def runTest(self):
es = edit_script(self.a, self.b)
tr = transform(self.a, es)
self.assertEqual(self.b, tr)
class TestEmptyString(_Base, unittest.TestCase):
a, b = "", ""
class TestAllMatch(_Base, unittest.TestCase):
a, b = "abcdef", "abcdef"
class TestLotsaNewlines(_Base, unittest.TestCase):
a, b = "Hello", "Hello\nWorld\nWorld\nWorld"
# def test_all_match(self):
# rv = edit_script("abcdef", "abcdef")
# self.assertEqual("MMMMMM", rv)
# def test_no_substr(self):
# rv = edit_script("abc", "def")
# self.assertEqual("SSS", rv)
# def test_paper_example(self):
# rv = edit_script("abcabba","cbabac")
# self.assertEqual(rv, "SMDMMDMI")
# def test_skiena_example(self):
# rv = edit_script("thou shalt not", "you should not")
# self.assertEqual(rv, "DSMMMMMISMSMMMM")
if __name__ == '__main__':
unittest.main()
# k = TestEditScript()
# unittest.TextTestRunner().run(k)