Eglot: add shutdown/reconnect bindings to eglot-list-connections buffer

* lisp/progmodes/eglot.el (eglot-list-connections-mode-map): New
defvar.

* lisp/progmodes/eglot.el (eglot--list-connections-entries): New
function, extracted from eglot-list-connections.

* lisp/progmodes/eglot.el (eglot--list-connections-cmd): New macro.

* lisp/progmodes/eglot.el (eglot-shutdown-listed-connection)
(eglot-reconnect-listed-connection): New commands.

* lisp/progmodes/eglot.el (eglot-list-connections): Use
eglot--list-connections-entries.

* doc/misc/eglot.texi: Document eglot-list-connections and new keys.

* etc/EGLOT-NEWS: Announce.
This commit is contained in:
João Távora
2026-04-16 09:28:16 +01:00
parent d7c9676ec8
commit 1c4c9d759a
3 changed files with 59 additions and 17 deletions

View File

@@ -713,6 +713,13 @@ Emacs session. As with @code{eglot-shutdown}, invoking this command
with a prefix argument avoids killing the buffers used for
communications with the language servers.
@item M-x eglot-list-connections
This command pops up a buffer listing all active Eglot connections,
showing aspects such as the server name, project, number of managed
buffers, major modes, and the server invocation. In this buffer,
@kbd{k} shuts down the server on the current line and @kbd{r}
reconnects to it.
@item M-x eglot-rename
This command renames the program symbol (a.k.a.@: @dfn{identifier}) at
point to another name. It prompts for the new name of the symbol, and

View File

@@ -17,6 +17,13 @@ This refers to https://github.com/joaotavora/eglot/issues/. That is,
to look up issue github#1234, go to
https://github.com/joaotavora/eglot/issues/1234.
* Changes to upcoming Eglot
** New commands for the 'M-x eglot-list-connections' major mode
'k' shuts down and 'r' reconnects the server on the current line.
* Changes in Eglot 1.23 (2/4/2026)

View File

@@ -4938,6 +4938,13 @@ If NOERROR, return predicate, else erroring function."
;;; List connections mode
(defvar eglot-list-connections-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "k" #'eglot-shutdown-listed-connection)
(define-key map "r" #'eglot-reconnect-listed-connection)
map)
"Keymap for `eglot-list-connections-mode'.")
(define-derived-mode eglot-list-connections-mode tabulated-list-mode
"" "Eglot mode for listing server connections.
\\{eglot-list-connections-mode-map}"
@@ -4947,6 +4954,25 @@ If NOERROR, return predicate, else erroring function."
("Modes" 20) ("Invocation" 32)])
(tabulated-list-init-header))
(defun eglot--list-connections-entries ()
"Compute `tabulated-list-entries' for the connections list buffer."
(mapcar
(lambda (server)
(list server
`[,(or (plist-get (eglot--server-info server) :name)
(jsonrpc-name server))
,(eglot-project-nickname server)
,(format "%s" (length (eglot--managed-buffers server)))
,(mapconcat #'symbol-name
(eglot--major-modes server)
", ")
,(let ((c (process-command
(jsonrpc--process server))))
(if (consp c) (mapconcat #'identity c " ")
"network"))]))
(cl-reduce #'append
(hash-table-values eglot--servers-by-project))))
(defun eglot-list-connections ()
"List currently active Eglot connections."
(interactive)
@@ -4955,26 +4981,24 @@ If NOERROR, return predicate, else erroring function."
(let ((inhibit-read-only t))
(erase-buffer)
(eglot-list-connections-mode)
(setq-local tabulated-list-entries
(mapcar
(lambda (server)
(list server
`[,(or (plist-get (eglot--server-info server) :name)
(jsonrpc-name server))
,(eglot-project-nickname server)
,(format "%s" (length (eglot--managed-buffers server)))
,(mapconcat #'symbol-name
(eglot--major-modes server)
", ")
,(let ((c (process-command
(jsonrpc--process server))))
(if (consp c) (mapconcat #'identity c " ")
"network"))]))
(cl-reduce #'append
(hash-table-values eglot--servers-by-project))))
(setq-local tabulated-list-entries #'eglot--list-connections-entries)
(revert-buffer)
(pop-to-buffer (current-buffer)))))
(cl-defmacro eglot--list-connections-cmd (name s doc &body body)
(declare (indent 2) (debug (sexp sexp sexp &rest form)))
`(defun ,name ()
,doc (interactive)
(if-let* ((,s (tabulated-list-get-id)))
(progn ,@body (tabulated-list-revert))
(user-error "No server on this line"))))
(eglot--list-connections-cmd eglot-shutdown-listed-connection s
"Shutdown Eglot server on current line" (eglot-shutdown s))
(eglot--list-connections-cmd eglot-reconnect-listed-connection s
"Reconnect Eglot server on current line" (eglot-reconnect s))
;;; Inlay hints
(defface eglot-inlay-hint-face '((t (:height 0.8 :inherit shadow)))
@@ -5634,6 +5658,10 @@ lock machinery calls us again."
eglot-stderr-buffer))
(function-put sym 'command-modes '(eglot--managed-mode)))
(dolist (sym '(eglot-shutdown-listed-connection
eglot-reconnect-listed-connection))
(function-put sym 'command-modes '(eglot-list-connections-mode)))
(provide 'eglot)