【问题标题】:start emacsclient within emacs (like magit does)在 emacs 中启动 emacsclient(就像 magit 一样)
【发布时间】:2014-07-10 17:33:30
【问题描述】:

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

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

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

更新:

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

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

更新 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))

并在shell-mode 中启动编辑器之前运行server-start-pid。

将此脚本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

【问题讨论】:

  • 您的目标是在 Emacs shell 模式缓冲区内运行一个 mini-Emacs 实例(emacsclient)吗?
  • 请说明你想做什么。您可以在shell-mode 中输入emacsclient somefile,但不清楚您为什么要这样做。您不能在shell-mode 中运行emacsclient -nw,但可以在ansi-term 中运行。
  • 为什么不直接从shell-mode 做git commit ...?不清楚为什么需要emacsclient。
  • FWIW,你可能会让 magit 为你发出正确的命令行。
  • 嗨@lawlist:是的,这就是我的目标。

标签: emacs emacsclient


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢magit作者的详细解答!我可以手动启动服务器。 shell 脚本可以知道 emacs 实例的 pid 并连接到该服务器吗?这并非完全没有麻烦,但可以解决我的大部分问题。
  • lsof -U -a -p $(ps -p $$ -o ppid=) |awk '$1 == "Emacs" { print $8; exit; }' on OS X 10.10 为我提供了套接字/服务器文件。我计划将其与INSIDE_EMACS 是否设置为适当分配EDITOR 的测试结合使用。如果我只在未定义时设置EDITOR,那么这应该适用于子shell,否则$$ 不会是Emacs。我的用例也是ansi-term/multi-term。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 2014-11-30
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
相关资源
最近更新 更多