From 35439b579e636e6096c27e1563faac331e65bf14 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Sun, 22 Jan 2012 01:01:03 +0100 Subject: [PATCH] Now reall all TODOs in TextObjects. Also final proofread. --- plugin/UltiSnips/TextObjects/__init__.py | 4 +- plugin/UltiSnips/TextObjects/_base.py | 144 +++++++----------- plugin/UltiSnips/TextObjects/_escaped_char.py | 2 +- plugin/UltiSnips/TextObjects/_mirror.py | 4 +- plugin/UltiSnips/TextObjects/_parser.py | 19 ++- plugin/UltiSnips/TextObjects/_python_code.py | 4 +- plugin/UltiSnips/TextObjects/_shell_code.py | 2 +- .../TextObjects/_snippet_instance.py | 20 ++- plugin/UltiSnips/TextObjects/_tabstop.py | 12 +- .../UltiSnips/TextObjects/_transformation.py | 5 +- plugin/UltiSnips/TextObjects/_viml_code.py | 3 +- plugin/UltiSnips/TextObjects/_visual.py | 7 +- test.py | 1 + 13 files changed, 94 insertions(+), 133 deletions(-) diff --git a/plugin/UltiSnips/TextObjects/__init__.py b/plugin/UltiSnips/TextObjects/__init__.py index 0995f4c..3df0757 100644 --- a/plugin/UltiSnips/TextObjects/__init__.py +++ b/plugin/UltiSnips/TextObjects/__init__.py @@ -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" ] diff --git a/plugin/UltiSnips/TextObjects/_base.py b/plugin/UltiSnips/TextObjects/_base.py index 87b3f3d..1278ef8 100755 --- a/plugin/UltiSnips/TextObjects/_base.py +++ b/plugin/UltiSnips/TextObjects/_base.py @@ -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 diff --git a/plugin/UltiSnips/TextObjects/_escaped_char.py b/plugin/UltiSnips/TextObjects/_escaped_char.py index a39e8fe..4fefe78 100755 --- a/plugin/UltiSnips/TextObjects/_escaped_char.py +++ b/plugin/UltiSnips/TextObjects/_escaped_char.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 -from ._base import NoneditableTextObject +from UltiSnips.TextObjects._base import NoneditableTextObject class EscapedChar(NoneditableTextObject): """ diff --git a/plugin/UltiSnips/TextObjects/_mirror.py b/plugin/UltiSnips/TextObjects/_mirror.py index 469b06c..7deb350 100755 --- a/plugin/UltiSnips/TextObjects/_mirror.py +++ b/plugin/UltiSnips/TextObjects/_mirror.py @@ -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 diff --git a/plugin/UltiSnips/TextObjects/_parser.py b/plugin/UltiSnips/TextObjects/_parser.py index 8ba4ace..5939bfa 100755 --- a/plugin/UltiSnips/TextObjects/_parser.py +++ b/plugin/UltiSnips/TextObjects/_parser.py @@ -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"] diff --git a/plugin/UltiSnips/TextObjects/_python_code.py b/plugin/UltiSnips/TextObjects/_python_code.py index da58bb9..ff13d3f 100755 --- a/plugin/UltiSnips/TextObjects/_python_code.py +++ b/plugin/UltiSnips/TextObjects/_python_code.py @@ -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 diff --git a/plugin/UltiSnips/TextObjects/_shell_code.py b/plugin/UltiSnips/TextObjects/_shell_code.py index d86ed2b..15ffa8e 100755 --- a/plugin/UltiSnips/TextObjects/_shell_code.py +++ b/plugin/UltiSnips/TextObjects/_shell_code.py @@ -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): diff --git a/plugin/UltiSnips/TextObjects/_snippet_instance.py b/plugin/UltiSnips/TextObjects/_snippet_instance.py index cfc3b4b..ae95f0c 100755 --- a/plugin/UltiSnips/TextObjects/_snippet_instance.py +++ b/plugin/UltiSnips/TextObjects/_snippet_instance.py @@ -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) - - - diff --git a/plugin/UltiSnips/TextObjects/_tabstop.py b/plugin/UltiSnips/TextObjects/_tabstop.py index d69dad5..ef9802e 100755 --- a/plugin/UltiSnips/TextObjects/_tabstop.py +++ b/plugin/UltiSnips/TextObjects/_tabstop.py @@ -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 + diff --git a/plugin/UltiSnips/TextObjects/_transformation.py b/plugin/UltiSnips/TextObjects/_transformation.py index 0a0132b..83d7780 100755 --- a/plugin/UltiSnips/TextObjects/_transformation.py +++ b/plugin/UltiSnips/TextObjects/_transformation.py @@ -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) diff --git a/plugin/UltiSnips/TextObjects/_viml_code.py b/plugin/UltiSnips/TextObjects/_viml_code.py index 38ed4bc..56b0ead 100755 --- a/plugin/UltiSnips/TextObjects/_viml_code.py +++ b/plugin/UltiSnips/TextObjects/_viml_code.py @@ -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): diff --git a/plugin/UltiSnips/TextObjects/_visual.py b/plugin/UltiSnips/TextObjects/_visual.py index 600bf6b..e319895 100755 --- a/plugin/UltiSnips/TextObjects/_visual.py +++ b/plugin/UltiSnips/TextObjects/_visual.py @@ -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): """ diff --git a/test.py b/test.py index 29842fb..da85d6d 100755 --- a/test.py +++ b/test.py @@ -27,6 +27,7 @@ # # TODO: visual line selection -> replace with more, less and == amount of lines # TODO: edit in mirror or transofmration -> kill element +# TODO: insert/delete in mirror or transformation import os import tempfile import unittest