From: Felicián Németh Date: Thu, 3 Oct 2019 19:11:18 +0000 (+0200) Subject: Support goto-{declaration, implementation, typedefinition} X-Git-Tag: emacs-29.0.90~1616^2~524^2~4^2~308 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=83ed46b6a30ae4067df1436f6aef6f539adf5e77;p=emacs.git Support goto-{declaration, implementation, typedefinition} Closes https://github.com/joaotavora/eglot/issues/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. --- diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 1dc57113984..e3ead963610 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -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 @@ -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) @@ -1796,6 +1800,36 @@ 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))) @@ -1803,7 +1837,7 @@ Try to visit the target file for a richer summary line." (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