Now reall all TODOs in TextObjects. Also final proofread.

This commit is contained in:
Holger Rapp 2012-01-22 01:01:03 +01:00
parent f9566d1fc7
commit 35439b579e
13 changed files with 94 additions and 133 deletions

View File

@ -1,9 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from _mirror import Mirror
from _transformation import Transformation
from _snippet_instance import SnippetInstance from _snippet_instance import SnippetInstance
__all__ = [ "Mirror", "Transformation", "SnippetInstance" ] __all__ = [ "SnippetInstance" ]

View File

@ -3,8 +3,6 @@
import vim import vim
from ..debug import debug, echo_to_hierarchy
from UltiSnips.Buffer import TextBuffer from UltiSnips.Buffer import TextBuffer
from UltiSnips.Compatibility import as_unicode from UltiSnips.Compatibility import as_unicode
from UltiSnips.Geometry import Span, Position from UltiSnips.Geometry import Span, Position
@ -99,30 +97,6 @@ class TextObject(object):
self._start.move(pivot, diff) self._start.move(pivot, diff)
self._end.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): class EditableTextObject(TextObject):
""" """
This base class represents any object in the text This base class represents any object in the text
@ -134,9 +108,6 @@ class EditableTextObject(TextObject):
self._childs = [] self._childs = []
self._tabstops = {} self._tabstops = {}
self._cts = 0
self._is_killed = False
############## ##############
# Properties # # Properties #
############## ##############
@ -159,59 +130,47 @@ class EditableTextObject(TextObject):
# Private/Protected functions # # Private/Protected functions #
############################### ###############################
def _do_edit(self, cmd): def _do_edit(self, cmd):
debug("cmd: %r, self: %r" % (cmd, self)) ctype, line, col, text = cmd
ctype, line, col, char = cmd assert( ('\n' not in text) or (text == "\n"))
assert( ('\n' not in char) or (char == "\n"))
pos = Position(line, col) pos = Position(line, col)
to_kill = set() to_kill = set()
new_cmds = [] new_cmds = []
for c in self._childs: for c in self._childs:
start = c._start if ctype == "I": # Insertion
end = c._end if (c._start <= pos <= c._end):
if isinstance(c, EditableTextObject):
debug("consider: c: %r" % (c)) c._do_edit(cmd)
if ctype == "D": return
if char == "\n": else:
delend = Position(line + 1, 0) # TODO: is this even needed? to_kill.add(c)
else: else: # Deletion
delend = pos + Position(0, len(char)) delend = pos + Position(0, len(text)) if text != "\n"\
# TODO: char is no longer true -> Text else Position(line + 1, 0)
# Case: this deletion removes the child if (c._start <= pos < c._end) and (c._start < delend <= c._end):
# Case: this edit command is completely for the child # this edit command is completely for the child
if (start <= pos < end) and (start < delend <= end): if isinstance(c, NoneditableTextObject):
debug("Case 2")
if isinstance(c, NoneditableTextObject): # Erasing inside NonTabstop -> Kill element
to_kill.add(c) to_kill.add(c)
continue continue
c._do_edit(cmd) c._do_edit(cmd)
return return
elif (pos < start and end <= delend) or (pos <= start and end < delend): elif (pos < c._start and c._end <= delend) or (pos <= c._start and c._end < delend):
debug("Case 1") # Case: this deletion removes the child
to_kill.add(c) to_kill.add(c)
# Case: partially for us, partially for the child elif (pos < c._start and (c._start < delend <= c._end)):
elif (pos < start and (start < delend <= end)): # Case: partially for us, partially for the child
debug("Case 3") my_text = text[:(c._start-pos).col]
my_text = char[:(start-pos).col] c_text = text[(c._start-pos).col:]
c_text = char[(start-pos).col:]
debug("my_text: %r, c_text: %r" % (my_text, c_text))
new_cmds.append((ctype, line, col, my_text)) new_cmds.append((ctype, line, col, my_text))
new_cmds.append((ctype, line, col, c_text)) new_cmds.append((ctype, line, col, c_text))
break break
elif (delend >= end and (start <= pos < end)): elif (delend >= c._end and (c._start <= pos < c._end)):
debug("Case 3") # Case: partially for us, partially for the child
c_text = char[(end-pos).col:] c_text = text[(c._end-pos).col:]
my_text = char[:(end-pos).col] my_text = text[:(c._end-pos).col]
debug("my_text: %r, c_text: %r" % (my_text, c_text))
new_cmds.append((ctype, line, col, c_text)) new_cmds.append((ctype, line, col, c_text))
new_cmds.append((ctype, line, col, my_text)) new_cmds.append((ctype, line, col, my_text))
break 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: for c in to_kill:
self._del_child(c) self._del_child(c)
@ -220,20 +179,12 @@ class EditableTextObject(TextObject):
self._do_edit(c) self._do_edit(c)
return return
# We have to handle this ourselves # 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 assert(self._start != self._end) # Makes no sense to delete in empty textobject
delta.line *= -1
if char == "\n": delta.col *= -1
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))
pivot = Position(line, col) pivot = Position(line, col)
self._child_has_moved(-1, pivot, delta) self._child_has_moved(-1, pivot, delta)
@ -243,6 +194,17 @@ class EditableTextObject(TextObject):
for c in self._childs: for c in self._childs:
c._move(pivot, diff) 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): def _get_next_tab(self, no):
if not len(self._tabstops.keys()): if not len(self._tabstops.keys()):
return return
@ -290,17 +252,6 @@ class EditableTextObject(TextObject):
return max(possible_sol) 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): def _get_tabstop(self, requester, no):
if no in self._tabstops: if no in self._tabstops:
return self._tabstops[no] return self._tabstops[no]
@ -314,12 +265,25 @@ class EditableTextObject(TextObject):
if self._parent and requester is not self._parent: if self._parent and requester is not self._parent:
return self._parent._get_tabstop(self, no) 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): def _add_child(self,c):
self._childs.append(c) self._childs.append(c)
self._childs.sort() self._childs.sort()
def _del_child(self,c): def _del_child(self,c):
c._is_killed = True c._parent = None
self._childs.remove(c) self._childs.remove(c)
# If this is a tabstop, delete it # If this is a tabstop, delete it

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from ._base import NoneditableTextObject from UltiSnips.TextObjects._base import NoneditableTextObject
class EscapedChar(NoneditableTextObject): class EscapedChar(NoneditableTextObject):
""" """

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from ._base import NoneditableTextObject from UltiSnips.TextObjects._base import NoneditableTextObject
class Mirror(NoneditableTextObject): class Mirror(NoneditableTextObject):
""" """
@ -13,7 +13,7 @@ class Mirror(NoneditableTextObject):
self._ts = tabstop self._ts = tabstop
def _update(self, done, not_done): def _update(self, done, not_done):
if self._ts._is_killed: # TODO: private parts if self._ts.is_killed:
self.overwrite("") self.overwrite("")
self._parent._del_child(self) self._parent._del_child(self)
return True return True

