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

Add workspace and document diagnostics picker #2013

Merged
merged 41 commits into from
Jun 30, 2022

Conversation

hirschenberger
Copy link
Contributor

fixes #1891

I mapped it to SPC g and SPC G but feel free to suggest better mappings. Also the style of the picker's lines is open for discussion.

I thought about adding another box on top of the code preview to display the whole diagnostic message without clipping. This adds more space to the list to display the uri.
But requires implementing a custom picker and may introduce a lot of code duplication or extending the existing picker in a smart way.

image

Comment on lines 426 to 429
self.editor
.diagnostics
.insert(params.uri.clone(), params.diagnostics.clone());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a whole bunch of duplication. Can we just store diagnostics on editor instead of document? I guess one painpoint is that raw lsp diagnostics don't have the offsets translated which makes this hard for files that haven't been opened yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean changing the local, already location-converted diagnostics to use the self.editor.diagnostics list and convert the locations on demand like it is done in the diags-picker?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's expensive to do that on the fly. How about using a map for diagnostics of buffers that aren't currently open? Then if the document gets opened you remove the entry from the map, convert the values and store them in the document.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using the editor.diagnostics map as single source of truth storing both like this? So we can cache already converted diags in a central place.

enum DiagnosticType {
    Hx(Diagnostic),
    Lsp(LspDiagnostic)
}

BTreeMap<lsp::Url, Vec<DiagnosticType>>

BTW: Another issue is the missing highlightling of the previews that have no open document. Are you planning to solve this? What would be a good way of solving this without huge performance impact?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using the editor.diagnostics map as single source of truth storing both like this? So we can cache already converted diags in a central place.

I think that's a smart way of doing it, with diagnostics being converted from LanguageServer to Local when possible.

BTW: Another issue is the missing highlightling of the previews that have no open document. Are you planning to solve this? What would be a good way of solving this without huge performance impact?

Yeah there's an issue open, I think we'll want to trigger highlighting after an idle timeout. That way it doesn't highlight hundreds of files if you're scrolling, but it will highlight the file you stop on.

helix-term/src/commands.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
helix-term/src/ui/mod.rs Outdated Show resolved Hide resolved
helix-term/src/ui/picker.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
@the-mikedavis the-mikedavis added the S-waiting-on-review Status: Awaiting review from a maintainer. label May 18, 2022
@photex
Copy link

photex commented Jun 7, 2022

Ahoy! I'd really like to see this feature land. Could we perhaps make a branch for the on-going effort so that more than one of us could contribute?

I've noticed after rebasing the work that @hirschenberger has done so far on top of HEAD:

  • SPC-G still appears to only show diagnostics for files that have already been opened.
    • If I open helix: hx ., select a file, and then SPC-G: I only see local diagnostics. If I open another file, then SPC-g is correctly limited to diagnostics in this file, while SPC-G is now showing the diagnostics from both open files. It would be ideal if SPC-G showed all of the feedback from clippy.
  • the function push_jump has changed and this PR needs to be updated 🤷 not a big deal, just happened to notice.

Having the diag list essentially duplicate entries in order to display messages isn't ideal (and doesn't suit the minimal and clean aesthetic of Helix). I'd personally vote that we only show the diagnostic once. Perfect is the enemy of good. I personally think that the suggestion to show extended info over the preview of each file is a good idea but could come after this feature.

@hirschenberger
Copy link
Contributor Author

Ahoy! I'd really like to see this feature land. Could we perhaps make a branch for the on-going effort so that more than one of us could contribute?

Hey, sorry for the delayed answer. I currently have not much time, but I'd also like to get this landed. I'm ok with adding more contributors to my branch to continue work on this,

I've noticed after rebasing the work that @hirschenberger has done so far on top of HEAD:

* SPC-G still appears to only show diagnostics for files that have already been opened.
  * If I open helix: `hx .`, select a file, and then `SPC-G`: I only see local diagnostics. If I open another file, then `SPC-g` is correctly limited to diagnostics in this file, while `SPC-G` is now showing the diagnostics from both open files. It would be ideal if `SPC-G` showed all of the feedback from clippy.

Strange, it works here with diagnostics for all files of the project. Which language have you tried? I tested it with rust and it works. Maybe because I enabled the clippy lints in rust-analyzer in my languages.toml

[[language]]
name="rust"

[language.config]
checkOnSave = {command = "clippy"}
cargo = {allFeatures = true}
procMacro = {enable = true }
auto-format = false
* the function `push_jump` has changed and this PR needs to be updated shrug not a big deal, just happened to notice.

I fixed it in my branch.

Having the diag list essentially duplicate entries in order to display messages isn't ideal (and doesn't suit the minimal and clean aesthetic of Helix). I'd personally vote that we only show the diagnostic once. Perfect is the enemy of good. I personally think that the suggestion to show extended info over the preview of each file is a good idea but could come after this feature.

I agree

@photex @BearOve Do you want to participate in this PR?

@hirschenberger
Copy link
Contributor Author

hirschenberger commented Jun 17, 2022

But it would be useful to see something like:

> [rs] db::models::User: E0432 - unresolved imports ...
  [rs] db::models::User: E0432 - unresolved imports ...
  [rs] db::models::Region: E0277 - the trait bound `Li...
  [rs] db::models::Region: E0277 - the trait bound `Li...
  [rs] db::models::Region: E0277 - the trait bound `Li...

Yes this would be a nice feature, but I don't really know where I can get the module path from. The lsp diagnostic does not contain such info.

@bjorn-ove
Copy link
Contributor

How about the last n characters if the file path?

@hirschenberger
Copy link
Contributor Author

How about the last n characters if the file path?

That may lead to e.g. on rust many lib.rs entries.
A deduplicated unique path representation would be nice to save some space and have a unique name.
E.g. like helix-tu*/s*/ba*/mod.rs or even helix-tu/s/ba/mod.rs indicating the shortened path components with a different color.

Anybody familiar of a crate that does this? Or we have to do it ourselves by using a patricia-tree

@the-mikedavis
Copy link
Member

I think that could be solved in-house (i.e. without adding a crate). It might be useful for #2759 as well

helix-core/src/path.rs Outdated Show resolved Hide resolved
@lazytanuki lazytanuki mentioned this pull request Jun 23, 2022
15 tasks
@hirschenberger
Copy link
Contributor Author

What else do we need here to get this PR landed?

@the-mikedavis
Copy link
Member

Afaik this just needs a round of review. Refactoring to use a table (#2814 (comment)) can be left for a follow-up PR.

let file = path.file_name().unwrap_or_default();
let base = path.parent().unwrap_or_else(|| Path::new(""));
let mut ret = PathBuf::new();
for d in base {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this loop necessary? d is an Option. I'd use if let Some()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to me you actually want to iterate over ancestors()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d is an OsStr and base is a &Path

Path implements Iterator for component traversal.

@@ -145,6 +150,97 @@ fn sym_picker(
.truncate_start(false)
}

fn diag_picker(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diagnostics_picker

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It follows the same naming schema as the sym_picker:

There's a function symbol_picker that calls a function sym_picker, the same as the function diagnostics_picker is calling diag_picker

helix-term/src/commands/lsp.rs Outdated Show resolved Hide resolved
true,
self.truncate_start,
);
spans.0.into_iter().fold(inner, |pos, span| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want set_spans? It has a specifiable max width

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it does not support highlighting fuzzy search results with a style callback function.

Copy link
Member

@archseer archseer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! Sorry the review took a while

@archseer archseer merged commit ed89f88 into helix-editor:master Jun 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add telecope-like list of lsp-diagnostics
10 participants