mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 22:31:47 +00:00
Enable tab completion for ruff rule
(#7560)
## Summary
Writing `ruff rule E1`, then tab, shows:
<img width="724" alt="Screen Shot 2023-09-20 at 9 29 09 PM"
src="00297f24
-8828-4485-a00e-6af1ab4e7875">
Closes https://github.com/astral-sh/ruff/issues/2812.
This commit is contained in:
parent
ad893f8295
commit
b685ee4749
4 changed files with 63 additions and 3 deletions
|
@ -10,7 +10,7 @@ use ruff_linter::registry::Rule;
|
||||||
use ruff_linter::settings::types::{
|
use ruff_linter::settings::types::{
|
||||||
FilePattern, PatternPrefixPair, PerFileIgnore, PreviewMode, PythonVersion, SerializationFormat,
|
FilePattern, PatternPrefixPair, PerFileIgnore, PreviewMode, PythonVersion, SerializationFormat,
|
||||||
};
|
};
|
||||||
use ruff_linter::{RuleSelector, RuleSelectorParser};
|
use ruff_linter::{RuleParser, RuleSelector, RuleSelectorParser};
|
||||||
use ruff_workspace::configuration::{Configuration, RuleSelection};
|
use ruff_workspace::configuration::{Configuration, RuleSelection};
|
||||||
use ruff_workspace::resolver::ConfigurationTransformer;
|
use ruff_workspace::resolver::ConfigurationTransformer;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ pub enum Command {
|
||||||
#[command(group = clap::ArgGroup::new("selector").multiple(false).required(true))]
|
#[command(group = clap::ArgGroup::new("selector").multiple(false).required(true))]
|
||||||
Rule {
|
Rule {
|
||||||
/// Rule to explain
|
/// Rule to explain
|
||||||
#[arg(value_parser=Rule::from_code, group = "selector")]
|
#[arg(value_parser=RuleParser, group = "selector", hide_possible_values = true)]
|
||||||
rule: Option<Rule>,
|
rule: Option<Rule>,
|
||||||
|
|
||||||
/// Explain all rules
|
/// Explain all rules
|
||||||
|
|
|
@ -225,7 +225,7 @@ fn explain_status_codes_ruf404() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: invalid value 'RUF404' for '[RULE]': unknown rule code
|
error: invalid value 'RUF404' for '[RULE]'
|
||||||
|
|
||||||
For more information, try '--help'.
|
For more information, try '--help'.
|
||||||
"###);
|
"###);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
//!
|
//!
|
||||||
//! [Ruff]: https://github.com/astral-sh/ruff
|
//! [Ruff]: https://github.com/astral-sh/ruff
|
||||||
|
|
||||||
|
#[cfg(feature = "clap")]
|
||||||
|
pub use registry::clap_completion::RuleParser;
|
||||||
#[cfg(feature = "clap")]
|
#[cfg(feature = "clap")]
|
||||||
pub use rule_selector::clap_completion::RuleSelectorParser;
|
pub use rule_selector::clap_completion::RuleSelectorParser;
|
||||||
pub use rule_selector::RuleSelector;
|
pub use rule_selector::RuleSelector;
|
||||||
|
|
|
@ -360,6 +360,64 @@ pub const INCOMPATIBLE_CODES: &[(Rule, Rule, &str); 2] = &[
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[cfg(feature = "clap")]
|
||||||
|
pub mod clap_completion {
|
||||||
|
use clap::builder::{PossibleValue, TypedValueParser, ValueParserFactory};
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
use crate::registry::Rule;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RuleParser;
|
||||||
|
|
||||||
|
impl ValueParserFactory for Rule {
|
||||||
|
type Parser = RuleParser;
|
||||||
|
|
||||||
|
fn value_parser() -> Self::Parser {
|
||||||
|
RuleParser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedValueParser for RuleParser {
|
||||||
|
type Value = Rule;
|
||||||
|
|
||||||
|
fn parse_ref(
|
||||||
|
&self,
|
||||||
|
cmd: &clap::Command,
|
||||||
|
arg: Option<&clap::Arg>,
|
||||||
|
value: &std::ffi::OsStr,
|
||||||
|
) -> Result<Self::Value, clap::Error> {
|
||||||
|
let value = value
|
||||||
|
.to_str()
|
||||||
|
.ok_or_else(|| clap::Error::new(clap::error::ErrorKind::InvalidUtf8))?;
|
||||||
|
|
||||||
|
Rule::from_code(value).map_err(|_| {
|
||||||
|
let mut error =
|
||||||
|
clap::Error::new(clap::error::ErrorKind::ValueValidation).with_cmd(cmd);
|
||||||
|
if let Some(arg) = arg {
|
||||||
|
error.insert(
|
||||||
|
clap::error::ContextKind::InvalidArg,
|
||||||
|
clap::error::ContextValue::String(arg.to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
error.insert(
|
||||||
|
clap::error::ContextKind::InvalidValue,
|
||||||
|
clap::error::ContextValue::String(value.to_string()),
|
||||||
|
);
|
||||||
|
error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn possible_values(&self) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> {
|
||||||
|
Some(Box::new(Rule::iter().map(|rule| {
|
||||||
|
let name = rule.noqa_code().to_string();
|
||||||
|
let help = rule.as_ref().to_string();
|
||||||
|
PossibleValue::new(name).help(help)
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue