All tests currently pass
This commit is contained in:
parent
61c059ea7f
commit
e8aa2885b8
103
PySnipEmu.py
103
PySnipEmu.py
@ -5,11 +5,19 @@ import vim
|
|||||||
import string
|
import string
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
def debug(s):
|
||||||
|
f = open("/tmp/file.txt","a")
|
||||||
|
f.write(s+'\n')
|
||||||
|
f.close()
|
||||||
|
|
||||||
class TextObject(object):
|
class TextObject(object):
|
||||||
def __init__(self, start, end):
|
def __init__(self, start, end):
|
||||||
self._start = start
|
self._start = start
|
||||||
self._end = end
|
self._end = end
|
||||||
|
|
||||||
|
self._delta_rows = 0
|
||||||
|
self._delta_cols = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def start(self):
|
def start(self):
|
||||||
return self._start
|
return self._start
|
||||||
@ -18,13 +26,6 @@ class TextObject(object):
|
|||||||
def end(self):
|
def end(self):
|
||||||
return self._end
|
return self._end
|
||||||
|
|
||||||
class Mirror(TextObject):
|
|
||||||
def __init__(self, ts, idx, start):
|
|
||||||
self._ts = ts
|
|
||||||
TextObject.__init__(self, (idx,start), (idx,start))
|
|
||||||
|
|
||||||
self._delta_rows = 0
|
|
||||||
self._delta_cols = 0
|
|
||||||
|
|
||||||
def delta_rows():
|
def delta_rows():
|
||||||
doc = "The RW foo property."
|
doc = "The RW foo property."
|
||||||
@ -44,6 +45,12 @@ class Mirror(TextObject):
|
|||||||
return locals()
|
return locals()
|
||||||
delta_cols = property(**delta_cols())
|
delta_cols = property(**delta_cols())
|
||||||
|
|
||||||
|
|
||||||
|
class Mirror(TextObject):
|
||||||
|
def __init__(self, ts, idx, start):
|
||||||
|
self._ts = ts
|
||||||
|
TextObject.__init__(self, (idx,start), (idx,start))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tabstop(self):
|
def tabstop(self):
|
||||||
return self._ts
|
return self._ts
|
||||||
@ -60,12 +67,11 @@ class Mirror(TextObject):
|
|||||||
elif len(lines) > 1:
|
elif len(lines) > 1:
|
||||||
self._end = (start[0],start[1]+len(lines[0]) )
|
self._end = (start[0],start[1]+len(lines[0]) )
|
||||||
|
|
||||||
class TabStop(object):
|
class TabStop(TextObject):
|
||||||
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]))
|
||||||
|
|
||||||
self._no = no
|
self._no = no
|
||||||
self._default_text = default_text
|
|
||||||
self._start = span[0]
|
|
||||||
self._lineidx = idx
|
|
||||||
self._ct = default_text
|
self._ct = default_text
|
||||||
|
|
||||||
def current_text():
|
def current_text():
|
||||||
@ -76,42 +82,45 @@ class TabStop(object):
|
|||||||
return locals()
|
return locals()
|
||||||
current_text = property(**current_text())
|
current_text = property(**current_text())
|
||||||
|
|
||||||
def line_idx(self):
|
|
||||||
return self._lineidx
|
|
||||||
line_idx = property(line_idx)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def span(self):
|
def span(self):
|
||||||
return (self._start,self._start+len(self._ct))
|
return (self._start[1]+self._delta_cols,self._start[1]+self._delta_cols+len(self._ct))
|
||||||
|
|
||||||
def default_text(self):
|
|
||||||
return self._default_text
|
|
||||||
default_text = property(default_text)
|
|
||||||
|
|
||||||
def number(self):
|
def number(self):
|
||||||
return self._no
|
return self._no
|
||||||
number = property(number)
|
number = property(number)
|
||||||
|
|
||||||
class SnippetInstance(object):
|
class SnippetInstance(TextObject):
|
||||||
def __init__(self,start,end, ts, mirrors):
|
def __init__(self,start,end, ts, mirrors):
|
||||||
self._start = start
|
TextObject.__init__(self, start, end)
|
||||||
self._end = end
|
|
||||||
self._ts = ts
|
self._ts = ts
|
||||||
self._mirrors = mirrors
|
self._mirrors = mirrors
|
||||||
|
self._text_objects = ts.values() + mirrors
|
||||||
|
self._selected_tab = None
|
||||||
|
|
||||||
self._cts = 1
|
self._cts = 0
|
||||||
|
|
||||||
def select_next_tab(self):
|
def select_next_tab(self):
|
||||||
|
self._cts += 1
|
||||||
|
|
||||||
if self._cts not in self._ts:
|
if self._cts not in self._ts:
|
||||||
if 0 in self._ts:
|
if 0 in self._ts:
|
||||||
self._cts = 0
|
self._cts = 0
|
||||||
else:
|
else:
|
||||||
self._cts = 1
|
self._cts = 1
|
||||||
|
|
||||||
|
debug("self._cts: %i" % self._cts)
|
||||||
|
|
||||||
ts = self._ts[self._cts]
|
ts = self._ts[self._cts]
|
||||||
lineno, col = self._start
|
lineno, col = self._start
|
||||||
|
|
||||||
newline = lineno + ts.line_idx
|
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]
|
||||||
if newline == lineno:
|
if newline == lineno:
|
||||||
newcol = col + ts.span[0]
|
newcol = col + ts.span[0]
|
||||||
endcol = col + ts.span[1]
|
endcol = col + ts.span[1]
|
||||||
@ -119,8 +128,6 @@ class SnippetInstance(object):
|
|||||||
newcol = ts.span[0]
|
newcol = ts.span[0]
|
||||||
endcol = ts.span[1]
|
endcol = ts.span[1]
|
||||||
|
|
||||||
self._cts += 1
|
|
||||||
|
|
||||||
vim.current.window.cursor = newline, newcol
|
vim.current.window.cursor = newline, newcol
|
||||||
|
|
||||||
# Select the word
|
# Select the word
|
||||||
@ -135,6 +142,8 @@ class SnippetInstance(object):
|
|||||||
|
|
||||||
vim.command(r'call feedkeys("\<Esc>%sv%il\<c-g>")'
|
vim.command(r'call feedkeys("\<Esc>%sv%il\<c-g>")'
|
||||||
% (move_one_right, endcol-newcol-1))
|
% (move_one_right, endcol-newcol-1))
|
||||||
|
self._selected_tab = ts
|
||||||
|
|
||||||
|
|
||||||
def _update_mirrors(self,for_ts):
|
def _update_mirrors(self,for_ts):
|
||||||
for m in self._mirrors:
|
for m in self._mirrors:
|
||||||
@ -159,39 +168,41 @@ class SnippetInstance(object):
|
|||||||
# om.delta_cols += len(lines[-1])
|
# om.delta_cols += len(lines[-1])
|
||||||
|
|
||||||
def _move_to_on_line(self,amount):
|
def _move_to_on_line(self,amount):
|
||||||
|
debug("Move on line: %i" % amount)
|
||||||
lineno,col = vim.current.window.cursor
|
lineno,col = vim.current.window.cursor
|
||||||
lineno -= 1
|
lineno -= 1
|
||||||
for m in self._mirrors:
|
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] > col:
|
if m.start[1]+m.delta_cols >= col:
|
||||||
m.delta_cols += amount
|
m.delta_cols += amount
|
||||||
|
debug(" m.delta_cols: %s" % (m.delta_cols))
|
||||||
|
|
||||||
|
|
||||||
def backspace(self,count):
|
def backspace(self,count):
|
||||||
if self._cts not in self._ts:
|
|
||||||
if 0 in self._ts:
|
|
||||||
self._cts = 0
|
|
||||||
else:
|
|
||||||
self._cts = 1
|
|
||||||
|
|
||||||
cts = self._ts[self._cts]
|
cts = self._ts[self._cts]
|
||||||
cts.current_text = cts.current_text[:-count]
|
ll = len(cts.current_text)
|
||||||
|
debug("backspace(%i):" % count)
|
||||||
|
|
||||||
# self._move_to_on_line(-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._update_mirrors(cts)
|
self._update_mirrors(cts)
|
||||||
|
|
||||||
def chars_entered(self, chars):
|
def chars_entered(self, chars):
|
||||||
if self._cts not in self._ts:
|
|
||||||
if 0 in self._ts:
|
|
||||||
self._cts = 0
|
|
||||||
else:
|
|
||||||
self._cts = 1
|
|
||||||
|
|
||||||
cts = self._ts[self._cts]
|
cts = self._ts[self._cts]
|
||||||
|
|
||||||
|
if self._selected_tab is not None:
|
||||||
|
self.backspace(len(cts.current_text))
|
||||||
|
self._selected_tab = None
|
||||||
|
|
||||||
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._move_to_on_line(len(chars))
|
||||||
|
|
||||||
self._update_mirrors(cts)
|
self._update_mirrors(cts)
|
||||||
@ -300,7 +311,6 @@ class Snippet(object):
|
|||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class SnippetManager(object):
|
class SnippetManager(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reset()
|
self.reset()
|
||||||
@ -316,6 +326,7 @@ class SnippetManager(object):
|
|||||||
def try_expand(self):
|
def try_expand(self):
|
||||||
if len(self._current_snippets):
|
if len(self._current_snippets):
|
||||||
self._current_snippets[-1].select_next_tab()
|
self._current_snippets[-1].select_next_tab()
|
||||||
|
self._last_cursor_pos = vim.current.window.cursor
|
||||||
return
|
return
|
||||||
|
|
||||||
line = vim.current.line
|
line = vim.current.line
|
||||||
@ -335,6 +346,8 @@ class SnippetManager(object):
|
|||||||
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
|
||||||
|
|
||||||
if len(self._current_snippets) and self._last_cursor_pos is not None:
|
if len(self._current_snippets) and self._last_cursor_pos is not None:
|
||||||
@ -352,10 +365,10 @@ class SnippetManager(object):
|
|||||||
chars = line[lcol:col]
|
chars = line[lcol:col]
|
||||||
cs.chars_entered(chars)
|
cs.chars_entered(chars)
|
||||||
|
|
||||||
ignore_jumping = False
|
|
||||||
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()
|
||||||
|
36
test.py
36
test.py
@ -8,18 +8,21 @@ import unittest
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
class _VimTest(unittest.TestCase):
|
class _VimTest(unittest.TestCase):
|
||||||
def type(self, str):
|
def send(self, s):
|
||||||
"""
|
|
||||||
Send the keystrokes to vim via screen. Pause after each tab, so
|
|
||||||
expansion can take place
|
|
||||||
"""
|
|
||||||
def _send(s):
|
|
||||||
os.system("screen -x %s -X stuff '%s'" % (self.session,s))
|
os.system("screen -x %s -X stuff '%s'" % (self.session,s))
|
||||||
|
|
||||||
splits = str.split('\t')
|
def type(self, str):
|
||||||
for w in splits[:-1]:
|
"""
|
||||||
_send(w + '\t')
|
Send the keystrokes to vim via screen. Pause after each char, so
|
||||||
_send(splits[-1])
|
vim can handle this
|
||||||
|
"""
|
||||||
|
for c in str:
|
||||||
|
self.send(c)
|
||||||
|
|
||||||
|
# splits = str.split('\t')
|
||||||
|
# for w in splits[:-1]:
|
||||||
|
# _send(w + '\t')
|
||||||
|
# _send(splits[-1])
|
||||||
|
|
||||||
|
|
||||||
def escape(self):
|
def escape(self):
|
||||||
@ -28,20 +31,20 @@ class _VimTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.escape()
|
self.escape()
|
||||||
|
|
||||||
self.type(":py PySnipSnippets.reset()\n")
|
self.send(":py PySnipSnippets.reset()\n")
|
||||||
|
|
||||||
for sv,content in self.snippets:
|
for sv,content in self.snippets:
|
||||||
self.type(''':py << EOF
|
self.send(''':py << EOF
|
||||||
PySnipSnippets.add_snippet("%s","""%s""")
|
PySnipSnippets.add_snippet("%s","""%s""")
|
||||||
EOF
|
EOF
|
||||||
''' % (sv,content))
|
''' % (sv,content))
|
||||||
|
|
||||||
# Clear the buffer
|
# Clear the buffer
|
||||||
self.type("bggVGd")
|
self.send("bggVGd")
|
||||||
|
|
||||||
if not self.interrupt:
|
if not self.interrupt:
|
||||||
# Enter insert mode
|
# Enter insert mode
|
||||||
self.type("i")
|
self.send("i")
|
||||||
|
|
||||||
# Execute the command
|
# Execute the command
|
||||||
self.cmd()
|
self.cmd()
|
||||||
@ -50,7 +53,7 @@ EOF
|
|||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
self.escape()
|
self.escape()
|
||||||
self.type(":w! %s\n" % fn)
|
self.send(":w! %s\n" % fn)
|
||||||
|
|
||||||
# Give screen a chance to send the cmd and vim to write the file
|
# Give screen a chance to send the cmd and vim to write the file
|
||||||
time.sleep(.01)
|
time.sleep(.01)
|
||||||
@ -212,8 +215,9 @@ class TextTabStopSimpleMirrorSameLine_ExceptCorrectResult(_VimTest):
|
|||||||
def cmd(self):
|
def cmd(self):
|
||||||
self.type("test\thallo")
|
self.type("test\thallo")
|
||||||
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertEqual(self.output,"hal\nhal")
|
self.assertEqual(self.output,"hallo hallo")
|
||||||
|
|
||||||
class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest):
|
class TextTabStopSimpleMirrorDeleteSomeEnterSome_ExceptCorrectResult(_VimTest):
|
||||||
snippets = (
|
snippets = (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user