TIL:在 macOS 中让 Emacs 常驻后台运行

【更新】如用 brew 安装的 emacs-plus 可以直接在命令行输入:

brew services start emacs

优点是不必那么麻烦,缺点是方案没有共通性。

如有错漏,不吝指正,谢谢。

等效于 emasc --daemon 命令,但每次系统启动之后输入这个命令会很烦。我用 Doom Emacs,Emacs 版本 29.4,系统 macOS。

网络上找到一个老外写的方法,实测靠谱,退出 GUI Emacs 之后后台仍然有常驻进程。

他的方法是,将 emacsclient 写进 macOS 的 LaunchAgent,作为系统自启动服务加载。

  1. 创建文件:~/Library/LaunchAgents/gnu.emacs.plist

  2. 在文件里添加如下内容:

注:要将 username 替换自己的系统账户名。

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>KeepAlive</key>
      <true/>
      <key>Label</key>
      <string>gnu.emacs</string>
      <key>ProgramArguments</key>
      <array>
        <string>/opt/homebrew/bin/emacs</string>
        <string>--fg-daemon</string>
      </array>
      <key>RunAtLoad</key>
      <true/>
      <key>StandardErrorPath</key>
      <string>/tmp/gnu-emacs-daemon.log</string>
      <key>StandardOutPath</key>
      <string>/tmp/gnu-emacs-daemon.log</string>
      <key>UserName</key>
      <string>USERNAME</string>
    </dict>
  </plist>

验证方法:

在终端输入如下命令:

plutil -lint ~/Library/LaunchAgents/gnu.emacs.plist

如果成功会看到成功的消息:

  /Users/USERNAME/Library/LaunchAgents/gnu.emacs.plist: OK

如下命令用于启动、关闭服务:

launchctl load -w /Users/USERNAME/Library/LaunchAgents/gnu.emacs.plist
  launchctl unload /Users/USERNAME/Library/LaunchAgents/gnu.emacs.plist
  launchctl list
1 个赞

按 brew 的提示用

brew services start emacs

可以吗?

你可以直接测试的呀,先把所有 emacs 进程退出, 然后输入这个命令,再退出 emacs,查看进程是否还在

哦,我表达的有问题。我的意思是,不用那么麻烦吧,直接 brew services start emacs 就可以了。

1 个赞

楼上说的对,假如你是用 brew 安装的别的 emacs 修改版比如 emacs-plus,同理也可以用 brew services start emacs-plus@30, 也是可以的。
它的原理和你写的是一样的,只不过 brew services 会帮你自动生成,不需要你手写。

当然如果你不是用 brew 安装的,手动安装的那就需要自己写了。

2 个赞

这个也可以。不过,不是最通用的解法。

我是看到 lz 写的 plist 文件里是表明是 brew 安装的,所以才提的那个建议。

感谢建议(字数补丁

我之前用 brew services start emacs。后来发现如果我要退出emacs,它会自动重启。所以关了。

现在就每次启动电脑手动启动 daemon。

会不会有点烦?daemon 的内存开销也不大

其实电脑开了机就不再关了。也就是很多天开机一次,才需要执行一次 emacs -daemon。 我有的电脑是经常关机的,顺手启动一下,也没什么麻烦的。

我在想是否可以用自动化脚本来处理。这样就不用每一次都自己手动处理。

图形界面的emacs,可以直接加到mac的启动项里去。

和开机自启动的需求有点不同,常驻后台运行 emacs 进程的目的是增强 emacs 的性能,和减少报错的概率。虽然看上去有点像,但实质不是启动 App,而是启动 progress。

1 个赞

如果你想要启动 emacs 就开启服务模式,退出就关闭不想重启,只需要在你的配置文件里加上

(server-start)

ref: Emacs Server (GNU Emacs Manual)

1 个赞

这个我就不懂了。

用brew添加到服务列表之后。退出emacs之后,mac会自动重启emacs。好像和emacs本身的server不是一回事。

我的配置里是由 server-start的。

会不会导致了冲突? 我只用一个配置,来设置同一个东西

这就是 server 的正确行为,确保一定有一个后台进程。

brew 的服务会添加 daemon 命令行参数启动 emacs,而 emacs 收到 daemon 命令行参数后就会执行 (start-server).

如果你已经用了 daemon 启动就不需要再在配置里执行 (start-server).


所以:

  • 关闭之后自动重启是 MacOS LaunchAgent 负责的,它就相当于 linux 的 systemd service 或者 init.d
  • brew service 生成的 LaunchAgent plist 会使用 daemon 命令行参数启动 emacs,daemon 参数 等价于 (start-server)
  • 如果你不希望使用 LaunchAgent 自动重启,又想启动 emacs 服务模式,则可以在你手动启动时添加 daemon 参数,或者在配置里添加 (start-server)
2 个赞

写得特别好,