Compare commits
1 Commits
charlie/na
...
dhruv/serv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c705787bb3 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2822,6 +2822,7 @@ dependencies = [
|
||||
"ruff_python_formatter",
|
||||
"ruff_python_parser",
|
||||
"ruff_python_trivia",
|
||||
"ruff_server",
|
||||
"ruff_workspace",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -3172,6 +3173,7 @@ dependencies = [
|
||||
"ruff_diagnostics",
|
||||
"ruff_formatter",
|
||||
"ruff_linter",
|
||||
"ruff_macros",
|
||||
"ruff_notebook",
|
||||
"ruff_python_ast",
|
||||
"ruff_python_codegen",
|
||||
|
||||
@@ -22,6 +22,7 @@ ruff_python_codegen = { workspace = true }
|
||||
ruff_python_formatter = { workspace = true }
|
||||
ruff_python_parser = { workspace = true }
|
||||
ruff_python_trivia = { workspace = true }
|
||||
ruff_server = { workspace = true }
|
||||
ruff_workspace = { workspace = true, features = ["schemars"] }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//!
|
||||
//! Used for <https://docs.astral.sh/ruff/settings/>.
|
||||
use itertools::Itertools;
|
||||
use ruff_server::ClientSettings;
|
||||
use std::fmt::Write;
|
||||
|
||||
use ruff_python_trivia::textwrap;
|
||||
@@ -15,12 +16,32 @@ pub(crate) fn generate() -> String {
|
||||
&mut output,
|
||||
Set::Toplevel(Options::metadata()),
|
||||
&mut Vec::new(),
|
||||
SetKind::Ruff,
|
||||
);
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>) {
|
||||
pub(crate) fn generate_server_options() -> String {
|
||||
let mut output = String::new();
|
||||
|
||||
generate_set(
|
||||
&mut output,
|
||||
Set::Toplevel(ClientSettings::metadata()),
|
||||
&mut Vec::new(),
|
||||
SetKind::RuffServer,
|
||||
);
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum SetKind {
|
||||
Ruff,
|
||||
RuffServer,
|
||||
}
|
||||
|
||||
fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>, set_kind: SetKind) {
|
||||
match &set {
|
||||
Set::Toplevel(_) => {
|
||||
output.push_str("### Top-level\n");
|
||||
@@ -53,7 +74,7 @@ fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>) {
|
||||
|
||||
// Generate the fields.
|
||||
for (name, field) in &fields {
|
||||
emit_field(output, name, field, parents.as_slice());
|
||||
emit_field(output, name, field, parents.as_slice(), set_kind);
|
||||
output.push_str("---\n\n");
|
||||
}
|
||||
|
||||
@@ -66,6 +87,7 @@ fn generate_set(output: &mut String, set: Set, parents: &mut Vec<Set>) {
|
||||
set: *sub_set,
|
||||
},
|
||||
parents,
|
||||
set_kind,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,7 +115,13 @@ impl Set {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[Set]) {
|
||||
fn emit_field(
|
||||
output: &mut String,
|
||||
name: &str,
|
||||
field: &OptionField,
|
||||
parents: &[Set],
|
||||
set_kind: SetKind,
|
||||
) {
|
||||
let header_level = if parents.is_empty() { "####" } else { "#####" };
|
||||
let parents_anchor = parents.iter().filter_map(|parent| parent.name()).join("_");
|
||||
|
||||
@@ -137,28 +165,46 @@ fn emit_field(output: &mut String, name: &str, field: &OptionField, parents: &[S
|
||||
output.push_str(&format!("**Type**: `{}`\n", field.value_type));
|
||||
output.push('\n');
|
||||
output.push_str("**Example usage**:\n\n");
|
||||
output.push_str(&format_tab(
|
||||
"pyproject.toml",
|
||||
&format_header(field.scope, parents, ConfigurationFile::PyprojectToml),
|
||||
field.example,
|
||||
));
|
||||
output.push_str(&format_tab(
|
||||
"ruff.toml",
|
||||
&format_header(field.scope, parents, ConfigurationFile::RuffToml),
|
||||
field.example,
|
||||
));
|
||||
|
||||
match set_kind {
|
||||
SetKind::Ruff => {
|
||||
output.push_str(&format_tab(
|
||||
"pyproject.toml",
|
||||
&format_content(field, parents, ConfigurationFile::PyprojectToml),
|
||||
));
|
||||
output.push_str(&format_tab(
|
||||
"ruff.toml",
|
||||
&format_content(field, parents, ConfigurationFile::RuffToml),
|
||||
));
|
||||
}
|
||||
SetKind::RuffServer => {}
|
||||
}
|
||||
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
fn format_tab(tab_name: &str, header: &str, content: &str) -> String {
|
||||
fn format_tab(tab_name: &str, content: &str) -> String {
|
||||
format!(
|
||||
"=== \"{}\"\n\n ```toml\n {}\n{}\n ```\n",
|
||||
"=== \"{}\"\n\n{}\n\n",
|
||||
tab_name,
|
||||
header,
|
||||
textwrap::indent(content, " ")
|
||||
)
|
||||
}
|
||||
|
||||
fn format_content(
|
||||
field: &OptionField,
|
||||
parents: &[Set],
|
||||
configuration: ConfigurationFile,
|
||||
) -> String {
|
||||
let header = format_header(field.scope, parents, configuration);
|
||||
|
||||
format!(
|
||||
"```toml\n{}\n{}\n```",
|
||||
header,
|
||||
textwrap::indent(field.example, " ")
|
||||
)
|
||||
}
|
||||
|
||||
/// Format the TOML header for the example usage for a given option.
|
||||
///
|
||||
/// For example: `[tool.ruff.format]` or `[tool.ruff.lint.isort]`.
|
||||
@@ -187,6 +233,15 @@ enum ConfigurationFile {
|
||||
RuffToml,
|
||||
}
|
||||
|
||||
fn format_server_content(field: &OptionField, editor: Editor) -> String {}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum Editor {
|
||||
VSCode,
|
||||
Neovim,
|
||||
Zed,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct CollectOptionsVisitor {
|
||||
groups: Vec<(String, OptionSet)>,
|
||||
|
||||
@@ -46,6 +46,8 @@ enum Command {
|
||||
GenerateRulesTable,
|
||||
/// Generate a Markdown-compatible listing of configuration options.
|
||||
GenerateOptions,
|
||||
/// Generate a Markdown-compatible listing of server options.
|
||||
GenerateServerOptions,
|
||||
/// Generate CLI help.
|
||||
GenerateCliHelp(generate_cli_help::Args),
|
||||
/// Generate Markdown docs.
|
||||
@@ -89,6 +91,9 @@ fn main() -> Result<ExitCode> {
|
||||
Command::GenerateKnotSchema(args) => generate_knot_schema::main(&args)?,
|
||||
Command::GenerateRulesTable => println!("{}", generate_rules_table::generate()),
|
||||
Command::GenerateOptions => println!("{}", generate_options::generate()),
|
||||
Command::GenerateServerOptions => {
|
||||
println!("{}", generate_options::generate_server_options())
|
||||
}
|
||||
Command::GenerateCliHelp(args) => generate_cli_help::main(&args)?,
|
||||
Command::GenerateDocs(args) => generate_docs::main(&args)?,
|
||||
Command::PrintAST(args) => print_ast::main(&args)?,
|
||||
|
||||
@@ -24,19 +24,22 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
}) => {
|
||||
let mut output = vec![];
|
||||
|
||||
let rename_value =
|
||||
RenameValue::from_attributes(struct_attributes.as_slice()).unwrap_or_default();
|
||||
|
||||
for field in &fields.named {
|
||||
if let Some(attr) = field
|
||||
.attrs
|
||||
.iter()
|
||||
.find(|attr| attr.path().is_ident("option"))
|
||||
{
|
||||
output.push(handle_option(field, attr)?);
|
||||
output.push(handle_option(field, attr, rename_value)?);
|
||||
} else if field
|
||||
.attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path().is_ident("option_group"))
|
||||
{
|
||||
output.push(handle_option_group(field)?);
|
||||
output.push(handle_option_group(field, rename_value)?);
|
||||
} else if let Some(serde) = field
|
||||
.attrs
|
||||
.iter()
|
||||
@@ -86,8 +89,8 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
|
||||
Ok(quote! {
|
||||
#[automatically_derived]
|
||||
impl crate::options_base::OptionsMetadata for #ident {
|
||||
fn record(visit: &mut dyn crate::options_base::Visit) {
|
||||
impl ruff_workspace::options_base::OptionsMetadata for #ident {
|
||||
fn record(visit: &mut dyn ruff_workspace::options_base::Visit) {
|
||||
#(#output);*
|
||||
}
|
||||
|
||||
@@ -105,7 +108,10 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
||||
/// For a field with type `Option<Foobar>` where `Foobar` itself is a struct
|
||||
/// deriving `ConfigurationOptions`, create code that calls retrieves options
|
||||
/// from that group: `Foobar::get_available_options()`
|
||||
fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
|
||||
fn handle_option_group(
|
||||
field: &Field,
|
||||
rename_value: RenameValue,
|
||||
) -> syn::Result<proc_macro2::TokenStream> {
|
||||
let ident = field
|
||||
.ident
|
||||
.as_ref()
|
||||
@@ -122,10 +128,10 @@ fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
|
||||
PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }),
|
||||
}) if type_ident == "Option" => {
|
||||
let path = &args[0];
|
||||
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
|
||||
let renamed_field = rename_value.apply(ident);
|
||||
|
||||
Ok(quote_spanned!(
|
||||
ident.span() => (visit.record_set(#kebab_name, crate::options_base::OptionSet::of::<#path>()))
|
||||
ident.span() => (visit.record_set(#renamed_field, ruff_workspace::options_base::OptionSet::of::<#path>()))
|
||||
))
|
||||
}
|
||||
_ => Err(syn::Error::new(
|
||||
@@ -154,7 +160,11 @@ fn parse_doc(doc: &Attribute) -> syn::Result<String> {
|
||||
|
||||
/// Parse an `#[option(doc="...", default="...", value_type="...",
|
||||
/// example="...")]` attribute and return data in the form of an `OptionField`.
|
||||
fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::TokenStream> {
|
||||
fn handle_option(
|
||||
field: &Field,
|
||||
attr: &Attribute,
|
||||
rename_value: RenameValue,
|
||||
) -> syn::Result<proc_macro2::TokenStream> {
|
||||
let docs: Vec<&Attribute> = field
|
||||
.attrs
|
||||
.iter()
|
||||
@@ -190,8 +200,7 @@ fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::To
|
||||
example,
|
||||
scope,
|
||||
} = parse_field_attributes(attr)?;
|
||||
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
|
||||
|
||||
let renamed_field = rename_value.apply(ident);
|
||||
let scope = if let Some(scope) = scope {
|
||||
quote!(Some(#scope))
|
||||
} else {
|
||||
@@ -214,14 +223,14 @@ fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::To
|
||||
let note = quote_option(deprecated.note);
|
||||
let since = quote_option(deprecated.since);
|
||||
|
||||
quote!(Some(crate::options_base::Deprecated { since: #since, message: #note }))
|
||||
quote!(Some(ruff_workspace::options_base::Deprecated { since: #since, message: #note }))
|
||||
} else {
|
||||
quote!(None)
|
||||
};
|
||||
|
||||
Ok(quote_spanned!(
|
||||
ident.span() => {
|
||||
visit.record_field(#kebab_name, crate::options_base::OptionField{
|
||||
visit.record_field(#renamed_field, ruff_workspace::options_base::OptionField{
|
||||
doc: &#doc,
|
||||
default: &#default,
|
||||
value_type: &#value_type,
|
||||
@@ -351,3 +360,66 @@ struct DeprecatedAttribute {
|
||||
since: Option<String>,
|
||||
note: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
enum RenameValue {
|
||||
#[default]
|
||||
KebabCase,
|
||||
CamelCase,
|
||||
}
|
||||
|
||||
impl RenameValue {
|
||||
fn from_attributes(attrs: &[Attribute]) -> Option<RenameValue> {
|
||||
let serde = attrs.iter().find(|attr| attr.path().is_ident("serde"))?;
|
||||
|
||||
let Meta::List(list) = &serde.meta else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let mut rename_value = None;
|
||||
|
||||
let _ = list.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("rename_all") {
|
||||
let value = meta.value()?;
|
||||
let s: LitStr = value.parse()?;
|
||||
match s.value().as_str() {
|
||||
"kebab-case" => {
|
||||
rename_value = Some(RenameValue::KebabCase);
|
||||
Ok(())
|
||||
}
|
||||
"camelCase" => {
|
||||
rename_value = Some(RenameValue::CamelCase);
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(meta.error("Expected `kebab-case` or `camelCase`")),
|
||||
}
|
||||
} else {
|
||||
Err(meta.error("Expected `rename_all`"))
|
||||
}
|
||||
});
|
||||
|
||||
rename_value
|
||||
}
|
||||
|
||||
fn apply(self, ident: &syn::Ident) -> syn::LitStr {
|
||||
let renamed = match self {
|
||||
RenameValue::KebabCase => ident.to_string().replace('_', "-"),
|
||||
RenameValue::CamelCase => {
|
||||
let mut result = String::new();
|
||||
let mut capitalize = false;
|
||||
for c in ident.to_string().chars() {
|
||||
if c == '_' {
|
||||
capitalize = true;
|
||||
} else if capitalize {
|
||||
result.push(c.to_ascii_uppercase());
|
||||
capitalize = false;
|
||||
} else {
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
};
|
||||
LitStr::new(&renamed, ident.span())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ license = { workspace = true }
|
||||
ruff_diagnostics = { workspace = true }
|
||||
ruff_formatter = { workspace = true }
|
||||
ruff_linter = { workspace = true }
|
||||
ruff_macros = { workspace = true }
|
||||
ruff_notebook = { workspace = true }
|
||||
ruff_python_ast = { workspace = true }
|
||||
ruff_python_codegen = { workspace = true }
|
||||
|
||||
@@ -5,6 +5,8 @@ use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
|
||||
use ruff_linter::{line_width::LineLength, RuleSelector};
|
||||
use ruff_macros::OptionsMetadata;
|
||||
use ruff_workspace::options_base::{OptionField, OptionsMetadata};
|
||||
|
||||
/// Maps a workspace URI to its associated client settings. Used during server initialization.
|
||||
pub(crate) type WorkspaceSettingsMap = FxHashMap<Url, ClientSettings>;
|
||||
@@ -57,27 +59,76 @@ pub(crate) enum ConfigurationPreference {
|
||||
EditorOnly,
|
||||
}
|
||||
|
||||
/// This is a direct representation of the settings schema sent by the client.
|
||||
#[derive(Debug, Deserialize, Default)]
|
||||
#[derive(Debug, Deserialize, Default, OptionsMetadata)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ClientSettings {
|
||||
/// Path to a `ruff.toml` or `pyproject.toml` file to use for configuration.
|
||||
///
|
||||
/// By default, Ruff will discover configuration for each project from the filesystem,
|
||||
/// mirroring the behavior of the Ruff CLI.
|
||||
#[option(
|
||||
default = r#"null"#,
|
||||
value_type = "string",
|
||||
example = r#""~/path/to/ruff.toml""#
|
||||
)]
|
||||
configuration: Option<String>,
|
||||
fix_all: Option<bool>,
|
||||
organize_imports: Option<bool>,
|
||||
lint: Option<LintOptions>,
|
||||
format: Option<FormatOptions>,
|
||||
code_action: Option<CodeActionOptions>,
|
||||
exclude: Option<Vec<String>>,
|
||||
line_length: Option<LineLength>,
|
||||
|
||||
/// The strategy to use when resolving settings across VS Code and the filesystem. By default,
|
||||
/// editor configuration is prioritized over `ruff.toml` and `pyproject.toml` files.
|
||||
///
|
||||
/// * `"editorFirst"`: Editor settings take priority over configuration files present in the
|
||||
/// workspace.
|
||||
/// * `"filesystemFirst"`: Configuration files present in the workspace takes priority over
|
||||
/// editor settings.
|
||||
/// * `"editorOnly"`: Ignore configuration files entirely i.e., only use editor settings.
|
||||
#[option(
|
||||
default = r#""editorFirst""#,
|
||||
value_type = r#""editorFirst" | "filesystemFirst" | "editorOnly""#,
|
||||
example = r#""filesystemFirst""#
|
||||
)]
|
||||
configuration_preference: Option<ConfigurationPreference>,
|
||||
|
||||
/// If `true` or [`None`], show syntax errors as diagnostics.
|
||||
/// A list of file patterns to exclude from linting and formatting. See [the
|
||||
/// documentation](https://docs.astral.sh/ruff/settings/#exclude) for more details.
|
||||
#[option(
|
||||
default = r#"null"#,
|
||||
value_type = "string[]",
|
||||
example = r#"["**/tests/**"]"#
|
||||
)]
|
||||
exclude: Option<Vec<String>>,
|
||||
|
||||
/// The line length to use for the linter and formatter.
|
||||
#[option(default = "null", value_type = "int", example = "100")]
|
||||
line_length: Option<LineLength>,
|
||||
|
||||
/// Whether to register the server as capable of handling `source.fixAll` code actions.
|
||||
#[option(default = "true", value_type = "bool", example = "false")]
|
||||
fix_all: Option<bool>,
|
||||
|
||||
/// Whether to register the server as capable of handling `source.organizeImports` code
|
||||
/// actions.
|
||||
#[option(default = "true", value_type = "bool", example = "false")]
|
||||
organize_imports: Option<bool>,
|
||||
|
||||
/// _New in Ruff [v0.5.0](https://astral.sh/blog/ruff-v0.5.0#changes-to-e999-and-reporting-of-syntax-errors)_
|
||||
///
|
||||
/// Whether to show syntax error diagnostics.
|
||||
///
|
||||
/// This is useful when using Ruff with other language servers, allowing the user to refer
|
||||
/// to syntax errors from only one source.
|
||||
#[option(default = "true", value_type = "bool", example = "false")]
|
||||
show_syntax_errors: Option<bool>,
|
||||
|
||||
#[option_group]
|
||||
lint: Option<LintOptions>,
|
||||
|
||||
#[option_group]
|
||||
format: Option<FormatOptions>,
|
||||
|
||||
#[option_group]
|
||||
code_action: Option<CodeActionOptions>,
|
||||
|
||||
// These settings are only needed for tracing, and are only read from the global configuration.
|
||||
// These will not be in the resolved settings.
|
||||
#[serde(flatten)]
|
||||
@@ -98,14 +149,26 @@ impl ClientSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Settings needed to initialize tracing. These will only be
|
||||
/// read from the global configuration.
|
||||
#[derive(Debug, Deserialize, Default)]
|
||||
#[derive(Debug, Deserialize, Default, OptionsMetadata)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct TracingSettings {
|
||||
/// The log level to use for the server.
|
||||
#[option(
|
||||
default = r#""info""#,
|
||||
value_type = r#""error" | "warn" | "info" | "debug" | "trace""#,
|
||||
example = r#""debug""#
|
||||
)]
|
||||
pub(crate) log_level: Option<crate::logging::LogLevel>,
|
||||
/// Path to the log file - tildes and environment variables are supported.
|
||||
|
||||
/// Path to the log file to use for the server.
|
||||
///
|
||||
/// If not set, logs will be written to stderr. Tildes and environment variables are expanded.
|
||||
#[option(
|
||||
default = r#"null"#,
|
||||
value_type = "string",
|
||||
example = r#""~/path/to/ruff.log""#
|
||||
)]
|
||||
pub(crate) log_file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@@ -121,14 +184,31 @@ struct WorkspaceSettings {
|
||||
workspace: Url,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
/// Settings specific to the Ruff linter.
|
||||
#[derive(Debug, Default, Deserialize, OptionsMetadata)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct LintOptions {
|
||||
/// Whether to enable linting. Set to `false` to use Ruff exclusively as a formatter.
|
||||
#[option(default = "true", value_type = "bool", example = "false")]
|
||||
enable: Option<bool>,
|
||||
|
||||
/// Whether to enable Ruff's preview mode when linting.
|
||||
#[option(default = "null", value_type = "bool", example = "true")]
|
||||
preview: Option<bool>,
|
||||
|
||||
/// Rules to enable by default. See [the
|
||||
/// documentation](https://docs.astral.sh/ruff/settings/#lint_select).
|
||||
#[option(default = "null", value_type = "string[]", example = r#"["E", "F"]"#)]
|
||||
select: Option<Vec<String>>,
|
||||
|
||||
/// Rules to enable in addition to those in [`lint.select`](#select).
|
||||
#[option(default = "null", value_type = "string[]", example = r#"["W"]"#)]
|
||||
extend_select: Option<Vec<String>>,
|
||||
|
||||
/// Rules to disable by default. See [the
|
||||
/// documentation](https://docs.astral.sh/ruff/settings/#lint_ignore).
|
||||
#[option(default = "null", value_type = "string[]", example = r#"["E4", "E7"]"#)]
|
||||
ignore: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
@@ -143,10 +223,13 @@ impl LintOptions {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
/// Settings specific to the Ruff formatter.
|
||||
#[derive(Debug, Default, Deserialize, OptionsMetadata)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct FormatOptions {
|
||||
/// Whether to enable Ruff's preview mode when formatting.
|
||||
#[option(default = "null", value_type = "bool", example = "true")]
|
||||
preview: Option<bool>,
|
||||
}
|
||||
|
||||
@@ -176,6 +259,38 @@ struct CodeActionParameters {
|
||||
enable: Option<bool>,
|
||||
}
|
||||
|
||||
impl OptionsMetadata for CodeActionOptions {
|
||||
fn record(visit: &mut dyn ruff_workspace::options_base::Visit) {
|
||||
visit.record_field(
|
||||
"disableRuleComment.enable",
|
||||
OptionField {
|
||||
doc: "Whether to display Quick Fix actions to disable rules via `noqa` suppression comments.",
|
||||
default: "true",
|
||||
value_type: "bool",
|
||||
scope: None,
|
||||
example: "false",
|
||||
deprecated: None,
|
||||
},
|
||||
);
|
||||
|
||||
visit.record_field(
|
||||
"fixViolation.enable",
|
||||
OptionField {
|
||||
doc: "Whether to display Quick Fix actions to autofix violations.",
|
||||
default: "true",
|
||||
value_type: "bool",
|
||||
scope: None,
|
||||
example: "false",
|
||||
deprecated: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn documentation() -> Option<&'static str> {
|
||||
Some("Enable or disable code actions provided by the server.")
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the exact schema for initialization options sent in by the client
|
||||
/// during initialization.
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::PathBuf;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate as ruff_workspace;
|
||||
use crate::options_base::{OptionsMetadata, Visit};
|
||||
use crate::settings::LineEnding;
|
||||
use ruff_formatter::IndentStyle;
|
||||
|
||||
Reference in New Issue
Block a user