Some refactorings. Mostly removing unused code

This commit is contained in:
Holger Rapp 2009-07-01 20:03:29 +02:00
parent e8aa2885b8
commit 36a06d1b73
3 changed files with 245 additions and 118 deletions

View File

@ -11,6 +11,10 @@ def debug(s):
f.close() f.close()
class TextObject(object): class TextObject(object):
"""
This base class represents any object in the text
that has a span in any ways
"""
def __init__(self, start, end): def __init__(self, start, end):
self._start = start self._start = start
self._end = end self._end = end
@ -26,9 +30,7 @@ class TextObject(object):
def end(self): def end(self):
return self._end return self._end
def delta_rows(): def delta_rows():
doc = "The RW foo property."
def fget(self): def fget(self):
return self._delta_rows return self._delta_rows
def fset(self, value): def fset(self, value):
@ -37,7 +39,6 @@ class TextObject(object):
delta_rows = property(**delta_rows()) delta_rows = property(**delta_rows())
def delta_cols(): def delta_cols():
doc = "The RW foo property."
def fget(self): def fget(self):
return self._delta_cols return self._delta_cols
def fset(self, value): def fset(self, value):
@ -47,31 +48,26 @@ class TextObject(object):
class Mirror(TextObject): class Mirror(TextObject):
"""
A Mirror object mirrors a TabStop that is, text is repeated here
"""
def __init__(self, ts, idx, start): def __init__(self, ts, idx, start):
self._ts = ts
TextObject.__init__(self, (idx,start), (idx,start)) TextObject.__init__(self, (idx,start), (idx,start))
self._tabstop = ts
@property @property
def tabstop(self): def tabstop(self):
return self._ts return self._tabstop
@property
def number(self):
return self._no
def update_span(self):
start = self._start
lines = self._ts.current_text.splitlines()
if len(lines) == 1:
self._end = (start[0]+len(lines)-1,len(lines[-1]))
elif len(lines) > 1:
self._end = (start[0],start[1]+len(lines[0]) )
class TabStop(TextObject): class TabStop(TextObject):
"""
This is the most important TextObject. A TabStop is were the cursor
comes to rest when the user taps through the Snippet.
"""
def __init__(self, no, idx, span, default_text = ""): def __init__(self, no, idx, span, default_text = ""):
TextObject.__init__(self, (idx,span[0]), (idx,span[1])) TextObject.__init__(self, (idx,span[0]), (idx,span[1]))
self._no = no
self._ct = default_text self._ct = default_text
def current_text(): def current_text():
@ -86,40 +82,56 @@ class TabStop(TextObject):
def span(self): def span(self):
return (self._start[1]+self._delta_cols,self._start[1]+self._delta_cols+len(self._ct)) return (self._start[1]+self._delta_cols,self._start[1]+self._delta_cols+len(self._ct))
def number(self):
return self._no
number = property(number)
class SnippetInstance(TextObject): class SnippetInstance(TextObject):
"""
A Snippet instance is an instance of a Snippet Definition. That is,
when the user expands a snippet, a SnippetInstance is created to
keep track of the corresponding TextObjects. The Snippet itself is
also a TextObject because it has a start an end
"""
def __init__(self,start,end, ts, mirrors): def __init__(self,start,end, ts, mirrors):
TextObject.__init__(self, start, end) TextObject.__init__(self, start, end)
self._ts = ts self._tabstops = ts
self._mirrors = mirrors self._mirrors = mirrors
self._text_objects = ts.values() + mirrors self._text_objects = ts.values() + mirrors
self._selected_tab = None self._selected_tab = None
self._cts = 0 self._cts = None
def select_next_tab(self): for ts in self._tabstops.values():
self._cts += 1 self._update_mirrors(ts)
if self._cts not in self._ts: def select_next_tab(self, backwards = False):
if 0 in self._ts: if self._cts == 0:
self._cts = 0 if not backwards:
return False
if backwards:
cts_bf = self._cts
if self._cts == 0:
self._cts = max(self._tabstops.keys())
else: else:
self._cts -= 1
if self._cts <= 0:
self._cts = cts_bf
else:
# All tabs handled?
if self._cts is None:
self._cts = 1 self._cts = 1
else:
self._cts += 1
debug("self._cts: %i" % self._cts) if self._cts not in self._tabstops:
self._cts = 0
if 0 not in self._tabstops:
return False
ts = self._ts[self._cts] ts = self._tabstops[self._cts]
lineno, col = self._start lineno, col = self._start
debug("ts._start: %s" % (ts.start,))
debug("ts._delta_cols: %s" % (ts._delta_cols,))
debug("ts.span: %s" % (ts.span,))
debug("ts._ct: '%s'" % (ts._ct,))
newline = lineno + ts.start[0] newline = lineno + ts.start[0]
if newline == lineno: if newline == lineno:
newcol = col + ts.span[0] newcol = col + ts.span[0]
@ -144,67 +156,64 @@ class SnippetInstance(TextObject):
% (move_one_right, endcol-newcol-1)) % (move_one_right, endcol-newcol-1))
self._selected_tab = ts self._selected_tab = ts
return True
def _update_mirrors(self,for_ts): def _update_mirrors(self,for_ts):
for m in self._mirrors: for m in self._mirrors:
if m.tabstop == for_ts: if m.tabstop == for_ts:
mirror_line = m.start[0] mirror_line = m.start[0]
line = vim.current.buffer[mirror_line] line = vim.current.buffer[mirror_line]
line = line[:m.start[1]+m.delta_cols] + for_ts.current_text # + line[m.end[1]+m.delta_cols:] line = line[:m.start[1]+m.delta_cols] + \
for_ts.current_text + \
line[m.end[1]+m.delta_cols:]
oldspan = m.end[1]-m.start[1]
# TODO: evil hack!
m._end = (m.start[0],m.start[1]+len(for_ts.current_text))
newspan = m.end[1]-m.start[1]
vim.current.buffer[mirror_line] = line vim.current.buffer[mirror_line] = line
# m.update_span() self._move_to_on_line(newspan-oldspan, m.start[0], m.start[1]+m.delta_cols,cobj=m)
# Now update all mirrors and tabstops, that they have moved def _move_to_on_line(self,amount, lineno = None, col = None, cobj = None):
# lines = for_ts.current_text.splitlines() if self._cts is None:
# if len(lines): return
# for om in self._mirrors:
# om.update_span() if lineno is None and col is None:
# lineno,col = vim.current.window.cursor
# # if om.start[0] > m.start[0]: lineno -= 1
# # om.delta_rows += len(lines)-1 cobj = self._tabstops[self._cts]
# if om.start[0] == m.start[0]:
# if om.start[1] >= m.start[1]:
# om.delta_cols += len(lines[-1])
def _move_to_on_line(self,amount):
debug("Move on line: %i" % amount)
lineno,col = vim.current.window.cursor
lineno -= 1
for m in self._text_objects: for m in self._text_objects:
debug(" m.start, lineno, col: %s %s %s" % (m.start, lineno, col))
if m.start[0] != lineno: if m.start[0] != lineno:
continue continue
if m.start[1]+m.delta_cols >= col: if m.start[1]+m.delta_cols >= col and m != cobj:
m.delta_cols += amount m.delta_cols += amount
debug(" m.delta_cols: %s" % (m.delta_cols))
def backspace(self,count): def backspace(self,count):
cts = self._ts[self._cts] cts = self._tabstops[self._cts]
ll = len(cts.current_text) ll = len(cts.current_text)
debug("backspace(%i):" % count)
cts.current_text = cts.current_text[:-count] cts.current_text = cts.current_text[:-count]
debug(" cts.current_text: %s" % cts.current_text)
self._move_to_on_line(len(cts.current_text)-ll) self._move_to_on_line(len(cts.current_text)-ll)
self._update_mirrors(cts) self._update_mirrors(cts)
def chars_entered(self, chars): def chars_entered(self, chars):
cts = self._ts[self._cts] cts = self._tabstops[self._cts]
if self._selected_tab is not None: if self._selected_tab is not None:
self.backspace(len(cts.current_text)) self._move_to_on_line(len(chars)-len(cts.current_text))
cts.current_text = ""
self._selected_tab = None self._selected_tab = None
else:
self._move_to_on_line(len(chars))
cts.current_text += chars cts.current_text += chars
debug("chars_entered(%s):" % chars)
debug(" cts.current_text: %s" % cts.current_text)
self._move_to_on_line(len(chars))
self._update_mirrors(cts) self._update_mirrors(cts)
@ -226,6 +235,7 @@ class Snippet(object):
no = int(m.group(1)) no = int(m.group(1))
def_text = m.group(2) def_text = m.group(2)
start, end = m.span() start, end = m.span()
val = val[:start] + def_text + val[end:] val = val[:start] + def_text + val[end:]
@ -234,7 +244,7 @@ class Snippet(object):
start_in_line = start - line_start start_in_line = start - line_start
ts = TabStop(no, line_idx, (start_in_line,start_in_line+len(def_text)), def_text) ts = TabStop(no, line_idx, (start_in_line,start_in_line+len(def_text)), def_text)
tabstops[ts.number] = ts tabstops[no] = ts
return val return val
@ -252,8 +262,8 @@ class Snippet(object):
m = Mirror(tabstops[no], line_idx, start_in_line) m = Mirror(tabstops[no], line_idx, start_in_line)
mirrors.append(m) mirrors.append(m)
else: else:
ts = TabStop(no, line_idx, (start_in_line,start_in_line), "") ts = TabStop(no, line_idx, (start_in_line,start_in_line))
tabstops[ts.number] = ts tabstops[no] = ts
return val return val
@ -323,9 +333,11 @@ class SnippetManager(object):
def add_snippet(self,trigger,value): def add_snippet(self,trigger,value):
self._snippets[trigger] = Snippet(trigger,value) self._snippets[trigger] = Snippet(trigger,value)
def try_expand(self): def try_expand(self, backwards = False):
if len(self._current_snippets): if len(self._current_snippets):
self._current_snippets[-1].select_next_tab() cs = self._current_snippets[-1]
if not cs.select_next_tab(backwards):
self._current_snippets.pop()
self._last_cursor_pos = vim.current.window.cursor self._last_cursor_pos = vim.current.window.cursor
return return
@ -342,11 +354,11 @@ class SnippetManager(object):
word = before.split()[-1] word = before.split()[-1]
if word in self._snippets: if word in self._snippets:
s = self._snippets[word].launch(before.rstrip()[:-len(word)], after) s = self._snippets[word].launch(before.rstrip()[:-len(word)], after)
self._last_cursor_pos = vim.current.window.cursor
if s is not None: if s is not None:
self._current_snippets.append(s) self._current_snippets.append(s)
def cursor_moved(self): def cursor_moved(self):
debug("CursorMoved: %s" % vim.eval("mode()"))
cp = vim.current.window.cursor cp = vim.current.window.cursor
@ -368,7 +380,6 @@ class SnippetManager(object):
self._last_cursor_pos = cp self._last_cursor_pos = cp
def entered_insert_mode(self): def entered_insert_mode(self):
debug("EnteredInsertMode: %s" % vim.eval("mode()"))
pass pass
PySnipSnippets = SnippetManager() PySnipSnippets = SnippetManager()

View File

@ -10,6 +10,14 @@ EOF
return "" return ""
endfunction endfunction
function! PyVimSnips_JumpBackwards()
py << EOF
from PySnipEmu import PySnipSnippets
PySnipSnippets.try_expand(True)
EOF
return ""
endfunction
function! PyVimSnips_SelectWord(len) function! PyVimSnips_SelectWord(len)
return "\<esc>".'v'.a:len."l\<c-g>" return "\<esc>".'v'.a:len."l\<c-g>"
@ -25,6 +33,8 @@ python from PySnipEmu import PySnipSnippets
inoremap <Tab> <C-R>=PyVimSnips_ExpandSnippet()<cr> inoremap <Tab> <C-R>=PyVimSnips_ExpandSnippet()<cr>
snoremap <Tab> <Esc>:call PyVimSnips_ExpandSnippet()<cr> snoremap <Tab> <Esc>:call PyVimSnips_ExpandSnippet()<cr>
inoremap + <C-R>=PyVimSnips_JumpBackwards()<cr>
snoremap + <Esc>:call PyVimSnips_JumpBackwards()<cr>
au CursorMovedI * py PySnipSnippets.cursor_moved() au CursorMovedI * py PySnipSnippets.cursor_moved()
au InsertEnter * py PySnipSnippets.entered_insert_mode() au InsertEnter * py PySnipSnippets.entered_insert_mode()

