emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/eglot 1db95974a7 07/15: Per #967: eglot-workspace-confi


From: ELPA Syncer
Subject: [elpa] externals/eglot 1db95974a7 07/15: Per #967: eglot-workspace-configuration can be a function
Date: Sun, 24 Jul 2022 14:57:34 -0400 (EDT)

branch: externals/eglot
commit 1db95974a7082a9915ad1c14bb17c49253efcc56
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    Per #967: eglot-workspace-configuration can be a function
    
    * README.md (Workspace configuration): Renamed from per-project
    configuration.  Rework.
    
    * NEWS.md: Mention change.
    
    * eglot.el (eglot-workspace-configuration): Overhaul.
    (eglot-signal-didChangeConfiguration): Use new
    eglot-workspace-configuration.
---
 NEWS.md   |  6 +++++-
 README.md | 47 ++++++++++++++++++++++++++++++++++-------------
 eglot.el  | 18 ++++++++++++++----
 3 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/NEWS.md b/NEWS.md
index 156fe761bb..47450927ba 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,8 @@
 # (upcoming)
 
-##### C-u M-. lists and completes arbitrary workspace symbols 
[#131][github#131])
+##### `eglot-workspace-configuration` can be a function ([#967][github#967])
+
+##### C-u M-. lists and completes arbitrary workspace symbols 
([#131][github#131])
 
 A very old request, now made possible by a relatively recent change to
 the `workspace/symbol` RPC method.
@@ -322,6 +324,7 @@ and now said bunch of references-->
 [github#121]: https://github.com/joaotavora/eglot/issues/121
 [github#124]: https://github.com/joaotavora/eglot/issues/124
 [github#126]: https://github.com/joaotavora/eglot/issues/126
+[github#131]: https://github.com/joaotavora/eglot/issues/131
 [github#138]: https://github.com/joaotavora/eglot/issues/138
 [github#144]: https://github.com/joaotavora/eglot/issues/144
 [github#154]: https://github.com/joaotavora/eglot/issues/154
@@ -383,3 +386,4 @@ and now said bunch of references-->
 [github#901]: https://github.com/joaotavora/eglot/issues/901
 [github#905]: https://github.com/joaotavora/eglot/issues/905
 [github#922]: https://github.com/joaotavora/eglot/issues/922
+[github#967]: https://github.com/joaotavora/eglot/issues/967
diff --git a/README.md b/README.md
index 8a54156882..2314eb2d32 100644
--- a/README.md
+++ b/README.md
@@ -128,14 +128,14 @@ it be started as a server.  Notice the `:autoport` symbol 
in there: it
 is replaced dynamically by a local port believed to be vacant, so that
 the ensuing TCP connection finds a listening server.
 
-## Per-project server configuration
+## Workspace configuration
 
 Most servers can guess good defaults and will operate nicely
 out-of-the-box, but some need to be configured specially via LSP
 interfaces.  Additionally, in some situations, you may also want a
 particular server to operate differently across different projects.
 
-Per-project settings are realized with Emacs's _directory variables_
+Per-project settings are realized with Emacs's _directory variables
 and the Elisp variable `eglot-workspace-configuration`.  To make a
 particular Python project always enable Pyls's snippet support, put a
 file named `.dir-locals.el` in the project's root:
@@ -147,15 +147,17 @@ file named `.dir-locals.el` in the project's root:
 ```
 
 This tells Emacs that any `python-mode` buffers in that directory
-should have a particular buffer-local value of
-`eglot-workspace-configuration`.  That variable's value should be
-_association list_ of _parameter sections_ which are presumably
-understood by the server.  In this example, we associate section
-`pyls` with the parameters object `(:plugins (:jedi_completion
-(:include_params t)))`.
-
-Now, supposing that you also had some Go code in the very same
-project, you can configure the Gopls server in the same file.  Adding
+should have a particular value of `eglot-workspace-configuration`.
+That variable's value should be _association list_ of _parameter
+sections_ which are presumably understood by the server.
+
+In this above, we associated the _section_ `:pyls` with the parameters
+object `(:plugins (:jedi_completion (:include_params t)))`.
+
+### Multiple workspace configuration for multiple servers
+
+Suppose you also had some Go code in the very same project, you can
+configure the Gopls server in the same `.dir-locals.el' file.  Adding
 a section for `go-mode`, the file's contents become:
 
 ```lisp
@@ -167,9 +169,28 @@ a section for `go-mode`, the file's contents become:
       . ((:gopls . (:usePlaceholders t)))))))
 ```
 
+As a matter of taste, you might prefer this equivalent setup.
+
+```lisp
+((nil
+  . ((eglot-workspace-configuration
+      . ((:pyls . (:plugins (:jedi_completion (:include_params t))))
+         (:gopls . (:usePlaceholders t)))))))
+```
+
+### Setting up without `.dir-locals.el`
+
 If you can't afford an actual `.dir-locals.el` file, or if managing
-these files becomes cumbersome, the Emacs manual teaches you
-programmatic ways to leverage per-directory local variables.
+this file becomes cumbersome, the Emacs manual (49.2.5 Per-Directory
+Local Variables) teaches you programmatic ways to leverage
+per-directory local variables.  Look for the functions
+`dir-locals-set-directory-class` and `dir-locals-set-class-variables`.
+
+### Setting a dynamic `eglot-workspace-configuration` dynamically
+
+If you need to decide `eglot-workspace-configuration` can be a function, too.  
It is passed
+the `eglot-lsp-server` instance and runs with `default-directory` set
+to the root of your project.
 
 ## Handling quirky servers
 
diff --git a/eglot.el b/eglot.el
index 0b64cd2301..582ad1fdee 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2199,12 +2199,22 @@ Records BEG, END and PRE-CHANGE-LENGTH locally."
 
 (defvar-local eglot-workspace-configuration ()
   "Alist of (SECTION . VALUE) entries configuring the LSP server.
-SECTION should be a keyword or a string, value can be anything
-that can be converted to JSON.")
+SECTION should be a keyword or a string.  VALUE is a
+plist or a primitive type converted to JSON.
+
+The value of this variable can also be a unary function of a
+`eglot-lsp-server' instance, the server connection requesting the
+configuration.  It should return an alist of the format described
+above.")
 
 ;;;###autoload
 (put 'eglot-workspace-configuration 'safe-local-variable 'listp)
 
+(defun eglot--workspace-configuration (server)
+  (if (functionp eglot-workspace-configuration)
+      (funcall eglot-workspace-configuration server)
+    eglot-workspace-configuration))
+
 (defun eglot-signal-didChangeConfiguration (server)
   "Send a `:workspace/didChangeConfiguration' signal to SERVER.
 When called interactively, use the currently active server"
@@ -2213,7 +2223,7 @@ When called interactively, use the currently active 
server"
    server :workspace/didChangeConfiguration
    (list
     :settings
-    (or (cl-loop for (section . v) in eglot-workspace-configuration
+    (or (cl-loop for (section . v) in (eglot--workspace-configuration server)
                  collect (if (keywordp section)
                              section
                            (intern (format ":%s" section)))
@@ -2235,7 +2245,7 @@ When called interactively, use the currently active 
server"
                          (project-root (eglot--project server)))))
                 (setq-local major-mode (eglot--major-mode server))
                 (hack-dir-local-variables-non-file-buffer)
-                (alist-get section eglot-workspace-configuration
+                (alist-get section (eglot--workspace-configuration server)
                            nil nil
                            (lambda (wsection section)
                              (string=



reply via email to

[Prev in Thread] Current Thread [Next in Thread]