-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Close #52: Use entire line as xref summary when possible #127
Conversation
This is an enhanced version of #103, my github-fu is probably lacking... |
eglot.el
Outdated
(goto-char (car erange)) | ||
(let ((snippet (buffer-substring (point-at-bol) (point-at-eol)))) | ||
(add-face-text-property character | ||
(min (+ character length) (length snippet)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these lines are really long, you should truncate them to 80 characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eglot.el
already has lines over 80 characters long, so I don't know if this style fix is worth the noise of an additional commit (but I'll be happy to do it if the author says so, of course).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this style fix is worth the noise of an additional commit
You can git commit --amend
to amend changes to the last commit, then push with --force
.
Line 1384 is very long (142 characters) and definitely needs to be fixed. You can see the problem with M-x toggle-truncate-lines
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't sure GitHub processes force-pushes rewritten branches correctly :)
@cmm Have you assigned copyright to the FSF? |
totally missed the requirement :/. |
OK, I give up. Is there a simple (or not simple, but at least clear) step-by-step process for this anywhere? (I did the assignment dance once, a long time ago, when I was working on Guile, but don't remember anything; quick googling only gives me explanations as to why I should assign my copyright to FSF, blog entries vaguely detailing changes to the procedure (without referencing said procedure), etc. Life's too short for this shit) |
Just send email to emacs-devel@gnu.org and explain that you want to assign
copyright. You'll get instructions off-list.
João
On Nov 2, 2018 09:43, "Michael Livshin" <notifications@github.com> wrote:
@cmm <https://github.com/cmm> Have you assigned copyright to the FSF?
OK, I give up. is there a simple (or not simple, but at least clear)
step-by-step process for this?
(I did the assignment dance once, a long time ago, when I was working on
Guile, but don't remember anything; quick googling only gives me
explanations as to why I should assign my copyright to FSF, blog entries
vaguely detailing changes to the procedure (without referencing said
procedure), etc. Life's too short for this shit)
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#127 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAXnw5v-OeuPXcoQSc9MSYfRBjfi4pDXks5urBPcgaJpZM4XK_jb>
.
|
57ccd02
to
4c1f656
Compare
(in case anyone wonders about the status of this PR: assign at gnu dot org has been ignoring me for 2 weeks now, no clue why) |
Have you contacted emacs-devel@gnu.org? If so, two weeks is a reasonable delay to ping them there again |
I did, yes, and also pinged the assign address a week ago. Eli says there's a new person handling assignments, so I'm not alarmed yet. |
Yeah, well if you're serious about doing the assingment, I don't see any problem in accepting your contribution before you get it done. But this doesn't mean I've accepted the contribution yet :-), because I haven't read it properly yet. |
* 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.
assignment done |
Hi @cmm, So I've finally had a look at this and have the following comments:
diff --git a/eglot.el b/eglot.el
index 4996f5b..2b90277 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1478,13 +1478,37 @@ 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))))
+(defun eglot--xref-make (name uri range)
+ "Like `xref-make' but with LSP's NAME, URI and RANGE.
+To provide more information, try to visit the target file and
+extract the full line of the reference as the reference's
+summary."
+ (cl-destructuring-bind (&key start end) range
+ (let* ((file (eglot--uri-to-path uri))
+ (visiting (find-buffer-visiting file))
+ (buffer (or visiting
+ (and (file-readable-p file)
+ (find-file-noselect file)))))
+ (pcase-let
+ ((`(,summary ,line ,column)
+ (if buffer
+ (unwind-protect
+ (with-current-buffer buffer
+ (eglot--widening
+ (goto-char (eglot--lsp-position-to-point start))
+ (let* ((bol (point-at-bol))
+ (summary
+ (buffer-substring-no-properties bol
+ (point-at-eol))))
+ (add-face-text-property
+ (- (point) bol)
+ (- (eglot--lsp-position-to-point end) bol)
+ 'highlight t summary)
+ (list summary (current-line) (current-column)))))
+ (unless visiting (kill-buffer buffer)))
+ ;; Fall back to the "dumb" strategy
+ (list name (1+ (cl-getf start :line)) (cl-getf start :character)))))
+ (xref-make summary (xref-make-file-location file line column))))))
(defun eglot--sort-xrefs (xrefs)
(sort xrefs
@@ -1537,7 +1561,7 @@ DUMMY is ignored."
(if (vectorp definitions) definitions (vector definitions)))))
(eglot--sort-xrefs
(mapcar (jsonrpc-lambda (&key uri range)
- (eglot--xref-make identifier uri (plist-get range :start)))
+ (eglot--xref-make identifier uri range))
locations))))
(cl-defmethod xref-backend-references ((_backend (eql eglot)) identifier)
@@ -1552,7 +1576,7 @@ DUMMY is ignored."
(eglot--sort-xrefs
(mapcar
(jsonrpc-lambda (&key uri range)
- (eglot--xref-make identifier uri (plist-get range :start)))
+ (eglot--xref-make identifier uri range))
(jsonrpc-request (eglot--current-server-or-lose)
:textDocument/references
(append
@@ -1566,7 +1590,7 @@ DUMMY is ignored."
(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--xref-make name uri range)))
(jsonrpc-request (eglot--current-server-or-lose)
:workspace/symbol
`(:query ,pattern)))))) |
@joaotavora looks great (also TIL about #125 is dealt with here by using (Helper functions vs painful indentation vs code going to outer space rightwards is a matter of taste, and yours is more important.) |
Yes, but you could also have used
Not 100% what those things mean, but I like to keep the ability to reason about a feature locally. Given this can be coded in about half the loc with no abstractions to learn, it's an easy decision. But I'll give you credit for the idea and original working implementation. :-) |
The "idea" being the fact that lsp-mode works this way, FWIW :) |
Oh, good to know. |
After an original implementation by Michael Livshin. Also close #127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'.
@joaotavora Won't your solution be doing more IO work when there are many xrefs in a file which is not visited by a buffer? Currently you're killing the visited buffer after each call to |
Good catch. This is untested, this is why I put it in a scratch branch. |
Don't know if this would work, but it would be gross, right? In this situation I'd rather have a helper function do the grouping. |
Yes, it would be pretty hacky. |
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
@mkcms have a look at the latest one. It's still completely untested (don't have any LS's right now). |
Works well, but sometimes I get the error below using ccls in emacs repo (src/eval.c:90:19)
|
Probably if the LSP |
Hmm, I just looked at your commit, I believe the problem is that you call |
Like this diff --git a/eglot.el b/eglot.el
index 1eb88be..8069563 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1495,13 +1495,13 @@ DUMMY is ignored."
"Like `xref-make' but with LSP's NAME, URI and RANGE.
Try to visit the target file for a richer summary line."
(pcase-let*
- ((`(,beg . ,end) (eglot--range-region range))
- (file (eglot--uri-to-path uri))
+ ((file (eglot--uri-to-path uri))
(visiting (or (find-buffer-visiting file)
(gethash uri eglot--temp-location-buffers)))
(collect (lambda ()
- (let* ((bol (progn (goto-char beg) (point-at-bol)))
- (substring (buffer-substring bol (point-at-eol))))
+ (pcase-let* ((`(,beg . ,end) (eglot--range-region range))
+ (bol (progn (goto-char beg) (point-at-bol)))
+ (substring (buffer-substring bol (point-at-eol))))
(add-face-text-property (- beg bol) (- end bol) 'highlight
t substring)
(list substring (current-line) (current-column))))) |
Yeah looks good. You can force-push this to my scratch branch, if you wish. |
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
Alright, I also made these changes:
|
We should also either bind |
After an original implementation by Michael Livshin. Also close #127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'.
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
This would seems to be a bug in xref.el. Shouldn't it be the one to add 1, given line-numbers in Emacs are 0-indexed? (though
ACK. Perhaps it's time for an |
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
I always thought Emacs lines were 1-based? Many other built-ins apparently start from 1, including |
Guess it depends where you look. |
@joaotavora Thanks for this feature, it's quite useful.
Should I just push this to master? Or do you want to use (defun eglot--current-column ()
(- (point) (point-at-bol))) |
Guess we could say there are two standards, and the choice is arbitrary (but documented in Anyway, it's probably too late to change now. |
Yeah I figure, but though I'd ask anyway. |
Go ahead.
No need. Just add a docstring. Or better yet, make it a one-liner (it's pretty self-documenting). Thanks |
After an original implementation by Michael Livshin. Also close joaotavora/eglot#127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'.
… xref summary line collection * eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
After an original implementation by Michael Livshin. Also close joaotavora/eglot#127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'.
… xref summary line collection * eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs.
After an original implementation by Michael Livshin. Also close #127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'. #52: joaotavora/eglot#52 #127: joaotavora/eglot#127
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs. #52: joaotavora/eglot#52 #127: joaotavora/eglot#127
After an original implementation by Michael Livshin. Also close joaotavora/eglot#127. * eglot.el (eglot--xref-make): Rework. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Simplify call to `eglot--xref-make'. GitHub-reference: fix joaotavora/eglot#52
* eglot.el (eglot--temp-location-buffers): New variable. (eglot--handling-xrefs): New macro. (eglot--xref-make): Use eglot--temp-location-buffers. (xref-backend-definitions, xref-backend-references) (xref-backend-apropos): Use eglot--handling-xrefs. GitHub-reference: per joaotavora/eglot#52 GitHub-reference: per joaotavora/eglot#127
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.