-
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
Send point or region as code action range #473
Conversation
There is a typo in the "subject": acrion -> action I like this PR. (Can you add a code-action test using one of the servers run by travis?) |
Fixed, thanks!
Do we really need the server to test this? Isn't it enough to test that the valid request is generated? |
Probably yes. Eglot has no tests in this regard, so a test of any kind is an improvement. |
Andrii Kolomoiets <notifications@github.com> writes:
> I like this PR. (Can you add a code-action test using one of the
> servers run by travis?)
I of course also like a pull request that deletes code and keeps the
same correct behaviour, but I'm not 100% sure those boundaries
calculations are useless. Maybe they weren't at the time and are now.
The arguments seem sound though.
Do we really need the server to test this? Isn't it enough to test
that the valid request is generated?
Perhaps it's not needed to test your particular change, but I would
appreciate a test of code actions where, say, a buffer had, say, 4
diagnostics and you request code actions for the middle 2. Though I
wouldn't spend an immense amount of effort there either. Does `pyls` do
code actions?
João
|
I mean in the subject of the commit message. Have you fixed that as well? |
* eglot.el (eglot-code-actions): Send region as codeAction range if region is active. Otherwise send just point.
Yes :) |
I've thought a bit more about this. How do I tell the server to give me all code actions for the whole buffer? That used to be the default. Do I just mark the whole buffer now? Not saying it's bad, mind you. |
Yes. IMO this is predictable behavior in contrast of sending whole buffer region when there are no selection.
I'll see what I can do about it.
No. Action support is declared in the server capabilities but there are no actions provided. "Inline variable" code action provided by recent |
OK. I'm sold. I like that logic.
Do you think |
Done. Not exactly with those diagnostic counts but see
I think so. Just
Yes.
IMO more important question is if we need the server in the tests at all. It is enough to test that eglot is making correct requests and correctly handle responses. I mean there are no need to install Because otherwise we testing servers :-) E.g. at the moment the travis config or the |
We need to do that. We need real-life fixtures, not idealized ones. |
Indeed I agree. Can you help us "pin" the pyls version in Travis? |
Got it. In this case it make sense to test how action actually applied to the buffer. I need your advice here: how can the test pick one of the actions returned by the server? |
Fixed on master branch. |
Friendly ping |
Andrii Kolomoiets <notifications@github.com> writes:
Friendly ping
Hi Andrii,
I've had a better look at this:
- I'm wasn't sure this PR wouldn't be breaking the [mouse-1] left-click
action on diagnotics. The one established by:
(define-key map [mouse-1] (eglot--mouse-call 'eglot-code-actions))
But I checked and it seems not to break, which is good news. The
reason it works is that flymake-diagnostics will defer to overlays-in,
which _will_ return some overlays. However, the docstring of
overlays-in isn't explicit about this. Something to fix in that
docstring, I suppose, so not our problem. But regardless, I think
it's better to default BEG to current point and END to nil.
- The docstring of eglot-code-actions has to be tweaked to say so.
I'll perform both these changes, squash the two commits together and
push, if I find no problems.
João
|
Hi again, Andrii
João Távora <joaotavora@gmail.com> writes:
Andrii Kolomoiets ***@***.***> writes:
> Friendly ping
But I checked and it seems not to break, which is good news.
Actually, it _does_ appear to break, so I fixed it. I think it's
slightly better to have this protocol:
(defun eglot-code-actions (beg &optional end)
"Offer to execute code actions between BEG and END.
Interactively, if a region is active, BEG and END are its bounds,
else BEG is point and END is nil, which results in a request for
code actions at point"
(interactive
(if (region-active-p) `(,(region-beginning) ,(region-end)) `(,(point) nil)))
which, of course, has the very same effect that you wanted.
Now, I pushed this under your name with a "Co-authored-by:"" tag (let me
know if you don't like this).
I didn't push the tests. Not because I don't like them, but because I
think these have some problems.
First, the code needs to be indented. Do this by making sure all the
macros are loaded and then indenting the region with the code. Now some
specific comments:
+ (flymake-start)
It would be nice to have a comment here saying that you do this to make
the diagnostics waited on appear as actual Flymake diagnostics.
+ (goto-char 94)
"94" seems waaay to brittle. Isn't there a better way?
+ (ignore-errors (call-interactively (eglot-code-actions)))
We certainly don't want ignore-errors, and it's better just to call:
(eglot-code-actions (point))
, becasue, in lisp programs such as tests, it's safer to rely on
eglot.el's Lisp interface, not the interactive specs (or at least not
like this). It's true there is an exception with xref-find-definitions,
but it's better not to repeat it.
+ (eglot--wait-for
+ (c-reqs)
+ (&key _id method params &allow-other-keys)
+ (and (string-equal method "textDocument/codeAction")
+ (equal (plist-get params :range)
+ '(:start
+ (:line 5 :character 10)
+ :end
+ (:line 5 :character 10)))
+ (let ((diags (plist-get
+ (plist-get params :context)
+ :diagnostics)))
+ (and (= (length diags) 1)
+ (equal (plist-get (aref diags 0) :range)
+ '(:start
+ (:line 5 :character 0)
+ :end
+ (:line 5 :character 19)))))))))))
It's OK to wait for the client request to go to the server, but the
specific wait for a request that meets exactly those characteristics
seems off to me. So basically I would only wait for:
(string-equal method "textDocument/codeAction")
Also, I wouldn't check the nitty gritty details of this request which,
again, are brittle. It's better to check more generic stuff, such as
(= (length diags) 1)
But I would do this with an `is` assertion after the wait.
If you prefer, you can even continue the test in the sense that you
eventually invoke the code-action request and then verify its results in
the buffer.
+ ;; selection as range and no diagnostic
+ (set-mark 0)
+ (goto-char 8)
Same comment as above
+ (activate-mark)
No need for this or the set-mark, I think. See below.
+ (eglot--sniffing
+ (:client-requests c-reqs)
+ (ignore-errors (call-interactively #'eglot-code-actions))
It's better to
(eglot-code-actions (region-beginning) (region-end))
João
|
Thanks!
Can confirm, works as expected.
My bad. Didn't know about
Got it.
Agree. I think
Not with
But my goal was to test that
I'm verifying here that the diagnostic from the current line is sent and not from the first line. Thats the reason to check all the details.
I need your advice here: how can the test pick one of the actions returned by the server?
Again, I wanted to test the One more thing: should I continue work in this PR or better move the test to the new one? Thanks again! |
If no region is active, ask for code actions at point, even if there are no diagnostics at point. Co-authored-by: João Távora <joaotavora@gmail.com> * eglot.el (eglot-code-actions): Simplify.
If no region is active, ask for code actions at point, even if there are no diagnostics at point. Co-authored-by: João Távora <joaotavora@gmail.com> * eglot.el (eglot-code-actions): Simplify.
If no region is active, ask for code actions at point, even if there are no diagnostics at point. Co-authored-by: João Távora <joaotavora@gmail.com> * eglot.el (eglot-code-actions): Simplify. #473: joaotavora/eglot#473
If no region is active, ask for code actions at point, even if there are no diagnostics at point. Co-authored-by: João Távora <joaotavora@gmail.com> * eglot.el (eglot-code-actions): Simplify. GitHub-reference: close joaotavora/eglot#473
Trying to implement
refactor.inline
code action provided by jedi.Looks like eglot never send the current point on
codeAction
request.This PR aimed to send region boundaries when region is active and just the point otherwise:
codeAction
range based on diagnostics under point.(point-min) (point-max)
.