From 00432df420de02dcf1d7f13671d73b28a1cb2ab8 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 13 Apr 2024 12:21:45 +0200 Subject: [PATCH] Trigger abbreviations after inserting process separators On a; we don't expand the abbreviation because the cursor is right of semicolon, not on the command token. Fix this by making sure that we call expand-abbr with the cursor on the semicolon which is the end of the command token. (Now that our bind command execution order is less surprising, this is doable.) This means that we need to fix the cursor after successfully expanding an abbreviation. Do this by setting the position explicitly even when no --set-position is in effect. An earlier version of this patch used bind space self-insert backward-char expand-abbr or forward-char The problem with that (as a failing test shows) was that given "abbr m myabbr", after typing "m space ctrl-z", the cursor would be after the "m", not after the space. The second space removes the space, not changing the cursor position, which is weird. I initially tried to fix this by adding a hack to the undo group logic, to always restore the cursor position from when begin-undo-group was used. bind space self-insert begin-undo-group backward-char expand-abbr end-undo-group or forward-char However this made test_torn_escapes.py fail for mysterious reasons. I believe this is because that test registers and triggers a SIGUSR1 handler; since the signal handler will rearrange char events, that probably messes with the undo group guards. I resorted to adding a tailor-made readline cmd. We could probably remove it and give the new behavior to expand-abbr, not sure. Fixes #9730 --- CHANGELOG.rst | 1 + .../functions/__fish_shared_key_bindings.fish | 24 +++++++++---------- src/input.rs | 1 + src/input_common.rs | 1 + src/reader.rs | 7 ++++++ tests/pexpects/abbrs.py | 3 +++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a9c2c1b8d..7af632b37 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -104,6 +104,7 @@ Interactive improvements - fish no longer fails to open a fifo if interrupted by a terminal resize signal (:issue:`10250`). - ``read --help`` and friends no longer ignore redirections. This fixes a regression in version 3.1 (:issue:`10274`). - Command abbreviations (those with ``--position command`` or without a ``--position``) now also expand after decorators like ``command`` (:issue:`10396`). +- Abbreviations now expand after process separators like ``;`` and ``|``. This fixes a regression in version 3.6 (:issue:`9730`). New or improved bindings ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/share/functions/__fish_shared_key_bindings.fish b/share/functions/__fish_shared_key_bindings.fish index 9530ea867..e6042253c 100644 --- a/share/functions/__fish_shared_key_bindings.fish +++ b/share/functions/__fish_shared_key_bindings.fish @@ -117,22 +117,20 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod or exit # protect against invalid $argv # Space and other command terminators expands abbrs _and_ inserts itself. - bind --preset $argv " " self-insert expand-abbr - bind --preset $argv ";" self-insert expand-abbr - bind --preset $argv "|" self-insert expand-abbr - bind --preset $argv "&" self-insert expand-abbr - bind --preset $argv ">" self-insert expand-abbr - bind --preset $argv "<" self-insert expand-abbr - bind --preset $argv shift-enter expand-abbr "commandline -i \n" - $legacy_bind --preset $argv \e\[27\;2\;13~ expand-abbr "commandline -i \n" # Sent with XTerm.vt100.formatOtherKeys: 0 - bind --preset $argv alt-enter expand-abbr "commandline -i \n" - # Closing a command substitution expands abbreviations - bind --preset $argv ")" self-insert expand-abbr - # Ctrl-space inserts space without expanding abbrs + bind --preset $argv " " self-insert expand-abbr-backtrack + bind --preset $argv ";" self-insert expand-abbr-backtrack + bind --preset $argv "|" self-insert expand-abbr-backtrack + bind --preset $argv "&" self-insert expand-abbr-backtrack + bind --preset $argv ">" self-insert expand-abbr-backtrack + bind --preset $argv "<" self-insert expand-abbr-backtrack + bind --preset $argv shift-enter "commandline -i \n" expand-abbr-backtrack + $legacy_bind --preset $argv \e\[27\;2\;13~ "commandline -i \n" expand-abbr-backtrack # Sent with XTerm.vt100.formatOtherKeys: 0 + bind --preset $argv alt-enter "commandline -i \n" expand-abbr-backtrack + bind --preset $argv ")" self-insert expand-abbr-backtrack # Closing a command substitution. bind --preset $argv ctrl-space 'test -n "$(commandline)" && commandline -i " "' bind --preset $argv -k nul 'test -n "$(commandline)" && commandline -i " "' # Shift-space behaves like space because it's easy to mistype. - bind --preset $argv shift-space 'commandline -i " "; commandline -f expand-abbr' + bind --preset $argv shift-space 'commandline -i " "' expand-abbr-backtrack bind --preset $argv enter execute bind --preset $argv ctrl-j execute diff --git a/src/input.rs b/src/input.rs index 0cf899117..31262d705 100644 --- a/src/input.rs +++ b/src/input.rs @@ -166,6 +166,7 @@ const INPUT_FUNCTION_METADATA: &[InputFunctionMetadata] = &[ make_md(L!("execute"), ReadlineCmd::Execute), make_md(L!("exit"), ReadlineCmd::Exit), make_md(L!("expand-abbr"), ReadlineCmd::ExpandAbbr), + make_md(L!("expand-abbr-backtrack"), ReadlineCmd::ExpandAbbrBacktrack), make_md(L!("force-repaint"), ReadlineCmd::ForceRepaint), make_md(L!("forward-bigword"), ReadlineCmd::ForwardBigword), make_md(L!("forward-char"), ReadlineCmd::ForwardChar), diff --git a/src/input_common.rs b/src/input_common.rs index 57feed3e5..28dc6a39d 100644 --- a/src/input_common.rs +++ b/src/input_common.rs @@ -111,6 +111,7 @@ pub enum ReadlineCmd { FuncAnd, FuncOr, ExpandAbbr, + ExpandAbbrBacktrack, DeleteOrExit, Exit, CancelCommandline, diff --git a/src/reader.rs b/src/reader.rs index ff63d7507..0a30c0de4 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -3069,6 +3069,13 @@ impl ReaderData { self.inputter.function_set_status(false); } } + rl::ExpandAbbrBacktrack => { + if self.expand_abbreviation_at_cursor(2) { + self.inputter.function_set_status(true); + } else { + self.inputter.function_set_status(false); + } + } rl::Undo | rl::Redo => { let (elt, el) = self.active_edit_line_mut(); let ok = if c == rl::Undo { el.undo() } else { el.redo() }; diff --git a/tests/pexpects/abbrs.py b/tests/pexpects/abbrs.py index d5f7bf4e8..918695804 100644 --- a/tests/pexpects/abbrs.py +++ b/tests/pexpects/abbrs.py @@ -29,6 +29,9 @@ expect_str(r"") send(r"echo alpha ?") expect_str(r"") +send(r"alpha;?") +expect_str(r"") + # Abbreviation expansions may have multiple words. sendline(r"abbr --add emacsnw emacs -nw -l") expect_prompt()