emacsclient: создайте фрейм, если фрейм не существует

2686
Idlecool

Я запускаю сервер Emacs, используя

emacs --daemon 

затем откройте файлы, используя

emacsclient filename.ext 

но первый файл должен быть открыт с помощью

emacsclient -c filename.ext 

чтобы создать новый фрейм, который впоследствии можно будет использовать в последующих файлах без использования -cфлага командной строки для emacsclient.

Я хочу автоматизировать это. msgstr "если фрейма emacs нет, emacsclient должен создать фрейм, иначе он должен использовать текущий фрейм". Как это можно сделать?

5
Когда я делаю `man emacsclient`, это не говорит мне о опции` -c`. Знаете ли вы, какие версии демонстрируют такое поведение? dmckee 12 лет назад 0
@dmckee `emacsclient -c` является новинкой в ​​значительно улучшенном emacsclient в Emacs 23. Gilles 12 лет назад 0

8 ответов на вопрос

6
Gilles

Сначала вы можете создать фрейм, если его еще нет, а затем открыть файл в уже существующем фрейме. Вот фрагмент кода, который создает рамку на начальном экране, если на оконном дисплее не было открыто ни одного кадра. Возможно, вы захотите изменить это несколькими способами, например, проверить, есть ли уже рамка на дисплее x-display-list. Вы нуждаетесь (require 'cl)в вашем `.emacs. Это может потребовать некоторой адаптации для работы на Windows или Aqua.

emacsclient -e '(unless (find-if (lambda (f) (let ((p (frame-parameters f))) (assq '\''window-system p))) (frame-list)) (make-frame-on-display (getenv "DISPLAY")))' emacsclient filename.ext 
6
dimitri

Вот скрипт emacs-client.sh, который я использую под Linux, чтобы сделать именно то, что вы просите:

#!/bin/sh  xprop -name emacs >/dev/null 2>/dev/null if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
Этот ответ нуждается в большем количестве голосов! Arash 10 лет назад 0
Это кажется запутанным, когда вы убиваете фрейм Emacs. В этот момент сервер emacs все еще работает, и строка xprop возвращает 0, поэтому он не открывает новый кадр после первого раза. Я что-то пропустил? demented hedgehog 8 лет назад 0
Решение Джима Ханзикера, похоже, не та же проблема. demented hedgehog 8 лет назад 0
4
Jim Hunziker

Это похоже на решение Дмитрия, но оно обрабатывает случай, когда emacs был запущен как emacs --daemon. emacs --daemonсоздает скрытое окно, которое приводит xpropк ложному срабатыванию при проверке существующего окна.

#!/bin/bash  emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" | grep t if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
2
Ivan Andrus

Я думаю, что добавление функции Жиля server-switch-hookможет сделать то, что вы хотите. К сожалению, я не могу заставить себя emacs --daemonпроверить это.

(add-hook 'server-switch-hook (lambda () (unless (find-if (lambda (f) (let ((p (frame-parameters f))) (assq 'window-system p))) (frame-list)) (make-frame-on-display (getenv "DISPLAY"))))) 
2
Jean-Marc E

Мое решение состоит в том, чтобы форсировать создание фрейма после запуска демона:

function em() { emacs --bg-daemon --display=:0 # Forces emacs to notice I'm using X as well. emacsclient --create-frame --display=:0 --no-wait } 

и тогда мне никогда не придется использовать --create-frame.

0
ws6079

В OSX я просто определяю эту функцию (аналогично подходу Джима Хунцикера)

emacs () { pgrep -xiq emacs && emacsclient -n $@ || emacsclient -n -c --alternate-editor="" $@; } 
0
brettk

Ответ Джима Ханзикера мне не совсем подходит (в некоторых ситуациях frame-list возвращает два элемента, даже если X-кадра нет). Предполагая, что вы используете только один DISPLAY, работает следующее:

#!/bin/bash  emacsclient -n -e "(null (cl-remove-if (lambda (frame) (null (display-graphic-p frame))) (frame-list)))" | grep >/dev/null nil if [ "$?" = "1" ]; then emacsclient -c -n -a "" "$@" else emacsclient -n -a "" "$@" fi 
0
Zitrax

Еще одна версия, которая также работает в режиме tty / console:

#!/bin/bash   emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" | grep t  if [ "$?" = "1" ]; then  if [ "$DISPLAY" = "" ]; then  emacsclient -c -a "" "$@"  else  emacsclient -c -n -a "" "$@"  fi  else  if [ "$DISPLAY" = "" ]; then  emacsclient -a "" "$@" else emacsclient -n -a "" "$@" fi fi 

(На основе ответа Джима Хунзикерса)

Похожие вопросы