Eglot: replace eglot-prefer-plaintext with eglot-documentation-renderer

The old boolean 'eglot-prefer-plaintext' is replaced by the more
expressive 'eglot-documentation-renderer', which can hold a major-mode
symbol, t (plain text), or nil (auto-detect each time).  By selecting a
renderer once at startup the repeated per-request lookups are avoided,
which helps with the slowness reported in bug#81150.

* lisp/progmodes/eglot.el (eglot-prefer-plaintext): Declare obsolete
alias to 'eglot-documentation-renderer'.
(eglot-documentation-renderer): New defcustom, reworked from from
eglot-prefer-plaintext.
(eglot--accepted-formats): Use new variable.
(eglot--format-markup): Use new variable.

* etc/EGLOT-NEWS: Announce change.

* doc/misc/eglot.texi (Customization Variables): Document
  eglot-documentation-renderer.
This commit is contained in:
João Távora 2026-05-30 14:28:32 +01:00
parent ec3d662de0
commit aac5e0457a
3 changed files with 45 additions and 14 deletions

View file

@ -996,6 +996,18 @@ same language server. That file is still outside your project
will consider it to be part of the workspace. The default is will consider it to be part of the workspace. The default is
@code{nil}. @code{nil}.
@cindex markdown renderer
@item eglot-documentation-renderer
This variable controls how Eglot renders at-point documentation
imported from the server (@pxref{Eglot Features}). By default, the
variable's value is set during startup to a markdown renderer if
available, either @code{markdown-ts-view-mode} or
@code{gfm-view-mode}. These utilities visually enhance the
documentation content through fontification and other formatting. If
you set it to @code{t}, plain text will be requested from the server
and no rendering is attempted. If the variable's value is @code{nil},
Eglot will attempt to find a suitable renderer every time.
@item eglot-mode-map @item eglot-mode-map
This variable is the keymap for binding Eglot-related command. It is in This variable is the keymap for binding Eglot-related command. It is in
effect only as long as the buffer is managed by Eglot. By default, it effect only as long as the buffer is managed by Eglot. By default, it

View file

@ -32,11 +32,15 @@ New key bindings: 'k' shuts down, 'r' reconnects, 'e' visits the events
buffer, 'w' shows workspace configuration, and 'RET' invokes buffer, 'w' shows workspace configuration, and 'RET' invokes
'eglot-describe-connection'. 'eglot-describe-connection'.
** Eglot uses new built-in 'markdown-ts-mode' of Emacs 31 (bug#80127) ** New LSP documentation rendering backends (bug#80127)
This means that on newer versions of Emacs the external Eglot uses new built-in 'markdown-ts-mode' of Emacs 31, which means that
'markdown-mode.el' package does not need to be installed to render on newer versions of Emacs the external 'markdown-mode.el' package does
Markdown content. not need to be installed to render Markdown content.
The variable 'eglot-documentation-renderer' replaces the now-obsolete
'eglot-prefer-plaintext'. By default, the variable selects a markdown
renderer to use throughout the session.
* Changes in Eglot 1.23 (2/4/2026) * Changes in Eglot 1.23 (2/4/2026)

View file

@ -149,6 +149,8 @@
'eglot-managed-mode-hook "1.6") 'eglot-managed-mode-hook "1.6")
(define-obsolete-variable-alias 'eglot-confirm-server-initiated-edits (define-obsolete-variable-alias 'eglot-confirm-server-initiated-edits
'eglot-confirm-server-edits "1.16") 'eglot-confirm-server-edits "1.16")
(define-obsolete-variable-alias 'eglot-prefer-plaintext
'eglot-documentation-renderer "1.24")
(make-obsolete-variable 'eglot-events-buffer-size (make-obsolete-variable 'eglot-events-buffer-size
'eglot-events-buffer-config "1.16") 'eglot-events-buffer-config "1.16")
(define-obsolete-function-alias 'eglot--uri-to-path #'eglot-uri-to-path "1.16") (define-obsolete-function-alias 'eglot--uri-to-path #'eglot-uri-to-path "1.16")
@ -535,10 +537,21 @@ or file operation kinds not in the alist."
"If non-nil, activate Eglot in cross-referenced non-project files." "If non-nil, activate Eglot in cross-referenced non-project files."
:type 'boolean) :type 'boolean)
(defcustom eglot-prefer-plaintext nil (defcustom eglot-documentation-renderer (cond ((eglot--builtin-mdown-p)
"If non-nil, always request plaintext responses to hover requests." 'markdown-ts-view-mode)
:type 'boolean ((fboundp 'gfm-view-mode)
:package-version '(Eglot . "1.17.30")) 'gfm-view-mode)
(t
nil))
"Control rendering of LSP documentation fragments.
If set to a major mode symbol `gfm-view-mode' or `markdown-ts-view-mode'
request markdown-snippets and use the corresponding Markdown renderer.
If t, always request and render plain text snippets. If set to nil,
decide dynamically."
:type '(choice (const :tag "Plain text" t)
(const :tag "Auto-detect" nil)
(function :tag "Renderer"))
:package-version '(Eglot . "1.24"))
(defcustom eglot-report-progress t (defcustom eglot-report-progress t
"If non-nil, show progress of long running LSP server work. "If non-nil, show progress of long running LSP server work.
@ -733,7 +746,7 @@ This can be useful when using docker to run a language server.")
(treesit-grammar-location 'markdown))) (treesit-grammar-location 'markdown)))
(defun eglot--accepted-formats () (defun eglot--accepted-formats ()
(if (and (not eglot-prefer-plaintext) (if (and (not (eq t eglot-documentation-renderer))
(or (fboundp 'gfm-view-mode) (eglot--builtin-mdown-p))) (or (fboundp 'gfm-view-mode) (eglot--builtin-mdown-p)))
["markdown" "plaintext"] ["markdown" "plaintext"]
["plaintext"])) ["plaintext"]))
@ -2263,12 +2276,14 @@ If MODE, force MODE to be used for fontifying MARKUP."
finally return (buffer-string))) finally return (buffer-string)))
(calc2 (forced-mode) (calc2 (forced-mode)
(cond (cond
(forced-mode `(,forced-mode)) (forced-mode forced-mode)
((eglot--builtin-mdown-p) `(,#'markdown-ts-view-mode)) ((fboundp eglot-documentation-renderer) eglot-documentation-renderer)
((fboundp 'gfm-view-mode) `(,#'gfm-view-mode ,#'gfm-extract)) ((eglot--builtin-mdown-p) #'markdown-ts-view-mode)
(t `(#'text-mode)))) ((fboundp 'gfm-view-mode) #'gfm-view-mode)
(t #'text-mode)))
(calc (s &optional (forced-mode mode) &aux (x (calc2 forced-mode))) (calc (s &optional (forced-mode mode) &aux (x (calc2 forced-mode)))
(setq string s render (car x) extract (or (cadr x) #'buffer-string)))) (setq string s render x
extract (if (eq x 'gfm-view-mode) #'gfm-extract #'buffer-string))))
(cond ((stringp markup) (calc markup)) ; plain string (cond ((stringp markup) (calc markup)) ; plain string
((setq lang (plist-get markup :language)) ; deprecated MarkedString ((setq lang (plist-get markup :language)) ; deprecated MarkedString
(calc (format "```%s\n%s\n```" lang (plist-get markup :value)))) (calc (format "```%s\n%s\n```" lang (plist-get markup :value))))