From d8d491741b1d01f67879dddc8e642b04a211afa2 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 10 Mar 2024 10:16:35 +0100 Subject: [PATCH] edit_command_buffer: preserve external editor's cursor position Unless the editor changed to a different file for some reason. Note that the Kakoune integration uses -always to export the cursor even if the user temporarily suppressed hooks - possibly a "fish_indent" hook. --- CHANGELOG.rst | 3 +- share/functions/edit_command_buffer.fish | 42 ++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 61c6c7352..e7ec373c0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -51,7 +51,8 @@ Interactive improvements - Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete ``git add`` for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (:issue:`3707`). - The :kbd:`Control-R` history search now uses glob syntax (:issue:`10131`). - When the cursor is on a command that resolves to a script, :kbd:`Alt-O` will now open that script in your editor. -- :kbd:`Alt-E` now passes the cursor position to the external editor also if the editor aliases a supported editor (via ``complete --wraps``). +- After using :kbd:`Alt-E` to edit the commandline in an external editor, the editor's cursor position will be copied over to fish. This is currently supported for Vim and Kakoune. +- When deciding how to pass the cursor position to and from the external editor, :kbd:`Alt-E` now resolves aliases. For example use ``complete --wraps my-vim vim`` to synchronize cursors when `EDITOR=my-vim`. - Option completion now uses fuzzy subsequence filtering as well. This means that ``--fb`` may be completed to ``--foobar`` if there is no better match. - ASCII control characters are now rendered using symbols from Unicode's Control Pictures block. diff --git a/share/functions/edit_command_buffer.fish b/share/functions/edit_command_buffer.fish index 6c6f60358..6e382b361 100644 --- a/share/functions/edit_command_buffer.fish +++ b/share/functions/edit_command_buffer.fish @@ -38,12 +38,34 @@ function edit_command_buffer --description 'Edit the command buffer in an extern set -a wrapped_commands $tmp[1] end set -l found false + set -l cursor_from_editor for editor_command in $editor_basename $wrapped_commands switch $editor_command case vi vim nvim - set -a editor +$line +"norm! $col|" $f - case emacs emacsclient gedit kak + if test $editor_command = vi && not set -l vi_version "$(vi --version 2>/dev/null)" + if printf %s $vi_version | grep -q BusyBox + break + end + set -a editor +{$line} $f + set found true + break + end + set cursor_from_editor (mktemp) + set -a editor +$line "+norm! $col|" $f \ + '+autocmd VimLeave * ++once call writefile( + [printf("%s %s %s", shellescape(bufname()), line("."), col("."))], + "'$cursor_from_editor'" + )' + case emacs emacsclient gedit set -a editor +$line:$col $f + case kak + set cursor_from_editor (mktemp) + set -a editor +$line:$col $f -e " + hook -always -once global ClientClose %val{client} %{ + echo -to-file $cursor_from_editor -quoting shell \ + %val{buffile} %val{cursor_line} %val{cursor_column} + } + " case nano set -a editor +$line,$col $f case joe ee @@ -80,6 +102,22 @@ function edit_command_buffer --description 'Edit the command buffer in an extern echo (_ "Ignoring the output of your editor since its exit status was non-zero") echo (_ "or the file was empty") end + if set -q cursor_from_editor[1] + eval set -l pos "$(cat $cursor_from_editor)" + if set -q pos[1] && test $pos[1] = $f + set -l line $pos[2] + set -l column $pos[3] + commandline -C 0 + for _line in (seq $line)[2..] + commandline -f down-line + end + commandline -f beginning-of-line + for _column in (seq $column)[2..] + commandline -f forward-single-char + end + end + command rm $cursor_from_editor + end command rm $f # We've probably opened something that messed with the screen. # A repaint seems in order.