View File

@ -2,18 +2,17 @@
# encoding: utf-8 # encoding: utf-8
from UltiSnips.Geometry import Position from UltiSnips.Geometry import Position
from ._lexer import tokenize, EscapeCharToken, VisualToken, \ from UltiSnips.TextObjects._lexer import tokenize, EscapeCharToken, VisualToken, \
TransformationToken, TabStopToken, MirrorToken, PythonCodeToken, \ TransformationToken, TabStopToken, MirrorToken, PythonCodeToken, \
VimLCodeToken, ShellCodeToken VimLCodeToken, ShellCodeToken
from UltiSnips.TextObjects._escaped_char import EscapedChar
from ._escaped_char import EscapedChar from UltiSnips.TextObjects._mirror import Mirror
from ._mirror import Mirror from UltiSnips.TextObjects._python_code import PythonCode
from ._python_code import PythonCode from UltiSnips.TextObjects._shell_code import ShellCode
from ._shell_code import ShellCode from UltiSnips.TextObjects._tabstop import TabStop
from ._tabstop import TabStop from UltiSnips.TextObjects._transformation import Transformation
from ._transformation import Transformation from UltiSnips.TextObjects._viml_code import VimLCode
from ._viml_code import VimLCode from UltiSnips.TextObjects._visual import Visual
from ._visual import Visual
__all__ = ["TOParser"] __all__ = ["TOParser"]

View File

@ -9,14 +9,14 @@ import vim
from UltiSnips.Compatibility import compatible_exec, as_unicode from UltiSnips.Compatibility import compatible_exec, as_unicode
from UltiSnips.Util import IndentUtil from UltiSnips.Util import IndentUtil
from ._base import NoneditableTextObject from UltiSnips.TextObjects._base import NoneditableTextObject
class _Tabs(object): class _Tabs(object):
def __init__(self, to): def __init__(self, to):
self._to = to self._to = to
def __getitem__(self, no): 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: if ts is None:
return "" return ""
return ts.current_text return ts.current_text

View File

@ -6,7 +6,7 @@ import subprocess
import stat import stat
import tempfile import tempfile
from ._base import NoneditableTextObject from UltiSnips.TextObjects._base import NoneditableTextObject
class ShellCode(NoneditableTextObject): class ShellCode(NoneditableTextObject):
def __init__(self, parent, token): def __init__(self, parent, token):

View File

