Skip to content

Commit

Permalink
Support goto-{declaration, implementation, typeDefinition}
Browse files Browse the repository at this point in the history
Closes #302.

* eglot.el (eglot--xref-definitions-method): New variable.
(xref-backend-definitions): Use it.
(eglot-find-declaration, eglot-find-implementation,
eglot-find-typeDefinition): New functions.

* README.md (Language features): Add new capabilities.

* eglot.el (eglot-client-capabilities): Add new capabilities.
(eglot-ignored-server-capabilites): Add new capability.

#302: joaotavora/eglot#302
  • Loading branch information
nemethf authored and joaotavora committed Oct 11, 2019
1 parent c689b7e commit 4c11b0b
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion lisp/progmodes/eglot.el
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ treated as in `eglot-dbind'."
(:labelOffsetSupport t)))
:references `(:dynamicRegistration :json-false)
:definition `(:dynamicRegistration :json-false)
:declaration `(:dynamicRegistration :json-false)
:implementation `(:dynamicRegistration :json-false)
:typeDefinition `(:dynamicRegistration :json-false)
:documentSymbol (list
:dynamicRegistration :json-false
:symbolKind `(:valueSet
Expand Down Expand Up @@ -1090,6 +1093,7 @@ under cursor."
(const :tag "Go to definition" :definitionProvider)
(const :tag "Go to type definition" :typeDefinitionProvider)
(const :tag "Go to implementation" :implementationProvider)
(const :tag "Go to declaration" :implementationProvider)
(const :tag "Find references" :referencesProvider)
(const :tag "Highlight symbols automatically" :documentHighlightProvider)
(const :tag "List symbols in buffer" :documentSymbolProvider)
Expand Down Expand Up @@ -1796,14 +1800,44 @@ Try to visit the target file for a richer summary line."
:textDocumentPositionParams
(eglot--TextDocumentPositionParams))))

(defvar eglot--xref-definitions-method :textDocument/definition
"The LSP method to map xref-find-definitions call.")

(defun eglot-find-declaration ()
"Find the declaration for the identifier at point.
See `xref-find-definitions' and `xref-prompt-for-identifier'."
(interactive)
(eglot--find-location 'declaration))

(defun eglot-find-implementation ()
"Find the implementation for the identifier at point.
See `xref-find-definitions' and `xref-prompt-for-identifier'."
(interactive)
(eglot--find-location 'implementation))

(defun eglot-find-typeDefinition ()
"Find the type definition for the identifier at point.
See `xref-find-definitions' and `xref-prompt-for-identifier'."
(interactive)
(eglot--find-location 'typeDefinition))

(defun eglot--find-location (kind)
(let* ((method-name (symbol-name kind))
(method (intern (concat ":textDocument/" method-name)))
(capability (intern (concat ":" method-name "Provider"))))
(if (eglot--server-capable capability)
(let ((eglot--xref-definitions-method method))
(call-interactively #'xref-find-definitions))
(eglot--error "Server is not a %sProvider" method-name))))

(cl-defmethod xref-backend-definitions ((_backend (eql eglot)) identifier)
(let* ((rich-identifier
(car (member identifier eglot--xref-known-symbols)))
(definitions
(if rich-identifier
(get-text-property 0 :locations rich-identifier)
(jsonrpc-request (eglot--current-server-or-lose)
:textDocument/definition
eglot--xref-definitions-method
(get-text-property
0 :textDocumentPositionParams identifier))))
(locations
Expand Down

0 comments on commit 4c11b0b

Please sign in to comment.