[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot b406818 07/54: Fix #326: support workspace/config
From: |
João Távora |
Subject: |
[elpa] externals/eglot b406818 07/54: Fix #326: support workspace/configuration |
Date: |
Thu, 16 Apr 2020 05:31:45 -0400 (EDT) |
branch: externals/eglot
commit b4068181a8db1129dcd4eaf3e881f10067662e0e
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Fix #326: support workspace/configuration
This helps users configure servers such as Gopls, which doesn't
support didChangeConfiguration signals.
* README.md (Per-project server configuration): New section.
* eglot.el (eglot-workspace-configuration): Fix docstring.
(eglot-signal-didChangeConfiguration): Rename a variable.
(eglot-handle-request workspace/configuration): New request
handler.
---
NEWS.md | 8 ++++++++
README.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
eglot.el | 40 ++++++++++++++++++++++++++++++++--------
3 files changed, 87 insertions(+), 13 deletions(-)
diff --git a/NEWS.md b/NEWS.md
index 2e05aa2..0b4cb9e 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,3 +1,10 @@
+# 1.6 (upcoming)
+
+##### Support workspace/configuration requests ([#326][github#326])
+
+Also a new section "Per-project server configuration" in the README.md
+should answer some faq's in this regard.
+
# 1.5 (20/10/2019)
Thanks a lot to Felicián Németh, Ingo Lohmar, and everyone else who
@@ -197,3 +204,4 @@ and now said bunch of references-->
[github#313]: https://github.com/joaotavora/eglot/issues/313
[github#316]: https://github.com/joaotavora/eglot/issues/316
[github#324]: https://github.com/joaotavora/eglot/issues/324
+[github#326]: https://github.com/joaotavora/eglot/issues/326
diff --git a/README.md b/README.md
index f0cbc1e..231266e 100644
--- a/README.md
+++ b/README.md
@@ -94,12 +94,54 @@ 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.
-## Handling quirky servers
+## Per-project server configuration
Most servers can guess good defaults and will operate nicely
-out-of-the-box, but some need to be configured specially via LSP's
-interfaces. If your server has some quirk or non-conformity, it's
-possible to extend Eglot to adapt to it. Here's an example on how to
+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_
+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:
+
+```lisp
+((python-mode
+ . ((eglot-workspace-configuration
+ . ((:pyls . (:plugins (:jedi_completion (:include_params t)))))))))
+```
+
+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
+a section for `go-mode`, the file's contents become:
+
+```lisp
+((python-mode
+ . ((eglot-workspace-configuration
+ . ((:pyls . (:plugins (:jedi_completion (:include_params t))))))))
+ (go-mode
+ . ((eglot-workspace-configuration
+ . ((:gopls . (:usePlaceholders t)))))))
+```
+
+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.
+
+## Handling quirky servers
+
+Some servers need even more special hand-holding to operate correctly.
+If your server has some quirk or non-conformity, it's possible to
+extend Eglot via Elisp to adapt to it. Here's an example on how to
get [cquery][cquery] working:
```lisp
@@ -283,7 +325,7 @@ eglot-shutdown`.
- [ ] workspace/workspaceFolders (3.6.0)
- [ ] workspace/didChangeWorkspaceFolders (3.6.0)
- [x] workspace/didChangeConfiguration
-- [ ] workspace/configuration (3.6.0)
+- [x] workspace/configuration (3.6.0)
- [x] workspace/didChangeWatchedFiles
- [x] workspace/symbol
- [x] workspace/executeCommand
diff --git a/eglot.el b/eglot.el
index 75ce937..b9496e1 100644
--- a/eglot.el
+++ b/eglot.el
@@ -218,6 +218,7 @@ let the buffer grow forever."
(defvar eglot--lsp-interface-alist
`(
(CodeAction (:title) (:kind :diagnostics :edit :command))
+ (ConfigurationItem () (:scopeUri :section))
(Command (:title :command) (:arguments))
(CompletionItem (:label)
(:kind :detail :documentation :deprecated :preselect
@@ -474,7 +475,8 @@ treated as in `eglot-dbind'."
:executeCommand `(:dynamicRegistration :json-false)
:workspaceEdit `(:documentChanges :json-false)
:didChangeWatchedFiles `(:dynamicRegistration t)
- :symbol `(:dynamicRegistration :json-false))
+ :symbol `(:dynamicRegistration :json-false)
+ :configuration t)
:textDocument
(list
:synchronization (list
@@ -1655,9 +1657,9 @@ Records BEG, END and PRE-CHANGE-LENGTH locally."
'((name . eglot--signal-textDocument/didChange)))
(defvar-local eglot-workspace-configuration ()
- "Alist of (SETTING . VALUE) entries configuring the LSP server.
-Setting should be a keyword, value can be any value that can be
-converted to JSON.")
+ "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.")
(put 'eglot-workspace-configuration 'safe-local-variable 'listp)
@@ -1669,12 +1671,34 @@ When called interactively, use the currently active
server"
server :workspace/didChangeConfiguration
(list
:settings
- (cl-loop for (k . v) in eglot-workspace-configuration
- collect (if (keywordp k)
- k
- (intern (format ":%s" k)))
+ (cl-loop for (section . v) in eglot-workspace-configuration
+ collect (if (keywordp section)
+ section
+ (intern (format ":%s" section)))
collect v))))
+(cl-defmethod eglot-handle-request
+ (server (_method (eql workspace/configuration)) &key items)
+ "Handle server request workspace/configuration."
+ (apply #'vector
+ (mapcar
+ (eglot--lambda ((ConfigurationItem) scopeUri section)
+ (let* ((path (eglot--uri-to-path scopeUri)))
+ (when (file-directory-p path)
+ (with-temp-buffer
+ (let ((default-directory path))
+ (setq-local major-mode (eglot--major-mode server))
+ (hack-dir-local-variables-non-file-buffer)
+ (alist-get section eglot-workspace-configuration
+ nil nil
+ (lambda (wsection section)
+ (string=
+ (if (keywordp wsection)
+ (substring (symbol-name wsection) 1)
+ wsection)
+ section))))))))
+ items)))
+
(defun eglot--signal-textDocument/didChange ()
"Send textDocument/didChange to server."
(when eglot--recent-changes
- [elpa] externals/eglot 8c9078e 19/54: Fix #343: Let other imenu functions work if LSP server's doesn't, (continued)
- [elpa] externals/eglot 8c9078e 19/54: Fix #343: Let other imenu functions work if LSP server's doesn't, João Távora, 2020/04/16
- [elpa] externals/eglot 4bd8773 23/54: Fix #339: fail when eglot-find-* finds no references, João Távora, 2020/04/16
- [elpa] externals/eglot 76d8f49 10/54: Per #50: use completionItem/resolve more abundantly, João Távora, 2020/04/16
- [elpa] externals/eglot a6fa773 25/54: Resolve compilation warnings, João Távora, 2020/04/16
- [elpa] externals/eglot b2e4687 29/54: Close #376: add metals as the language server for Scala, João Távora, 2020/04/16
- [elpa] externals/eglot 097eed5 31/54: Close #382: new eglot-confirm-server-initiated-edits defcustom, João Távora, 2020/04/16
- [elpa] externals/eglot 2ab8b59 08/54: Don't run mode hooks in eglot--format-markup, João Távora, 2020/04/16
- [elpa] externals/eglot 88311a2 12/54: Simplify "maybe"-activation, dump "server" arg, João Távora, 2020/04/16
- [elpa] externals/eglot 7f9784c 11/54: Merge -onoff proxy code into minor mode function, João Távora, 2020/04/16
- [elpa] externals/eglot 9eac9de 16/54: Fix #341: protect against empty-string insertText in completions, João Távora, 2020/04/16
- [elpa] externals/eglot b406818 07/54: Fix #326: support workspace/configuration,
João Távora <=
- [elpa] externals/eglot ef34797 14/54: Fix #340: Don't choke on workspace/configuration with no scopeUri, João Távora, 2020/04/16
- [elpa] externals/eglot 27fb0c6 18/54: Support serverInfo of LSP 3.15.0, João Távora, 2020/04/16
- [elpa] externals/eglot 893a05a 20/54: Fix #330: ensure process starts in project's root, João Távora, 2020/04/16
- [elpa] externals/eglot 678feb9 21/54: * eglot.el (eglot-completion-at-point): Remove spurious unrelated change., João Távora, 2020/04/16
- [elpa] externals/eglot 53056a5 22/54: Fix #349: waste less space in completion annotations, João Távora, 2020/04/16
- [elpa] externals/eglot 02f71fd 26/54: Make Travis run company-specific tests, João Távora, 2020/04/16
- [elpa] externals/eglot a7a2b52 27/54: Fix #362: unbreak window/showMessageRequest, João Távora, 2020/04/16
- [elpa] externals/eglot add568b 28/54: Fix #357: allow non-standard keys in textDocument/publishDiagnostics., João Távora, 2020/04/16
- [elpa] externals/eglot 3879d57 33/54: * eglot.el (eglot-eldoc-function): Fix outdated docstring., João Távora, 2020/04/16
- [elpa] externals/eglot a4c83a6 37/54: Merge pull request #400 from joaotavora/scratch/fix-277-exit-notification, João Távora, 2020/04/16