From 1602f19adc472b0f7cbeddcd02fdc1ec0902577b Mon Sep 17 00:00:00 2001 From: Rodrigo Kassick Date: Wed, 10 Jul 2024 22:14:44 -0300 Subject: [PATCH] fix: lsp--find-workspaces-for workspace/executeCommand respects the target command Calling (lsp--find-workspaces-for '(:method "workspace/executeCommand" :params (:command "arbitrary-command"))) would return *any* workspace that had the :executeCommandProvider capability registerd. This would result in a given command being forwarded for **all active workspaces**. Some servers (such as ruff) would raise a KeyError for unknown commands -- causing the minibuffer to, sometimes, show an error. This change introduces a new :check-message callback that can be used in lsp-method-requirements -- this callback receives the workspace and the message to be sent. Ths entry for workspace/executeCommand has been updated to check if the target workspace can execute the required command. --- lsp-mode.el | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lsp-mode.el b/lsp-mode.el index 05cac9b3c2..c0f4bec8ad 100644 --- a/lsp-mode.el +++ b/lsp-mode.el @@ -1036,7 +1036,13 @@ directory") ("textDocument/typeDefinition" :capability :typeDefinitionProvider) ("textDocument/typeHierarchy" :capability :typeHierarchyProvider) ("textDocument/diagnostic" :capability :diagnosticProvider) - ("workspace/executeCommand" :capability :executeCommandProvider) + ("workspace/executeCommand" + :capability :executeCommandProvider + :check-message (lambda (workspace msg) + (-let* (((&plist :method :params) msg) + ((&plist :command) params)) + (with-lsp-workspace workspace + (lsp-can-execute-command? command))))) ("workspace/symbol" :capability :workspaceSymbolProvider)) "Map methods to requirements. @@ -6640,14 +6646,15 @@ REFERENCES? t when METHOD returns references." (evil-set-command-property 'lsp-find-references :jump t) (evil-set-command-property 'lsp-find-type-definition :jump t)) -(defun lsp--workspace-method-supported? (check-command method capability workspace) +(defun lsp--workspace-method-supported? (check-command method check-message msg capability workspace) (with-lsp-workspace workspace - (if check-command - (funcall check-command workspace) - (or - (when capability (lsp--capability capability)) - (lsp--registered-capability method) - (and (not capability) (not check-command)))))) + (cond + (check-command (funcall check-command workspace)) + (check-message (funcall check-message workspace msg)) + (t (or + (when capability (lsp--capability capability)) + (lsp--registered-capability method) + (and (not capability) (not check-command))))))) (defun lsp-disable-method-for-server (method server-id) "Disable METHOD for SERVER-ID." @@ -6662,20 +6669,23 @@ REFERENCES? t when METHOD returns references." (eq server-id)) (lsp--workspace-method-supported? check-command method + nil + nil capability workspace)))))) (alist-get method lsp-method-requirements nil nil 'string=))) (defun lsp--find-workspaces-for (msg-or-method) "Find all workspaces in the current project that can handle MSG." - (let ((method (if (stringp msg-or-method) - msg-or-method - (plist-get msg-or-method :method)))) + + (-let (((method . msg) (if (stringp msg-or-method) + (cons msg-or-method `(:method ,msg-or-method)) + (cons (plist-get msg-or-method :method) msg-or-method)))) (-if-let (reqs (cdr (assoc method lsp-method-requirements))) - (-let (((&plist :capability :check-command) reqs)) + (-let (((&plist :capability :check-command :check-message) reqs)) (-filter (-partial #'lsp--workspace-method-supported? - check-command method capability) + check-command method check-message msg capability) (lsp-workspaces))) (lsp-workspaces))))