Change the way placeholders are selected.

Fixes #157.
This commit is contained in:
Holger Rapp 2014-03-22 16:43:57 +01:00
parent 5aaeae5e85
commit 69e0acd58a
5 changed files with 48 additions and 58 deletions

View File

@ -108,74 +108,42 @@ def new_scratch_buffer(text):
feedkeys(r"\<Esc>") feedkeys(r"\<Esc>")
def virtual_position(line, col):
"""Runs the position through virtcol() and returns the result."""
nbytes = col2byte(line, col)
return line, int(eval('virtcol([%d, %d])' % (line, nbytes)))
def select(start, end): def select(start, end):
"""Select the span in Select mode""" """Select the span in Select mode"""
_unmap_select_mode_mapping() _unmap_select_mode_mapping()
delta = end - start col = col2byte(start.line + 1, start.col)
lineno, col = start.line, start.col vim.current.window.cursor = start.line + 1, col
col = col2byte(lineno + 1, col)
vim.current.window.cursor = lineno + 1, col
move_cmd = "" move_cmd = ""
if eval("mode()") != 'n': if eval("mode()") != 'n':
move_cmd += r"\<Esc>" move_cmd += r"\<Esc>"
# Case 1: Zero Length Tabstops if start == end:
if delta.line == delta.col == 0: # Zero Length Tabstops, use 'i' or 'a'.
if col == 0 or eval("mode()") not in 'i' and \ if col == 0 or eval("mode()") not in 'i' and \
col < len(buf[lineno]): col < len(buf[start.line]):
move_cmd += "i" move_cmd += "i"
else: else:
move_cmd += "a" move_cmd += "a"
else: else:
# Case 2a: Non zero length # Non zero length, use Visual selection.
# If a tabstop immediately starts with a newline, the selection must move_cmd += "v"
# start after the last character in the current line. But if we are in if "inclusive" in eval("&selection"):
# insert mode and <Esc> out of it, we cannot go past the last character
# with move_one_right and therefore cannot visual-select this newline.
# We have to hack around this by adding an extra space which we can
# select. Note that this problem could be circumvent by selecting the
# tab backwards (that is starting at the end); one would not need to
# modify the line for this. This creates other trouble though
if col >= len(buf[lineno]):
buf[lineno] += " "
if delta.line:
move_lines = "%ij" % delta.line
else:
move_lines = ""
# Depending on the current mode and position, we
# might need to move escape out of the mode and this
# will move our cursor one left
if col != 0 and eval("mode()") == 'i':
move_one_right = "l"
else:
move_one_right = ""
# After moving to the correct line, we go back to column 0
# and select right from there. Note that the we have to select
# one column less since Vim's visual selection is including the
# ending while Python slicing is excluding the ending.
inclusive = "inclusive" in eval("&selection")
if end.col == 0: if end.col == 0:
# Selecting should end at beginning of line -> Select the move_cmd += "%iG$" % end.line
# previous line till its end
do_select = "k$"
if not inclusive:
do_select += "j0"
elif end.col > 1:
do_select = "0%il" % (end.col-1 if inclusive else end.col)
else: else:
do_select = "0" if inclusive else "0l" move_cmd += "%iG%i|" % virtual_position(end.line + 1, end.col)
else:
move_cmd += _LangMapTranslator().translate( move_cmd += "%iG%i|" % virtual_position(end.line + 1, end.col + 1)
r"%sv%s%s\<c-g>" % (move_one_right, move_lines, do_select) move_cmd += "o%iG%i|o\\<c-g>" % virtual_position(
) start.line + 1, start.col + 1)
feedkeys(_LangMapTranslator().translate(move_cmd))
feedkeys(move_cmd)
def _unmap_select_mode_mapping(): def _unmap_select_mode_mapping():
"""This function unmaps select mode mappings if so wished by the user. """This function unmaps select mode mappings if so wished by the user.

View File

@ -35,7 +35,8 @@ if sys.version_info >= (3, 0):
Convert a valid column index into a byte index inside Convert a valid column index into a byte index inside
of vims buffer. of vims buffer.
""" """
pre_chars = vim.current.buffer[line-1][:col] # We pad the line so that selecting the +1 st column still works.
pre_chars = (vim.current.buffer[line-1] + " ")[:col]
return len(_vim_enc(pre_chars)) return len(_vim_enc(pre_chars))
def byte2col(line, nbyte): def byte2col(line, nbyte):
@ -68,7 +69,8 @@ else:
Convert a valid column index into a byte index inside Convert a valid column index into a byte index inside
of vims buffer. of vims buffer.
""" """
pre_chars = _vim_dec(vim.current.buffer[line-1])[:col] # We pad the line so that selecting the +1 st column still works.
pre_chars = _vim_dec(vim.current.buffer[line-1] + " ")[:col]
return len(_vim_enc(pre_chars)) return len(_vim_enc(pre_chars))
def byte2col(line, nbyte): def byte2col(line, nbyte):

View File

@ -497,6 +497,8 @@ class SnippetManager(object):
self._visual_content.reset() self._visual_content.reset()
self._csnippets.append(si) self._csnippets.append(si)
si.update_textobjects()
self._ignore_movements = True self._ignore_movements = True
self._vstate.remember_buffer(self._csnippets[0]) self._vstate.remember_buffer(self._csnippets[0])

View File

@ -28,3 +28,7 @@ class TabStop(EditableTextObject):
"""True if this tabstop has been typed over and the user therefore can """True if this tabstop has been typed over and the user therefore can
no longer jump to it.""" no longer jump to it."""
return self._parent is None return self._parent is None
def __repr__(self):
return "TabStop(%s,%r->%r,%r)" % (self.number, self._start,
self._end, self.current_text)

20
test.py
View File

@ -740,6 +740,10 @@ class TabStopSimpleReplace_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${0:End} ${1:Beginning}") snippets = ("hallo", "hallo ${0:End} ${1:Beginning}")
keys = "hallo" + EX + "na" + JF + "Du Nase" keys = "hallo" + EX + "na" + JF + "Du Nase"
wanted = "hallo Du Nase na" wanted = "hallo Du Nase na"
class TabStopSimpleReplaceZeroLengthTabstops_ExpectCorrectResult(_VimTest):
snippets = ("test", r":latex:\`$1\`$0")
keys = "test" + EX + "Hello" + JF + "World"
wanted = ":latex:`Hello`World"
class TabStopSimpleReplaceReversed_ExpectCorrectResult(_VimTest): class TabStopSimpleReplaceReversed_ExpectCorrectResult(_VimTest):
snippets = ("hallo", "hallo ${1:End} ${0:Beginning}") snippets = ("hallo", "hallo ${1:End} ${0:Beginning}")
keys = "hallo" + EX + "na" + JF + "Du Nase" keys = "hallo" + EX + "na" + JF + "Du Nase"
@ -3156,6 +3160,16 @@ class Bug1251994(_VimTest):
keys = " test" + EX + "hello" + JF + "world" + JF + "blub" keys = " test" + EX + "hello" + JF + "world" + JF + "blub"
wanted = " world hello;blub" wanted = " world hello;blub"
# End: 1251994 #}}} # End: 1251994 #}}}
# Test for https://github.com/SirVer/ultisnips/issues/157 (virtualedit) {{{#
class VirtualEdit(_VimTest):
snippets = ("pd", "padding: ${1:0}px")
keys = "\t\t\tpd" + EX + "2"
wanted = "\t\t\tpadding: 2px"
def _extra_options_pre_init(self, vim_config):
vim_config.append('set virtualedit=all')
vim_config.append('set noexpandtab')
# End: 1251994 #}}}
# Test for Github Pull Request #134 - Retain unnamed register {{{# # Test for Github Pull Request #134 - Retain unnamed register {{{#
class RetainsTheUnnamedRegister(_VimTest): class RetainsTheUnnamedRegister(_VimTest):
snippets = ("test", "${1:hello} ${2:world} ${0}") snippets = ("test", "${1:hello} ${2:world} ${0}")
@ -3339,7 +3353,7 @@ class MySnippetSource(SnippetSource):
# End: Snippet Source #}}} # End: Snippet Source #}}}
# Plugin: YouCompleteMe {{{# # Plugin: YouCompleteMe {{{#
class YouCompleteMe_IntegrationTest(_VimTest): class Plugin_YouCompleteMe_IntegrationTest(_VimTest):
def skip_if(self): def skip_if(self):
r = python3() r = python3()
if r: if r:
@ -3362,7 +3376,7 @@ class YouCompleteMe_IntegrationTest(_VimTest):
time.sleep(1) time.sleep(1)
# End: Plugin: YouCompleteMe #}}} # End: Plugin: YouCompleteMe #}}}
# Plugin: Neocomplete {{{# # Plugin: Neocomplete {{{#
class Neocomplete_BugTest(_VimTest): class Plugin_Neocomplete_BugTest(_VimTest):
# Test for https://github.com/SirVer/ultisnips/issues/228 # Test for https://github.com/SirVer/ultisnips/issues/228
def skip_if(self): def skip_if(self):
if "+lua" not in self.version: if "+lua" not in self.version:
@ -3381,7 +3395,7 @@ class Neocomplete_BugTest(_VimTest):
vim_config.append('let g:neocomplete#enable_refresh_always = 1') vim_config.append('let g:neocomplete#enable_refresh_always = 1')
# End: Plugin: Neocomplete #}}} # End: Plugin: Neocomplete #}}}
# Plugin: Supertab {{{# # Plugin: Supertab {{{#
class SuperTab_SimpleTest(_VimTest): class Plugin_SuperTab_SimpleTest(_VimTest):
plugins = ["ervandew/supertab"] plugins = ["ervandew/supertab"]
snippets = ("long", "Hello", "", "w") snippets = ("long", "Hello", "", "w")
keys = ( "longtextlongtext\n" + keys = ( "longtextlongtext\n" +