From 59fa04bd914535da0d86b2be793c049fdfc0d314 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Tue, 6 Dec 2016 19:24:08 -0800 Subject: [PATCH] function for editing command line in ext editor This implements a standard function and bindings for editing the command line in an external editor. This feature has been requested multiple times in the past year with various solutions cut and pasted into those issues. This change combines the best aspects of those solutions. Fixes #1215 --- doc_src/index.hdr.in | 4 ++ .../functions/__fish_shared_key_bindings.fish | 4 ++ share/functions/edit_command_buffer.fish | 44 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 share/functions/edit_command_buffer.fish diff --git a/doc_src/index.hdr.in b/doc_src/index.hdr.in index ee8f1ae7e..a7da811ea 100644 --- a/doc_src/index.hdr.in +++ b/doc_src/index.hdr.in @@ -1001,6 +1001,10 @@ Some bindings are shared between emacs- and vi-mode because they aren't text edi - @key{Alt,w} prints a short description of the command under the cursor. +- @key{Alt,e} edit the current command line in an external editor. The editor is chosen from the first available of the `$VISUAL` or `$EDITOR` variables. + +- @key{Alt,v} Same as @key{Alt,e}. + \subsection emacs-mode Emacs mode commands - @key{Home} or @key{Control,A} moves the cursor to the beginning of the line. diff --git a/share/functions/__fish_shared_key_bindings.fish b/share/functions/__fish_shared_key_bindings.fish index f015fd851..b011a9241 100644 --- a/share/functions/__fish_shared_key_bindings.fish +++ b/share/functions/__fish_shared_key_bindings.fish @@ -96,4 +96,8 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod # Make it easy to turn an unexecuted command into a comment in the shell history. Also, # remove the commenting chars so the command can be further edited then executed. bind $argv \e\# __fish_toggle_comment_commandline + + # The [meta-e] and [meta-v] keystrokes invoke an external editor on the command buffer. + bind \ee edit_command_buffer + bind \ev edit_command_buffer end diff --git a/share/functions/edit_command_buffer.fish b/share/functions/edit_command_buffer.fish new file mode 100644 index 000000000..afeff4d10 --- /dev/null +++ b/share/functions/edit_command_buffer.fish @@ -0,0 +1,44 @@ +function edit_command_buffer --description 'Edit the command buffer in an external editor' + set -l f (mktemp) + if set -q f[1] + mv $f $f.fish + set f $f.fish + else + # We should never execute this block but better to be paranoid. + if set -q TMPDIR + set f $TMPDIR/fish.(echo %self).fish + else + set f /tmp/fish.(echo %self).fish + end + touch $f + or return 1 + end + + # Edit the command line with the users preferred editor or vim or emacs. + commandline -b >$f + if set -q VISUAL + eval $VISUAL $f + else if set -q EDITOR + eval $EDITOR $f + else + echo + echo (_ 'External editor requested but $VISUAL or $EDITOR not set.') + echo (_ 'Please set VISUAL or EDITOR to your preferred editor.') + commandline -f repaint + command rm $f + return 1 + end + + # Here we're checking the exit status of the editor. + if test $status -eq 0 -a -s $f + # Set the command to the output of the edited command and move the cursor to the + # end of the edited command. + commandline -r (cat $f) + commandline -C 999999 + else + echo + echo (_ "Ignoring the output of your editor since its exit status was non-zero") + echo (_ "or the file was empty") + end + command rm $f +end