确定 Emacs server 是否启动 或者说 server-running-p 的迷思
一个小问题:如何确定当前 Emacs 实例是否启动了服务器?
快速搜索一下,我们可以得到三种方法: server-mode
, (daemonp)
和 (server-running-p)
。这太多了,但是其中一个肯定是正确答案对吗? 然而,并不是. 因为这个小问题的真正答案是:你无能为力。
- 且仅当服务器使用
server-mode
函数启动时server-mode
的值才为t
。但是我们还有其他方法可以启动服务器,比如M-x server-start
或emacs --daemon
。 - 且仅当 Emacs 在守护进程模式下启动时,
(daemonp)
才会返回t
。
那么 (server-run-p)
呢?它看起来可能很不错,但是也有坑。
它初看起来很不错:执行 M-x server-start
后, (server-running-p)
会返回 t
!那么我们是不是就可以选它了呢?还不行!让我们启动一个新的 Emacs 实例,在不启动服务器的情况下执行 (server-run-p)
会发现依然返回 t
!
怎么回事?事实上 (server-running-p)
有点名不符实. 以下是其完整的源代码:
(defun server-running-p (&optional name)
"Test whether server NAME is running.
Return values:
nil the server is definitely not running.
t the server seems to be running.
something else we cannot determine whether it's running without using
commands which may have to wait for a long time."
(unless name (setq name server-name))
(condition-case nil
(if server-use-tcp
(with-temp-buffer
(insert-file-contents-literally (expand-file-name name server-auth-dir))
(or (and (looking-at "127\.0\.0\.1:[0-9]+ \([0-9]+\)")
(assq 'comm
(process-attributes
(string-to-number (match-string 1))))
t)
:other))
(delete-process
(make-network-process
:name "server-client-test" :family 'local :server nil :noquery t
:service (expand-file-name name server-socket-dir)))
t)
(file-error nil)))
doc-string 中描述了恐怖的细节。函数中的 -p
后缀说明这是一个谓词,即布尔函数。但在 server-running-p
, 返回 非 nil
值并不一定就是响亮而明确的 是!
, 它的意思其实是 嗯,也许吧,谁知道呢?
这是第三种可能,因为 Emacs 并不是黑白分明的。
但是这个函数做什么呢?它试图确定一个名叫 NAME
的服务器是否正在运行,方法是假设该服务器的配置与正在运行的实例完全一致。它可能最终会查看当前服务器的套接字文件,或者尝试启动一个 TCP 连接(这个开销非常昂贵)。
你可能会在构建 mode line 时调用 server-running-p
函数: 但是它会让你立刻冻结 Emacs 运行而且还无法恢复。
它的使用场景目前还不太清楚. 它无法确定正在运行的实例是否启用了服务器,但是它会使用该服务器的配置去搜索潜在的完全不同的其他服务器。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论