Haga que emacsclient cree un marco solo si aún no hay uno

11

¿Cómo puedo hacer emacsclient -a '' -ncrear un nuevo marco solo si todavía no hay uno?

El problema con la -cbandera es que crea un nuevo marco cada vez. El problema sin esto es que si no hay un marco abierto, se abrirá en la línea de comando.

Si puedo verificar si hay un marco abierto de Emacs desde el shell, puedo llamar con o sin -cdepender de eso para obtener el comportamiento que quiero. Lo intenté:

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

Siempre obtengo el mismo resultado.

Podría usar archivos temporales o pgrep, pero esos enfoques son muy propensos a errores.

Esto es similar a esta pregunta , pero no es un duplicado, ya que el OP allí estaba satisfecho con tener un marco abierto antes de llamar emacsclient.

spelufo
fuente
1
La misma pregunta superuser.com/questions/358037/… con elisp, bashy shrespuestas.
Konstantin Morenko

Respuestas:

3

Terminé haciendo este script basado en esto

#!/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 "$@"

Si no hay pantalla, se abre con -nw. Si $DISPLAYestá configurado, busca marcos en esa pantalla para ver si necesita hacer uno nuevo.

Editar: lo modifiqué para que pueda especificar manualmente -nwsi desea abrir en un terminal, incluso si hay una pantalla.

spelufo
fuente
1
Nitpick menor: $@ debe ser citado .
dshepherd
0

Puedes usar:

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

para verificar si el servidor Emacs "server_name"ya se está ejecutando. Si el comando devuelve el código de salida 0, se está ejecutando. Si es así, solo use el emacsclientcomando:

emacsclient -s server_name -n file_name.txt

Si no se está ejecutando, puede abrir un nuevo servidor Emacs con, por ejemplo:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
Håkon Hægland
fuente
Pero de esa manera, una vez que cierre el shell, matará al servidor, ¿verdad? Se emacsclient -a ''inicia emacs --daemonsi es necesario, lo que persiste incluso si cierra el shell.
spelufo
@spelufo El servidor no se mata al matar el shell. Tenga &en cuenta el al final del comando; significa ejecutar el servidor como un proceso en segundo plano ..
Håkon Hægland
Lo que lo bifurca al fondo del shell actual. No se mata cuando recuperas tu caparazón, pero se mata cuando cierras esa capa por completo ( C-d).
spelufo
El demonio sigue funcionando incluso si cierra todas sus terminales. Solo seguiría ejecutándose si server-startinicia el servidor como proceso de daemon. ¿Qué obtienes si inicias emacs de esa manera y luego cierras todos los emacs y terminales, luego abres una nueva terminal y corres pgrep emacs?
spelufo
@spelufo En realidad todavía se está ejecutando después C-d. Intenté esto ahora usando gnome-terminalUbuntu 14.10 .. ¿Creo que te refieres a una instancia en ejecución después de cerrar todos los marcos de Emacs? Entonces, eso requeriría un proceso de demonio, sí ..
Håkon Hægland