Skip to content
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

Inline Diagnostics #6417

Merged
merged 15 commits into from
Jul 15, 2024
Merged

Conversation

pascalkuthe
Copy link
Member

@pascalkuthe pascalkuthe commented Mar 24, 2023

Closes #3272
Closes #3078
closes #1462
Closes #1953
Supersedes #6059

This PR implements inline diagnostics just like #6059. However, it also contains a streamlined virtual text API and significantly improves on the implementation in #6059.

The various improvements and bugfixes made to the virtual text API are currently part of this PR until it's been tested more. I will spin those out into a separate PR later. These should address the various bugs and panics discovered by poeple in #6059. Only the last commit contains an implementation of inline diagnostics.

Due to the changes to the virtual text API I had to essentially rebuild #6059 as most changes in that PR became unnecessary by the improvements in the virtual text API.

I also rebuild the ASCII rendering to support soft wrapping. Diagnostics which exceed the width of the screen are now soft wrapped automatically. Additionally, there is a minimum width setting for diagnostics. Any diagnostics so far to the right that there is not this minimum width available are displayed using a backwards arching line. See screenshot below:

image

Additionally, this PR implements a severity-based filter for diagnostics. This allows users to choose one of the following:

  • a minimum severity for inline diagnostics: "warning"
  • a list of severities to allow (useful if a certain LSP spams one particular severity). ["warning", "errror"] Using an empty list disables inline diagnostics

The diagnostics to display can be separately configured for the line that currently contains the cursor. By disabling diagnostics for all other lines users can therefore only display diagnostics on the current line too. By default, only warnings/errors are displayed, on the cursor line all diagnostics are displayed. I am open to changing the default here, but this did feel quite nice to use in my testing.

Additionally, some details of the soft wrapping can be configured.
Currently, a draft as this needs more documentation, a separate PR for most of the virtual text changes, and more testing. That said it should work quite well already, and I invite people to try this out.

@pascalkuthe pascalkuthe changed the title use slices instead of Rc for virtual text Inlien Diagnostics Mar 24, 2023
@pascalkuthe pascalkuthe added E-hard Call for participation: Experience needed to fix: Hard / a lot S-waiting-on-review Status: Awaiting review from a maintainer. E-testing-wanted Call for participation: Experimental features suitable for testing S-waiting-on-pr Status: This is waiting on another PR to be merged first labels Mar 24, 2023
@pascalkuthe
Copy link
Member Author

