Skip to content

Instantly share code, notes, and snippets.

@ZedThree
Forked from jwalt/rtags-xref.el
Last active July 30, 2018 12:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZedThree/03c09ff373d24e87371bbf7e9ec2fcd0 to your computer and use it in GitHub Desktop.
Save ZedThree/03c09ff373d24e87371bbf7e9ec2fcd0 to your computer and use it in GitHub Desktop.
Emacs25 rtags xref bindings
;;; rtags-xref.el -- rtags backend for xref.el
;;; Commentary:
;;;
;;; This adds support for the Emacs25 xref API (`xref-find-definitions' and
;;; friends) to rtags. Just `require' it and the default Emacs keybindings
;;; (M-., M-,, M-? etc.) use rtags.
;;;
;;; Enable like this:
;;;
;;; (require 'rtags-xref)
;;; (add-hook 'c-mode-common-hook 'rtags-xref-enable)
;;;
;;; Code:
(require 'xref)
(require 'rtags)
(cl-defgeneric xref-backend-identifier-at-point ((_backend (eql rtags)))
"Return the relevant identifier at point."
(let ((thing (thing-at-point 'symbol)))
(and thing (propertize (substring-no-properties thing)
:rtags-fn (rtags-buffer-file-name)
:rtags-loc (rtags-current-location)))))
(defun rtags--xref-backend-find (symbol func)
"Return definition of SYMBOL, searching via FUNC."
(save-match-data
(with-temp-buffer
(let* ((fn (get-text-property 0 :rtags-fn symbol))
(loc (get-text-property 0 :rtags-loc symbol))
(args (if fn (list :path fn "-K") (list "-K"))))
(apply func symbol loc args))
(let ((result nil))
(goto-char (point-min))
(while (= 0 (forward-line 1))
(forward-line -1)
(if (looking-at "\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\)?:\t\\(.*\\)$")
(let ((file (match-string-no-properties 1))
(line (string-to-number (match-string-no-properties 2)))
(column (string-to-number (match-string-no-properties 3)))
(summary (match-string-no-properties 4)))
(push (xref-make summary
(xref-make-file-location file line column))
result)))
(forward-line 1))
(nreverse result)))))
(cl-defmethod xref-backend-definitions ((_backend (eql rtags)) symbol)
"Return definition of SYMBOL."
(rtags--xref-backend-find
symbol
(lambda (symbol loc &rest args)
(if loc
(apply #'rtags-call-rc "-f" loc "--all-targets" args))
(if (= (rtags-buffer-lines) 0)
(apply #'rtags-call-rc "-F" symbol "--definition-only" args))
(if (= (rtags-buffer-lines) 0)
(apply #'rtags-call-rc "-F" symbol args)))))
(cl-defmethod xref-backend-apropos ((_backend (eql rtags)) pattern)
"Find all symbols that match regexp PATTERN"
(rtags--xref-backend-find
pattern
(lambda (symbol loc &rest args)
(apply #'rtags-call-rc "-Z" "-F" symbol args))))
(cl-defmethod xref-backend-references ((_backend (eql rtags)) symbol)
"Return references for SYMBOL."
(rtags--xref-backend-find
symbol
(lambda (symbol loc &rest args)
(if loc
(apply #'rtags-call-rc "-r" loc args))
(if (= (rtags-buffer-lines) 0)
(apply #'rtags-call-rc "-R" symbol args)))))
(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql rtags)))
"Return completion function."
#'rtags-symbolname-complete)
(defun rtags--xref-backend () "Return 'rtags." 'rtags)
(defun rtags-xref-enable ()
"Use rtags as xref backend."
(interactive)
(add-hook 'xref-backend-functions #'rtags--xref-backend nil t))
(provide 'rtags-xref)
;;; rtags-xref.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment