Lots of code cleanups and smaller bug fixes
- Removed some dead code - Added some unittests, mainly for debugging
This commit is contained in:
parent
5982bdf6c3
commit
59dd11690a
@ -201,7 +201,7 @@ exec g:_uspy "UltiSnips_Manager.backward_trigger = vim.eval('g:UltiSnipsJumpBack
|
||||
au CursorMovedI * call UltiSnips_CursorMoved()
|
||||
" au CursorMoved * call UltiSnips_CursorMoved()
|
||||
au InsertEnter * call UltiSnips_EnteredInsertMode()
|
||||
"au WinLeave * call UltiSnips_LeavingWindow()
|
||||
au WinLeave * call UltiSnips_LeavingWindow()
|
||||
|
||||
call UltiSnips_MapKeys()
|
||||
|
||||
|
@ -5,27 +5,11 @@ import vim
|
||||
from UltiSnips.Geometry import Position
|
||||
from UltiSnips.Compatibility import make_suitable_for_vim, as_unicode
|
||||
|
||||
__all__ = [ "TextBuffer", "VimBuffer" ]
|
||||
__all__ = [ "TextBuffer" ]
|
||||
|
||||
from debug import debug
|
||||
|
||||
class Buffer(object):
|
||||
def _replace(self, start, end, content, first_line, last_line):
|
||||
text = content[:]
|
||||
if len(text) == 1:
|
||||
arr = [ first_line + text[0] + last_line ]
|
||||
new_end = start + Position(0,len(text[0]))
|
||||
else:
|
||||
arr = [ first_line + text[0] ] + \
|
||||
text[1:-1] + \
|
||||
[ text[-1] + last_line ]
|
||||
new_end = Position(start.line + len(text)-1, len(text[-1]))
|
||||
|
||||
self[start.line:end.line+1] = arr
|
||||
|
||||
return new_end
|
||||
|
||||
class TextBuffer(Buffer):
|
||||
class TextBuffer(object):
|
||||
def __init__(self, textblock):
|
||||
# We do not use splitlines() here because it handles cases like 'text\n'
|
||||
# differently than we want it here
|
||||
@ -43,7 +27,6 @@ class TextBuffer(Buffer):
|
||||
buf = vim.current.buffer
|
||||
|
||||
# Open any folds this might have created
|
||||
cc = vim.current.window.cursor
|
||||
vim.current.window.cursor = start.line + 1, 0
|
||||
vim.command("normal zv")
|
||||
|
||||
@ -58,15 +41,8 @@ class TextBuffer(Buffer):
|
||||
lines[-1] += after
|
||||
buf[start.line:end.line + 1] = make_suitable_for_vim(lines)
|
||||
|
||||
vim.current.window.cursor = cc
|
||||
|
||||
return new_end
|
||||
|
||||
def replace_text( self, start, end, content ): # TODO: no longer needed?
|
||||
first_line = self[start.line][:start.col]
|
||||
last_line = self[end.line][end.col:]
|
||||
return self._replace( start, end, content, first_line, last_line)
|
||||
|
||||
def __getitem__(self, a):
|
||||
try:
|
||||
s, e = a.start, a.end
|
||||
@ -86,29 +62,3 @@ class TextBuffer(Buffer):
|
||||
return repr('\n'.join(self._lines))
|
||||
def __str__(self):
|
||||
return '\n'.join(self._lines)
|
||||
|
||||
class VimBuffer(Buffer): # TODO: this should become obsolete
|
||||
def __init__(self, before, after):
|
||||
self._bf = before
|
||||
self._af = after
|
||||
def __getitem__(self, a):
|
||||
if isinstance(a, slice):
|
||||
return [ as_unicode(k) for k in vim.current.buffer[a] ]
|
||||
return as_unicode(vim.current.buffer[a])
|
||||
|
||||
def __setitem__(self, a, b):
|
||||
if isinstance(a,slice):
|
||||
vim.current.buffer[a.start:a.stop] = make_suitable_for_vim(b)
|
||||
else:
|
||||
vim.current.buffer[a] = make_suitable_for_vim(b)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "VimBuffer()"
|
||||
|
||||
def replace_lines( self, fline, eline, content ):
|
||||
start = Position(fline,0 )
|
||||
end = Position(eline, 100000)
|
||||
return self._replace( start, end, content, self._bf, self._af)
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ import sys
|
||||
|
||||
import vim
|
||||
|
||||
__all__ = ['as_unicode', 'compatible_exec', 'CheapTotalOrdering', 'vim_cursor', 'set_vim_cursor']
|
||||
__all__ = ['as_unicode', 'compatible_exec', 'vim_cursor', 'set_vim_cursor']
|
||||
|
||||
if sys.version_info >= (3,0):
|
||||
from UltiSnips.Compatibility_py3 import *
|
||||
@ -34,22 +34,6 @@ if sys.version_info >= (3,0):
|
||||
|
||||
col = len(raw_bytes.decode("utf-8"))
|
||||
return line, col
|
||||
class CheapTotalOrdering:
|
||||
"""Total ordering only appears in python 2.7. We try to stay compatible with
|
||||
python 2.5 for now, so we define our own"""
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.__cmp__(other) < 0
|
||||
|
||||
def __le__(self, other):
|
||||
return self.__cmp__(other) <= 0
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.__cmp__(other) > 0
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.__cmp__(other) >= 0
|
||||
|
||||
def as_unicode(s):
|
||||
if isinstance(s, bytes):
|
||||
return s.decode("utf-8")
|
||||
@ -80,23 +64,6 @@ else:
|
||||
col = len(raw_bytes.decode("utf-8"))
|
||||
return line, col
|
||||
|
||||
|
||||
class CheapTotalOrdering(object):
|
||||
"""Total ordering only appears in python 2.7. We try to stay compatible with
|
||||
python 2.5 for now, so we define our own"""
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.__cmp__(other) < 0
|
||||
|
||||
def __le__(self, other):
|
||||
return self.__cmp__(other) <= 0
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.__cmp__(other) > 0
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.__cmp__(other) >= 0
|
||||
|
||||
def as_unicode(s):
|
||||
if isinstance(s, str):
|
||||
return s.decode("utf-8")
|
||||
|
@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from UltiSnips.Compatibility import CheapTotalOrdering # TODO: no longer in use
|
||||
|
||||
__all__ = [ "Position", "Span" ]
|
||||
|
||||
class Position(object):
|
||||
@ -37,21 +35,31 @@ class Position(object):
|
||||
|
||||
return Position(self.line + pos.line, self.col + pos.col)
|
||||
|
||||
# def geometric_add(self, delta): # TODO
|
||||
# assert(delta.line >= 0 and delta.col >= 0)
|
||||
# if delta.line == 0:
|
||||
# return Position(self.line, self.col + other.col)
|
||||
# return Position(self.line + delta.line,
|
||||
|
||||
def __sub__(self,pos): # TODO: is this really true?
|
||||
if not isinstance(pos,Position):
|
||||
raise TypeError("unsupported operand type(s) for +: " \
|
||||
"'Position' and %s" % type(pos))
|
||||
|
||||
return Position(self.line - pos.line, self.col - pos.col)
|
||||
|
||||
def gsub(self,pos): # TODO: is this really true?
|
||||
if not isinstance(pos,Position):
|
||||
raise TypeError("unsupported operand type(s) for +: " \
|
||||
"'Position' and %s" % type(pos))
|
||||
if self.line == pos.line:
|
||||
return Position(0, self.col - pos.col)
|
||||
else:
|
||||
#if self > pos: # Idea: self + delta = pos
|
||||
if self > pos:
|
||||
return Position(self.line - pos.line, self.col)
|
||||
else:
|
||||
return Position(self.line - pos.line, pos.col)
|
||||
# else: return Position(self.line - pos.line, -self.col)
|
||||
|
||||
return Position(self.line - pos.line, self.col - pos.col)
|
||||
def __eq__(self, other):
|
||||
return (self._line, self._col) == (other._line, other._col)
|
||||
def __ne__(self, other):
|
||||
return (self._line, self._col) != (other._line, other._col)
|
||||
def __lt__(self, other):
|
||||
return (self._line, self._col) < (other._line, other._col)
|
||||
def __le__(self, other):
|
||||
@ -87,3 +95,158 @@ class Span(object):
|
||||
def __repr__(self):
|
||||
return "(%s -> %s)" % (self._s, self._e)
|
||||
|
||||
import unittest
|
||||
|
||||
def _move(obj, pivot, diff):
|
||||
"""pivot is the position of the first changed
|
||||
character, diff is how text after it moved"""
|
||||
if obj < pivot: return
|
||||
# TODO: test >= test here again
|
||||
if diff.line == 0:
|
||||
if obj.line == pivot.line:
|
||||
obj.col += diff.col
|
||||
elif diff.line > 0:
|
||||
if obj.line == pivot.line:
|
||||
obj.col += diff.col - pivot.col
|
||||
obj.line += diff.line
|
||||
else:
|
||||
obj.line += diff.line
|
||||
if obj.line == pivot.line:
|
||||
obj.col += - diff.col + pivot.col
|
||||
|
||||
class _MPBase(object):
|
||||
def runTest(self):
|
||||
obj = Position(*self.obj)
|
||||
for pivot, diff, wanted in self.steps:
|
||||
_move(obj, Position(*pivot), Position(*diff))
|
||||
self.assertEqual(Position(*wanted), obj)
|
||||
|
||||
class MovePosition_DelSameLine(_MPBase, unittest.TestCase):
|
||||
# hello wor*ld -> h*ld -> hl*ld
|
||||
obj = (0, 9)
|
||||
steps = (
|
||||
((0, 1), (0, -8), (0, 1)),
|
||||
((0, 1), (0, 1), (0, 2)),
|
||||
)
|
||||
class MovePosition_DelSameLine1(_MPBase, unittest.TestCase):
|
||||
# hel*lo world -> hel*world -> hel*worl
|
||||
obj = (0,3)
|
||||
steps = (
|
||||
((0, 4), (0, -3), (0,3)),
|
||||
((0, 8), (0, -1), (0,3)),
|
||||
)
|
||||
class MovePosition_InsSameLine1(_MPBase, unittest.TestCase):
|
||||
# hel*lo world -> hel*woresld
|
||||
obj = (0, 3)
|
||||
steps = (
|
||||
((0, 4), (0, -3), (0, 3)),
|
||||
((0, 6), (0, 2), (0, 3)),
|
||||
((0, 8), (0, -1), (0, 3))
|
||||
)
|
||||
class MovePosition_InsSameLine2(_MPBase, unittest.TestCase):
|
||||
# hello wor*ld -> helesdlo wor*ld
|
||||
obj = (0, 9)
|
||||
steps = (
|
||||
((0, 3), (0, 3), (0, 12)),
|
||||
)
|
||||
|
||||
class MovePosition_DelSecondLine(_MPBase, unittest.TestCase):
|
||||
# hello world. sup hello world.*a, was
|
||||
# *a, was ach nix
|
||||
# ach nix
|
||||
obj = (1, 0)
|
||||
steps = (
|
||||
((0, 12), (0, -4), (1, 0)),
|
||||
((0, 12), (-1, 0), (0, 12)),
|
||||
)
|
||||
class MovePosition_DelSecondLine1(_MPBase, unittest.TestCase):
|
||||
# hello world. sup
|
||||
# a, *was
|
||||
# ach nix
|
||||
# hello world.a*was
|
||||
# ach nix
|
||||
obj = (1, 3)
|
||||
steps = (
|
||||
((0, 12), (0, -4), (1, 3)),
|
||||
((0, 12), (-1, 0), (0, 15)),
|
||||
((0, 12), (0, -3), (0, 12)),
|
||||
((0, 12), (0, 1), (0, 13)),
|
||||
)
|
||||
|
||||
class RandomTest1(_MPBase, unittest.TestCase):
|
||||
a = 'cbaca\nabccAc\nbc'
|
||||
b = 'Aba\naca\nab'
|
||||
|
||||
'Aba\naca\nabccAc\nbc'
|
||||
obj = (1,4)
|
||||
steps = (
|
||||
((0, 0), (0, -1), (1, 4)),
|
||||
((0, 0), (0, 1), (1, 4)),
|
||||
((0, 3), (1, -3), (2, 4)),
|
||||
((1, 0), (0, 1), (2, 4)),
|
||||
((2, 2),(-1, -2), (0, 1)),
|
||||
)
|
||||
|
||||
from edit_distance import transform, edit_script
|
||||
import random, string
|
||||
|
||||
class RandomTests(unittest.TestCase):
|
||||
def runTest(self):
|
||||
nlines = random.randint(1, 3)
|
||||
def make_random_text():
|
||||
text =[]
|
||||
for i in range(nlines):
|
||||
ncols = random.randint(1,5)
|
||||
text.append(''.join(random.choice("abc") for i in range(ncols)))
|
||||
lidx = random.randint(0, len(text)-1)
|
||||
cidx = random.randint(0, len(text[lidx])-1)
|
||||
text[lidx] = text[lidx][:cidx] + 'A' + text[lidx][cidx:]
|
||||
|
||||
return '\n'.join(text), (lidx, cidx)
|
||||
|
||||
def find_A(txt):
|
||||
idx = txt.find('A')
|
||||
line_idx = txt[:idx].count("\n")
|
||||
return line_idx, txt.split("\n")[line_idx].find('A')
|
||||
|
||||
txt, initial_pos = make_random_text()
|
||||
txt2 = make_random_text()[0]
|
||||
self.assertEqual(find_A(txt), initial_pos)
|
||||
print "txt: %r, txt2: %r" % (txt, txt2)
|
||||
|
||||
obj = Position(*initial_pos)
|
||||
for cmd in edit_script(txt, txt2):
|
||||
ctype, line, col, text = cmd
|
||||
|
||||
if ctype == 'D':
|
||||
if text == "\n":
|
||||
delta = Position(-1, 0)
|
||||
else:
|
||||
delta = Position(0, -len(text))
|
||||
else:
|
||||
if text == "\n":
|
||||
delta = Position(1, 0)
|
||||
else:
|
||||
delta = Position(0, len(text))
|
||||
|
||||
txt = transform(txt, (cmd,))
|
||||
_move(obj, Position(line, col), delta)
|
||||
|
||||
# Apos = Position(*find_A(txt))
|
||||
# self.assertEqual(Apos.line, obj.line)
|
||||
# if Apos.col != -1:
|
||||
# self.assertEqual(Apos.col, obj.col)
|
||||
|
||||
self.assertEqual(txt, txt2)
|
||||
Apos = Position(*find_A(txt))
|
||||
self.assertEqual(Apos, obj)
|
||||
|
||||
print "line: %r, col: %r" % (line, col)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# unittest.main()
|
||||
k = RandomTest1()
|
||||
unittest.TextTestRunner().run(k)
|
||||
|
||||
|
@ -5,10 +5,10 @@ import os
|
||||
import re
|
||||
import stat
|
||||
import tempfile
|
||||
|
||||
import vim
|
||||
|
||||
from UltiSnips.Buffer import TextBuffer
|
||||
from UltiSnips.Compatibility import CheapTotalOrdering
|
||||
from UltiSnips.Compatibility import compatible_exec, as_unicode
|
||||
from UltiSnips.Geometry import Span, Position
|
||||
from UltiSnips.Lexer import tokenize, EscapeCharToken, VisualToken, \
|
||||
@ -218,34 +218,7 @@ class _TOParser(object):
|
||||
###########################################################################
|
||||
# Public classes #
|
||||
###########################################################################
|
||||
# TODO: this function is related to text object and should maybe be private
|
||||
def _move_nocheck(obj, old_end, new_end, diff):
|
||||
assert(diff == (new_end - old_end)) # TODO: argument has no sense
|
||||
if obj < old_end: return
|
||||
debug("obj: %r, new_end: %r, diff: %r" % (obj, new_end, diff))
|
||||
if diff.line >= 0:
|
||||
obj.line += diff.line
|
||||
if obj.line == new_end.line:
|
||||
obj.col += diff.col
|
||||
else:
|
||||
debug("diff: %r" % (diff))
|
||||
obj.line += diff.line
|
||||
if obj.line == new_end.line:
|
||||
obj.col += diff.col
|
||||
|
||||
def _move(obj, sp, diff):
|
||||
if obj < sp: return
|
||||
|
||||
debug("obj: %r, sp: %r, diff: %r" % (obj, sp, diff))
|
||||
if diff.line >= 0:
|
||||
if obj.line == sp.line:
|
||||
obj.col += diff.col
|
||||
obj.line += diff.line
|
||||
else:
|
||||
debug("diff: %r" % (diff))
|
||||
obj.line += diff.line
|
||||
if obj.line == sp.line:
|
||||
obj.col += sp.col
|
||||
from UltiSnips.Geometry import _move # TODO
|
||||
|
||||
class TextObject(object):
|
||||
"""
|
||||
@ -276,16 +249,28 @@ class TextObject(object):
|
||||
|
||||
def initial_replace(self):
|
||||
# TODO: could this be replaced via _really_updateman?
|
||||
ct = self._initial_text # TODO: Initial Text is nearly unused.
|
||||
tb = self._initial_text # TODO: Initial Text is nearly unused.
|
||||
old_end = self._end
|
||||
self._end = ct.to_vim(self._start, self._end)
|
||||
self.child_end_moved2(old_end, self._end)
|
||||
self._end = tb.to_vim(self._start, self._end) # TODO: to vim returns something unused
|
||||
|
||||
# TODO: child_end_moved2 is a stupid name for this function
|
||||
self.child_end_moved3(min(old_end, self._end), self._end.gsub(old_end))
|
||||
|
||||
def __lt__(self, other):
|
||||
return self._start < other._start
|
||||
def __le__(self, other):
|
||||
return self._start <= other._start
|
||||
|
||||
def __repr__(self):
|
||||
ct = ""
|
||||
try:
|
||||
ct = self.current_text
|
||||
except IndexError:
|
||||
ct = "<err>"
|
||||
|
||||
return "%s(%r->%r,%r)" % (self.__class__.__name__,
|
||||
self._start, self._end, ct)
|
||||
|
||||
##############
|
||||
# PROPERTIES #
|
||||
##############
|
||||
@ -334,15 +319,59 @@ class TextObject(object):
|
||||
return c._find_parent_for_new_to(pos)
|
||||
return self
|
||||
|
||||
def child_end_moved2(self, old_end, new_end): # TODO: pretty wasteful, give index
|
||||
def child_end_moved3(self, pivot, diff):
|
||||
if not (self._parent):
|
||||
return
|
||||
|
||||
debug("child_end_moved3: self: %r, pivot: %r, diff: %r" % (self, pivot, diff))
|
||||
_move(self._parent._end, pivot, diff)
|
||||
def _move_all(o):
|
||||
_move(o._start, pivot, diff)
|
||||
_move(o._end, pivot, diff)
|
||||
|
||||
for oc in o._childs:
|
||||
_move_all(oc)
|
||||
|
||||
for c in self._parent._childs[self._parent._childs.index(self)+1:]:
|
||||
st,en = c._start.copy(), c._end.copy()
|
||||
_move_all(c)
|
||||
if (st != c._start) or (en != c._end):
|
||||
debug("moved -> (%r,%r) c: %r" % (st, en, c))
|
||||
|
||||
self._parent.child_end_moved3(pivot, diff)
|
||||
_do_print_all(self)
|
||||
|
||||
|
||||
def child_end_moved2(self, old_end, new_end):
|
||||
if not (self._parent) or old_end == new_end:
|
||||
return
|
||||
|
||||
# TODO: rename function
|
||||
diff = new_end - old_end
|
||||
diff1 = old_end - new_end
|
||||
# def _move_obj(obj):
|
||||
# # if obj < old_end: return
|
||||
# _move(obj, old_end, diff1)
|
||||
|
||||
def _move_obj(obj):
|
||||
if obj < old_end:
|
||||
debug("DENIED!") # TODO
|
||||
return
|
||||
if diff.line >= 0:
|
||||
obj.line += diff.line
|
||||
if obj.line == new_end.line:
|
||||
obj.col += diff.col
|
||||
else:
|
||||
debug("diff: %r" % (diff))
|
||||
obj.line += diff.line
|
||||
if obj.line == new_end.line:
|
||||
obj.col += diff.col
|
||||
|
||||
pold_end = self._parent._end.copy()
|
||||
_move_nocheck(self._parent._end, old_end, new_end, new_end - old_end)
|
||||
_move_obj(self._parent._end)
|
||||
def _move_all(o):
|
||||
_move_nocheck(o._start, old_end, new_end, new_end - old_end)
|
||||
_move_nocheck(o._end, old_end, new_end, new_end - old_end)
|
||||
_move_obj(o._start)
|
||||
_move_obj(o._end)
|
||||
|
||||
for oc in o._childs:
|
||||
_move_all(oc)
|
||||
@ -353,6 +382,7 @@ class TextObject(object):
|
||||
self._parent.child_end_moved2(pold_end, self._parent._end)
|
||||
|
||||
def _do_edit(self, cmd):
|
||||
debug("cmd: %r, self: %r" % (cmd, self))
|
||||
ctype, line, col, char = cmd
|
||||
assert( ('\n' not in char) or (char == "\n"))
|
||||
pos = Position(line, col)
|
||||
@ -416,17 +446,18 @@ class TextObject(object):
|
||||
assert(self._start != self._end) # Makes no sense to delete in empty textobject
|
||||
|
||||
if char == "\n":
|
||||
delta = Position(-1, col) # TODO: this feels somehow incorrect:
|
||||
delta = Position(-1, 0) # TODO: this feels somehow incorrect:
|
||||
else:
|
||||
delta = Position(0, -len(char))
|
||||
else:
|
||||
if char == "\n":
|
||||
delta = Position(1, -col) # TODO: this feels somehow incorrect
|
||||
delta = Position(1, 0) # TODO: this feels somehow incorrect
|
||||
else:
|
||||
delta = Position(0, len(char))
|
||||
old_end = self._end.copy()
|
||||
_move(self._end, Position(line, col), delta)
|
||||
self.child_end_moved2(old_end, self._end)
|
||||
pivot = Position(line, col)
|
||||
_move(self._end, pivot, delta)
|
||||
self.child_end_moved3(pivot, delta)
|
||||
|
||||
def edited(self, cmds): # TODO: Only in SnippetInstance
|
||||
assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0)
|
||||
@ -435,13 +466,12 @@ class TextObject(object):
|
||||
for cmd in cmds:
|
||||
self._do_edit(cmd)
|
||||
|
||||
_do_print_all(self)
|
||||
|
||||
def do_edits(self): # TODO: only in snippets instance, stupid name
|
||||
debug("In do_edits")
|
||||
# Do our own edits; keep track of the Cursor
|
||||
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
|
||||
|
||||
|
||||
done = set()
|
||||
not_done = set()
|
||||
@ -462,44 +492,13 @@ class TextObject(object):
|
||||
raise RuntimeError("Cyclic dependency in TextElements!")
|
||||
|
||||
|
||||
#debug("self._childs: %r, vc: %r" % (self._childs, vc))
|
||||
vc.update_position()
|
||||
self._del_child(vc)
|
||||
assert(len([c for c in self._childs if isinstance(c, VimCursor)]) == 0)
|
||||
debug("self._childs: %r" % (self._childs))
|
||||
|
||||
_do_print_all(self)
|
||||
|
||||
|
||||
def update(self):
|
||||
pass # TODO: remove this function
|
||||
# def _update_childs(childs):
|
||||
# for idx,c in childs:
|
||||
# oldend = Position(c.end.line, c.end.col)
|
||||
|
||||
# new_end = c.update()
|
||||
|
||||
# moved_lines = new_end.line - oldend.line
|
||||
# moved_cols = new_end.col - oldend.col
|
||||
|
||||
# self._current_text.replace_text(c.start, oldend, c._current_text)
|
||||
|
||||
# self._move_textobjects_behind(c.start, oldend, moved_lines,
|
||||
# moved_cols, idx)
|
||||
|
||||
# _update_childs((idx, c) for idx, c in enumerate(self._childs) if isinstance(c, TabStop))
|
||||
# _update_childs((idx, c) for idx, c in enumerate(self._childs) if not isinstance(c, TabStop))
|
||||
|
||||
# self._do_update()
|
||||
|
||||
# new_end = self._current_text.calc_end(self._start)
|
||||
|
||||
# self._end = new_end
|
||||
|
||||
# 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())
|
||||
@ -558,29 +557,6 @@ class TextObject(object):
|
||||
if self._really_updateman(done, not_done):
|
||||
done.add(self)
|
||||
|
||||
# def _move_textobjects_behind(self, start, end, lines, cols, obj_idx):
|
||||
# if lines == 0 and cols == 0:
|
||||
# return
|
||||
|
||||
# for idx,m in enumerate(self._childs[obj_idx+1:]):
|
||||
# delta_lines = 0
|
||||
# delta_cols_begin = 0
|
||||
# delta_cols_end = 0
|
||||
|
||||
# if m.start.line > end.line:
|
||||
# delta_lines = lines
|
||||
# elif m.start.line == end.line:
|
||||
# if m.start.col >= end.col:
|
||||
# if lines:
|
||||
# delta_lines = lines
|
||||
# delta_cols_begin = cols
|
||||
# if m.start.line == m.end.line:
|
||||
# delta_cols_end = cols
|
||||
# m.start.line += delta_lines
|
||||
# m.end.line += delta_lines
|
||||
# m.start.col += delta_cols_begin
|
||||
# m.end.col += delta_cols_end
|
||||
|
||||
def _get_tabstop(self, requester, no):
|
||||
if no in self._tabstops:
|
||||
return self._tabstops[no]
|
||||
@ -600,14 +576,12 @@ class TextObject(object):
|
||||
|
||||
def _del_child(self,c):
|
||||
c._is_killed = True # TODO: private parts
|
||||
debug("len(self._childs): %r, self._childs: %r" % (len(self._childs), self._childs))
|
||||
self._childs.remove(c)
|
||||
debug("len(self._childs): %r, self._childs: %r" % (len(self._childs), self._childs))
|
||||
|
||||
if isinstance(c, TabStop):
|
||||
del self._tabstops[c.no]
|
||||
|
||||
def _add_tabstop(self, ts):
|
||||
def _add_tabstop(self, ts): # Why is tabstop not doing this in __init__? TODO
|
||||
self._tabstops[ts.no] = ts
|
||||
|
||||
class NoneditableTextObject(TextObject):
|
||||
@ -619,9 +593,10 @@ class NoneditableTextObject(TextObject):
|
||||
debug("_replace_text: self: %r, tb: %r" % (self, tb))
|
||||
old_end = self._end
|
||||
self._end = tb.to_vim(self._start, self._end) # TODO: to vim returns something unused
|
||||
assert(not len(self._childs))
|
||||
|
||||
# TODO: child_end_moved2 is a stupid name for this function
|
||||
self.child_end_moved2(old_end, self._end)
|
||||
self.child_end_moved3(min(old_end, self._end), self._end.gsub(old_end))
|
||||
|
||||
class EscapedChar(NoneditableTextObject):
|
||||
"""
|
||||
@ -643,10 +618,6 @@ class VimCursor(NoneditableTextObject):
|
||||
assert(self._start == self._end)
|
||||
vim.current.window.cursor = (self._start.line + 1, self._start.col)
|
||||
|
||||
def __repr__(self):
|
||||
return "VimCursor(%r)" % (self._start)
|
||||
|
||||
|
||||
class Mirror(NoneditableTextObject):
|
||||
"""
|
||||
A Mirror object mirrors a TabStop that is, text is repeated here
|
||||
@ -672,9 +643,6 @@ class Mirror(NoneditableTextObject):
|
||||
self._replace_text(tb)
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return "Mirror(%s -> %s, %r)" % (self._start, self._end, self.current_text)
|
||||
|
||||
class Visual(NoneditableTextObject):
|
||||
"""
|
||||
A ${VISUAL} placeholder that will use the text that was last visually
|
||||
@ -704,11 +672,6 @@ class Visual(NoneditableTextObject):
|
||||
self._parent._del_child(self)
|
||||
return True
|
||||
|
||||
# TODO: __repr__ is now basically the same for all elements
|
||||
def __repr__(self):
|
||||
return "Visual(%s -> %s)" % (self._start, self._end)
|
||||
|
||||
|
||||
class Transformation(Mirror):
|
||||
def __init__(self, parent, ts, token):
|
||||
Mirror.__init__(self, parent, ts, token)
|
||||
@ -743,9 +706,6 @@ class Transformation(Mirror):
|
||||
self._replace_text(TextBuffer(t))
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return "Transformation(%s -> %s)" % (self._start, self._end)
|
||||
|
||||
class ShellCode(NoneditableTextObject):
|
||||
def __init__(self, parent, token):
|
||||
code = token.code.replace("\\`", "`")
|
||||
@ -770,9 +730,6 @@ class ShellCode(NoneditableTextObject):
|
||||
token.initial_text = output
|
||||
NoneditableTextObject.__init__(self, parent, token)
|
||||
|
||||
def __repr__(self):
|
||||
return "ShellCode(%s -> %s)" % (self._start, self._end)
|
||||
|
||||
class VimLCode(NoneditableTextObject):
|
||||
def __init__(self, parent, token):
|
||||
self._code = token.code.replace("\\`", "`").strip()
|
||||
@ -783,9 +740,6 @@ class VimLCode(NoneditableTextObject):
|
||||
self._replace_text(TextBuffer(as_unicode(vim.eval(self._code))))
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return "VimLCode(%s -> %s)" % (self._start, self._end)
|
||||
|
||||
class _Tabs(object):
|
||||
def __init__(self, to):
|
||||
self._to = to
|
||||
@ -987,9 +941,6 @@ class PythonCode(NoneditableTextObject):
|
||||
return False
|
||||
return True
|
||||
|
||||
def __repr__(self):
|
||||
return "PythonCode(%s -> %s)" % (self._start, self._end)
|
||||
|
||||
class TabStop(TextObject):
|
||||
"""
|
||||
This is the most important TextObject. A TabStop is were the cursor
|
||||
@ -1007,11 +958,6 @@ class TabStop(TextObject):
|
||||
return self._no
|
||||
no = property(no)
|
||||
|
||||
# TODO: none of the _repr_ must access _current_text
|
||||
def __repr__(self):
|
||||
return "TabStop(%i, %s -> %s, %s)" % (self._no, self._start, self._end,
|
||||
repr(self.current_text))
|
||||
|
||||
class SnippetInstance(TextObject):
|
||||
"""
|
||||
A Snippet instance is an instance of a Snippet Definition. That is,
|
||||
@ -1037,9 +983,6 @@ class SnippetInstance(TextObject):
|
||||
_do_print_all(self)
|
||||
self.do_edits()
|
||||
|
||||
def __repr__(self):
|
||||
return "SnippetInstance(%s -> %s, %r)" % (self._start, self._end, self.current_text)
|
||||
|
||||
def _get_tabstop(self, requester, no):
|
||||
# SnippetInstances are completely self contained, therefore, we do not
|
||||
# need to ask our parent for Tabstops
|
||||
|
@ -16,7 +16,7 @@ import vim
|
||||
from UltiSnips.Geometry import Position, Span
|
||||
from UltiSnips.Compatibility import make_suitable_for_vim, set_vim_cursor, vim_cursor
|
||||
from UltiSnips.TextObjects import *
|
||||
from UltiSnips.Buffer import VimBuffer, TextBuffer
|
||||
from UltiSnips.Buffer import TextBuffer
|
||||
from UltiSnips.Util import IndentUtil, vim_string, as_unicode
|
||||
from UltiSnips.Langmap import LangMapTranslator
|
||||
|
||||
@ -500,7 +500,7 @@ class VimState(object):
|
||||
self._cline = as_unicode(vim.current.buffer[line])
|
||||
|
||||
def select_span(self, r):
|
||||
self._unmap_select_mode_mapping() # TODO: Bring this back!
|
||||
self._unmap_select_mode_mapping()
|
||||
|
||||
delta = r.end - r.start
|
||||
lineno, col = r.start.line, r.start.col
|
||||
@ -557,7 +557,6 @@ class VimState(object):
|
||||
move_cmd = LangMapTranslator().translate(
|
||||
r"\<Esc>%sv%s%s\<c-g>" % (move_one_right, move_lines, do_select)
|
||||
)
|
||||
debug("move_cmd: %r" % (move_cmd))
|
||||
|
||||
feedkeys(move_cmd)
|
||||
|
||||
@ -793,7 +792,6 @@ class SnippetManager(object):
|
||||
@err_to_scratch_buffer
|
||||
def cursor_moved(self):
|
||||
self._vstate.update()
|
||||
debug("self._vstate.pos: %r, self._vstate.ppos: %r" % (self._vstate.pos, self._vstate.ppos))
|
||||
|
||||
if self._csnippets:
|
||||
abs_end = self._vstate.pos
|
||||
@ -804,8 +802,6 @@ class SnippetManager(object):
|
||||
abs_end = Position(len(vim.current.buffer)-1, 10000)
|
||||
span = Span(abs_start, abs_end)
|
||||
|
||||
debug("span: %r" % (span))
|
||||
|
||||
# TODO
|
||||
# ct = TextBuffer('\n'.join(vim.current.buffer))[span]
|
||||
# lt = self._lvb[span]
|
||||
@ -813,38 +809,34 @@ class SnippetManager(object):
|
||||
lt = as_unicode(self._lvb)
|
||||
|
||||
rv = edit_distance.edit_script(lt, ct, abs_start.line, abs_start.col)
|
||||
debug("edit_script: %r" % (rv,))
|
||||
self._csnippets[0].edited(rv)
|
||||
|
||||
self._check_if_still_inside_snippet()
|
||||
if self._csnippets:
|
||||
self._csnippets[0].do_edits()
|
||||
|
||||
debug("## self._csnippets: %r" % (self._csnippets[0]))
|
||||
debug("## self._cnsippets._childs: %r" % (self._csnippets[0]._childs))
|
||||
self._lvb = TextBuffer('\n'.join(vim.current.buffer)) # TODO: no need to cache everything
|
||||
self._vstate.update()
|
||||
|
||||
|
||||
@err_to_scratch_buffer # TODO: will be needed again
|
||||
@err_to_scratch_buffer
|
||||
def entered_insert_mode(self):
|
||||
# TODO: very harsh
|
||||
# TODO: very harsh, we can be more freely now
|
||||
self._vstate.update()
|
||||
if self._cs and self._vstate.has_moved:
|
||||
while len(self._csnippets):
|
||||
self._current_snippet_is_done()
|
||||
self._reinit()
|
||||
|
||||
# @err_to_scratch_buffer # TODO: will be needed again
|
||||
# def leaving_window(self):
|
||||
# """
|
||||
# Called when the user switches tabs. It basically means that all
|
||||
# snippets must be properly terminated
|
||||
# """
|
||||
# self._vstate.update()
|
||||
# while len(self._csnippets):
|
||||
# self._current_snippet_is_done()
|
||||
# self._reinit()
|
||||
@err_to_scratch_buffer # TODO: does this still does the correct thing?
|
||||
def leaving_window(self):
|
||||
"""
|
||||
Called when the user switches tabs. It basically means that all
|
||||
snippets must be properly terminated
|
||||
"""
|
||||
self._vstate.update()
|
||||
while len(self._csnippets):
|
||||
self._current_snippet_is_done()
|
||||
self._reinit()
|
||||
|
||||
|
||||
###################################
|
||||
@ -873,8 +865,6 @@ class SnippetManager(object):
|
||||
self._ctab = None
|
||||
|
||||
# Did we leave the snippet with this movement?
|
||||
if self._cs:
|
||||
debug("self._vstate.pos: %r, self._cs.span: %r" % (self._vstate.pos, self._cs.span))
|
||||
if self._cs and not (self._vstate.pos in self._cs.span):
|
||||
self._current_snippet_is_done()
|
||||
|
||||
@ -891,11 +881,8 @@ class SnippetManager(object):
|
||||
|
||||
def _jump(self, backwards = False):
|
||||
jumped = False
|
||||
debug("self._cs: %r" % (self._cs))
|
||||
if self._cs:
|
||||
self._ctab = self._cs.select_next_tab(backwards)
|
||||
debug("self._ctab: %r" % (self._ctab))
|
||||
debug("self._ctab.span: %r" % (self._ctab.span))
|
||||
if self._ctab:
|
||||
self._vstate.select_span(self._ctab.span)
|
||||
jumped = True
|
||||
@ -1032,7 +1019,6 @@ class SnippetManager(object):
|
||||
self._visual_content = ""
|
||||
|
||||
self._lvb = TextBuffer('\n'.join(vim.current.buffer)) # TODO: no need to cache everything
|
||||
debug("in launch: self._lvb: %r" % (self._lvb))
|
||||
|
||||
self._jump()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user