(one test is failing for a type of virtual text that is currently not used yet. I forgot to clean that up, will look into that tomorrow, this shouldn't affect usage)

@archseer archseer changed the title Inlien Diagnostics Inline Diagnostics Mar 24, 2023
@carrascomj
Copy link

I noticed a bug (or strange behavior) trying this when combining wrapping with splits: on insert, the cursor moves away from the place where the actual insertion takes place.

See an example here: https://asciinema.org/a/DlnOVhiM8g2kXVtGBjwVFk8lo

(Maybe it is also a problem in master, mark as off-topic if that's the case).

@pascalkuthe
Copy link
Member Author

thanks for testing! This is a new regression with this PR and doesn't occur on master.

@pascalkuthe pascalkuthe added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from a maintainer. labels Mar 24, 2023
book/src/configuration.md Outdated Show resolved Hide resolved
@yuyidegit
Copy link

After merged this PR, LSP Type Hints #5934 have no effect.

@pascalkuthe
Copy link
Member Author

pascalkuthe commented Mar 25, 2023

Thank you for your feedback @yuyidegit] both bugs have been fixed (the test failures too).

This PR now depends on #6440 which fixes a bunch of bugs relevant to this PR. I will create another PR for the more complex virtual text API improvements once that one is merged

@pascalkuthe pascalkuthe removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Mar 25, 2023
@pascalkuthe pascalkuthe force-pushed the inline-diagnostics branch 3 times, most recently from c0eb133 to c0f5627 Compare March 25, 2023 23:54
@gabydd
Copy link
Member

gabydd commented Mar 26, 2023

found a pretty nasty bug to reproduce:

  1. open helix running this pr in the helix repo
  2. open helix-core/src/comment.rs
  3. delete the s in lines on line 21
  4. save the file so an error appears
  5. scroll down the file till line 28 is the top line
  6. when you go to the next line helix will crash with(some of the backtrace omitted that doesn't matter)
thread 'main' panicked at 'attempt to add with overflow', helix-term/src/ui/text_decorations.rs:136:16
 3: helix_term::ui::text_decorations::DecorationManager::render_virtual_lines
             at ./helix-term/src/ui/text_decorations.rs:136:16
   4: helix_term::ui::document::render_text
             at ./helix-term/src/ui/document.rs:166:17
   5: helix_term::ui::document::render_document
             at ./helix-term/src/ui/document.rs:79:5
   6: helix_term::ui::editor::EditorView::render_view
             at ./helix-term/src/ui/editor.rs:208:9
   7: <helix_term::ui::editor::EditorView as helix_term::compositor::Component>::render
             at ./helix-term/src/ui/editor.rs:1394:13
   8: helix_term::compositor::Compositor::render
             at ./helix-term/src/compositor.rs:170:13

I can reproduce this same panic for any inline diagnostic, seems like an edge case when the line that an error comes from does not fit on the screen. So the diagnostic would be the first line. But the first line rendered in this case would be line 27 which is technically row 2 so it has a visual_pos.row of 1 as well as nothing has been rendered last_line_pos.visual_line is equal to u16::MAX. because we are technically rendering the second line the check here passes https://github.com/pascalkuthe/helix/blob/c0f5627dd482de6266175e544c6ff2932c0f3925/helix-term/src/ui/document.rs#L160 and as last_line_pos.visual_line is u16::MAX and virt_off is 1, tada it panic.

@ocharles
Copy link
Contributor

I just gave this a try and see to get a whopping big inline diagnostic that's much bigger than the diagnostic itself:

image

@pascalkuthe pascalkuthe force-pushed the inline-diagnostics branch 2 times, most recently from 22f82b2 to 60f4dc7 Compare March 26, 2023 17:15
The line annotation as implemented in helix-editor#5420 had two shortcomings:
* It required the height of virtual text lines to be known ahead time
* It checked for line anchors at every grapheme

The first problem made the API impractical to use in practice because
almost all virtual text needs to be softwrapped. For example inline
diagnostics should be softwrapped to avoid cutting off the diagnostic
message (as no scrolling is possible). While more complex virtual text
like side by side diffs must dynamically calculate the number of empty
lines two align two documents (which requires taking account both
softwrap and virtual text). To address this, the API has been
refactored to use a trait.

The second issue caused some performance overhead and unnecessarily
complicated the `DocumentFormatter`. It was addressed by only calling
the trait mentioned above at line breaks (instead of always). This
allows offers additional flexibility to annotations as it offers
the flexibility to align lines (needed for side by side diffs).
This commit brings the text decoration API inline with the
LineAnnotation API (so they are consistent) resulting in a single
streamlined API instead of multiple ADHOK callbacks.
@archseer archseer merged commit 107cdf3 into helix-editor:master Jul 15, 2024
6 checks passed
@kanashimia
Copy link

kanashimia commented Jul 15, 2024

Can't reproduce what @kanashimia shows. I think that may be an older build and is already fixed for a while

That was on 418ac23 which was the latest build at that point. It is just slightly difficult to reproduce, as I said, because you need to have a very specific editor width and diagnostic for it to occur, for example rust-analyzer may change its output between versions.
Ideally it would be nice to just dump the editor state for you to see as a test, but I don't think it is possible.

I can still reproduce on commit 386fa37 obviously as nothing important was changed
rust-analyzer 1.81.0-nightly (4bc39f0 2024-06-26)
rustc 1.81.0-nightly (4bc39f028 2024-06-26)
cargo 1.81.0-nightly (4ed7bee47 2024-06-25)

And a terminal width
echo $COLUMNS $LINES
87 35

Here is a recording of it https://asciinema.org/a/cd8tFNbUwqCmcay91vXH1pKXB

Also multiple lines are still concatenated without a space for an eol diagnostic.

Well now that this was merged can just file a bug report.

@rmburg
Copy link

rmburg commented Jul 16, 2024

I can reproduce @kanashimia's issue, and I'm assuming it's caused by the line break in the 4th syntax error. There is a mismatch between the actual height of the diagnostics and the number of "virtual lines" inserted.

@aral
Copy link
Contributor

aral commented Jul 16, 2024

@pascalkuthe It’s merged – yay! 🎉

Thank you so much for your 1yr+ of work on this.

💕

@blitzarx1
Copy link

blitzarx1 commented Jul 16, 2024

Thanks for this long awaited feature <3. I have a stupid question:

I 've installed version from master helix 24.7 (22a05140), but my diagnostic messages are not inlined but in old top-right-corner style. Should I enable it somehow?

@mxmerz
Copy link

mxmerz commented Jul 16, 2024

You need to enable it in the config, for example:

[editor.inline-diagnostics]
cursor-line = "hint"
other-lines = "error"

@blitzarx1
Copy link

Thank you @mxmerz! It helped! Thanks again to the contributors of this great feature.

@flippette
Copy link

tfw the feature you've been waiting a year for misses the release train by 1 day

Anyway, congratulations @pascalkuthe on landing this! 🎉

@karthago1
Copy link
Contributor

@pascalkuthe thank you for this PR. Now I don't need to move my head to the upper right corner 😃 🎉

@Niedzwiedzw
Copy link

just tested it, it's awesome!!!

@lytedev
Copy link
Contributor

lytedev commented Aug 8, 2024

Can confirm, this is lovely (after you get used to it 😉). Thank you for getting this over the line, all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-core Area: Helix core improvements A-helix-term Area: Helix term improvements E-hard Call for participation: Experience needed to fix: Hard / a lot S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet