Skip to content

Commit

Permalink
lsp-rust: support rust-analyzer.showReference lens (#2299)
Browse files Browse the repository at this point in the history
* lsp-rust: support rust-analyzer.showReference lens

Add a rust-analyzer specific :action-handler for the showReference lens,
which leverages `lsp-show-xrefs'. Refactor: eliminate
`lsp-execute-command', because it caused the :title to be lost, which is
needed to distinguish between the "references" or "implementations"
variants of that lens.

Defining a new `lsp-interface' to destructure
"rust-analyzer.showReference" was impossible, as the former doesn't
support destructuring lists (the :arguments? paramter is a special,
3-element list.).

* lsp-lens.el: fix byte-compile warnings

* Restore `lsp-execute-command' as an obsolete defun

Its original function, being a `cl-defgeneric' that can be overriden per
language server is gone; however, PRs were provided to eliminate all
uses of it in that context. To remain backwards-compatible, it will
still remain as an obsolete `defun' that calls `lsp--execute-command'
internally.

* Fix byte-compile

* Remove `lsp-execute-command' as an obsolete defun

Since it wouldn't do what it did previously (being an extension point),
restoring that function doesn't actually improve backwards
compatibility.

Reverts 957a056.

* Support `lsp-execute-command'

`lsp-execute-command' now works as an extension point again, but a deprecation
warning is shown if it is used to handle a command.

To implement this, leverage `cl-no-applicable-method': call
`lsp-execute-command' first, and then, if there is no implementation, go trough
the handler hash tables as usual.

* `lsp-execute-command': use `make-obsolete'

The proper way to mark a function as deprecated is to use
`make-obsolete'; use that instead of `lsp--warn'.

* lsp-rust: remove redundant `lsp-interface' comment

`lsp-interface' wasn't designed to destructure lists; stating that fact
before `lsp-rust--analyzer-show-references' is as such redundant, since
that is normal and not noteworthy.

* `lsp-lens--create-interactive-command': non-nil

The COMMAND? argument of that function mustn't be nil, which is unclear
from its name (?). Note that fact in its docstring.

The name of that argument is still good though, because it refers to a
field name in `CodeAction' and `CodeLens'.

Based on a discussion with @kiennq.

* Fix `byte-compile': `lsp-execute-command'

Unlike previously assumed, calling `lsp-execute-command' causes
byte-compile warnings, not just using it in `cl-defmethod'. Wrap the
call in `with-no-warnings', since that should be the only use of that
function.
  • Loading branch information
nbfalcon authored Mar 1, 2021
1 parent 4cdd1e9 commit b8a7455
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 20 deletions.
10 changes: 8 additions & 2 deletions clients/lsp-rust.el
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ PARAMS progress report notification data."
(lsp-workspace-status nil workspace)
(lsp-workspace-status (format "%s - %s" title (or message? "")) workspace))))

(cl-defmethod lsp-execute-command (_server (_command (eql rls.run)) params)
(lsp-defun lsp-rust--rls-run ((&Command :arguments? params))
(-let* (((&rls:Cmd :env :binary :args :cwd) (lsp-seq-first params))
(default-directory (or cwd (lsp-workspace-root) default-directory) ))
(compile
Expand Down Expand Up @@ -635,6 +635,11 @@ them with `crate` or the crate name they refer to."
(lsp-defun lsp-rust--analyzer-run-single ((&Command :arguments?))
(lsp-rust-analyzer-run (lsp-seq-first arguments?)))

(lsp-defun lsp-rust--analyzer-show-references
((&Command :title :arguments? [_uri _filepos references]))
(lsp-show-xrefs (lsp--locations-to-xref-items references) nil
(s-contains-p "reference" title)))

(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection
Expand All @@ -648,7 +653,8 @@ them with `crate` or the crate name they refer to."
:priority (if (eq lsp-rust-server 'rust-analyzer) 1 -1)
:initialization-options 'lsp-rust-analyzer--make-init-options
:notification-handlers (ht<-alist lsp-rust-notification-handlers)
:action-handlers (ht ("rust-analyzer.runSingle" #'lsp-rust--analyzer-run-single))
:action-handlers (ht ("rust-analyzer.runSingle" #'lsp-rust--analyzer-run-single)
("rust-analyzer.showReferences" #'lsp-rust--analyzer-show-references))
:library-folders-fn (lambda (_workspace) lsp-rust-library-directories)
:after-open-fn (lambda ()
(when lsp-rust-analyzer-server-display-inlay-hints
Expand Down
21 changes: 8 additions & 13 deletions lsp-lens.el
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,14 @@ See `lsp-lens--schedule-refresh' for details."
(define-key [mouse-1] (lsp-lens--create-interactive-command command))))

(defun lsp-lens--create-interactive-command (command?)
"Create an interactive COMMAND? for the lens."
(let ((server-id (->> (lsp-workspaces)
(cl-first)
(or lsp--cur-workspace)
(lsp--workspace-client)
(lsp--client-server-id))))
(if (functionp (lsp:command-command command?))
(lsp:command-command command?)
(lambda ()
(interactive)
(lsp-execute-command server-id
(intern (lsp:command-command command?))
(lsp:command-arguments? command?))))))
"Create an interactive COMMAND? for the lens.
COMMAND? shall be an `&Command' (e.g. `&CodeLens' :command?) and
mustn't be nil."
(if (functionp (lsp:command-command command?))
(lsp:command-command command?)
(lambda ()
(interactive)
(lsp--execute-command command?))))

(defun lsp-lens--display (lenses)
"Show LENSES."
Expand Down
20 changes: 15 additions & 5 deletions lsp-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,8 @@ calling `remove-overlays'.")
(defvar-local lsp--virtual-buffer-point-max nil)

(cl-defgeneric lsp-execute-command (server command arguments)
"Ask SERVER to execute COMMAND with ARGUMENTS.")
"Ask SERVER to execute COMMAND with ARGUMENTS."
(declare (obsolete "use `make-lsp-client' with :action-handlers instead." "7.1.0")))

(defun lsp-elt (sequence n)
"Return Nth element of SEQUENCE or nil if N is out of range."
Expand Down Expand Up @@ -5208,9 +5209,18 @@ It will filter by KIND if non nil."

(lsp-defun lsp--execute-command ((action &as &Command :command :arguments?))
"Parse and execute a code ACTION represented as a Command LSP type."
(-if-let* ((action-handler (lsp--find-action-handler command)))
(funcall action-handler action)
(lsp--send-execute-command command arguments?)))
(let ((server-id (->> (lsp-workspaces)
(cl-first)
(or lsp--cur-workspace)
(lsp--workspace-client)
(lsp--client-server-id))))
(condition-case nil
(with-no-warnings
(lsp-execute-command server-id (intern command) arguments?))
(cl-no-applicable-method
(if-let ((action-handler (lsp--find-action-handler command)))
(funcall action-handler action)
(lsp--send-execute-command command arguments?))))))

(lsp-defun lsp-execute-code-action ((action &as &CodeAction :command? :edit?))
"Execute code action ACTION.
Expand Down Expand Up @@ -5740,7 +5750,7 @@ REFERENCES? t when METHOD returns references."
(lsp-request "workspace/executeCommand" params)))

(defun lsp--send-execute-command (command &optional args)
"Execute workspace COMMAND with ARGS showing error if command is not mapped client-side."
"Create and send a 'workspace/executeCommand' message having command COMMAND and optional ARGS."
(condition-case-unless-debug err
(lsp-workspace-command-execute command args)
(error
Expand Down

0 comments on commit b8a7455

Please sign in to comment.