my usecase
I'm currently running GNU Emacs version=24.3.1 graphically (i.e., under GNOME/X though started from a script invoked from a gnome-terminal
running bash) on a Debian Linux. Just now I was using commandline abcde
to rip audio CDs when its terminal suddenly opened an instance of The Editor Which Must Not Be Named (to resolve an MP3 tagging question). I realized that, when I setup the box I'm currently using, I failed to set either of the bash environment variables EDITOR
or VISUAL
in my .bashrc
.
what I want
I nearly always have an graphical/X instance of Emacs running. If I'm not running Emacs, I probably have a good reason not to (e.g., a problem with my config files, or that I'm running in a tty). So I'm wondering, how to set EDITOR
or VISUAL
so that an application that wants to open an editor does one of the following, in descending order of preference:
- If I already have an instance of Emacs running (i.e.,
pgrep -l emacs | wc -l
->1
): open the thing to be edited in a new buffer in the running Emacs. - If I do not have an instance of Emacs running (i.e.,
pgrep -l emacs | wc -l
->0
): start a new instance ofemacs -nw -q
in the terminal.
If I can't get both those preferences, or if there's a reason why I should deprecate one or both, feel free to recommend Something Completely Different.
solution
emacsclient
is finicky about its arguments (TODO: put a bug on it!), but that can be worked-around:
Per Francesco's suggestion I made
~/bin/emacs-nw-q.sh
(and of course set mode=executable)### Purely for use with `emacsclient`: see https://emacs.stackexchange.com/a/8089/5444 emacs -nw -q $@
Added a stanza to the end of my
.bashrc
:if [[ -z "${EDITOR}" ]] ; then export ALTERNATE_EDITOR="${HOME}/bin/emacs-nw-q.sh" export EDITOR='emacsclient' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With this, and
- a running "emacs+server" (i.e., a previously-running graphical Emacs, in which I have done
M-x server-start
): an edit-seeking application successfully opens a buffer in the running emacs on the desired file, and killing that buffer unpauses the edit-seeking application. - no running emacs+server: an edit-seeking application opens a "bare-bones" Emacs in its same terminal, as desired, with a buffer open to the desired file, and killing that buffer returns control to the edit-seeking application.
how I failed
I'm putting a stanza at the end of my .bashrc
: each of the stanzas I've tried is listed below, with the resulting error. To test each stanza, after I [edit, save] .bashrc
(via emacs -nw -q ~/.bashrc
in a separate gnome-terminal
tab), I open a fresh gnome-terminal
tab to exercise it.
With a running emacs (and after
M-x server-start
), following fails withemacsclient: unrecognized option '-''
if [[ -z "${EDITOR}" ]] ; then export EDITOR="emacsclient --alternate-editor='emacs -nw -q'" fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With a running emacs+server, following fails with
emacsclient: unrecognized option '-"'
if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient --alternate-editor="emacs -nw -q"' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following fails with
emacsclient: error executing alternate editor ""emacs""
. So I guess--alternate-editor
just won't take a quoted argument?if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient --alternate-editor="emacs"' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following starts a brand-new graphical emacs with everything (including full
desktop
, which I don't want for this usecase) ... but it gets worse: after I save and kill the buffer opened by the caller app, that caller app just sits there!if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient --alternate-editor=emacs' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following fails with
emacsclient: error executing alternate editor """"
if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient --alternate-editor=""' # sorta suggested by erikstokes at above link fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following fails with
emacsclient: error executing alternate editor """"
(i.e., same as previous)if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient -a""' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following fails with
emacsclient: error executing alternate editor "''"
if [[ -z "${EDITOR}" ]] ; then export EDITOR="emacsclient -a''" fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
With no running emacs, following
if [[ -z "${EDITOR}" ]] ; then export EDITOR='emacsclient' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
fails with
emacsclient: No socket or alternate editor. Please use: --socket-name --server-file (or environment variable EMACS_SERVER_FILE) --alternate-editor (or environment variable ALTERNATE_EDITOR)
With no running emacs, following fails with
emacsclient: error executing alternate editor "emacs -nw -q"
if [[ -z "${EDITOR}" ]] ; then export ALTERNATE_EDITOR='emacs -nw -q' export EDITOR='emacsclient' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
Per Francesco's suggestion I made
~/bin/emacs-nw-q.sh
### Purely for use with `emacsclient`: see https://emacs.stackexchange.com/a/8089/5444 emacs -nw -q
and changed my
.bashrc
stanza toif [[ -z "${EDITOR}" ]] ; then export ALTERNATE_EDITOR="${HOME}/bin/emacs-nw-q.sh" export EDITOR='emacsclient' fi if [[ -n "${EDITOR}" && -z "${VISUAL}" ]] ; then export VISUAL="${EDITOR}" fi
Good news: with running emacs (and after
M-x server-start
), an edit-seeking application successfully opens a buffer in the running emacs on the desired file, and killing that buffer returns control to the edit-seeking application.More good news: with no running emacs+server, the edit-seeking application opens a "bare-bones" Emacs in its same terminal, as desired.
Bad news: with no running emacs+server, the "bare-bones" Emacs does not open the needed file in a buffer. It does create the following buffers:
*GNU Emacs*
,*Messages*
,*scratch*
... but not the needed buffer.