@ -4,10 +4,8 @@
from UltiSnips.Geometry import Position from UltiSnips.Geometry import Position
from UltiSnips.Compatibility import vim_cursor, set_vim_cursor from UltiSnips.Compatibility import vim_cursor, set_vim_cursor
from ..debug import debug, echo_to_hierarchy # TODO remove all debug from UltiSnips.TextObjects._base import EditableTextObject, NoneditableTextObject
from UltiSnips.TextObjects._parser import TOParser
from ._base import EditableTextObject, NoneditableTextObject
from ._parser import TOParser
class SnippetInstance(EditableTextObject): class SnippetInstance(EditableTextObject):
""" """
@ -23,6 +21,8 @@ class SnippetInstance(EditableTextObject):
if end is None: if end is None:
end = Position(0,0) end = Position(0,0)
self._cts = 0
self.locals = {"match" : last_re} self.locals = {"match" : last_re}
self.globals = globals self.globals = globals
self.visual_content = visual_content self.visual_content = visual_content
@ -50,7 +50,9 @@ class SnippetInstance(EditableTextObject):
self._do_edit(cmd) self._do_edit(cmd)
def update_textobjects(self): 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) vc = _VimCursor(self)
done = set() done = set()
@ -61,7 +63,6 @@ class SnippetInstance(EditableTextObject):
for c in obj._childs: for c in obj._childs:
_find_recursive(c) _find_recursive(c)
not_done.add(obj) not_done.add(obj)
_find_recursive(self) _find_recursive(self)
counter = 10 counter = 10
@ -73,7 +74,6 @@ class SnippetInstance(EditableTextObject):
if counter == 0: if counter == 0:
raise RuntimeError("Cyclic dependency in TextElements!") raise RuntimeError("Cyclic dependency in TextElements!")
vc.to_vim() vc.to_vim()
self._del_child(vc) self._del_child(vc)
@ -113,8 +113,9 @@ class SnippetInstance(EditableTextObject):
class _VimCursor(NoneditableTextObject): class _VimCursor(NoneditableTextObject):
"""Helper class to keep track of the Vim Cursor"""
def __init__(self, parent): def __init__(self, parent):
"""Helper class to keep track of the vim Cursor"""
line, col = vim_cursor() line, col = vim_cursor()
NoneditableTextObject.__init__( NoneditableTextObject.__init__(
self, parent, Position(line-1, col), Position(line-1, col) self, parent, Position(line-1, col), Position(line-1, col)
@ -123,6 +124,3 @@ class _VimCursor(NoneditableTextObject):
def to_vim(self): def to_vim(self):
assert(self._start == self._end) assert(self._start == self._end)
set_vim_cursor(self._start.line + 1, self._start.col) set_vim_cursor(self._start.line + 1, self._start.col)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from ._base import EditableTextObject from UltiSnips.TextObjects._base import EditableTextObject
__all__ = ['EditableTextObject'] __all__ = ['EditableTextObject']
@ -15,12 +15,16 @@ class TabStop(EditableTextObject):
self._no = token self._no = token
EditableTextObject.__init__(self, parent, start, end) EditableTextObject.__init__(self, parent, start, end)
else: else:
EditableTextObject.__init__(self, parent, token)
self._no = token.no self._no = token.no
EditableTextObject.__init__(self, parent, token)
parent._tabstops[self._no] = self parent._tabstops[self._no] = self
@property
def no(self): def no(self):
return self._no return self._no
no = property(no)
@property
def is_killed(self):
return self._parent is None

View File

@ -3,7 +3,7 @@
import re import re
from ._mirror import Mirror from UltiSnips.TextObjects._mirror import Mirror
class _CleverReplace(object): class _CleverReplace(object):
""" """
@ -67,7 +67,6 @@ class _CleverReplace(object):
while m: while m:
start = m.start() start = m.start()
end = _find_closingbrace(v,start+4) end = _find_closingbrace(v,start+4)
args = _part_conditional(v[start+4:end-1]) args = _part_conditional(v[start+4:end-1])
rv = "" rv = ""
@ -112,7 +111,7 @@ class Transformation(Mirror):
if "g" in token.options: if "g" in token.options:
self._match_this_many = 0 self._match_this_many = 0
if "i" in token.options: if "i" in token.options:
flags |= re.IGNORECASE flags |= re.IGNORECASE
self._find = re.compile(token.search, flags | re.DOTALL) self._find = re.compile(token.search, flags | re.DOTALL)
self._replace = _CleverReplace(token.replace) self._replace = _CleverReplace(token.replace)

View File

@ -4,8 +4,7 @@
import vim import vim
from UltiSnips.Compatibility import as_unicode from UltiSnips.Compatibility import as_unicode
from UltiSnips.TextObjects._base import NoneditableTextObject
from ._base import NoneditableTextObject
class VimLCode(NoneditableTextObject): class VimLCode(NoneditableTextObject):
def __init__(self, parent, token): def __init__(self, parent, token):

View File

@ -5,10 +5,9 @@ import re
import vim import vim
from ..Compatibility import as_unicode from UltiSnips.Compatibility import as_unicode
from ..Util import IndentUtil from UltiSnips.Util import IndentUtil
from UltiSnips.TextObjects._base import NoneditableTextObject
from ._base import NoneditableTextObject
class Visual(NoneditableTextObject): class Visual(NoneditableTextObject):
""" """

View File

@ -27,6 +27,7 @@
# #
# TODO: visual line selection -> replace with more, less and == amount of lines # TODO: visual line selection -> replace with more, less and == amount of lines
# TODO: edit in mirror or transofmration -> kill element # TODO: edit in mirror or transofmration -> kill element
# TODO: insert/delete in mirror or transformation
import os import os
import tempfile import tempfile
import unittest import unittest