mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +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::{
|
||||
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::resolver::ConfigurationTransformer;
|
||||
|
||||
|
@ -39,7 +39,7 @@ pub enum Command {
|
|||
#[command(group = clap::ArgGroup::new("selector").multiple(false).required(true))]
|
||||
Rule {
|
||||
/// Rule to explain
|
||||
#[arg(value_parser=Rule::from_code, group = "selector")]
|
||||
#[arg(value_parser=RuleParser, group = "selector", hide_possible_values = true)]
|
||||
rule: Option<Rule>,
|
||||
|
||||
/// Explain all rules
|
||||
|
|
|
@ -225,7 +225,7 @@ fn explain_status_codes_ruf404() {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: invalid value 'RUF404' for '[RULE]': unknown rule code
|
||||
error: invalid value 'RUF404' for '[RULE]'
|
||||
|
||||
For more information, try '--help'.
|
||||
"###);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
//!
|
||||
//! [Ruff]: https://github.com/astral-sh/ruff
|
||||
|
||||
#[cfg(feature = "clap")]
|
||||
pub use registry::clap_completion::RuleParser;
|
||||
#[cfg(feature = "clap")]
|
||||
pub use rule_selector::clap_completion::RuleSelectorParser;
|
||||
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)]
|
||||
mod tests {
|
||||
use std::mem::size_of;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue