|
32 | 32 |
|
33 | 33 | (require 'thingatpt) |
34 | 34 |
|
| 35 | +(defcustom cider-use-xref t |
| 36 | + "Enable xref integration." |
| 37 | + :type 'boolean |
| 38 | + :safe #'booleanp |
| 39 | + :group 'cider |
| 40 | + :version '(cider . "1.2.0")) |
| 41 | + |
35 | 42 | (defun cider--find-var-other-window (var &optional line) |
36 | 43 | "Find the definition of VAR, optionally at a specific LINE. |
37 | 44 |
|
@@ -226,5 +233,71 @@ thing at point." |
226 | 233 | (cider--find-ns kw-ns arg) |
227 | 234 | (search-forward-regexp kw-to-find nil 'noerror))) |
228 | 235 |
|
| 236 | +(defun cider--xref-backend () |
| 237 | + "Used for xref integration." |
| 238 | + 'cider) |
| 239 | + |
| 240 | +(cl-defmethod xref-backend-identifier-at-point ((_backend (eql cider))) |
| 241 | + "Return the relevant identifier at point." |
| 242 | + (cider-symbol-at-point 'look-back)) |
| 243 | + |
| 244 | +(defun cider--var-to-xref-location (var) |
| 245 | + "Get location of definition of VAR." |
| 246 | + (when-let* ((info (cider-var-info var)) |
| 247 | + (line (nrepl-dict-get info "line")) |
| 248 | + (file (nrepl-dict-get info "file")) |
| 249 | + (buf (cider--find-buffer-for-file file))) |
| 250 | + (xref-make-buffer-location |
| 251 | + buf |
| 252 | + (with-current-buffer buf |
| 253 | + (save-excursion |
| 254 | + (goto-char 0) |
| 255 | + (forward-line (1- line)) |
| 256 | + (back-to-indentation) |
| 257 | + (point)))))) |
| 258 | + |
| 259 | +(cl-defmethod xref-backend-definitions ((_backend (eql cider)) var) |
| 260 | + "Find definitions of VAR." |
| 261 | + (cider-ensure-connected) |
| 262 | + (cider-ensure-op-supported "ns-path") |
| 263 | + (when-let* ((loc (cider--var-to-xref-location var))) |
| 264 | + (list (xref-make var loc)))) |
| 265 | + |
| 266 | +(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql cider))) |
| 267 | + "Return the completion table for identifiers." |
| 268 | + (cider-ensure-connected) |
| 269 | + (when-let* ((ns (cider-current-ns)) |
| 270 | + (results (cider-sync-request:ns-vars ns))) |
| 271 | + results)) |
| 272 | + |
| 273 | +(cl-defmethod xref-backend-references ((_backend (eql cider)) var) |
| 274 | + "Find references of VAR." |
| 275 | + (cider-ensure-connected) |
| 276 | + (cider-ensure-op-supported "fn-refs") |
| 277 | + (when-let* ((ns (cider-current-ns)) |
| 278 | + (results (cider-sync-request:fn-refs ns var))) |
| 279 | + (mapcar (lambda (info) |
| 280 | + (let* ((filename (nrepl-dict-get info "file")) |
| 281 | + (column (nrepl-dict-get info "column")) |
| 282 | + (line (nrepl-dict-get info "line")) |
| 283 | + (loc (xref-make-file-location filename line column))) |
| 284 | + (xref-make filename loc))) |
| 285 | + results))) |
| 286 | + |
| 287 | +(cl-defmethod xref-backend-apropos ((_backend (eql cider)) pattern) |
| 288 | + "Find all symbols that match regexp PATTERN." |
| 289 | + (cider-ensure-connected) |
| 290 | + (cider-ensure-op-supported "apropos") |
| 291 | + (when-let* ((ns (cider-current-ns)) |
| 292 | + (results (cider-sync-request:apropos pattern ns t t completion-ignore-case))) |
| 293 | + (mapcar (lambda (info) |
| 294 | + (let* ((symbol (nrepl-dict-get info "name")) |
| 295 | + (loc (cider--var-to-xref-location symbol)) |
| 296 | + (type (nrepl-dict-get info "type")) |
| 297 | + (doc (nrepl-dict-get info "doc"))) |
| 298 | + (xref-make (format "[%s] %s\n %s" (propertize symbol 'face 'bold) (capitalize type) doc) |
| 299 | + loc))) |
| 300 | + results))) |
| 301 | + |
229 | 302 | (provide 'cider-find) |
230 | 303 | ;;; cider-find.el ends here |
0 commit comments