30 Sep 2023

Using Emacs as $EDITOR

Continuing on from my experiment with using Emacs as for scrollback in my terminal multiplexer I thought I'd try to use it as my $EDITOR as well.

The two main cases where I use $EDITOR is

  1. The occasional use of git on the command line, rebasing or writing a commit message, and
  2. Use of ZSH's edit-command-line functionality.

To make sure Emacs is starting up quickly enough I'm using the same small setup I created for the scrollback editing, so I'm now setting EDITOR like this

export EDITOR="emacs -nw --init-directory ~/.se.d"

Now that I want to use the same setup for editing I can't really jump into view-mode every time Emacs starts so I have to be a bit more clever. The following bit won't do

(add-hook 'find-file-hook #'view-mode)

I need to somehow find out what starts Emacs and then only modify the hook when needed. Unfortunately I haven't found anything that reveals that Emacs is started by zellij. Creating a separate little script that zellij uses would be an option, of course, but for now I've opted to make it the default and instead refrain from adding the hook in the other two use cases.

ZSH doesn't make it easy to find out that it's edit-command-line either, but as I've observed that the command line sometimes doesn't look right after leaving the editor I wanted to call redisplay to fix it up. That means I need to have a function anyway, so using an environment variable becomes an easy way to check if Emacs is being used to edit the command line.

function se-edit-command-line() {
    export SE_SKIP_VIEW=y
    zle edit-command-line
    unset SE_SKIP_VIEW
    zle redisplay
}
zle -N se-edit-command-line

bindkey -M vicmd '^V' se-edit-command-line
bindkey -M viins '^V' se-edit-command-line

Unfortunately is seems zle edit-command-line doesn't pass on non-exported environment variables, hence the explicit export and unset.

When git starts an editor it sets a few environment variables so it was easy to just pick one that is set in both cases I care about. I picked GIT_EXEC_PATH.

With these things in place I changed the slim setup to only add the hook when neither of the environment variables are present

(unless (or (getenv "SE_SKIP_VIEW")
            (getenv "GIT_EXEC_PATH"))
  (add-hook 'find-file-hook #'view-mode))

Hopefully this works out well enough that I won't feel a need to go back to using Neovim as my $EDITOR.

Tags: emacs zsh
Comment here.