From 6bcdacf1ce4b0767415e63245a3eb26555bfea05 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Sat, 30 Jul 2016 07:26:10 -0400 Subject: [PATCH] Implement readline's backward-kill-word. This restores the previous behavior of `unix-word-rubout` as `backward-kill-word`, which is closer to the naming used in readline. It is bound to by default, though will also work due to a builtin binding. Resolves #1698. --- doc/help/commands.asciidoc | 9 ++++++++- qutebrowser/config/configdata.py | 3 ++- qutebrowser/misc/readline.py | 18 +++++++++++++++++- tests/unit/misc/test_readline.py | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 537f3d675..1b0d6a734 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -946,6 +946,7 @@ How many steps to zoom out. |<>|Repeat the last executed command. |<>|Move back a character. |<>|Delete the character before the cursor. +|<>|Remove chars from the cursor to the beginning of the word. |<>|Move back to the start of the current or previous word. |<>|Move to the start of the line. |<>|Delete the character after the cursor. @@ -1193,6 +1194,12 @@ Delete the character before the cursor. This acts like readline's backward-delete-char. +[[rl-backward-kill-word]] +=== rl-backward-kill-word +Remove chars from the cursor to the beginning of the word. + +This acts like readline's backward-kill-word. Any non-alphanumeric character is considered a word delimiter. + [[rl-backward-word]] === rl-backward-word Move back to the start of the current or previous word. @@ -1251,7 +1258,7 @@ This acts like readline's unix-line-discard. === rl-unix-word-rubout Remove chars from the cursor to the beginning of the word. -This acts like readline's unix-word-rubout. +This acts like readline's unix-word-rubout. Whitespace is used as a word delimiter. [[rl-yank]] === rl-yank diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 5110a6090..9506b2f70 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1587,7 +1587,8 @@ KEY_DATA = collections.OrderedDict([ ('rl-unix-line-discard', ['']), ('rl-kill-line', ['']), ('rl-kill-word', ['']), - ('rl-unix-word-rubout', ['', '']), + ('rl-unix-word-rubout', ['']), + ('rl-backward-kill-word', ['']), ('rl-yank', ['']), ('rl-delete-char', ['']), ('rl-backward-delete-char', ['']), diff --git a/qutebrowser/misc/readline.py b/qutebrowser/misc/readline.py index e527a9abe..517837a59 100644 --- a/qutebrowser/misc/readline.py +++ b/qutebrowser/misc/readline.py @@ -153,7 +153,8 @@ class ReadlineBridge: 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. + This acts like readline's unix-word-rubout. Whitespace is used as a + word delimiter. """ widget = self._widget() if widget is None: @@ -178,6 +179,21 @@ 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_backward_kill_word(self): + """Remove chars from the cursor to the beginning of the word. + + This acts like readline's backward-kill-word. Any non-alphanumeric + character is considered a word delimiter. + """ + widget = self._widget() + if widget is None: + return + widget.cursorWordBackward(True) + self._deleted[widget] = widget.selectedText() + widget.del_() + @cmdutils.register(instance='readline-bridge', hide=True, modes=[typ.KeyMode.command, typ.KeyMode.prompt]) def rl_kill_word(self): diff --git a/tests/unit/misc/test_readline.py b/tests/unit/misc/test_readline.py index f59828779..419ad6f04 100644 --- a/tests/unit/misc/test_readline.py +++ b/tests/unit/misc/test_readline.py @@ -269,6 +269,25 @@ def test_rl_kill_word(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'), + fixme(('test delfoobar', 'delete', 'test |foobar')), + ('test delfoobar', 'del', 'test |ete foobar'), # wrong +]) +def test_rl_backward_kill_word(lineedit, bridge, text, deleted, rest): + """Delete to word beginning and see if it comes back with yank.""" + lineedit.set_aug_text(text) + bridge.rl_backward_kill_word() + assert bridge._deleted[lineedit] == deleted + assert lineedit.aug_text() == rest + lineedit.clear() + bridge.rl_yank() + assert lineedit.aug_text() == deleted + '|' + + def test_rl_yank_no_text(lineedit, bridge): """Test yank without having deleted anything.""" lineedit.clear()