Заставьте emacsclient создать фрейм, только если его еще нет

11

Как я могу emacsclient -a '' -nсоздать новый кадр, только если его еще нет?

Проблема с -cфлагом заключается в том, что он каждый раз создает новый кадр. Проблема без него состоит в том, что если нет открытого кадра, он откроется в командной строке.

Если я могу проверить, есть ли открытый фрейм Emacs из оболочки, я могу вызвать с или без, в -cзависимости от этого, чтобы получить поведение, которое я хочу. Я попытался:

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

Я всегда получаю один и тот же результат.

Я мог бы использовать временные файлы или pgrep, но эти подходы очень подвержены ошибкам.

Это похоже на этот вопрос , но оно не является дубликатом, так как OP был удовлетворен необходимостью открыть кадр перед вызовом emacsclient.

spelufo
источник
1
Тот же вопрос superuser.com/questions/358037/... с elisp, bashи shответы.
Константин Моренко

Ответы:

3

Я закончил делать этот сценарий на основе этого

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

Если нет дисплея, он открывается с помощью -nw. Если $DISPLAYустановлено, он ищет кадры на этом дисплее, чтобы увидеть, нужно ли создавать новый.

Изменить: я изменил его, так что вы можете вручную указать -nw, хотите ли вы открыть в терминале, даже если есть дисплей.

spelufo
источник
1
Незначительный придурок: $@ следует процитировать .
dshepherd
0

Ты можешь использовать:

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

проверить, "server_name"запущен ли сервер Emacs . Если команда возвращает код выхода 0, она выполняется. Если это так, просто используйте emacsclientкоманду:

emacsclient -s server_name -n file_name.txt

Если он не запущен, вы можете открыть новый сервер Emacs, например:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
Хокон Хагланд
источник
Но таким образом, закрыв оболочку, вы убьете сервер, верно? В emacsclient -a ''начинается emacs --daemonпри необходимости, которая сохраняется даже при закрытии оболочки.
spelufo
@spelufo Сервер не убивает, убивая оболочку. Обратите внимание &на в конце команды; это означает, что сервер запускается как фоновый процесс ..
Håkon Hægland
Который разветвляется на фоне текущей оболочки. Он не убивается, когда вы возвращаете свою оболочку, но он убивается, когда вы полностью закрываете эту оболочку ( C-d).
spelufo
Демон продолжает работать, даже если вы закроете все свои терминалы. Он будет продолжать работать только в том случае, если server-startсервер запускается как процесс-демон. Что вы получите, если вы запустите emacs таким образом, а затем закроете все emacs и терминалы, затем откроете новый терминал и запустите pgrep emacs?
spelufo
@spelufo На самом деле это все еще работает после C-d. Я попробовал это сейчас, используя gnome-terminalв Ubuntu 14.10. Я думаю, что вы ссылаетесь на работающий экземпляр после закрытия всех фреймов Emacs? Тогда, это потребовало бы процесса демона, да ..
Håkon Hægland