]> git.eshelyaron.com Git - emacs.git/commitdiff
Revert "Eglot: add new chapter about Elisp extensions to Eglot manual"
authorJoão Távora <joaotavora@gmail.com>
Mon, 4 Sep 2023 01:08:58 +0000 (02:08 +0100)
committerJoão Távora <joaotavora@gmail.com>
Mon, 4 Sep 2023 01:08:58 +0000 (02:08 +0100)
This reverts commit 2a66334bada5173f351e452f40d4289b5e06f04c.

One of the co-authors doesn't yet have a FSF copyright assignment.

doc/misc/eglot.texi

index 89813a179442ce4239c02912ca37175a453f8cb9..3338756c63c553f99f56ec45d621a3eece187628 100644 (file)
@@ -99,7 +99,6 @@ This manual documents how to configure, use, and customize Eglot.
 * Using Eglot::                 Important Eglot commands and variables.
 * Customizing Eglot::           Eglot customization and advanced features.
 * Advanced server configuration::  Fine-tune a specific language server
-* Extending Eglot::             Writing Eglot extensions in Elisp
 * Troubleshooting Eglot::       Troubleshooting and reporting bugs.
 * GNU Free Documentation License::  The license for this manual.
 * Index::
@@ -1265,154 +1264,6 @@ is serialized by Eglot to the following JSON text:
 @}
 @end example
 
-@node Extending Eglot
-@chapter Extending Eglot
-
-Sometimes it may be useful to extend existing Eglot functionality
-using Elisp its public methods.  A good example of when this need may
-arise is adding support for a custom LSP protocol extension only
-implemented by a specific server.
-
-The best source of documentation for this is probably Eglot source
-code itself, particularly the section marked ``API''.
-
-Most of the functionality is implemented with Common-Lisp style
-generic functions (@pxref{Generics,,,eieio,EIEIO}) that can be easily
-extended or overridden.  The Eglot code itself is an example on how to
-do this.
-
-The following is a relatively simple example that adds support for the
-@code{inactiveRegions} experimental feature introduced in version 17
-of the @command{clangd} C/C++ language server++.
-
-Summarily, the feature works by first having the server detect the
-Eglot's advertisement of the @code{inactiveRegions} client capability
-during startup, whereupon the language server will report a list of
-regions of inactive code for each buffer.  This is usually code
-surrounded by C/C++ @code{#ifdef} macros that the preprocessor removes
-based on compile-time information.
-
-The language server reports the regions by periodically sending a
-@code{textDocument/inactiveRegions} notification for each managed
-buffer (@pxref{Eglot and Buffers}). Normally, unknown server
-notifications are ignored by Eglot, but we're going change that.
-
-Both the announcement of the client capability and the handling of the
-new notification is done by adding methods to generic functions.
-
-@itemize @bullet
-@item
-The first method extends @code{eglot-client-capabilities} using a
-simple heuristic to detect if current server is @command{clangd} and
-enables the @code{inactiveRegion} capability.
-
-@lisp
-(cl-defmethod eglot-client-capabilities :around (server)
-  (let ((base (cl-call-next-method)))
-    (when (cl-find "clangd" (process-command
-                              (jsonrpc--process server))
-                   :test #'string-match)
-      (setf (cl-getf (cl-getf base :textDocument)
-                     :inactiveRegionsCapabilities)
-            '(:inactiveRegions t)))
-    base))
-@end lisp
-
-Notice we use an internal function of the @code{jsonrpc.el} library,
-and a regexp search to detect @command{clangd}.  An alternative would
-be to define a new EIEIO subclass of @code{eglot-lsp-server}, maybe
-called @code{eglot-clangd}, so that the method would be simplified:
-
-@lisp
-(cl-defmethod eglot-client-capabilities :around ((_s eglot-clangd))
-  (let ((base (cl-call-next-method)))
-    (setf (cl-getf (cl-getf base :textDocument)
-                     :inactiveRegionsCapabilities)
-            '(:inactiveRegions t))))
-@end lisp
-
-However, this would require that users tweak
-@code{eglot-server-program} to tell Eglot instantiate such sub-classes
-instead of the generic @code{eglot-lsp-server} (@pxref{Setting Up LSP
-Servers}). For the purposes of this particular demonstration, we're
-going to use the more hacky regexp route which doesn't require that.
-
-Note, however, that detecting server versions before announcing new
-capabilities is generally not needed, as both server and client are
-required by LSP to ignore unknown capabilities advertised by their
-counterparts.
-
-@item
-The second method implements @code{eglot-handle-notification} to
-process the server notification for the LSP method
-@code{textDocument/inactiveRegions}.  For each region received it
-creates an overlay applying the @code{shadow} face to the region.
-Overlays are recreated every time a new notification of this kind is
-received.
-
-To learn about how @command{clangd}'s special JSONRPC notification
-message is structured in detail you could consult that server's
-documentation.  Another possibility is to evaluate the first
-capability-announcing method, reconnect to the server and peek in the
-events buffer (@pxref{Eglot Commands, eglot-events-buffer}).  You
-could find something like:
-
-@lisp
-[server-notification] Mon Sep  4 01:10:04 2023:
-(:jsonrpc "2.0" :method "textDocument/inactiveRegions" :params
-          (:textDocument
-           (:uri "file:///path/to/file.cpp")
-           :regions
-           [(:start (:character 0 :line 18)
-             :end (:character 58 :line 19))
-            (:start (:character 0 :line 36)
-             :end (:character 1 :line 38))]))
-@end lisp
-
-This reveals that the @code{textDocument/inactiveRegions} notification
-contains a @code{:textDocument} property to designate the managed
-buffer and an array of LSP regions under the @code{:regions} property.
-Notice how the message (originally in JSON format), is represented as
-Elisp plists (@pxref{JSONRPC objects in Elisp}).
-
-The Eglot generic function machinery will automatically destructure
-the incoming message, so these two properties can simply be added to
-the new method's lambda list as @code{&key} arguments.  Also, the
-@code{eglot-uri-to-path} and@code{eglot-range-region} may be used to
-easily parse the LSP @code{:uri} and @code{:start ... :end ...}
-objects to obtain Emacs objects for file names and positions.
-
-The remainder of the implementation consists of standard Elisp
-techniques to loop over arrays, manage buffers and overlays.
-
-@lisp
-(defvar-local eglot-clangd-inactive-region-overlays '())
-
-(cl-defmethod eglot-handle-notification
-  (_server (_method (eql textDocument/inactiveRegions))
-           &key regions textDocument &allow-other-keys)
-  (if-let* ((path (expand-file-name (eglot-uri-to-path
-                                     (cl-getf textDocument :uri))))
-            (buffer (find-buffer-visiting path)))
-      (with-current-buffer buffer
-        (mapc #'delete-overlay eglot-clangd-inactive-region-overlays)
-        (cl-loop
-         for r across regions
-         for (beg . end) = (eglot-range-region r)
-         for ov = (make-overlay beg end)
-         do
-         (overlay-put ov 'face 'shadow)
-         (push ov eglot-clangd-inactive-region-overlays)))))
-@end lisp
-
-@end itemize
-
-After evaluating these two additions and reconnecting to the
-@command{clangd} language server (version 17), the result will be that
-all the inactive code in the buffer will be nicely grayed out using
-the LSP server knowledge about current compile time preprocessor
-defines.
-
 @node Troubleshooting Eglot
 @chapter Troubleshooting Eglot
 @cindex troubleshooting Eglot