Now reall all TODOs in TextObjects. Also final proofread.
This commit is contained in:
parent
f9566d1fc7
commit
35439b579e
@ -1,9 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from _mirror import Mirror
|
||||
from _transformation import Transformation
|
||||
from _snippet_instance import SnippetInstance
|
||||
|
||||
__all__ = [ "Mirror", "Transformation", "SnippetInstance" ]
|
||||
__all__ = [ "SnippetInstance" ]
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
import vim
|
||||
|
||||
from ..debug import debug, echo_to_hierarchy
|
||||
|
||||
from UltiSnips.Buffer import TextBuffer
|
||||
from UltiSnips.Compatibility import as_unicode
|
||||
from UltiSnips.Geometry import Span, Position
|
||||
@ -99,30 +97,6 @@ class TextObject(object):
|
||||
self._start.move(pivot, diff)
|
||||
self._end.move(pivot, diff)
|
||||
|
||||
def child_end_moved3(self, pivot, diff):
|
||||
if not (self._parent):
|
||||
return
|
||||
|
||||
self._parent._end.move(pivot, diff)
|
||||
for c in self._parent._childs[self._parent._childs.index(self)+1:]:
|
||||
c._move(pivot, diff)
|
||||
|
||||
self._parent.child_end_moved3(pivot, diff)
|
||||
|
||||
def _child_has_moved(self, idx, pivot, diff):
|
||||
self._end.move(pivot, diff)
|
||||
|
||||
try:
|
||||
for c in self._childs[idx+1:]:
|
||||
c._move(pivot, diff)
|
||||
except AttributeError: # TODO: fix this
|
||||
pass
|
||||
|
||||
if self._parent:
|
||||
self._parent._child_has_moved(
|
||||
self._parent._childs.index(self), pivot, diff
|
||||
)
|
||||
|
||||
class EditableTextObject(TextObject):
|
||||
"""
|
||||
This base class represents any object in the text
|
||||
@ -134,9 +108,6 @@ class EditableTextObject(TextObject):
|
||||
self._childs = []
|
||||
self._tabstops = {}
|
||||
|
||||
self._cts = 0
|
||||
self._is_killed = False
|
||||
|
||||
##############
|
||||
# Properties #
|
||||
##############
|
||||
@ -159,59 +130,47 @@ class EditableTextObject(TextObject):
|
||||
# Private/Protected functions #
|
||||
###############################
|
||||
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"))
|
||||
ctype, line, col, text = cmd
|
||||
assert( ('\n' not in text) or (text == "\n"))
|
||||
pos = Position(line, col)
|
||||
|
||||
to_kill = set()
|
||||
new_cmds = []
|
||||
for c in self._childs:
|
||||
start = c._start
|
||||
end = c._end
|
||||
|
||||
debug("consider: c: %r" % (c))
|
||||
if ctype == "D":
|
||||
if char == "\n":
|
||||
delend = Position(line + 1, 0) # TODO: is this even needed?
|
||||
else:
|
||||
delend = pos + Position(0, len(char))
|
||||
# TODO: char is no longer true -> Text
|
||||
# Case: this deletion removes the child
|
||||
# Case: this edit command is completely for the child
|
||||
if (start <= pos < end) and (start < delend <= end):
|
||||
debug("Case 2")
|
||||
if isinstance(c, NoneditableTextObject): # Erasing inside NonTabstop -> Kill element
|
||||
if ctype == "I": # Insertion
|
||||
if (c._start <= pos <= c._end):
|
||||
if isinstance(c, EditableTextObject):
|
||||
c._do_edit(cmd)
|
||||
return
|
||||
else:
|
||||
to_kill.add(c)
|
||||
else: # Deletion
|
||||
delend = pos + Position(0, len(text)) if text != "\n"\
|
||||
else Position(line + 1, 0)
|
||||
if (c._start <= pos < c._end) and (c._start < delend <= c._end):
|
||||
# this edit command is completely for the child
|
||||
if isinstance(c, NoneditableTextObject):
|
||||
to_kill.add(c)
|
||||
continue
|
||||
c._do_edit(cmd)
|
||||
return
|
||||
elif (pos < start and end <= delend) or (pos <= start and end < delend):
|
||||
debug("Case 1")
|
||||
elif (pos < c._start and c._end <= delend) or (pos <= c._start and c._end < delend):
|
||||
# Case: this deletion removes the child
|
||||
to_kill.add(c)
|
||||
# Case: partially for us, partially for the child
|
||||
elif (pos < start and (start < delend <= end)):
|
||||
debug("Case 3")
|
||||
my_text = char[:(start-pos).col]
|
||||
c_text = char[(start-pos).col:]
|
||||
debug("my_text: %r, c_text: %r" % (my_text, c_text))
|
||||
elif (pos < c._start and (c._start < delend <= c._end)):
|
||||
# Case: partially for us, partially for the child
|
||||
my_text = text[:(c._start-pos).col]
|
||||
c_text = text[(c._start-pos).col:]
|
||||
new_cmds.append((ctype, line, col, my_text))
|
||||
new_cmds.append((ctype, line, col, c_text))
|
||||
break
|
||||
elif (delend >= end and (start <= pos < end)):
|
||||
debug("Case 3")
|
||||
c_text = char[(end-pos).col:]
|
||||
my_text = char[:(end-pos).col]
|
||||
debug("my_text: %r, c_text: %r" % (my_text, c_text))
|
||||
elif (delend >= c._end and (c._start <= pos < c._end)):
|
||||
# Case: partially for us, partially for the child
|
||||
c_text = text[(c._end-pos).col:]
|
||||
my_text = text[:(c._end-pos).col]
|
||||
new_cmds.append((ctype, line, col, c_text))
|
||||
new_cmds.append((ctype, line, col, my_text))
|
||||
break
|
||||
elif ctype == "I": # Else would be okay as well
|
||||
if isinstance(c, NoneditableTextObject): # TODO: make this nicer
|
||||
continue
|
||||
if (start <= pos <= end):
|
||||
c._do_edit(cmd)
|
||||
return
|
||||
|
||||
for c in to_kill:
|
||||
self._del_child(c)
|
||||
@ -220,20 +179,12 @@ class EditableTextObject(TextObject):
|
||||
self._do_edit(c)
|
||||
return
|
||||
|
||||
|
||||
# We have to handle this ourselves
|
||||
if ctype == "D": # TODO: code duplication
|
||||
delta = Position(1, 0) if text == "\n" else Position(0, len(text))
|
||||
if ctype == "D":
|
||||
assert(self._start != self._end) # Makes no sense to delete in empty textobject
|
||||
|
||||
if char == "\n":
|
||||
delta = Position(-1, 0) # TODO: this feels somehow incorrect:
|
||||
else:
|
||||
delta = Position(0, -len(char))
|
||||
else:
|
||||
if char == "\n":
|
||||
delta = Position(1, 0) # TODO: this feels somehow incorrect
|
||||
else:
|
||||
delta = Position(0, len(char))
|
||||
delta.line *= -1
|
||||
delta.col *= -1
|
||||
pivot = Position(line, col)
|
||||
self._child_has_moved(-1, pivot, delta)
|
||||
|
||||
@ -243,6 +194,17 @@ class EditableTextObject(TextObject):
|
||||
for c in self._childs:
|
||||
c._move(pivot, diff)
|
||||
|
||||
def _child_has_moved(self, idx, pivot, diff):
|
||||
self._end.move(pivot, diff)
|
||||
|
||||
for c in self._childs[idx+1:]:
|
||||
c._move(pivot, diff)
|
||||
|
||||
if self._parent:
|
||||
self._parent._child_has_moved(
|
||||
self._parent._childs.index(self), pivot, diff
|
||||
)
|
||||
|
||||
def _get_next_tab(self, no):
|
||||
if not len(self._tabstops.keys()):
|
||||
return
|
||||
@ -290,17 +252,6 @@ class EditableTextObject(TextObject):
|
||||
|
||||
return max(possible_sol)
|
||||
|
||||
def _update(self, done, not_done):
|
||||
"""
|
||||
Return False if you want to be called again
|
||||
for this edit cycle. Otherwise return True.
|
||||
"""
|
||||
if all((c in done) for c in self._childs):
|
||||
assert(self not in done)
|
||||
|
||||
done.add(self)
|
||||
return True
|
||||
|
||||
def _get_tabstop(self, requester, no):
|
||||
if no in self._tabstops:
|
||||
return self._tabstops[no]
|
||||
@ -314,12 +265,25 @@ class EditableTextObject(TextObject):
|
||||
if self._parent and requester is not self._parent:
|
||||
return self._parent._get_tabstop(self, no)
|
||||
|
||||
def _update(self, done, not_done):
|
||||
"""
|
||||
Update this object inside the Vim Buffer.
|
||||
|
||||
Return False if you want to be called again
|
||||
for this edit cycle. Otherwise return True.
|
||||
"""
|
||||
if all((c in done) for c in self._childs):
|
||||
assert(self not in done)
|
||||
|
||||
done.add(self)
|
||||
return True
|
||||
|
||||
def _add_child(self,c):
|
||||
self._childs.append(c)
|
||||
self._childs.sort()
|
||||
|
||||
def _del_child(self,c):
|
||||
c._is_killed = True
|
||||
c._parent = None
|
||||
self._childs.remove(c)
|
||||
|
||||
# If this is a tabstop, delete it
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class EscapedChar(NoneditableTextObject):
|
||||
"""
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class Mirror(NoneditableTextObject):
|
||||
"""
|
||||
@ -13,7 +13,7 @@ class Mirror(NoneditableTextObject):
|
||||
self._ts = tabstop
|
||||
|
||||
def _update(self, done, not_done):
|
||||
if self._ts._is_killed: # TODO: private parts
|
||||
if self._ts.is_killed:
|
||||
self.overwrite("")
|
||||
self._parent._del_child(self)
|
||||
return True
|
||||
|
@ -2,18 +2,17 @@
|
||||
# encoding: utf-8
|
||||
|
||||
from UltiSnips.Geometry import Position
|
||||
from ._lexer import tokenize, EscapeCharToken, VisualToken, \
|
||||
from UltiSnips.TextObjects._lexer import tokenize, EscapeCharToken, VisualToken, \
|
||||
TransformationToken, TabStopToken, MirrorToken, PythonCodeToken, \
|
||||
VimLCodeToken, ShellCodeToken
|
||||
|
||||
from ._escaped_char import EscapedChar
|
||||
from ._mirror import Mirror
|
||||
from ._python_code import PythonCode
|
||||
from ._shell_code import ShellCode
|
||||
from ._tabstop import TabStop
|
||||
from ._transformation import Transformation
|
||||
from ._viml_code import VimLCode
|
||||
from ._visual import Visual
|
||||
from UltiSnips.TextObjects._escaped_char import EscapedChar
|
||||
from UltiSnips.TextObjects._mirror import Mirror
|
||||
from UltiSnips.TextObjects._python_code import PythonCode
|
||||
from UltiSnips.TextObjects._shell_code import ShellCode
|
||||
from UltiSnips.TextObjects._tabstop import TabStop
|
||||
from UltiSnips.TextObjects._transformation import Transformation
|
||||
from UltiSnips.TextObjects._viml_code import VimLCode
|
||||
from UltiSnips.TextObjects._visual import Visual
|
||||
|
||||
__all__ = ["TOParser"]
|
||||
|
||||
|
@ -9,14 +9,14 @@ import vim
|
||||
from UltiSnips.Compatibility import compatible_exec, as_unicode
|
||||
from UltiSnips.Util import IndentUtil
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class _Tabs(object):
|
||||
def __init__(self, to):
|
||||
self._to = to
|
||||
|
||||
def __getitem__(self, no):
|
||||
ts = self._to._get_tabstop(self._to, int(no)) # TODO: private parts
|
||||
ts = self._to._get_tabstop(self._to, int(no))
|
||||
if ts is None:
|
||||
return ""
|
||||
return ts.current_text
|
||||
|
@ -6,7 +6,7 @@ import subprocess
|
||||
import stat
|
||||
import tempfile
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class ShellCode(NoneditableTextObject):
|
||||
def __init__(self, parent, token):
|
||||
|
@ -4,10 +4,8 @@
|
||||
from UltiSnips.Geometry import Position
|
||||
from UltiSnips.Compatibility import vim_cursor, set_vim_cursor
|
||||
|
||||
from ..debug import debug, echo_to_hierarchy # TODO remove all debug
|
||||
|
||||
from ._base import EditableTextObject, NoneditableTextObject
|
||||
from ._parser import TOParser
|
||||
from UltiSnips.TextObjects._base import EditableTextObject, NoneditableTextObject
|
||||
from UltiSnips.TextObjects._parser import TOParser
|
||||
|
||||
class SnippetInstance(EditableTextObject):
|
||||
"""
|
||||
@ -23,6 +21,8 @@ class SnippetInstance(EditableTextObject):
|
||||
if end is None:
|
||||
end = Position(0,0)
|
||||
|
||||
self._cts = 0
|
||||
|
||||
self.locals = {"match" : last_re}
|
||||
self.globals = globals
|
||||
self.visual_content = visual_content
|
||||
@ -50,7 +50,9 @@ class SnippetInstance(EditableTextObject):
|
||||
self._do_edit(cmd)
|
||||
|
||||
def update_textobjects(self):
|
||||
# Do our own edits; keep track of the Cursor
|
||||
"""Update the text objects that should change automagically after
|
||||
the users edits have been replayed. This might also move the Cursor
|
||||
"""
|
||||
vc = _VimCursor(self)
|
||||
|
||||
done = set()
|
||||
@ -61,7 +63,6 @@ class SnippetInstance(EditableTextObject):
|
||||
for c in obj._childs:
|
||||
_find_recursive(c)
|
||||
not_done.add(obj)
|
||||
|
||||
_find_recursive(self)
|
||||
|
||||
counter = 10
|
||||
@ -73,7 +74,6 @@ class SnippetInstance(EditableTextObject):
|
||||
if counter == 0:
|
||||
raise RuntimeError("Cyclic dependency in TextElements!")
|
||||
|
||||
|
||||
vc.to_vim()
|
||||
self._del_child(vc)
|
||||
|
||||
@ -113,8 +113,9 @@ class SnippetInstance(EditableTextObject):
|
||||
|
||||
|
||||
class _VimCursor(NoneditableTextObject):
|
||||
"""Helper class to keep track of the Vim Cursor"""
|
||||
|
||||
def __init__(self, parent):
|
||||
"""Helper class to keep track of the vim Cursor"""
|
||||
line, col = vim_cursor()
|
||||
NoneditableTextObject.__init__(
|
||||
self, parent, Position(line-1, col), Position(line-1, col)
|
||||
@ -123,6 +124,3 @@ class _VimCursor(NoneditableTextObject):
|
||||
def to_vim(self):
|
||||
assert(self._start == self._end)
|
||||
set_vim_cursor(self._start.line + 1, self._start.col)
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from ._base import EditableTextObject
|
||||
from UltiSnips.TextObjects._base import EditableTextObject
|
||||
|
||||
__all__ = ['EditableTextObject']
|
||||
|
||||
@ -15,12 +15,16 @@ class TabStop(EditableTextObject):
|
||||
self._no = token
|
||||
EditableTextObject.__init__(self, parent, start, end)
|
||||
else:
|
||||
EditableTextObject.__init__(self, parent, token)
|
||||
self._no = token.no
|
||||
|
||||
EditableTextObject.__init__(self, parent, token)
|
||||
parent._tabstops[self._no] = self
|
||||
|
||||
@property
|
||||
def no(self):
|
||||
return self._no
|
||||
no = property(no)
|
||||
|
||||
@property
|
||||
def is_killed(self):
|
||||
return self._parent is None
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import re
|
||||
|
||||
from ._mirror import Mirror
|
||||
from UltiSnips.TextObjects._mirror import Mirror
|
||||
|
||||
class _CleverReplace(object):
|
||||
"""
|
||||
@ -67,7 +67,6 @@ class _CleverReplace(object):
|
||||
while m:
|
||||
start = m.start()
|
||||
end = _find_closingbrace(v,start+4)
|
||||
|
||||
args = _part_conditional(v[start+4:end-1])
|
||||
|
||||
rv = ""
|
||||
@ -112,7 +111,7 @@ class Transformation(Mirror):
|
||||
if "g" in token.options:
|
||||
self._match_this_many = 0
|
||||
if "i" in token.options:
|
||||
flags |= re.IGNORECASE
|
||||
flags |= re.IGNORECASE
|
||||
|
||||
self._find = re.compile(token.search, flags | re.DOTALL)
|
||||
self._replace = _CleverReplace(token.replace)
|
||||
|
@ -4,8 +4,7 @@
|
||||
import vim
|
||||
|
||||
from UltiSnips.Compatibility import as_unicode
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class VimLCode(NoneditableTextObject):
|
||||
def __init__(self, parent, token):
|
||||
|
@ -5,10 +5,9 @@ import re
|
||||
|
||||
import vim
|
||||
|
||||
from ..Compatibility import as_unicode
|
||||
from ..Util import IndentUtil
|
||||
|
||||
from ._base import NoneditableTextObject
|
||||
from UltiSnips.Compatibility import as_unicode
|
||||
from UltiSnips.Util import IndentUtil
|
||||
from UltiSnips.TextObjects._base import NoneditableTextObject
|
||||
|
||||
class Visual(NoneditableTextObject):
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user