1

我正在寻找在 shell 模式下启动 emacs 的方法,并且我希望客户端连接到封闭的 emacs 实例,因此我不需要切换到运行服务器的实例来编辑文件。

我觉得这是可行的,因为 magit 已经在做这样的事情:提交消息由 emacsclient 编辑,并且总是在封闭的实例中打开。我什至不需要显式启动服务器!

我的主要用途是从 shell 模式执行 git commit。我不能依赖 magit,因为我必须使用一些带有特殊命令的自定义 git 版本。无论如何,我认为这将是一件很酷的事情。

更新:

我在这里找到了可以解决问题的 magit 函数magit-with-emacsclienthttps ://github.com/magit/magit/blob/master/magit.el#L1979

任何将函数转换为可以充当 git 的默认编辑器的 shell 脚本的帮助将不胜感激!如果我能让它工作,我也会尝试发布代码。

更新 2:

这是我的解决方案。它需要预先在套接字名称中使用 pid 启动服务器,然后将您设置$EDITORemacsclient连接到该服务器。

把它放在你的 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
4

1 回答 1

4

我已将负责客户端-服务器交互的代码拆分为一个单独的库with-editor。它是 git-modes 下一个分支的一部分。一旦我将它的下一个分支合并到 master中,Magit 就会开始使用它。您应该研究它而不是 magit 本身中的旧实现,因为它将与此相关的所有内容都放在一个地方,并且在许多方面也得到了改进。例如,它在使用 tramp 时也可以工作。

with-editors可以被除 magit 之外的其他软件包使用。这就是我将其拆分为单独的库/包的原因之一。但是我还没有实现 magit 实际不需要的部分。例如,它提供的功能也可以与 一起使用shell-command,请参阅https://github.com/magit/git-modes/pull/96

类似的东西也可能适用于 shell 模式。从一个非常快速的角度来看,我认为在这种情况下需要建议的功能是comint-exec. 我可能不会很快解决这个问题,但最终我会回到这个问题上。同时你自己看看那个图书馆。但是,如果不充分了解 elisp 以及 emacs 如何处理子进程,理解它的作用并不容易。我可以在这里给你的唯一建议是阅读github 上with-editor的存储库中关注的问题。magit/git-modes

附言。将其转换为 shell 脚本是行不通的,因为在 Emacs 中必须在子进程启动之前发生某些事情,例如启动服务器。

于 2014-07-11T21:22:26.213 回答