Implement unix_filename_rubout.

unix_filename_rubout deletes to the previous slash or whitespace,
unlike the previously implemented backwards-kill-word which treats and
non-alphanumeric character as a boundary.

To illustrate, given the text 'foo/bar.baz', unix_filename_rubout will
delete 'bar.baz' while backwards-kill-word will delete only 'baz'.

See #1710.
This commit is contained in:
Ryan Roden-Corrent 2016-07-30 19:02:05 -04:00
parent 6bcdacf1ce
commit a086095954
2 changed files with 46 additions and 14 deletions

View File

@ -148,14 +148,8 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_word_rubout(self):
"""Remove chars from the cursor to the beginning of the word.
This acts like readline's unix-word-rubout. Whitespace is used as a
word delimiter.
"""
def _rubout(self, delim):
"""Delete backwards using the characters in delim as boundaries."""
widget = self._widget()
if widget is None:
return
@ -164,14 +158,14 @@ class ReadlineBridge:
target_position = cursor_position
is_word_boundary = True
while is_word_boundary and target_position > 0:
is_word_boundary = text[target_position - 1] == " "
is_boundary = True
while is_boundary and target_position > 0:
is_boundary = text[target_position - 1] in delim
target_position -= 1
is_word_boundary = False
while not is_word_boundary and target_position > 0:
is_word_boundary = text[target_position - 1] == " "
is_boundary = False
while not is_boundary and target_position > 0:
is_boundary = text[target_position - 1] in delim
target_position -= 1
moveby = cursor_position - target_position - 1
@ -179,6 +173,25 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
@cmdutils.register(instance='readline-bridge', hide=True,
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_word_rubout(self):
"""Remove chars from the cursor to the beginning of the word.
This acts like readline's unix-word-rubout. Whitespace is used as a
word delimiter.
"""
self._rubout([' '])
@cmdutils.register(instance='readline-bridge', hide=True,
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_filename_rubout(self):
"""Remove chars from the cursor to the previous path separator.
This acts like readline's unix-filename-rubout.
"""
self._rubout([' ', '/'])
@cmdutils.register(instance='readline-bridge', hide=True,
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_kill_word(self):

View File

@ -250,6 +250,24 @@ def test_rl_unix_word_rubout(lineedit, bridge, text, deleted, rest):
assert lineedit.aug_text() == deleted + '|'
@pytest.mark.parametrize('text, deleted, rest', [
('test delete|foobar', 'delete', 'test |foobar'),
('test delete |foobar', 'delete ', 'test |foobar'),
('open -t github.com/foo/bar |', 'bar ', 'open -t github.com/foo/|'),
('open -t |github.com/foo/bar', '-t ', 'open |github.com/foo/bar'),
('open foo/bar.baz|', 'bar.baz', 'open foo/|'),
])
def test_rl_unix_filename_rubout(lineedit, bridge, text, deleted, rest):
"""Delete filename segment and see if it comes back with yank."""
lineedit.set_aug_text(text)
bridge.rl_unix_filename_rubout()
assert bridge._deleted[lineedit] == deleted
assert lineedit.aug_text() == rest
lineedit.clear()
bridge.rl_yank()
assert lineedit.aug_text() == deleted + '|'
@pytest.mark.parametrize('text, deleted, rest', [
fixme(('test foobar| delete', ' delete', 'test foobar|')),
('test foobar| delete', ' ', 'test foobar|delete'), # wrong
@ -276,6 +294,7 @@ def test_rl_kill_word(lineedit, bridge, text, deleted, rest):
('open -t |github.com/foo/bar', 't ', 'open -|github.com/foo/bar'),
fixme(('test del<ete>foobar', 'delete', 'test |foobar')),
('test del<ete >foobar', 'del', 'test |ete foobar'), # wrong
('open foo/bar.baz|', 'baz', 'open foo/bar.|'),
])
def test_rl_backward_kill_word(lineedit, bridge, text, deleted, rest):
"""Delete to word beginning and see if it comes back with yank."""