Запустить emacsclient внутри emacs (как делает magit)

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

Я чувствую, что это выполнимо, потому что magit уже делает что-то вроде этого: сообщение коммита редактируется emacsclient и всегда открывается в включающем экземпляре. Мне даже не нужно явно запускать сервер!

Я использую git commit из shell-mode. Я не могу полагаться на magit, потому что мне нужно использовать какую-то настроенную версию git со специальной командой. Во всяком случае, я думаю, что это было бы круто.

ОБНОВИТЬ:

Я нашел функцию магита magit-with-emacsclient здесь можно добиться успеха: https://github.com/magit/magit/blob/master/magit.el#L1979

Будем весьма благодарны за любую помощь в превращении функции в скрипт оболочки, который может выступать в качестве редактора по умолчанию для git! Я также постараюсь опубликовать код, если смогу заставить его работать.

ОБНОВЛЕНИЕ 2:

Вот мое решение. Требуется предварительно запустить сервер с pid в имени сокета, а затем установить ваш $EDITOR быть emacsclient подключение к этому серверу.

Поместите это в свой init.el

; start a server with a pid
(require 'server)
(defun server-start-pid ()
  (interactive)
  (when (server-running-p server-name)
    (setq server-name (format "server%s" (emacs-pid)))
    (when (server-running-p server-name)
      (server-force-delete server-name)))
  (server-start))

и беги server-start-pid прежде чем запустить редактор в вашем shell-mode,

поставить этот скрипт emacsclient-pid в вашем PATH, Он рекурсивно находит родительский процесс, пока не найдет экземпляр emacs и не вызовет emacsclient в правом гнезде:

#! /usr/bin/python
import os, sys
import psutil

def get_pid(name):
    pid = os.getppid()
    while True:
        proc = psutil.Process(pid)
        if name in proc.name():
            break
        pid = proc.ppid()
    return pid

if __name__ == '__main__':
    pid = get_pid("emacs")
    # pass the argument to emacsclient
    args = ' '.join(sys.argv[1:])
    cmd = "emacsclient -s server{pid} {args}".format(**globals())
    print cmd
    os.system(cmd)

И поместите это в свой .bashrc

if [[ $EMACS"x" == tx || $TERM"x" == dumbx ]]; then
    export PAGER=/bin/cat
    export EDITOR='emacsclient-pid'
else
    export PAGER=/usr/bin/less
    export EDITOR='emacs -q -nw'
fi

1 ответ

Решение

Я разделил код, отвечающий за взаимодействие клиент-сервер, в отдельную библиотеку with-editor, Это часть следующей ветки git-mode. Magit начнет использовать это, как только я объединю следующую ветку с master. Вы должны изучить это вместо старой реализации в самом magit, потому что она объединяет все связанные с этим вещи в одном месте и потому что она также улучшена многими способами. Например, это также работает при использовании бродяги.

with-editors может использоваться другими пакетами, кроме magit. Это одна из причин, почему я разделил ее на отдельную библиотеку / пакет. Но я еще не реализовал части, которые на самом деле не нужны Magit. Например, предоставляемые им функциональные возможности также можно использовать с shell-command см. https://github.com/magit/git-modes/pull/96.

Нечто подобное, вероятно, будет работать и в режиме оболочки. С очень быстрого взгляда я думаю, что функция, которая должна быть советами в этом случае, comint-exec, Я, вероятно, не буду работать над этим в ближайшее время, но в конце концов я вернусь к этому. А пока посмотри на эту библиотеку. Однако понять, что это делает, будет нелегко без хорошего знания elisp и того, как emacs обрабатывает дочерние процессы. Единственный совет, который я могу дать вам здесь, это также прочитать вопросы, которые касаются with-editor в magit/git-modes хранилище на github.

Ps. Преобразование этого в сценарий оболочки не будет работать, потому что в Emacs должны произойти определенные вещи до запуска дочернего процесса, например, запуск сервера.

Другие вопросы по тегам