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

improve handling of different URI schemes over LSP #9633

Closed
wants to merge 3 commits into from

Conversation

soqb
Copy link
Contributor

@soqb soqb commented Feb 15, 2024

Objective

url::Url::to_file_path does not check which scheme the URI adheres to, meaning currently when a language server sends us a URI containing an unrecognized scheme, we blindly treat it as if it were a file path, leading to strange results.

This was causing issues for me using csharp-ls since when it resolves definitions over assembly boundaries, it will return a csharp:/metadata/foo/bar/Baz.cs URI, which a willing client can use to get readonly, decompiled definition info. In the current version, helix opens a blank buffer at /metadata/foo/bar/Baz.cs.

Solution

This PR introduces a uri_to_file_path method which performs the expected behaviour, first checking the scheme, and changes all relevant uses of Url::to_file_path to go via the new method instead and error without panicking when an unexpected scheme is found.

Details

It appears the LSP spec says nothing about which schemes are valid, so I don't think csharp-ls is at fault here (though I wouldn't expect us to support the "csharp" scheme without plugins).

Note

Strangely, while csharp-ls uses its own scheme, omnisharp's URIs are of the form file:///$metadata$/foo/bar/Baz.cs. It seems they adhere strongly to VSCode's lsp model which lets an extension act as middleware to intercept that URI to use other behaviour. Ergo, this PR does not fix the issue for omnisharp.

@the-mikedavis the-mikedavis added A-language-server Area: Language server client S-waiting-on-review Status: Awaiting review from a maintainer. labels Feb 15, 2024
@pascalkuthe
Copy link
Member

Oh I always thought that method did that check automatically but apparently it does not according to the docs. Good catch

helix-lsp/src/lib.rs Outdated Show resolved Hide resolved
helix-lsp/src/lib.rs Outdated Show resolved Hide resolved
helix-term/src/commands/lsp.rs Show resolved Hide resolved
helix-view/src/handlers/lsp.rs Outdated Show resolved Hide resolved
Err(err) => {
let err = format!("{err}: {uri}");
log::error!("{err}");
self.set_error(err);
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure we need this error on the statusline - I think the error line in the log is enough

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed although we do statusline report for all the related errors in the file, and did for the FilePathError::UnableToConvert case before i refactored it out.

@the-mikedavis the-mikedavis 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 Feb 15, 2024
Comment on lines 192 to 206
fn location_to_file_location(location: &lsp::Location) -> Option<FileLocation> {
match uri_to_file_path(&location.uri) {
Ok(path) => {
let line = Some((
location.range.start.line as usize,
location.range.end.line as usize,
));
Some((path.into(), line))
}
Err(FilePathError::UnsupportedScheme) => None,
Err(FilePathError::UnableToConvert) => unreachable!(
"file path should be able to be acquired from URI: {}",
location.uri
),
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't really think the panic is correct here this actually caused crashes in the past. The real fix is #7367 not sure what to do with this until then.

Copy link
Contributor Author

@soqb soqb Feb 15, 2024

Choose a reason for hiding this comment

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

i've edited this not to panic to air on the safe side, so both simply return None. note that if this crash is pervasive enough, #7367 isn't a complete fix since this function is also used for goto defintion and friends.

@the-mikedavis the-mikedavis added S-waiting-on-review Status: Awaiting review from a maintainer. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 15, 2024
@gzmorell
Copy link

I can confirm that this patch, at this moment, does not solve the problem with helix not showing lsp detected errors under Windows, while #7367 solves the problem.

@the-mikedavis
Copy link
Member

This handles a different kind of error than #7367 - this covers the language server sending us URIs that can't be understood as file paths while #7367 handles language servers sending us valid URIs that correspond to real paths but aren't normalized (e.g. URL encoding characters like +/&)

@the-mikedavis
Copy link
Member

There is a little overlap between how we solve the problems actually. We talked about this internally and we'd prefer to introduce a custom URI type and take care of invalid LSP URLs in TryFrom<url::Url> for Uri. In the long run we might want to have custom schemes (for example accessing files over networks) and that would mean throwing out the changes in #7367. But we can solve both problems with a custom URI type.

I've pushed up #9652 re-using most of this work

@soqb
Copy link
Contributor Author

soqb commented Feb 18, 2024

closing in favour of #9652.

@soqb soqb closed this Feb 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-language-server Area: Language server client S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants