From d9b5f618baa31e97a5d675c665c9094cf757d184 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 27 Dec 2023 06:38:31 -0600 Subject: [PATCH] Eglot: introduce eglot-events-buffer-config * doc/misc/eglot.texi (Eglot Variables): Reword. (Performance): Reword. * lisp/progmodes/eglot.el (eglot-events-buffer-size): Obsolete. (eglot-events-buffer-config): New customization variable. (eglot--connect): Use eglot-events-buffer-config. --- doc/misc/eglot.texi | 26 ++++++++++++++------------ lisp/progmodes/eglot.el | 38 ++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index c0592a6fe68..fbf0b411633 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -836,13 +836,13 @@ in the background. The value of @code{t} means block during the whole waiting period. The value of @code{nil} or @code{0} means don't block at all during the waiting period. -@item eglot-events-buffer-size -This determines the size of the Eglot events buffer. @xref{Eglot -Commands, eglot-events-buffer}, for how to display that buffer. If -the value is changed, for it to take effect the connection should be -restarted using @kbd{M-x eglot-reconnect}. +@item eglot-events-buffer-config +This configures the size and format of the Eglot events buffer. +@xref{Eglot Commands, eglot-events-buffer}, for how to access that +buffer. If the value is changed, the connection should be restarted +using @kbd{M-x eglot-reconnect} for the new value to take effect. @c FIXME: Shouldn't the defcustom do this by itself using the :set -@c attribute? +@c attribute? Maybe not because reconnecting is a complex task. @xref{Troubleshooting Eglot}, for when this could be useful. @item eglot-autoshutdown @@ -1455,12 +1455,14 @@ indicate the problems or at least provide a hint. @node Performance @section Performance @cindex performance problems, with Eglot -A common and easy-to-fix cause of performance problems is the length -of the Eglot events buffer because it represent additional work that -Eglot must do. After verifying Eglot is operating correctly but -slowly, try to customize the variable @code{eglot-events-buffer-size} -(@pxref{Eglot Variables}) to 0. This will disable any debug logging -and may speed things up. +A common and easy-to-fix cause of performance problems in Eglot +(especially in older versions) is its events buffer, since it +represent additional work that Eglot must do (@pxref{Eglot Commands, +eglot-events-buffer}). If you find Eglot is operating correctly but +slowly, try to customize the variable +@code{eglot-events-buffer-config} (@pxref{Eglot Variables}) and set +its @code{:size} property to 0. This will disable recording any +events and may speed things up. In other situations, the cause of poor performance lies in the language server itself. Servers use aggressive caching and other diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index d777e488c43..9b11a22dafb 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -138,6 +138,8 @@ 'eglot-managed-mode-hook "1.6") (define-obsolete-variable-alias 'eglot-confirm-server-initiated-edits 'eglot-confirm-server-edits "1.16") +(make-obsolete-variable 'eglot-events-buffer-size + '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--path-to-uri 'eglot-path-to-uri "1.16") (define-obsolete-function-alias 'eglot--range-region 'eglot-range-region "1.16") @@ -413,17 +415,29 @@ as 0, i.e. don't block at all." "Don't tell server of changes before Emacs's been idle for this many seconds." :type 'number) -(defcustom eglot-events-buffer-size 2000000 - "Control the size of the Eglot events buffer. -If a number, don't let the buffer grow larger than that many -characters. If 0, don't use an event's buffer at all. If nil, -let the buffer grow forever. - -For changes on this variable to take effect on a connection -already started, you need to restart the connection. That can be -done by `eglot-reconnect'." - :type '(choice (const :tag "No limit" nil) - (integer :tag "Number of characters"))) +(defcustom eglot-events-buffer-config + (list :size (or (bound-and-true-p eglot-events-buffer-size) 2000000) + :format 'full) + "Configure the Eglot events buffer. + +Value is a plist accepting the keys `:size', which controls the +size in characters of the buffer (0 disables, nil means +infinite), and `:format', which controls the shape of each log +entry (`full' includes the original JSON, `lisp' uses +pretty-printed Lisp). + +For changes on this variable to take effect, you need to restart +the LSP connection. That can be done by `eglot-reconnect'." + :type '(plist :key-type (symbol :tag "Keyword") + :options (((const :tag "Size" :size) + (choice + (const :tag "No limit" nil) + (integer :tag "Number of characters"))) + ((const :tag "Format" :format) + (choice + (const :tag "Full with original JSON" full) + (const :tag "Shortened" short) + (const :tag "Pretty-printed lisp" lisp)))))) (defcustom eglot-confirm-server-edits '((eglot-rename . nil) (t . maybe-summary)) @@ -1513,7 +1527,7 @@ This docstring appeases checkdoc, that's all." (apply #'make-instance class :name readable-name - :events-buffer-config `(:size ,eglot-events-buffer-size :format full) + :events-buffer-config eglot-events-buffer-config :notification-dispatcher (funcall spread #'eglot-handle-notification) :request-dispatcher (funcall spread #'eglot-handle-request) :on-shutdown #'eglot--on-shutdown -- 2.39.2