Lassen Sie emacsclient nur dann einen Frame erstellen, wenn noch keiner vorhanden ist

11

Wie kann ich emacsclient -a '' -nnur dann einen neuen Rahmen erstellen, wenn noch keiner vorhanden ist?

Das Problem mit dem -cFlag ist, dass es jedes Mal einen neuen Frame erstellt. Das Problem ohne es ist, dass wenn kein Frame geöffnet ist, er in der Befehlszeile geöffnet wird.

Wenn ich überprüfen kann, ob ein offener Emacs-Frame in der Shell vorhanden ist, kann ich mit oder ohne davon aufrufen -c, um das gewünschte Verhalten zu erhalten. Ich habe es versucht:

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

Ich bekomme immer das gleiche Ergebnis.

Ich könnte temporäre Dateien oder pgrep verwenden, aber diese Ansätze sind sehr fehleranfällig.

Dies ähnelt dieser Frage , ist jedoch kein Duplikat, da das dortige OP damit zufrieden war, vor dem Aufruf einen Frame geöffnet zu haben emacsclient.

spelufo
quelle
1
Die gleiche Frage superuser.com/questions/358037/... mit elisp, bashund shAntworten.
Konstantin Morenko

Antworten:

3

Am Ende habe ich dieses Skript basierend darauf erstellt

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

Wenn keine Anzeige vorhanden ist, wird sie mit geöffnet -nw. Wenn festgelegt, $DISPLAYwird in dieser Anzeige nach Frames gesucht, um festzustellen, ob ein neuer erstellt werden muss.

Bearbeiten: Ich habe es so geändert, dass Sie manuell angeben können, -nwob Sie in einem Terminal öffnen möchten, auch wenn eine Anzeige vorhanden ist.

spelufo
quelle
1
Minor nitpick: $@ sollte zitiert werden .
Dshepherd
0

Sie können verwenden:

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

um zu überprüfen, ob der Emacs-Server "server_name"bereits ausgeführt wird. Wenn der Befehl den Exit-Code 0 zurückgibt, wird er ausgeführt. Wenn ja, verwenden Sie einfach den emacsclientBefehl:

emacsclient -s server_name -n file_name.txt

Wenn es nicht ausgeführt wird, können Sie einen neuen Emacs-Server öffnen, zum Beispiel mit:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
Håkon Hægland
quelle
Aber auf diese Weise wird der Server getötet, sobald Sie die Shell schließen, oder? Das emacsclient -a ''startet emacs --daemonbei Bedarf, was auch dann bestehen bleibt, wenn Sie die Shell schließen.
Spelufo
@spelufo Der Server wird nicht durch das Beenden der Shell getötet. Beachten Sie das &am Ende des Befehls; Es bedeutet, den Server als Hintergrundprozess
auszuführen
Was es in den Hintergrund der aktuellen Shell bringt. Es wird nicht getötet, wenn Sie Ihre Shell zurückbekommen, aber es wird getötet, wenn Sie diese Shell vollständig schließen ( C-d).
Spelufo
Der Daemon läuft weiter, auch wenn Sie alle Terminals schließen. Es wird nur weiter ausgeführt, wenn server-startder Server als Daemon-Prozess gestartet wird. Was erhalten Sie, wenn Sie Emacs auf diese Weise starten und dann alle Emacs und Terminals schließen, dann ein neues Terminal öffnen und ausführen pgrep emacs?
Spelufo
@spelufo Eigentlich läuft es noch nach C-d. Ich habe dies jetzt unter gnome-terminalUbuntu 14.10 versucht . Ich denke, Sie beziehen sich auf eine laufende Instanz, nachdem Sie alle Emacs-Frames geschlossen haben. Dann würde das einen Daemon-Prozess erfordern, ja ..
Håkon Hægland