mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
Add support for using uv as an alternative formatter backend (#19665)
This adds a new `backend: internal | uv` option to the LSP `FormatOptions` allowing users to perform document and range formatting operations though uv. The idea here is to prototype a solution for users to transition to a `uv format` command without encountering version mismatches (and consequently, formatting differences) between the LSP's version of `ruff` and uv's version of `ruff`. The primarily alternative to this would be to use uv to discover the `ruff` version used to start the LSP in the first place. However, this would increase the scope of a minimal `uv format` command beyond "run a formatter", and raise larger questions about how uv should be used to coordinate toolchain discovery. I think those are good things to explore, but I'm hesitant to let them block a `uv format` implementation. Another downside of using uv to discover `ruff`, is that it needs to be implemented _outside_ the LSP; e.g., we'd need to change the instructions on how to run the LSP and implement it in each editor integration, like the VS Code plugin. --------- Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
This commit is contained in:
parent
79706a2e26
commit
9cdac2d6fb
12 changed files with 696 additions and 22 deletions
|
@ -401,6 +401,7 @@ impl ConfigurationTransformer for EditorConfigurationTransformer<'_> {
|
|||
configuration,
|
||||
format_preview,
|
||||
lint_preview,
|
||||
format_backend: _,
|
||||
select,
|
||||
extend_select,
|
||||
ignore,
|
||||
|
|
|
@ -7,9 +7,12 @@ use serde_json::{Map, Value};
|
|||
|
||||
use ruff_linter::{RuleSelector, line_width::LineLength, rule_selector::ParseError};
|
||||
|
||||
use crate::session::{
|
||||
Client,
|
||||
settings::{ClientSettings, EditorSettings, GlobalClientSettings, ResolvedConfiguration},
|
||||
use crate::{
|
||||
format::FormatBackend,
|
||||
session::{
|
||||
Client,
|
||||
settings::{ClientSettings, EditorSettings, GlobalClientSettings, ResolvedConfiguration},
|
||||
},
|
||||
};
|
||||
|
||||
pub(crate) type WorkspaceOptionsMap = FxHashMap<Url, ClientOptions>;
|
||||
|
@ -124,6 +127,7 @@ impl ClientOptions {
|
|||
configuration,
|
||||
lint_preview: lint.preview,
|
||||
format_preview: format.preview,
|
||||
format_backend: format.backend,
|
||||
select: lint.select.and_then(|select| {
|
||||
Self::resolve_rules(
|
||||
&select,
|
||||
|
@ -283,11 +287,13 @@ impl Combine for LintOptions {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
struct FormatOptions {
|
||||
preview: Option<bool>,
|
||||
backend: Option<FormatBackend>,
|
||||
}
|
||||
|
||||
impl Combine for FormatOptions {
|
||||
fn combine_with(&mut self, other: Self) {
|
||||
self.preview.combine_with(other.preview);
|
||||
self.backend.combine_with(other.backend);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -443,6 +449,12 @@ pub(crate) trait Combine {
|
|||
fn combine_with(&mut self, other: Self);
|
||||
}
|
||||
|
||||
impl Combine for FormatBackend {
|
||||
fn combine_with(&mut self, other: Self) {
|
||||
*self = other;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Combine for Option<T>
|
||||
where
|
||||
T: Combine,
|
||||
|
@ -584,6 +596,7 @@ mod tests {
|
|||
format: Some(
|
||||
FormatOptions {
|
||||
preview: None,
|
||||
backend: None,
|
||||
},
|
||||
),
|
||||
code_action: Some(
|
||||
|
@ -640,6 +653,7 @@ mod tests {
|
|||
format: Some(
|
||||
FormatOptions {
|
||||
preview: None,
|
||||
backend: None,
|
||||
},
|
||||
),
|
||||
code_action: Some(
|
||||
|
@ -704,6 +718,7 @@ mod tests {
|
|||
format: Some(
|
||||
FormatOptions {
|
||||
preview: None,
|
||||
backend: None,
|
||||
},
|
||||
),
|
||||
code_action: Some(
|
||||
|
@ -782,6 +797,7 @@ mod tests {
|
|||
configuration: None,
|
||||
lint_preview: Some(true),
|
||||
format_preview: None,
|
||||
format_backend: None,
|
||||
select: Some(vec![
|
||||
RuleSelector::Linter(Linter::Pyflakes),
|
||||
RuleSelector::Linter(Linter::Isort)
|
||||
|
@ -819,6 +835,7 @@ mod tests {
|
|||
configuration: None,
|
||||
lint_preview: Some(false),
|
||||
format_preview: None,
|
||||
format_backend: None,
|
||||
select: Some(vec![
|
||||
RuleSelector::Linter(Linter::Pyflakes),
|
||||
RuleSelector::Linter(Linter::Isort)
|
||||
|
@ -919,6 +936,7 @@ mod tests {
|
|||
configuration: None,
|
||||
lint_preview: None,
|
||||
format_preview: None,
|
||||
format_backend: None,
|
||||
select: None,
|
||||
extend_select: None,
|
||||
ignore: Some(vec![RuleSelector::from_str("RUF001").unwrap()]),
|
||||
|
|
|
@ -8,6 +8,7 @@ use ruff_workspace::options::Options;
|
|||
|
||||
use crate::{
|
||||
ClientOptions,
|
||||
format::FormatBackend,
|
||||
session::{
|
||||
Client,
|
||||
options::{ClientConfiguration, ConfigurationPreference},
|
||||
|
@ -84,6 +85,7 @@ pub(crate) struct EditorSettings {
|
|||
pub(super) configuration: Option<ResolvedConfiguration>,
|
||||
pub(super) lint_preview: Option<bool>,
|
||||
pub(super) format_preview: Option<bool>,
|
||||
pub(super) format_backend: Option<FormatBackend>,
|
||||
pub(super) select: Option<Vec<RuleSelector>>,
|
||||
pub(super) extend_select: Option<Vec<RuleSelector>>,
|
||||
pub(super) ignore: Option<Vec<RuleSelector>>,
|
||||
|
@ -163,3 +165,9 @@ impl ClientSettings {
|
|||
&self.editor_settings
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorSettings {
|
||||
pub(crate) fn format_backend(&self) -> FormatBackend {
|
||||
self.format_backend.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue