La description
Le comportement par défaut lors de l'appel à emacsclient est un peu conservateur. Découvrez ce commentaire d'
emacsclient.c :
/* Unless we are certain we don't want to occupy the tty, send our
tty information to Emacs. For example, in daemon mode Emacs may
need to occupy this tty if no other frame is available. */
D'après votre description et vos commentaires, il semble que vous essayez de démarrer le serveur Emacs à la demande tout en utilisant le -n
drapeau. Le commentaire "par exemple" est ici pourquoi emacsclient -n -a '' FILE
ne satisfait pas ce que vous recherchez quand aucun serveur n'est en cours d'exécution.
- La
-a ''
logique démarre un démon.
- Lui
emacsclient
dit ensuite de créer un nouveau cadre de terminal, car c'est la valeur par défaut, sauf si vous évaluez elisp.
- La
-n
logique tue immédiatement cette nouvelle trame terminale.
Si vous pouviez changer l'étape 2 pour créer un nouveau cadre graphique par défaut, alors vous
emacsclient -n -a '' FILE
feriez ce que vous voulez.
Elisp Solution
Vous pouvez amener Emacs à créer un nouveau cadre graphique par défaut si vous conseillez la fonction server-process-filter
comme ceci:
(defadvice server-process-filter (before prefer-graphical activate)
;; STRING is a sequence of commands sent from emacsclient to the server.
(when (and
;; Check that we're editing a file, as opposed to evaluating elisp.
(string-match "-file" string)
;; Check that there are no frames beyond the Emacs daemon's terminal.
(daemonp)
(null (cdr (frame-list)))
(eq (selected-frame) terminal-frame)
;; Check that we have a graphical display.
;; `display-graphic-p' doesn't work here.
(getenv "DISPLAY"))
(setq string (concat
;; STRING must be all one line, but comes to us
;; newline-terminated. Strip off the trailing newline.
(replace-regexp-in-string "\n$" "" string)
;; Add the commands to create a graphical frame.
"-window-system "
"-display " (getenv "DISPLAY")
;; Add back the newline.
"\n"))))
Mettez-le dans votre fichier init, puis, comme dit, emacsclient -n -a '' FILE
et Bob est votre oncle.
Comparez avec Shell Solution
D'une part, je peux souligner quelques avantages à utiliser cette approche par défaut par rapport à l'utilisation du
script suggéré par Archenoth
#!/bin/bash
emacs --eval '(server-start)' $* &
comme éditeur alternatif. Avec le defadvice:
save-buffers-kill-terminal
( C-x C-c
par défaut) se comporte de manière cohérente dans toutes les images. Cela ne tue jamais le processus Emacs, car chaque trame est toujours une trame client.
- Le cadre terminal du démon traîne. Les commandes comme
find-grep
ce shell vers les processus externes se comportent mieux lorsque le terminal muet est là. Au moins, je ressens moins de maux de tête liés à l'échappement.
D'un autre côté ... ouais.
- Ce script shell est magnifiquement simple.
- Le protocole de communication d'Emacs ne l'est pas.
Conclusion
Peut-être y a-t-il un compromis? C'est le mieux que j'ai pu trouver. Vous le définissez comme votre $ EDITOR.
#!/bin/sh
emacsclient -e "(frames-on-display-list \"${DISPLAY}\")" 1>/dev/null 2>/dev/null
if [ "$?" = "1" ]; then
emacsclient -c -n -a "" "$@"
else
emacsclient -n "$@"
fi
-a ''
option «Démarrer le démon Emacs et réessayer emacsclient»?