Niech emacsclient utworzy ramkę tylko wtedy, gdy jeszcze jej nie ma

11

Jak mogę emacsclient -a '' -nutworzyć nową ramkę, tylko jeśli jeszcze jej nie ma?

Problem z -cflagą polega na tym, że za każdym razem tworzy nową ramkę. Problem bez tego polega na tym, że jeśli nie ma otwartej ramki, otworzy się w wierszu poleceń.

Jeśli mogę sprawdzić, czy z powłoki jest otwarta ramka Emacsa, mogę zadzwonić z tym lub bez niego -c, aby uzyskać pożądane zachowanie. Próbowałem:

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

Zawsze otrzymuję ten sam wynik.

Mógłbym użyć plików tymczasowych lub pgrep, ale te podejścia są bardzo podatne na błędy.

Jest to podobne do tego pytania , ale nie jest to duplikat, ponieważ OP był zadowolony z konieczności otwarcia ramki przed wywołaniem emacsclient.

spelufo
źródło
1
To samo pytanie superuser.com/questions/358037/... z elisp, bashi shodpowiedzi.
Konstantin Morenko,

Odpowiedzi:

3

Skończyło się na co ten skrypt w oparciu o ten

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

Jeśli nie ma wyświetlacza, otwiera się za pomocą -nw. Jeśli $DISPLAYjest ustawiony, to szuka ramek na tym ekranie, aby sprawdzić, czy musi utworzyć nową.

Edycja: Zmodyfikowałem go, abyś mógł ręcznie określić, -nwczy chcesz otwierać w terminalu, nawet jeśli jest wyświetlacz.

spelufo
źródło
1
Drobny nitpick: $@ należy zacytować .
dshepherd
0

Możesz użyć:

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

aby sprawdzić, czy serwer Emacs "server_name"już działa. Jeśli polecenie zwraca kod wyjścia 0, jest uruchomione. Jeśli tak, po prostu użyj emacsclientpolecenia:

emacsclient -s server_name -n file_name.txt

Jeśli nie jest uruchomiony, możesz otworzyć nowy serwer Emacs, na przykład:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
Håkon Hægland
źródło
Ale w ten sposób po zamknięciu powłoki zabijesz serwer, prawda? Do emacsclient -a ''rozpoczyna emacs --daemonrazie potrzeby, która utrzymuje się nawet po zamknięciu osłony.
spelufo
@spelufo Serwer nie zostaje zabity przez zabicie powłoki. Uwaga &na końcu polecenia; oznacza to uruchomienie serwera jako procesu w tle.
Håkon Hægland
Który powoduje, że przechodzi w tło bieżącej powłoki. Nie jest zabijany po odzyskaniu powłoki, ale JEST zabijany po całkowitym zamknięciu tej powłoki ( C-d).
spelufo
Demon nadal działa, nawet jeśli zamkniesz wszystkie terminale. Będzie działał tylko wtedy, gdy uruchomi server-startserwer jako proces demona. Co otrzymasz, jeśli uruchomisz emacsa w ten sposób, a następnie zamkniesz wszystkie emacsy i terminale, a następnie otworzysz nowy terminal i uruchomisz pgrep emacs?
spelufo
@spelufo Właściwie nadal działa po C-d. Próbowałem tego teraz gnome-terminalna Ubuntu 14.10 .. Myślę, że masz na myśli działającą instancję po zamknięciu wszystkich ramek Emacsa? W takim przypadku wymagałoby to procesu demona tak ..
Håkon Hægland