7

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

emacs --daemon

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

emacsclient filename.ext

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

emacsclient -c filename.ext

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

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

8 ответов8

7

Сначала вы можете создать фрейм, если его еще нет, а затем открыть файл в уже существующем фрейме. Вот фрагмент кода, который создает рамку на начальном экране, если на оконном дисплее не было открыто ни одной рамки. Вы можете настроить это несколькими способами, например, проверить, есть ли уже рамка на дисплее с помощью 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

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

#!/bin/bash

emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" | grep -q t
if [ "$?" = "1" ]; then
    emacsclient -c -n -a "" "$@"
else
    emacsclient -n -a "" "$@"
fi
6

Вот скрипт 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
2

Я думаю, что добавление функции Gilles к 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

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

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

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

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

Еще одна версия, которая также работает в режиме 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

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

0

Ответ Джима Ханзикера мне не совсем подходит (в некоторых ситуациях 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .