Faire en sorte qu'emacsclient crée un cadre uniquement s'il n'y en a pas déjà un

11

Comment puis-je emacsclient -a '' -ncréer un nouveau cadre uniquement s'il n'y en a pas déjà un?

Le problème avec le -cdrapeau est qu'il crée un nouveau cadre à chaque fois. Le problème sans cela est que s'il n'y a pas de cadre ouvert, il s'ouvrira dans la ligne de commande.

Si je peux vérifier s'il y a un cadre Emacs ouvert à partir du shell, je peux appeler avec ou sans en -cfonction de cela pour obtenir le comportement que je veux. J'ai essayé:

$ emacsclient -a '' --eval '(frames-on-display-list)'
(#<frame F1 0xba2740>)

J'obtiens toujours le même résultat.

Je pourrais utiliser des fichiers temporaires ou pgrep, mais ces approches sont très sujettes aux erreurs.

C'est similaire à cette question , mais ce n'est pas un doublon, car l'OP y était satisfait d'avoir à avoir une trame ouverte avant d'appeler emacsclient.

spelufo
la source
1
La même question superuser.com/questions/358037/... avec elisp, bashet des shréponses.
Konstantin Morenko

Réponses:

3

J'ai fini par faire ce script basé sur ça

#!/bin/bash -e

if [[ "$DISPLAY" ]]; then
        frame=`emacsclient -a '' -e "(member \"$DISPLAY\" (mapcar 'terminal-name (frames-on-display-list)))" 2>/dev/null`
        [[ "$frame" == "nil" ]] && opts='-c' # if there is no frame open create one
        [[ "${@/#-nw/}" == "$@" ]] && opts="$opts -n" # don't wait unless we've asked to run in a terminal
else
        opts='-nw'
fi

exec emacsclient -a '' $opts "$@"

S'il n'y a pas d'affichage, il s'ouvre avec -nw. Si $DISPLAYest défini, il recherche des cadres dans cet affichage pour voir s'il doit en créer un nouveau.

Edit: je l'ai modifié pour que vous puissiez spécifier manuellement -nwsi vous souhaitez ouvrir dans un terminal même s'il y a un affichage.

spelufo
la source
1
Petite piqûre: $@ doit être citée .
dshepherd
0

Vous pouvez utiliser:

emacsclient -s server_name -e '(+ 1 0)' >/dev/null 2>&1

pour vérifier si le serveur Emacs "server_name"est déjà en cours d'exécution. Si la commande renvoie le code de sortie 0, elle est en cours d'exécution. Si oui, utilisez simplement la emacsclientcommande:

emacsclient -s server_name -n file_name.txt

S'il ne fonctionne pas, vous pouvez ouvrir un nouveau serveur Emacs avec par exemple:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
Håkon Hægland
la source
Mais de cette façon, une fois que vous fermerez le shell, vous tuerez le serveur, non? Le emacsclient -a ''démarre emacs --daemonsi nécessaire, qui persiste même si vous fermez la coque.
spelufo
@spelufo Le serveur n'est pas tué en tuant le shell. Notez le &à la fin de la commande; cela signifie exécuter le serveur en tant que processus d'arrière-plan ..
Håkon Hægland
Ce qui le place à l'arrière-plan du shell actuel. Il n'est pas tué lorsque vous récupérez votre obus, mais il EST tué lorsque vous fermez complètement cet obus ( C-d).
spelufo
Le démon continue de fonctionner même si vous fermez tous vos terminaux. Il ne continuerait à fonctionner que si server-startle serveur démarre en tant que processus démon. Qu'obtenez-vous si vous démarrez emacs de cette façon, puis fermez tous les emacs et terminaux, puis ouvrez un nouveau terminal et exécutez pgrep emacs?
spelufo
@spelufo En fait, il fonctionne toujours après C-d. J'ai essayé ceci en utilisant maintenant gnome-terminalsur Ubuntu 14.10 .. Je pense que vous faites référence à une instance en cours d'exécution après avoir fermé tous les cadres Emacs? Alors, cela nécessiterait un processus démon oui ..
Håkon Hægland