这个Emacs会话有客户端 - 我该如何查找原因?

4

不时地,Emacs会提示“This Emacs session has clients; exit anyway?”。

(我使用的是Windows 7上的Emacs 24beta,如果有关系的话。)

我原本以为可能有一些通过emacsclientw.exe打开的文件仍在编辑中 - 但我没有找到任何这样的文件。

(我运行了git config --global core.editor "/c/lang/emacs-24beta/bin/emacsclientw.exe")

有没有办法找出哪些buffer正在被客户端占用?(或者还有其他要查找的东西吗?)

2个回答

10
有什么方法可以找出哪些缓冲区有客户端吗?
当一个缓冲区有客户端时,它的`server-buffer-clients`变量的值将是非空的。
我相信还有更好的方法,但这段代码应该会给出带有客户端的缓冲区列表:
```html
(require 'cl)
(defvar server-buffers nil)
(defun show-server-buffers () (interactive) (setq server-buffers nil) (let ((original-buffer (current-buffer))) (loop for buf in (buffer-list) do (progn (switch-to-buffer buf) (if (and server-buffer-clients (buffer-live-p buf)) (add-to-list 'server-buffers buf)))) (switch-to-buffer original-buffer) (message "server-buffers: %s" server-buffers)))
```

有趣。在编辑提交后(并关闭其缓冲区)它说:server-buffers: (#<killed buffer>)。 - Falko
顺便问一下:有没有更好的方法来关闭这样一个缓冲区,而不是保存C-c C-s然后杀掉缓冲区C-c C-k? - Falko
我已经编辑了我的答案,排除了被杀死的缓冲区,并正确清除了我的服务器缓冲区变量。 - Luke Girvin
4
通常情况下,你会使用C-x #而不是C-x k来告诉服务器你已经完成了该缓冲区和客户端的操作(当你启动客户端时,你应该看到这样一条消息)。请注意,翻译后不能添加解释或其他返回结果。 - phils

2

我已经对 list-processes 进行了适应,用于列出客户端。 使用新定义的命令 list-clients,您可以获得一个表格形式的客户端进程列表。 每个客户端都与服务端编辑缓冲区一起列出,该客户端是 server-buffer-clients 中的第一个条目。

(define-derived-mode client-menu-mode process-menu-mode "Client Menu"
  "Major mode for listing the currently connected client processes."
  (remove-hook 'tabulated-list-revert-hook #'list-processes--refresh t)
  (add-hook 'tabulated-list-revert-hook #'server-list-clients--refresh nil t))

(defun server-list-clients (&optional query-only buffer)
  "Display a list of all clients of this emacs session.
If optional argument QUERY-ONLY is non-nil, only processes with
the query-on-exit flag set are listed.
Any process listed as exited or signaled is actually eliminated
after the listing is made.
Optional argument BUFFER specifies a buffer to use, instead of
\"*Client List*\".
The return value is always nil."
  (interactive)
  (or (fboundp 'process-list)
      (error "Asynchronous subprocesses are not supported on this system"))
  (unless (bufferp buffer)
    (setq buffer (get-buffer-create "*Client Process List*")))
  (with-current-buffer buffer
    (client-menu-mode)
    (setq process-menu-query-only query-only)
    (server-list-clients--refresh)
    (tabulated-list-print))
  (display-buffer buffer)
  nil)

(defalias #'list-clients #'server-list-clients)

(defun server-client-buffer (client)
  "Return buffer with client in `server-buffer-clients'."
  (catch :found
    (dolist (buf (buffer-list))
      (if (memq client (with-current-buffer buf server-buffer-clients))
          (throw :found buf)))))

(defun server-list-clients--refresh ()
  "Recompute the list of client processes for the Client List buffer.
Also, delete any process that is exited or signaled."
  (setq tabulated-list-entries nil)
  (dolist (p server-clients)
    (cond ((memq (process-status p) '(exit signal closed))
       (delete-process p))
      ((or (not process-menu-query-only)
           (process-query-on-exit-flag p))
       (let* ((buf (server-client-buffer p))
          (type (process-type p))
          (name (process-name p))
          (status (symbol-name (process-status p)))
          (buf-label (if (buffer-live-p buf)
                 `(,(buffer-name buf)
                   face link
                   help-echo ,(format-message
                           "Visit buffer `%s'"
                           (buffer-name buf))
                   follow-link t
                   process-buffer ,buf
                   action process-menu-visit-buffer)
                   "--"))
          (tty (or (process-tty-name p) "--"))
          (cmd
           (if (memq type '(network serial))
               (let ((contact (process-contact p t)))
             (if (eq type 'network)
                 (format "(%s %s)"
                     (if (plist-get contact :type)
                     "datagram"
                       "network")
                     (if (plist-get contact :server)
                     (format "server on %s"
                         (or
                          (plist-get contact :host)
                          (plist-get contact :local)))
                       (format "connection to %s"
                           (plist-get contact :host))))
               (format "(serial port %s%s)"
                   (or (plist-get contact :port) "?")
                   (let ((speed (plist-get contact :speed)))
                     (if speed
                     (format " at %s b/s" speed)
                       "")))))
             (mapconcat 'identity (process-command p) " "))))
         (push (list p (vector name status buf-label tty cmd))
           tabulated-list-entries))))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接