196
test.py
View File

@ -19,12 +19,6 @@ class _VimTest(unittest.TestCase):
for c in str: for c in str:
self.send(c) self.send(c)
# splits = str.split('\t')
# for w in splits[:-1]:
# _send(w + '\t')
# _send(splits[-1])
def escape(self): def escape(self):
self.type("\x1b") self.type("\x1b")
@ -33,6 +27,9 @@ class _VimTest(unittest.TestCase):
self.send(":py PySnipSnippets.reset()\n") self.send(":py PySnipSnippets.reset()\n")
if not isinstance(self.snippets[0],tuple):
self.snippets = ( self.snippets, )
for sv,content in self.snippets: for sv,content in self.snippets:
self.send(''':py << EOF self.send(''':py << EOF
PySnipSnippets.add_snippet("%s","""%s""") PySnipSnippets.add_snippet("%s","""%s""")
@ -70,9 +67,7 @@ EOF
# Simple Expands # # Simple Expands #
################## ##################
class _SimpleExpands(_VimTest): class _SimpleExpands(_VimTest):
snippets = ( snippets = ("hallo", "Hallo Welt!")
("hallo", "Hallo Welt!"),
)
class SimpleExpand_ExceptCorrectResult(_SimpleExpands): class SimpleExpand_ExceptCorrectResult(_SimpleExpands):
def cmd(self): def cmd(self):
@ -141,61 +136,131 @@ class MultilineExpandTestTyping_ExceptCorrectResult(_VimTest):
############ ############
# TabStops # # TabStops #
############ ############
class ExitTabStop_ExceptCorrectResult(_VimTest): class TabStopSimpleReplace_ExceptCorrectResult(_VimTest):
snippets = ( snippets = ("hallo", "hallo ${0:End} ${1:Beginning}")
("echo", "$0 run"), def cmd(self):
) self.type("hallo\tna\tDu Nase")
def runTest(self):
self.assertEqual(self.output,"hallo Du Nase na")
class TabStopSimpleReplaceSurrounded_ExceptCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${0:End} a small feed")
def cmd(self):
self.type("hallo\tNase")
def runTest(self):
self.assertEqual(self.output,"hallo Nase a small feed")
class TabStopSimpleReplaceSurrounded1_ExceptCorrectResult(_VimTest):
snippets = ("hallo", "hallo $0 a small feed")
def cmd(self):
self.type("hallo\tNase")
def runTest(self):
self.assertEqual(self.output,"hallo Nase a small feed")
class ExitTabStop_ExceptCorrectResult(_VimTest):
snippets = ("echo", "$0 run")
def cmd(self): def cmd(self):
self.type("echo\ttest") self.type("echo\ttest")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"test run") self.assertEqual(self.output,"test run")
class TextTabStopNoReplace_ExceptCorrectResult(_VimTest): class TabStopNoReplace_ExceptCorrectResult(_VimTest):
snippets = ( snippets = ("echo", "echo ${1:Hallo}")
("echo", "echo ${1:Hallo}"),
)
def cmd(self): def cmd(self):
self.type("echo\t") self.type("echo\t")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"echo Hallo") self.assertEqual(self.output,"echo Hallo")
class TextTabStopSimpleReplace_ExceptCorrectResult(_VimTest): class TabStopTestJumping_ExceptCorrectResult(_VimTest):
snippets = ( snippets = ("hallo", "hallo ${0:End} mitte ${1:Beginning}")
("hallo", "hallo ${0:End} ${1:Beginning}"),
)
def cmd(self): def cmd(self):
self.type("hallo\tna\tDu Nase") self.type("hallo\t\tTest\tHi")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"hallo Du Nase na") self.assertEqual(self.output,"hallo TestHi mitte Beginning")
class TabStopTestJumping2_ExceptCorrectResult(_VimTest):
class TextTabStopSimpleReplace_ExceptCorrectResult(_VimTest): snippets = ("hallo", "hallo $0 $1")
snippets = (
("hallo", "hallo ${0:End} ${1:Beginning}"),
)
def cmd(self): def cmd(self):
self.type("hallo\tna\tDu Nase") self.type("hallo\t\tTest\tHi")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"hallo Du Nase na") self.assertEqual(self.output,"hallo TestHi ")
# TODO: multiline mirrors class TabStopTestBackwardJumping_ExceptCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${0:End} mitte${1:Beginning}")
def cmd(self):
self.type("hallo\tSomelengthy Text\tHi+Lets replace it again\tBlah\t++\t")
def runTest(self):
self.assertEqual(self.output,"hallo Blah mitteLets replace it again")
class TabStopTestBackwardJumping2_ExceptCorrectResult(_VimTest):
snippets = ("hallo", "hallo $0 $1")
def cmd(self):
self.type("hallo\tSomelengthy Text\tHi+Lets replace it again\tBlah\t++\t")
def runTest(self):
self.assertEqual(self.output,"hallo Blah Lets replace it again")
class TextTabStopSimpleMirror_ExceptCorrectResult(_VimTest): # TODO: pasting with <C-R> while mirroring
snippets = ( ###########
("test", "$1\n$1"), # MIRRORS #
) ###########
class TextTabStopTextAfterTab_ExceptCorrectResult(_VimTest):
snippets = ("test", "$1 Hinten\n$1")
def cmd(self): def cmd(self):
self.type("test\thallo") self.type("test\thallo")
def runTest(self):
self.assertEqual(self.output,"hallo Hinten\nhallo")
class TextTabStopTextBeforeTab_ExceptCorrectResult(_VimTest):
snippets = ("test", "Vorne $1\n$1")
def cmd(self):
self.type("test\thallo")
def runTest(self):
self.assertEqual(self.output,"Vorne hallo\nhallo")
class TextTabStopTextSurroundedTab_ExceptCorrectResult(_VimTest):
snippets = ("test", "Vorne $1 Hinten\n$1")
def cmd(self):
self.type("test\thallo test")
def runTest(self):
self.assertEqual(self.output,"Vorne hallo test Hinten\nhallo test")
class TextTabStopTextBeforeMirror_ExceptCorrectResult(_VimTest):
snippets = ("test", "$1\nVorne $1")
def cmd(self):
self.type("test\thallo")
def runTest(self):
self.assertEqual(self.output,"hallo\nVorne hallo")
class TextTabStopAfterMirror_ExceptCorrectResult(_VimTest):
snippets = ("test", "$1\n$1 Hinten")
def cmd(self):
self.type("test\thallo")
def runTest(self):
self.assertEqual(self.output,"hallo\nhallo Hinten")
class TextTabStopSurroundMirror_ExceptCorrectResult(_VimTest):
snippets = ("test", "$1\nVorne $1 Hinten")
def cmd(self):
self.type("test\thallo welt")
def runTest(self):
self.assertEqual(self.output,"hallo welt\nVorne hallo welt Hinten")
class TextTabStopAllSurrounded_ExceptCorrectResult(_VimTest):
snippets = ("test", "ObenVorne $1 ObenHinten\nVorne $1 Hinten")
def cmd(self):
self.type("test\thallo welt")
def runTest(self):
self.assertEqual(self.output,"ObenVorne hallo welt ObenHinten\nVorne hallo welt Hinten")
# TODO: mirror mit tabstop mit default variable
# TODO: Mehrer tabs und mehrere mirrors
class TextTabStopSimpleMirrorMultiline_ExceptCorrectResult(_VimTest):
snippets = ("test", "$1\n$1")
def cmd(self):
self.type("test\thallo")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"hallo\nhallo") self.assertEqual(self.output,"hallo\nhallo")
class TextTabStopSimpleMirrorMultilineMany_ExceptCorrectResult(_VimTest):
snippets = ("test", " $1\n$1\na$1b\n$1\ntest $1 mich")
def cmd(self):
self.type("test\thallo")
def runTest(self):
self.assertEqual(self.output," hallo\nhallo\nahallob\nhallo\ntest hallo mich")
class TextTabStopSimpleMirrorDelete_ExceptCorrectResult(_VimTest): class TextTabStopSimpleMirrorDelete_ExceptCorrectResult(_VimTest):
snippets = ( snippets = (
@ -210,15 +275,24 @@ class TextTabStopSimpleMirrorDelete_ExceptCorrectResult(_VimTest):
class TextTabStopSimpleMirrorSameLine_ExceptCorrectResult(_VimTest): class TextTabStopSimpleMirrorSameLine_ExceptCorrectResult(_VimTest):
snippets = ( snippets = (
("test", "$1 $1"), ("test", "$1 $1"),
) )
def cmd(self): def cmd(self):
self.type("test\thallo") self.type("test\thallo")
def runTest(self): def runTest(self):
self.assertEqual(self.output,"hallo hallo") self.assertEqual(self.output,"hallo hallo")
class TextTabStopSimpleMirrorSameLineMany_ExceptCorrectResult(_VimTest):
snippets = (
("test", "$1 $1 $1 $1"),
)
def cmd(self):
self.type("test\thallo du")
def runTest(self):
self.assertEqual(self.output,"hallo du hallo du hallo du hallo du")
class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest): class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest):
snippets = ( snippets = (
("test", "$1\n$1"), ("test", "$1\n$1"),
@ -229,7 +303,36 @@ class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest):
def runTest(self): def runTest(self):
self.assertEqual(self.output,"halhups\nhalhups") self.assertEqual(self.output,"halhups\nhalhups")
# TODO: this is not yet finished
class TextTabStopSimpleTabstopWithDefaultSimpelType_ExceptCorrectResult(_VimTest):
snippets = ("test", "ha ${1:defa}\n$1")
def cmd(self):
self.type("test\tworld")
def runTest(self):
self.assertEqual(self.output, "ha world\nworld")
class TextTabStopSimpleTabstopWithDefaultComplexType_ExceptCorrectResult(_VimTest):
snippets = ("test", "ha ${1:default value} $1\nanother: $1 mirror")
def cmd(self):
self.type("test\tworld")
def runTest(self):
self.assertEqual(self.output,
"ha world world\nanother: world mirror")
class TextTabStopSimpleTabstopWithDefaultSimpelKeep_ExceptCorrectResult(_VimTest):
snippets = ("test", "ha ${1:defa}\n$1")
def cmd(self):
self.type("test\t")
def runTest(self):
self.assertEqual(self.output, "ha defa\ndefa")
class TextTabStopSimpleTabstopWithDefaultComplexKeep_ExceptCorrectResult(_VimTest):
snippets = ("test", "ha ${1:default value} $1\nanother: $1 mirror")
def cmd(self):
self.type("test\t")
def runTest(self):
self.assertEqual(self.output,
"ha default value default value\nanother: default value mirror")
# class TextTabStopMirrorMoreInvolved_ExceptCorrectResult(_VimTest): # class TextTabStopMirrorMoreInvolved_ExceptCorrectResult(_VimTest):
# snippets = ( # snippets = (
# ("for", "for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})\n{\n\t${0:/* code */}\n}"), # ("for", "for(size_t ${2:i} = 0; $2 < ${1:count}; ${3:++$2})\n{\n\t${0:/* code */}\n}"),
@ -240,6 +343,9 @@ class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest):
# #
# def runTest(self): # def runTest(self):
# self.assertEqual(self.output,"hallo Du Nase na") # self.assertEqual(self.output,"hallo Du Nase na")
# TODO: recursive expansion
# TODO: mirrors in default expansion
# TODO: $1 ${1:This is the tabstop}
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys