-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
ruff server
: Add support for documents not exist on disk
#11588
Conversation
955f9d5
to
cbd5a84
Compare
cbd5a84
to
abd95b4
Compare
|
crates/ruff_server/src/server/api/notifications/did_change_workspace.rs
Outdated
Show resolved
Hide resolved
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. Overall this looks good to me and is exactly what I wanted to do as well.
I think the only part that I planned to add and isn't part of this PR is that we can't use SourceType::from_path
for a new file and instead should respect the language setting coming from VS Code. In theory, this also applies for existing files because a user could have mapped all .py
files to notebooks
in their configuration.
That's why I think we should infer the SourceType
in the didOpen
request from the item.languageId
. Unfortunately, the language id doesn't distinguish between python and python stub files. That's why query.source_type()
still needs to look at the path if the source type communicated by VS code is Python.
@T-256 - Do you want to address Micha's feedback, or want me to do so? |
I opened this PR as POC that what could be happened. I wanted to get time to test it yesterday, but unfortunately it didn't happen. @MichaReiser Thanks for review, few comments still unsolved, I'd be happy to Charlie help me solve them. |
Thank you, @T-256 for all the work. I'll take a look at addressing the remaining review comments. |
…s maps actual paths * Use `Url.to_file_path` as we used to before switching to PathBuf in the notebook PR * Rename some `*path` variables to `*url` * Change `take_snapshot` to take an owned `Url` because it always clones the URL internally * More smaller fixes
// If there's only a single workspace, use that configuration for an untitled document. | ||
if self.settings.len() == 1 { | ||
tracing::debug!( | ||
"Falling back to configuration of the only active workspace for the new document '{url}'." | ||
); | ||
self.settings.values().next() | ||
} else { | ||
None | ||
} |
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'm not entirely sure about this. It's nice because the file is most likely to be part of the workspace and it would be unfortunate if we show lint errors for rules that are disabled in this workspace.
However, it has the downside that the shown lint errors change when the user has an unsaved document and then opens a new workspace. A next pull diagnostic now uses the default configuration which is different from the last run. I think that's fine, considering that adding a workspace AND having an unsaved file is rare.
/// Get the path for the document selected by this query. | ||
/// | ||
/// Returns `None` if this is an unsaved (untitled) document. | ||
/// | ||
/// The path isn't guaranteed to point to a real path on the filesystem. This is the case | ||
/// for unsaved (untitled) documents. | ||
pub(crate) fn file_path(&self) -> Option<PathBuf> { | ||
self.file_url().to_file_path().ok() | ||
} | ||
|
||
/// Get the path for the document selected by this query, ignoring whether the file exists on disk. | ||
/// | ||
/// Returns the URL's path if this is an unsaved (untitled) document. | ||
pub(crate) fn virtual_file_path(&self) -> &Path { | ||
Path::new(self.file_url().path()) | ||
} | ||
|
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 it's worth to distinguish between the two. E.g., I think we shouldn't test for exclusion for unsaved files because we don't have a real path.
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 am wondering if we should make Path
optional for the Ruff APIs like lint_fix
...?
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.
Like, could we remove this entirely? Why is the path needed in such cases? (If it's just for the extension, we could implement something special in source_type
.)
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 for diagnostics and maybe file based lint rules?
We might get away with it but I'm not very eager to change it. Like it would probably be an improvement but I rather finish res knot where this will be gone anyway 😅
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.
LGTM, Thanks for done this.
Just for last question, shouldn't we explicitly specify what URL schemes we support? AFAIK and according to docs of LSP specification it should be file
or untitled
. but URL itself could contain other schemes, IMO we should disallow other schemes. what do you think?
// For a new unsaved and untitled document, use the ruff settings from the top of the workspace | ||
// but only IF: | ||
// * It is the only workspace | ||
// * The ruff setting is at the top of the workspace (in the root folder) | ||
// Otherwise, use the fallback settings. | ||
if self.settings.len() == 1 { | ||
let workspace_path = self.settings.keys().next().unwrap(); | ||
settings.ruff_settings.get(workspace_path) | ||
} else { | ||
settings.ruff_settings.fallback() | ||
} |
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 users generally want this (take the settings from the root configuration in the only active workspace). But it does have the downside that adding a second workspace later on means that we suddenly take the fallback which changes the output. But I think that's fine.
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 there are such cases in vscode internals too. IIRC they solved by choosing first workspace was added. can we consider same at here?
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.
Possibly. We would need to keep a second vector that stores the workspace URLs in insertion order. I would prefer to leave this out of this PR for now.
c5b4ea4
to
edeaae6
Compare
I tested:
I didn't change the code to use the language from the |
); | ||
return Ok(Fixes::default()); | ||
} | ||
let package = if let Some(document_path) = document_path.as_ref() { |
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.
The way I implemented it here is that an untitled file can never be excluded. However, that means that an exclude = ["*"]
won't apply where users might expect that it should.
But other than that, I think not handling it in exclusion makes sense because we don't know in which folder the document will be stored.
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.
Makes sense.
Summary
before this PR
ruff server
at first layer checked that url received from lsp-client most matchedfile://
and existed on disk, there are some scenarios that urls are not alwaysfile://
-scheme. After this PR ruff server would also support urls other thanfile://
For example:
Closes #11510
Test Plan
Open VSCode
Enable ruff extension's native server option
Ctrl+Win+Alt+N
-> selectPython File
Try write some codes and verify ruff works