diff options
Diffstat (limited to 'lisp/citre-backend.el')
| -rw-r--r-- | lisp/citre-backend.el | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/lisp/citre-backend.el b/lisp/citre-backend.el index eefdd31..9169d31 100644 --- a/lisp/citre-backend.el +++ b/lisp/citre-backend.el @@ -31,6 +31,12 @@ The value `safe' filters by an explicitly declared receiver type only when at le :type '(set (const scope) (const source) (const count)) :group 'my/citre) +(defcustom my/citre-reference-program "rg" + "Program used to search references. +It must accept ripgrep's options and honour the project's ignore files." + :type 'string + :group 'my/citre) + (defcustom my/citre-completion-type-resolvers '(my/citre-backend--resolve-go-type my/citre-backend--resolve-rust-or-python-type @@ -248,14 +254,14 @@ Each function receives a receiver name and the beginning of its member expressio (let* ((type (plist-get context :type)) (matching (and type (seq-filter (lambda (tag) (my/citre-backend--scope-match-p type tag)) tags))) (visible (if (and (eq my/citre-completion-context-filter 'safe) matching) matching tags)) - (groups (make-hash-table :test #'equal)) (current-scope (my/citre-backend--current-scope))) - (dolist (tag tags) - (push tag (gethash (citre-get-tag-field 'name tag) groups))) (setq visible (sort visible (lambda (a b) (my/citre-backend--rank-less-p a b context current-scope)))) (if (not (eq my/citre-completion-deduplication 'name)) visible - (let ((seen (make-hash-table :test #'equal)) result) + (let ((groups (make-hash-table :test #'equal)) + (seen (make-hash-table :test #'equal)) result) + (dolist (tag tags) + (push tag (gethash (citre-get-tag-field 'name tag) groups))) (dolist (tag visible (nreverse result)) (let ((name (citre-get-tag-field 'name tag))) (unless (gethash name seen) @@ -316,16 +322,15 @@ Each function receives a receiver name and the beginning of its member expressio (context (list revision (car bounds) major-mode citre-tags-substr-completion (buffer-substring-no-properties (line-beginning-position) (car bounds)) member-context)) - (tick (buffer-chars-modified-tick)) (cache my/citre-backend--completion-cache) (tags (if (and revision (equal context (plist-get cache :context)) (string-prefix-p (plist-get cache :prefix) symbol)) - (progn (plist-put cache :tick tick) (plist-get cache :tags)) + (plist-get cache :tags) (let ((tags (my/citre-backend--prepare-completions (my/citre-backend--query 'completion) member-context))) (setq my/citre-backend--completion-cache (list :context context :prefix (substring-no-properties symbol) - :tick tick :tags tags)) + :tags tags)) tags)))) (when tags (list (car bounds) (cdr bounds) tags))))) @@ -359,6 +364,44 @@ Each function receives a receiver name and the beginning of its member expressio "Return the current file's symbols for Imenu, including unsaved changes." (my/citre-backend--query 'imenu)) +(defun my/citre-backend--reference-root () + "Return the directory searched for references." + (or (and my/citre-index--state (my/citre-index-state-root my/citre-index--state)) + (when-let* ((project (project-current nil))) (project-root project)) + default-directory)) + +(defun my/citre-backend-references-of-id (identifier) + "Return textual references to IDENTIFIER below the project root. +Universal Ctags records definitions only, so references come from a +whole-word search that honours the project's ignore files." + (when-let* ((program (executable-find my/citre-reference-program)) + (name (substring-no-properties identifier)) + (root (my/citre-backend--reference-root))) + (unless (string-empty-p name) + (let ((default-directory root) tags) + (with-temp-buffer + (process-file program nil t nil + "--no-heading" "--line-number" "--color=never" + "--word-regexp" "--fixed-strings" "--" name ".") + (goto-char (point-min)) + (while (not (eobp)) + ;; Citre renders the matched line from the file itself, so only the + ;; location is recorded here. + (when (looking-at "\\([^:\n]+\\):\\([0-9]+\\):") + (push (citre-make-tag + 'name name + 'ext-abspath (expand-file-name (match-string-no-properties 1) root) + 'line (match-string-no-properties 2) + 'extras "reference") + tags)) + (forward-line 1))) + (nreverse tags))))) + +(defun my/citre-backend-references () + "Return textual references to the symbol at point." + (when-let* ((symbol (citre-tags-symbol-at-point))) + (my/citre-backend-references-of-id symbol))) + (defun my/citre-backend-usable-p () "Whether the current buffer has an automatic or conventional tags index." (or my/citre-index--state (citre-tags-usable-p))) @@ -381,6 +424,8 @@ Each function receives a receiver name and the beginning of its member expressio :completions-fn #'my/citre-backend-completions :defs-fn #'my/citre-backend-definitions :defs-of-id-fn #'my/citre-backend-definitions-of-id + :refs-fn #'my/citre-backend-references + :refs-of-id-fn #'my/citre-backend-references-of-id :id-list-fn #'my/citre-backend-identifiers :tags-in-buffer-fn #'my/citre-backend-imenu :after-jump-fn #'my/citre-index-attach)) |
