Skip to content

Commit

Permalink
Close #52: Use entire line as xref summary when possible
Browse files Browse the repository at this point in the history
* eglot.el (eglot--xref-make): Make the item with summary being the
  whole line at given location, when possible
(eglot--locations-to-xrefs,eglot--path-xrefs,eglot--buf-xrefs):
Convert location list to xref list, trying to open each file just once.
(xref-backend-identifier-at-point):
(xref-backend-definitions):
(xref-backend-references): Pass the list of locations to
eglot--locations-to-xrefs.
  • Loading branch information
mkcms authored and cmm committed Oct 7, 2018
1 parent 69b8428 commit 3f08a66
Showing 1 changed file with 57 additions and 18 deletions.
75 changes: 57 additions & 18 deletions eglot.el
Original file line number Diff line number Diff line change
Expand Up @@ -1308,14 +1308,6 @@ DUMMY is ignored."
(advice-add 'xref-find-definitions :after #'eglot--xref-reset-known-symbols)
(advice-add 'xref-find-references :after #'eglot--xref-reset-known-symbols)

(defun eglot--xref-make (name uri position)
"Like `xref-make' but with LSP's NAME, URI and POSITION."
(cl-destructuring-bind (&key line character) position
(xref-make name (xref-make-file-location
(eglot--uri-to-path uri)
;; F!@(#*&#$)CKING OFF-BY-ONE again
(1+ line) character))))

(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql eglot)))
(when (eglot--server-capable :documentSymbolProvider)
(let ((server (eglot--current-server-or-lose))
Expand Down Expand Up @@ -1346,6 +1338,58 @@ DUMMY is ignored."
:textDocumentPositionParams
(eglot--TextDocumentPositionParams))))

(defun eglot--xref-make (identifier location)
"Make an `xref-item' for given IDENTIFIER and LSP LOCATION.
If IDENTIFIER is nil, use the current buffer's contents at
LOCATION as the summary."
(cl-destructuring-bind (&key uri range) location
(cl-destructuring-bind (&key start &allow-other-keys) range
(cl-destructuring-bind (&key line character) start
(xref-make
(or identifier
(let* ((erange (eglot--range-region range))
(length (- (cdr erange) (car erange))))
(eglot--widening
(goto-char (car erange))
(let ((snippet
(buffer-substring-no-properties (point-at-bol)
(point-at-eol))))
(add-face-text-property
character (min (+ character length) (length snippet))
'highlight t snippet)
snippet))))
(xref-make-file-location (eglot--uri-to-path uri)
;; F!@(#*&#$)CKING OFF-BY-ONE again
(1+ line) character))))))

(defun eglot--buf-xrefs (identifier locations)
(mapcar (apply-partially #'eglot--xref-make identifier)
locations))

(defun eglot--path-xrefs (identifier path-and-locations)
(cl-destructuring-bind (path . locations) path-and-locations
(let (already-visiting)
(cond
((setq already-visiting (find-buffer-visiting path))
(with-current-buffer already-visiting
(eglot--buf-xrefs nil locations)))
((file-readable-p path)
(with-temp-buffer
(insert-file-contents-literally path)
(eglot--buf-xrefs nil locations)))
(t
(eglot--buf-xrefs identifier locations))))))

(defun eglot--locations-to-xrefs (identifier locations)
(let ((locations-by-path
(seq-group-by (lambda (location)
(cl-destructuring-bind (&key uri range) location
(eglot--uri-to-path uri)))
locations)))
(apply #'append
(mapcar (apply-partially #'eglot--path-xrefs identifier)
locations-by-path))))

(cl-defmethod xref-backend-definitions ((_backend (eql eglot)) identifier)
(let* ((rich-identifier
(car (member identifier eglot--xref-known-symbols)))
Expand All @@ -1356,9 +1400,7 @@ DUMMY is ignored."
:textDocument/definition
(get-text-property
0 :textDocumentPositionParams identifier)))))
(mapcar (jsonrpc-lambda (&key uri range)
(eglot--xref-make identifier uri (plist-get range :start)))
location-or-locations)))
(eglot--locations-to-xrefs identifier location-or-locations)))

(cl-defmethod xref-backend-references ((_backend (eql eglot)) identifier)
(unless (eglot--server-capable :referencesProvider)
Expand All @@ -1369,9 +1411,8 @@ DUMMY is ignored."
(and rich (get-text-property 0 :textDocumentPositionParams rich))))))
(unless params
(eglot--error "Don' know where %s is in the workspace!" identifier))
(mapcar
(jsonrpc-lambda (&key uri range)
(eglot--xref-make identifier uri (plist-get range :start)))
(eglot--locations-to-xrefs
identifier
(jsonrpc-request (eglot--current-server-or-lose)
:textDocument/references
(append
Expand All @@ -1381,10 +1422,8 @@ DUMMY is ignored."

(cl-defmethod xref-backend-apropos ((_backend (eql eglot)) pattern)
(when (eglot--server-capable :workspaceSymbolProvider)
(mapcar
(jsonrpc-lambda (&key name location &allow-other-keys)
(cl-destructuring-bind (&key uri range) location
(eglot--xref-make name uri (plist-get range :start))))
(eglot--locations-to-xrefs
pattern
(jsonrpc-request (eglot--current-server-or-lose)
:workspace/symbol
`(:query ,pattern)))))
Expand Down

0 comments on commit 3f08a66

Please sign in to comment.