-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Conversation
helix-term/src/application.rs
Outdated
self.editor | ||
.diagnostics | ||
.insert(params.uri.clone(), params.diagnostics.clone()); | ||
|
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.
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.
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.
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?
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.
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.
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.
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?
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.
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.
# Conflicts: # helix-term/src/commands/lsp.rs
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:
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. |
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,
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 [[language]]
name="rust"
[language.config]
checkOnSave = {command = "clippy"}
cargo = {allFeatures = true}
procMacro = {enable = true }
auto-format = false
I fixed it in my branch.
I agree @photex @BearOve Do you want to participate in this PR? |
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. |
How about the last n characters if the file path? |
That may lead to e.g. on rust many Anybody familiar of a crate that does this? Or we have to do it ourselves by using a patricia-tree |
I think that could be solved in-house (i.e. without adding a crate). It might be useful for #2759 as well |
What else do we need here to get this PR landed? |
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 { |
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.
Is this loop necessary? d
is an Option
. I'd use if let Some()
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.
Seems to me you actually want to iterate over ancestors()
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.
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( |
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.
diagnostics_picker
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.
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
true, | ||
self.truncate_start, | ||
); | ||
spans.0.into_iter().fold(inner, |pos, span| { |
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 think you want set_spans
? It has a specifiable max width
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.
Yes, but it does not support highlighting fuzzy search results with a style callback function.
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.
Thanks for working on this! Sorry the review took a while
fixes #1891
I mapped it to
SPC g
andSPC 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.