diff --git a/modules/feature/jump/autoload/jump.el b/modules/feature/jump/autoload/jump.el index fb05e433f..b4bfb937a 100644 --- a/modules/feature/jump/autoload/jump.el +++ b/modules/feature/jump/autoload/jump.el @@ -3,25 +3,39 @@ (defvar +jump--rg-installed-p (executable-find "rg")) (defvar +jump--ag-installed-p (executable-find "ag")) +(defun +jump-to (prop identifier &optional other-window) + (with-selected-window + (if other-window + (save-excursion (other-window) (selected-window)) + (selected-window)) + (let ((fn (plist-get +jump-current-functions prop))) + (if (commandp fn) + (call-interactively fn) + (funcall fn identifier))))) + ;;;###autoload -(defun +jump/definition (&optional other-window) +(defun +jump/definition (identifier &optional other-window) "Jump to the definition of the symbol at point. Tries xref and falls back to `dumb-jump', then rg/ag, then `evil-goto-definition' (if evil is active)." - (interactive "P") - (let ((sym (thing-at-point 'symbol t)) - successful) - (cond ((null sym) - (user-error "Nothing under point")) + (interactive + (list (thing-at-point 'symbol t) + current-prefix-arg)) + (cond ((null identifier) + (user-error "Nothing under point")) - ((ignore-errors (if other-window - (xref-find-definitions-other-window sym) - (xref-find-definitions sym)) - t)) + ((plist-member +jump-current-functions :definition) + (+jump-to :definition identifier)) - ((and (fboundp 'dumb-jump-go) - ;; dumb-jump doesn't tell us if it succeeded or not + ((ignore-errors (if other-window + (xref-find-definitions-other-window identifier) + (xref-find-definitions identifier)) + t)) + + ((and (fboundp 'dumb-jump-go) + ;; dumb-jump doesn't tell us if it succeeded or not + (let (successful) (cl-letf (((symbol-function 'dumb-jump-result-follow) `(lambda (result &optional use-tooltip proj) (setq successful t) @@ -30,48 +44,59 @@ Tries xref and falls back to `dumb-jump', then rg/ag, then (if other-window (dumb-jump-go-other-window) (dumb-jump-go)) - successful))) + successful)))) - ((and sym - (featurep 'counsel) - (let ((regex (rxt-quote-pcre sym))) - (or (and +jump--rg-installed-p - (counsel-rg regex (doom-project-root))) - (and +jump--ag-installed-p - (counsel-ag regex (doom-project-root))))))) + ((and identifier + (featurep 'counsel) + (let ((regex (rxt-quote-pcre identifier))) + (or (and +jump--rg-installed-p + (counsel-rg regex (doom-project-root))) + (and +jump--ag-installed-p + (counsel-ag regex (doom-project-root))))))) - ((and (featurep 'evil) - evil-mode - (destructuring-bind (beg end) (bounds-of-thing-at-point 'symbol) - (evil-goto-definition) - (let ((pt (point))) - (not (and (>= pt beg) - (< pt end))))))) + ((and (featurep 'evil) + evil-mode + (destructuring-bind (beg end) + (bounds-of-thing-at-point 'symbol) + (evil-goto-definition) + (let ((pt (point))) + (not (and (>= pt beg) + (< pt end))))))) - (t (user-error "Couldn't find '%s'" sym))))) + (t (user-error "Couldn't find '%s'" identifier)))) ;;;###autoload -(defun +jump/references () +(defun +jump/references (identifier) "Show a list of references to the symbol at point. Tries `xref-find-references' and falls back to rg/ag." - (interactive) - (let ((sym (thing-at-point 'symbol t))) - (cond ((ignore-errors (xref-find-references sym) - t)) + (interactive (list (thing-at-point 'symbol t))) + (cond ((plist-member +jump-current-functions :references) + (+jump-to :references identifier)) - ((and sym - (featurep 'counsel) - (let ((regex (rxt-quote-pcre sym))) - (or (and (executable-find "rg") - (counsel-rg regex (doom-project-root))) - (and (executable-find "ag") - (counsel-ag regex (doom-project-root))))))) + ((ignore-errors (xref-find-references identifier) + t)) - (t (error "Couldn't find '%s'" sym))))) + ((and identifier + (featurep 'counsel) + (let ((regex (rxt-quote-pcre identifier))) + (or (and (executable-find "rg") + (counsel-rg regex (doom-project-root))) + (and (executable-find "ag") + (counsel-ag regex (doom-project-root))))))) + + (t (error "Couldn't find '%s'" identifier)))) + +;;;###autoload +(defun +jump/documentation (identifier) + "Show documentation for the symbol at point, if available." + (interactive (list (thing-at-point 'symbol t))) + (cond ((plist-member +jump-current-functions :documentation) + (+jump-to :documentation identifier)) + (t + (+jump/online (caar +jump-search-url-alist) identifier)))) (defvar +jump--online-last nil) - ;;;###autoload (defun +jump/online (where search) "Looks up SEARCH online, in you browser, as dictated by WHERE. diff --git a/modules/feature/jump/config.el b/modules/feature/jump/config.el index 02ebca132..c868d0f92 100644 --- a/modules/feature/jump/config.el +++ b/modules/feature/jump/config.el @@ -22,29 +22,46 @@ "An alist that maps online resources to their search url or a function that produces an url. Used by `+jump/online'.") -(def-setting! :xref-backend (mode function) - "TODO" - `(add-hook! ,mode - (add-hook 'xref-backend-functions #',function nil t))) +(defvar +jump-function-alist nil + "TODO") -(set! :popup "*xref*" :noselect t :autokill t :autoclose t) +(defvar-local +jump-current-functions nil + "TODO") + +(def-setting! :jump (modes &rest plist) + "TODO" + `(dolist (mode (doom-enlist ,modes)) + (push (cons mode (list ,@plist)) +jump-function-alist))) ;; Let me control what backends to fall back on (setq-default xref-backend-functions '(t)) +(set! :popup "*xref*" :noselect t :autokill t :autoclose t) + ;; Recenter after certain jumps (add-hook! '(imenu-after-jump-hook evil-jumps-post-jump-hook counsel-grep-post-action-hook dumb-jump-after-jump-hook) #'recenter) +(defun +jump|init () + "Initialize `+jump-current-functions', used by `+jump/definition', +`+jump/references' and `+jump/documentation'." + (when-let (plist (cdr (assq major-mode +jump-function-alist))) + (when-let (backend (plist-get plist :xref-backend)) + (make-variable-buffer-local 'xref-backend-functions) + (cl-pushnew backend xref-backend-functions :test #'eq)) + (setq-local +jump-current-functions plist))) +(add-hook 'after-change-major-mode-hook #'+jump|init) + ;; ;; Packages ;; (def-package! dumb-jump - :commands (dumb-jump-go dumb-jump-quick-look dumb-jump-back) + :commands (dumb-jump-go dumb-jump-quick-look + dumb-jump-back dumb-jump-result-follow) :config (setq dumb-jump-default-project doom-emacs-dir dumb-jump-aggressive nil diff --git a/modules/lang/emacs-lisp/config.el b/modules/lang/emacs-lisp/config.el index 00022fba2..cfc8855f5 100644 --- a/modules/lang/emacs-lisp/config.el +++ b/modules/lang/emacs-lisp/config.el @@ -7,6 +7,7 @@ :config (set! :repl 'emacs-lisp-mode #'+emacs-lisp/repl) (set! :eval 'emacs-lisp-mode #'+emacs-lisp-eval) + (set! :jump 'emacs-lisp-mode :documentation #'describe-symbol) (set! :rotate 'emacs-lisp-mode :symbols '(("t" "nil") ("let" "let*") diff --git a/modules/lang/javascript/config.el b/modules/lang/javascript/config.el index c3d74e4df..6065a38eb 100644 --- a/modules/lang/javascript/config.el +++ b/modules/lang/javascript/config.el @@ -11,6 +11,10 @@ (add-hook! 'js2-mode-hook #'(flycheck-mode highlight-indentation-mode rainbow-delimiters-mode)) + (set! :repl 'js2-mode '+javascript/repl) + (set! :electric 'js2-mode :chars '(?\} ?\) ?.)) + (set! :jump 'js2-mode :xref-backend #'xref-js2-xref-backend) + ;; Conform switch-case indentation to editorconfig's config (set! :editorconfig :add '(js2-mode js2-basic-offset js-switch-indent-offset)) @@ -23,10 +27,6 @@ (setq-local flycheck-javascript-eslint-executable eslint)))) (add-hook 'flycheck-mode-hook #'+javascript|init-flycheck-elint) - (set! :repl 'js2-mode '+javascript/repl) - (set! :electric 'js2-mode :chars '(?\} ?\) ?.)) - (set! :xref-backend 'js2-mode 'xref-js2-xref-backend) - (sp-with-modes '(js2-mode rjsx-mode) (sp-local-pair "/* " " */" :post-handlers '(("| " "SPC")))) diff --git a/modules/lang/typescript/config.el b/modules/lang/typescript/config.el index 7c7258fbd..7b224cf22 100644 --- a/modules/lang/typescript/config.el +++ b/modules/lang/typescript/config.el @@ -26,10 +26,7 @@ (flycheck-mode +1) (eldoc-mode +1))) (add-hook! (typescript-mode web-mode) #'+typescript|tide-setup) - - (map! :map typescript-mode-map - :m "gd" #'tide-jump-to-definition - :localleader + (map! :localleader :m "fh" #'tide-documentation-at-point)) @@ -37,6 +34,11 @@ :after typescript-mode :config (set! :company-backend 'typescript-mode '(company-tide)) + (set! :jump 'typescript-mode + :definition #'tide-jump-to-definition + :references #'tide-references + :documentation #'tide-documentation-at-point) + (setq tide-format-options '(:insertSpaceAfterFunctionKeywordForAnonymousFunctions t :placeOpenBraceOnNewLineForFunctions nil)) diff --git a/modules/private/hlissner/+bindings.el b/modules/private/hlissner/+bindings.el index 780988de9..1bcc1c4f1 100644 --- a/modules/private/hlissner/+bindings.el +++ b/modules/private/hlissner/+bindings.el @@ -292,6 +292,7 @@ :m "gT" #'+workspace/switch-left :m "gd" #'+jump/definition :m "gD" #'+jump/references + :m "gh" #'+jump/documentation :n "gp" #'+evil/reselect-paste :n "gr" #'+eval:region :n "gR" #'+eval/buffer