From 4f6e4dc7a162ef2808de55cedc349843feda3d59 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Sat, 26 Oct 2019 22:51:57 +0100 Subject: [PATCH] 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. GitHub-reference: fix https://github.com/joaotavora/eglot/issues/326 --- lisp/progmodes/eglot.el | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 75ce9376104..b9496e166d2 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/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 -- 2.39.2