From 9158395d10cfa584a988ba093cf7a93a70b48578 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Thu, 11 Apr 2024 12:34:58 +0200 Subject: [PATCH] Fix __fish_list_current_token and friends for multiline commandlines Some of these handled multiline prompts but not multiline command lines. We first need to move the cursor to the end of the commandline, then we can print a message. Finally, we need to move the cursor back to where it was. --- CHANGELOG.rst | 1 + share/functions/__fish_anyeditor.fish | 7 +++-- share/functions/__fish_echo.fish | 8 ++++++ .../functions/__fish_list_current_token.fish | 13 ++++----- .../__fish_whatis_current_token.fish | 7 +---- share/functions/fish_job_summary.fish | 27 ++++++++----------- 6 files changed, 29 insertions(+), 34 deletions(-) create mode 100644 share/functions/__fish_echo.fish diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 57e0272ce..1ae4b522e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -114,6 +114,7 @@ New or improved bindings - The editor's cursor position is copied back to fish. This is currently supported for Vim and Kakoune. - Cursor position synchronization is only supported for a set of known editors. This has been extended by also resolving aliases. For example use ``complete --wraps my-vim vim`` to synchronize cursors when `EDITOR=my-vim`. - ``backward-kill-path-component`` and friends now treat ``#`` as part of a path component (:issue:`10271`). +- Bindings like :kbd:`alt-l` that print output in between prompts now work correctly with multiline commandlines. - The ``E`` binding in vi mode now correctly handles the last character of the word, by jumping to the next word (:issue:`9700`). - If the terminal supports shifted key codes from the [kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/), ``shift-enter`` now inserts a newline instead of executing the command line. - Vi mode has seen some improvements but continues to suffer from the lack of people working on it. diff --git a/share/functions/__fish_anyeditor.fish b/share/functions/__fish_anyeditor.fish index 2f80fe256..2385d800e 100644 --- a/share/functions/__fish_anyeditor.fish +++ b/share/functions/__fish_anyeditor.fish @@ -5,10 +5,9 @@ function __fish_anyeditor --description "Print a editor to use, or an error mess else if set -q EDITOR echo $EDITOR | read -at editor else - echo >&2 - echo >&2 (_ 'External editor requested but $VISUAL or $EDITOR not set.') - echo >&2 (_ 'Please set VISUAL or EDITOR to your preferred editor.') - commandline -f repaint + __fish_echo string join \n -- \ + (_ 'External editor requested but $VISUAL or $EDITOR not set.') \ + (_ 'Please set VISUAL or EDITOR to your preferred editor.') return 1 end string join \n $editor diff --git a/share/functions/__fish_echo.fish b/share/functions/__fish_echo.fish new file mode 100644 index 000000000..94768fbdc --- /dev/null +++ b/share/functions/__fish_echo.fish @@ -0,0 +1,8 @@ +function __fish_echo --description 'run the given command after the current commandline and redraw the prompt' + set -l line (commandline --line) + string >&2 repeat -N \n --count=(math (commandline | count) - $line + 1) + $argv >&2 + string >&2 repeat -N \n --count=(math (count (fish_prompt)) - 1) + string >&2 repeat -N \n --count=(math $line - 1) + commandline -f repaint +end diff --git a/share/functions/__fish_list_current_token.fish b/share/functions/__fish_list_current_token.fish index 59db6697f..5ecac9fec 100644 --- a/share/functions/__fish_list_current_token.fish +++ b/share/functions/__fish_list_current_token.fish @@ -3,19 +3,16 @@ function __fish_list_current_token -d "List contents of token under the cursor if it is a directory, otherwise list the contents of the current directory" set -l val (commandline -t | string replace -r '^~' "$HOME") - printf "\n" + set -l cmd if test -d $val - ls $val + set cmd ls $val else set -l dir (dirname -- $val) if test $dir != . -a -d $dir - ls $dir + set cmd ls $dir else - ls + set cmd ls end end - - string repeat -N \n --count=(math (count (fish_prompt)) - 1) - - commandline -f repaint + __fish_echo $cmd end diff --git a/share/functions/__fish_whatis_current_token.fish b/share/functions/__fish_whatis_current_token.fish index 62cf09fbb..7034c791c 100644 --- a/share/functions/__fish_whatis_current_token.fish +++ b/share/functions/__fish_whatis_current_token.fish @@ -6,7 +6,6 @@ function __fish_whatis_current_token -d "Show man page entries or function descr test -n "$token" or return - printf "\n" set -l desc "$token: nothing appropriate." set -l tokentype (type --type $token 2>/dev/null) @@ -26,9 +25,5 @@ function __fish_whatis_current_token -d "Show man page entries or function descr and set desc $tmpdesc end - printf "%s\n" $desc - - string repeat -N \n --count=(math (count (fish_prompt)) - 1) - - commandline -f repaint + __fish_echo string join \n -- $desc end diff --git a/share/functions/fish_job_summary.fish b/share/functions/fish_job_summary.fish index fbff670de..9a8bdffa6 100644 --- a/share/functions/fish_job_summary.fish +++ b/share/functions/fish_job_summary.fish @@ -27,30 +27,25 @@ function fish_job_summary -a job_id is_foreground cmd_line signal_or_end_name si set -l max_cmd_len 32 set cmd_line (string shorten -m$max_cmd_len -- $cmd_line) - if test $is_foreground -eq 0; and test $signal_or_end_name != STOPPED - # Add a newline *before* our message so we get the message after the commandline. - echo >&2 - end - + set -l message switch $signal_or_end_name case STOPPED - printf ( _ "fish: Job %s, '%s' has stopped\n" ) $job_id $cmd_line + set message (printf ( _ "fish: Job %s, '%s' has stopped\n" ) $job_id $cmd_line) case ENDED - printf ( _ "fish: Job %s, '%s' has ended\n" ) $job_id $cmd_line + set message (printf ( _ "fish: Job %s, '%s' has ended\n" ) $job_id $cmd_line) case 'SIG*' if test -n "$proc_pid" - printf ( _ "fish: Process %s, '%s' from job %s, '%s' terminated by signal %s (%s)\n" ) \ - $proc_pid $proc_name $job_id $cmd_line $signal_or_end_name $signal_desc + set message (printf ( _ "fish: Process %s, '%s' from job %s, '%s' terminated by signal %s (%s)\n" ) \ + $proc_pid $proc_name $job_id $cmd_line $signal_or_end_name $signal_desc) else - printf ( _ "fish: Job %s, '%s' terminated by signal %s (%s)\n" ) \ - $job_id $cmd_line $signal_or_end_name $signal_desc + set message (printf ( _ "fish: Job %s, '%s' terminated by signal %s (%s)\n" ) \ + $job_id $cmd_line $signal_or_end_name $signal_desc) end - end >&2 + end if test $is_foreground -eq 0; and test $signal_or_end_name != STOPPED - # We want one newline per line in the prompt after the first. - # To ensure that, don't let `string repeat` add a newline. See #9044. - string repeat -N \n --count=(math (count (fish_prompt)) - 1) >&2 - commandline -f repaint + __fish_echo string join \n -- $message + else + string join >&2 \n -- $message end end