mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 13:33:50 +00:00
ruff server
: Fix multiple issues with Neovim and Helix (#11497)
## Summary Fixes https://github.com/astral-sh/ruff/issues/11236. This PR fixes several issues, most of which relate to non-VS Code editors (Helix and Neovim). 1. Global-only initialization options are now correctly deserialized from Neovim and Helix 2. Empty diagnostics are now published correctly for Neovim and Helix. 3. A workspace folder is created at the current working directory if the initialization parameters send an empty list of workspace folders. 4. The server now gracefully handles opening files outside of any known workspace, and will use global fallback settings taken from client editor settings and a user settings TOML, if it exists. ## Test Plan I've tested to confirm that each issue has been fixed. * Global-only initialization options are now correctly deserialized from Neovim and Helix + the server gracefully handles opening files outside of any known workspace4f33477f
-20c8-4e50-8214-6608b1a1ea6b * Empty diagnostics are now published correctly for Neovim and Helixc93f56a0
-f75d-466f-9f40-d77f99cf0637 * A workspace folder is created at the current working directory if the initialization parameters send an empty list of workspace folders.b4b2e818
-4b0d-40ce-961d-5831478cc726
This commit is contained in:
parent
519a65007f
commit
94abea4b08
7 changed files with 120 additions and 101 deletions
|
@ -237,12 +237,27 @@ impl Index {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn make_document_ref(&self, key: DocumentKey) -> Option<DocumentQuery> {
|
||||
pub(super) fn make_document_ref(
|
||||
&self,
|
||||
key: DocumentKey,
|
||||
global_settings: &ClientSettings,
|
||||
) -> Option<DocumentQuery> {
|
||||
let path = self.path_for_key(&key)?.clone();
|
||||
let document_settings = self
|
||||
.settings_for_path(&path)?
|
||||
.workspace_settings_index
|
||||
.get(&path);
|
||||
.settings_for_path(&path)
|
||||
.map(|settings| settings.workspace_settings_index.get(&path))
|
||||
.unwrap_or_else(|| {
|
||||
tracing::warn!(
|
||||
"No settings available for {} - falling back to default settings",
|
||||
path.display()
|
||||
);
|
||||
let resolved_global = ResolvedClientSettings::global(global_settings);
|
||||
let root = path.parent().unwrap_or(&path);
|
||||
Arc::new(RuffSettings::fallback(
|
||||
resolved_global.editor_settings(),
|
||||
root,
|
||||
))
|
||||
});
|
||||
|
||||
let controller = self.documents.get(&path)?;
|
||||
let cell_uri = match key {
|
||||
|
|
|
@ -43,6 +43,32 @@ impl std::fmt::Display for RuffSettings {
|
|||
}
|
||||
|
||||
impl RuffSettings {
|
||||
pub(crate) fn fallback(editor_settings: &ResolvedEditorSettings, root: &Path) -> RuffSettings {
|
||||
let fallback = find_user_settings_toml()
|
||||
.and_then(|user_settings| {
|
||||
ruff_workspace::resolver::resolve_root_settings(
|
||||
&user_settings,
|
||||
Relativity::Cwd,
|
||||
&EditorConfigurationTransformer(editor_settings, root),
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
let default_configuration = ruff_workspace::configuration::Configuration::default();
|
||||
EditorConfigurationTransformer(editor_settings, root)
|
||||
.transform(default_configuration)
|
||||
.into_settings(root)
|
||||
.expect(
|
||||
"editor configuration should merge successfully with default configuration",
|
||||
)
|
||||
});
|
||||
|
||||
RuffSettings {
|
||||
formatter: fallback.formatter,
|
||||
linter: fallback.linter,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn linter(&self) -> &ruff_linter::settings::LinterSettings {
|
||||
&self.linter
|
||||
}
|
||||
|
@ -80,32 +106,9 @@ impl RuffSettingsIndex {
|
|||
}
|
||||
}
|
||||
|
||||
let fallback = find_user_settings_toml()
|
||||
.and_then(|user_settings| {
|
||||
ruff_workspace::resolver::resolve_root_settings(
|
||||
&user_settings,
|
||||
Relativity::Cwd,
|
||||
&EditorConfigurationTransformer(editor_settings, root),
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
let default_configuration = ruff_workspace::configuration::Configuration::default();
|
||||
EditorConfigurationTransformer(editor_settings, root)
|
||||
.transform(default_configuration)
|
||||
.into_settings(root)
|
||||
.expect(
|
||||
"editor configuration should merge successfully with default configuration",
|
||||
)
|
||||
});
|
||||
let fallback = Arc::new(RuffSettings::fallback(editor_settings, root));
|
||||
|
||||
Self {
|
||||
index,
|
||||
fallback: Arc::new(RuffSettings {
|
||||
formatter: fallback.formatter,
|
||||
linter: fallback.linter,
|
||||
}),
|
||||
}
|
||||
Self { index, fallback }
|
||||
}
|
||||
|
||||
pub(super) fn get(&self, document_path: &Path) -> Arc<RuffSettings> {
|
||||
|
@ -118,11 +121,6 @@ impl RuffSettingsIndex {
|
|||
return settings.clone();
|
||||
}
|
||||
|
||||
tracing::info!(
|
||||
"No Ruff settings file found for {}; falling back to default configuration",
|
||||
document_path.display()
|
||||
);
|
||||
|
||||
self.fallback.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,8 @@ enum InitializationOptions {
|
|||
workspace_settings: Vec<WorkspaceSettings>,
|
||||
},
|
||||
GlobalOnly {
|
||||
settings: Option<ClientSettings>,
|
||||
#[serde(flatten)]
|
||||
settings: ClientSettings,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ impl AllSettings {
|
|||
|
||||
fn from_init_options(options: InitializationOptions) -> Self {
|
||||
let (global_settings, workspace_settings) = match options {
|
||||
InitializationOptions::GlobalOnly { settings } => (settings.unwrap_or_default(), None),
|
||||
InitializationOptions::GlobalOnly { settings } => (settings, None),
|
||||
InitializationOptions::HasWorkspaces {
|
||||
global_settings,
|
||||
workspace_settings,
|
||||
|
@ -341,7 +342,9 @@ impl ResolvedClientSettings {
|
|||
|
||||
impl Default for InitializationOptions {
|
||||
fn default() -> Self {
|
||||
Self::GlobalOnly { settings: None }
|
||||
Self::GlobalOnly {
|
||||
settings: ClientSettings::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,52 +629,50 @@ mod tests {
|
|||
|
||||
assert_debug_snapshot!(options, @r###"
|
||||
GlobalOnly {
|
||||
settings: Some(
|
||||
ClientSettings {
|
||||
configuration: None,
|
||||
fix_all: Some(
|
||||
false,
|
||||
),
|
||||
organize_imports: None,
|
||||
lint: Some(
|
||||
LintOptions {
|
||||
enable: None,
|
||||
preview: None,
|
||||
select: None,
|
||||
extend_select: None,
|
||||
ignore: Some(
|
||||
[
|
||||
"RUF001",
|
||||
],
|
||||
),
|
||||
},
|
||||
),
|
||||
format: None,
|
||||
code_action: Some(
|
||||
CodeActionOptions {
|
||||
disable_rule_comment: Some(
|
||||
CodeActionParameters {
|
||||
enable: Some(
|
||||
false,
|
||||
),
|
||||
},
|
||||
),
|
||||
fix_violation: None,
|
||||
},
|
||||
),
|
||||
exclude: Some(
|
||||
[
|
||||
"third_party",
|
||||
],
|
||||
),
|
||||
line_length: Some(
|
||||
LineLength(
|
||||
80,
|
||||
settings: ClientSettings {
|
||||
configuration: None,
|
||||
fix_all: Some(
|
||||
false,
|
||||
),
|
||||
organize_imports: None,
|
||||
lint: Some(
|
||||
LintOptions {
|
||||
enable: None,
|
||||
preview: None,
|
||||
select: None,
|
||||
extend_select: None,
|
||||
ignore: Some(
|
||||
[
|
||||
"RUF001",
|
||||
],
|
||||
),
|
||||
},
|
||||
),
|
||||
format: None,
|
||||
code_action: Some(
|
||||
CodeActionOptions {
|
||||
disable_rule_comment: Some(
|
||||
CodeActionParameters {
|
||||
enable: Some(
|
||||
false,
|
||||
),
|
||||
},
|
||||
),
|
||||
fix_violation: None,
|
||||
},
|
||||
),
|
||||
exclude: Some(
|
||||
[
|
||||
"third_party",
|
||||
],
|
||||
),
|
||||
line_length: Some(
|
||||
LineLength(
|
||||
80,
|
||||
),
|
||||
configuration_preference: None,
|
||||
},
|
||||
),
|
||||
),
|
||||
configuration_preference: None,
|
||||
},
|
||||
}
|
||||
"###);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue