From 13134726dca553460c5d836afaa19f58e5888578 Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Tue, 12 May 2020 00:43:16 +0900 Subject: [PATCH 1/2] tools/lookup: Support implementations lookup handlers --- modules/tools/lookup/autoload/lookup.el | 26 +++++++++++++++++++++---- modules/tools/lookup/config.el | 11 +++++++++++ modules/tools/lsp/config.el | 2 ++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/modules/tools/lookup/autoload/lookup.el b/modules/tools/lookup/autoload/lookup.el index a77ace491..25fa41305 100644 --- a/modules/tools/lookup/autoload/lookup.el +++ b/modules/tools/lookup/autoload/lookup.el @@ -15,6 +15,9 @@ properties: :definition FN Run when jumping to a symbol's definition. Used by `+lookup/definition'. +:implementations FN + Run when looking for implementations of a symbol in the current project. Used + by `+lookup/implementations'. :references FN Run when looking for usage references of a symbol in the current project. Used by `+lookup/references'. @@ -46,8 +49,8 @@ change the current buffer or window or return non-nil when it succeeds. If it doesn't change the current buffer, or it returns nil, the lookup module will fall back to the next handler in `+lookup-definition-functions', -`+lookup-references-functions', `+lookup-file-functions' or -`+lookup-documentation-functions'. +`+lookup-implementations-functions', `+lookup-references-functions', +`+lookup-file-functions' or `+lookup-documentation-functions'. Consecutive `set-lookup-handlers!' calls will overwrite previously defined handlers for MODES. If used on minor modes, they are stacked onto handlers @@ -57,7 +60,7 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (set-lookup-handlers! 'python-mode nil) -\(fn MODES &key DEFINITION REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)" +\(fn MODES &key DEFINITION IMPLEMENTATIONS REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)" (declare (indent defun)) (dolist (mode (doom-enlist modes)) (let ((hook (intern (format "%s-hook" mode))) @@ -69,15 +72,17 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (fset fn (lambda () - (cl-destructuring-bind (&key definition references documentation file xref-backend async) + (cl-destructuring-bind (&key definition implementations references documentation file xref-backend async) plist (cl-mapc #'+lookup--set-handler (list definition + implementations references documentation file xref-backend) (list '+lookup-definition-functions + '+lookup-implementations-functions '+lookup-references-functions '+lookup-documentation-functions '+lookup-file-functions @@ -133,6 +138,7 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (let* ((origin (point-marker)) (handlers (plist-get (list :definition '+lookup-definition-functions + :implementations '+lookup-implementations-functions :references '+lookup-references-functions :documentation '+lookup-documentation-functions :file '+lookup-file-functions) @@ -241,6 +247,18 @@ evil-mode is active." ((+lookup--jump-to :definition identifier nil arg)) ((error "Couldn't find the definition of %S" identifier)))) +;;;###autoload +(defun +lookup/implementations (identifier &optional arg) + "Jump to the implementations of IDENTIFIER (defaults to the symbol at point). + +Each function in `+lookup-implementations-functions' is tried until one changes +the point or current buffer." + (interactive (list (doom-thing-at-point-or-region) + current-prefix-arg)) + (cond ((null identifier) (user-error "Nothing under point")) + ((+lookup--jump-to :implementations identifier nil arg)) + ((error "Couldn't find the implementations of %S" identifier)))) + ;;;###autoload (defun +lookup/references (identifier &optional arg) "Show a list of usages of IDENTIFIER (defaults to the symbol at point) diff --git a/modules/tools/lookup/config.el b/modules/tools/lookup/config.el index 8f392cd76..ba631536f 100644 --- a/modules/tools/lookup/config.el +++ b/modules/tools/lookup/config.el @@ -3,6 +3,8 @@ ;; "What am I looking at?" This module helps you answer this question. ;; ;; + `+lookup/definition': a jump-to-definition that should 'just work' +;; + `+lookup/implementations': find a symbol's implementations in the current +;; project ;; + `+lookup/references': find a symbol's references in the current project ;; + `+lookup/file': open the file referenced at point ;; + `+lookup/online'; look up a symbol on online resources @@ -52,6 +54,15 @@ If the argument is interactive (satisfies `commandp'), it is called with argument: the identifier at point. See `set-lookup-handlers!' about adding to this list.") +(defvar +lookup-implementations-functions () + "Function for `+lookup/implementations' to try. Stops at the first function to +return non-nil or change the current window/point. + +If the argument is interactive (satisfies `commandp'), it is called with +`call-interactively' (with no arguments). Otherwise, it is called with one +argument: the identifier at point. See `set-lookup-handlers!' about adding to +this list.") + (defvar +lookup-references-functions '(+lookup-xref-references-backend-fn +lookup-project-search-backend-fn) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index 51f18346e..e6d9373f1 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -54,6 +54,7 @@ working on that project after closing the last buffer.") (set-lookup-handlers! 'lsp-mode :async t :documentation #'lsp-describe-thing-at-point :definition #'lsp-find-definition + :implementations #'lsp-find-implementation :references #'lsp-find-references) ;; TODO Lazy load these. They don't need to be loaded all at once unless the @@ -189,6 +190,7 @@ auto-killed (which is a potentially expensive process)." (when (featurep! +peek) (set-lookup-handlers! 'lsp-ui-mode :async t :definition 'lsp-ui-peek-find-definitions + :implementations 'lsp-ui-peek-find-implementation :references 'lsp-ui-peek-find-references))) From d08f2dd8888b2c600795b0544c8db55ddd555f1e Mon Sep 17 00:00:00 2001 From: Seong Yong-ju Date: Tue, 12 May 2020 01:06:23 +0900 Subject: [PATCH 2/2] tools/lookup: Support type definition lookup handlers --- modules/tools/lookup/autoload/lookup.el | 27 +++++++++++++++++++++---- modules/tools/lookup/config.el | 9 +++++++++ modules/tools/lsp/config.el | 1 + 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/modules/tools/lookup/autoload/lookup.el b/modules/tools/lookup/autoload/lookup.el index 25fa41305..33d5818f8 100644 --- a/modules/tools/lookup/autoload/lookup.el +++ b/modules/tools/lookup/autoload/lookup.el @@ -18,6 +18,9 @@ properties: :implementations FN Run when looking for implementations of a symbol in the current project. Used by `+lookup/implementations'. +:type-definition FN + Run when jumping to a symbol's type definition. Used by + `+lookup/type-definition'. :references FN Run when looking for usage references of a symbol in the current project. Used by `+lookup/references'. @@ -49,8 +52,9 @@ change the current buffer or window or return non-nil when it succeeds. If it doesn't change the current buffer, or it returns nil, the lookup module will fall back to the next handler in `+lookup-definition-functions', -`+lookup-implementations-functions', `+lookup-references-functions', -`+lookup-file-functions' or `+lookup-documentation-functions'. +`+lookup-implementations-functions', `+lookup-type-definition-functions', +`+lookup-references-functions', `+lookup-file-functions' or +`+lookup-documentation-functions'. Consecutive `set-lookup-handlers!' calls will overwrite previously defined handlers for MODES. If used on minor modes, they are stacked onto handlers @@ -60,7 +64,7 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (set-lookup-handlers! 'python-mode nil) -\(fn MODES &key DEFINITION IMPLEMENTATIONS REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)" +\(fn MODES &key DEFINITION IMPLEMENTATIONS TYPE-DEFINITION REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)" (declare (indent defun)) (dolist (mode (doom-enlist modes)) (let ((hook (intern (format "%s-hook" mode))) @@ -72,17 +76,19 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (fset fn (lambda () - (cl-destructuring-bind (&key definition implementations references documentation file xref-backend async) + (cl-destructuring-bind (&key definition implementations type-definition references documentation file xref-backend async) plist (cl-mapc #'+lookup--set-handler (list definition implementations + type-definition references documentation file xref-backend) (list '+lookup-definition-functions '+lookup-implementations-functions + '+lookup-type-definition-functions '+lookup-references-functions '+lookup-documentation-functions '+lookup-file-functions @@ -139,6 +145,7 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g. (handlers (plist-get (list :definition '+lookup-definition-functions :implementations '+lookup-implementations-functions + :type-definition '+lookup-type-definition-functions :references '+lookup-references-functions :documentation '+lookup-documentation-functions :file '+lookup-file-functions) @@ -259,6 +266,18 @@ the point or current buffer." ((+lookup--jump-to :implementations identifier nil arg)) ((error "Couldn't find the implementations of %S" identifier)))) +;;;###autoload +(defun +lookup/type-definition (identifier &optional arg) + "Jump to the type definition of IDENTIFIER (defaults to the symbol at point). + +Each function in `+lookup-type-definition-functions' is tried until one changes +the point or current buffer." + (interactive (list (doom-thing-at-point-or-region) + current-prefix-arg)) + (cond ((null identifier) (user-error "Nothing under point")) + ((+lookup--jump-to :type-definition identifier nil arg)) + ((error "Couldn't find the definition of %S" identifier)))) + ;;;###autoload (defun +lookup/references (identifier &optional arg) "Show a list of usages of IDENTIFIER (defaults to the symbol at point) diff --git a/modules/tools/lookup/config.el b/modules/tools/lookup/config.el index ba631536f..22f944972 100644 --- a/modules/tools/lookup/config.el +++ b/modules/tools/lookup/config.el @@ -63,6 +63,15 @@ If the argument is interactive (satisfies `commandp'), it is called with argument: the identifier at point. See `set-lookup-handlers!' about adding to this list.") +(defvar +lookup-type-definition-functions () + "Functions for `+lookup/type-definition' to try. Stops at the first function to +return non-nil or change the current window/point. + +If the argument is interactive (satisfies `commandp'), it is called with +`call-interactively' (with no arguments). Otherwise, it is called with one +argument: the identifier at point. See `set-lookup-handlers!' about adding to +this list.") + (defvar +lookup-references-functions '(+lookup-xref-references-backend-fn +lookup-project-search-backend-fn) diff --git a/modules/tools/lsp/config.el b/modules/tools/lsp/config.el index e6d9373f1..3657b82ef 100644 --- a/modules/tools/lsp/config.el +++ b/modules/tools/lsp/config.el @@ -55,6 +55,7 @@ working on that project after closing the last buffer.") :documentation #'lsp-describe-thing-at-point :definition #'lsp-find-definition :implementations #'lsp-find-implementation + :type-definition #'lsp-find-type-definition :references #'lsp-find-references) ;; TODO Lazy load these. They don't need to be loaded all at once unless the