If I have a list of file locations in elisp, how would I create an xref window, showing these locations?
You will need to convert that list to "xref item" values.
xref--collect-matches-1 for how this is done. Since your locations are not "xref matches", though, you will call
xref-make instead of
xref-make-match, and won't need the
Note that you will also need the string contents on that line (it will be shown in the xref buffer as "summary").
To show the list, you call
xref--show-xrefs. The first argument,
fetcher, must be a function that returns that list we computed above. Depending on how you retrieve that list, the fetcher could call the retrieval logic as well and then create the xref items from the result. Then
xref-revert-buffer will work as expected in such buffers.
Alternatively, if the list is static, fetcher can just process that list (by either looking up a lexical var up the scope, or some global var defined in the package). Also, for now,
fetcher can be a simple list (of xref items). But that's an obsolete convention.
xref--show-xrefs is ostensibly a "private" function. But it should be stable enough in the near future.
This function creates an
xref buffer from a list of references (thanks to @Dmitry's answer).
(defun my-xref-from-file-references (file-references) "Create an xref buffer from FILE-REFERENCES ((file line column display-text) ...)." ;; Needed for xref API. (require 'xref) (let ((xrefs (list))) (dolist (item file-references) (pcase-let ((`(,file ,line ,col ,display-text) item)) (push (xref-make display-text (xref-make-file-location file line col)) xrefs)) (xref--show-xrefs (lambda () xrefs) nil))))
(filepath line column) isn't quite enough information for
xref, so a
display-text has been included which would typically be the line of text - but can be anything.
Not an answer, but too much code for a comment.
May be you can reuse and adapt this code:
(save-excursion (and ;;; try finding file from make buffer javac error (re-search-forward "(\\(\\([A-Za-z]:\\)?\\.?\\.?/?[a-zA-Z0-9._/+-]+\\.[a-zA-Z0-9_/,+-]+\\):\\([0-9]+\\))" nil t) (or (and (file-readable-p (match-string 1)) (let ((file (match-string 1)) (line (string-to-int (match-string 3)))) (find-file file) (goto-line line) (recenter) t )) (and (get-buffer (file-name-nondirectory (match-string 1))) (let ((file (get-buffer (file-name-nondirectory (match-string 1)))) (line (string-to-int (match-string 3)))) (switch-to-buffer file) (goto-line line) (recenter) t )) )))