mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-19 01:51:30 +00:00
Implement shell autocompletion for rule codes
For example: $ ruff check --select=EM<Tab> EM -- flake8-errmsg EM10 EM1 -- EM101 -- raw-string-in-exception EM102 -- f-string-in-exception EM103 -- dot-format-in-exception (You will need to enable autocompletion as described in the Autocompletion section in the README.) Fixes #2808. (The --help help change in the README is due to a clap bug, for which I already submitted a fix: https://github.com/clap-rs/clap/pull/4710.)
This commit is contained in:
parent
ca49b00e55
commit
70e378b736
5 changed files with 86 additions and 7 deletions
|
@ -468,7 +468,7 @@ Options:
|
|||
--show-settings
|
||||
See the settings Ruff will use to lint a given Python file
|
||||
-h, --help
|
||||
Print help
|
||||
Print help (see more with '--help')
|
||||
|
||||
Rule selection:
|
||||
--select <RULE_CODE>
|
||||
|
|
|
@ -21,7 +21,7 @@ bisection = { version = "0.1.0" }
|
|||
bitflags = { version = "1.3.2" }
|
||||
cfg-if = { version = "1.0.0" }
|
||||
chrono = { version = "0.4.21", default-features = false, features = ["clock"] }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
clap = { workspace = true, features = ["derive", "env", "string"] }
|
||||
colored = { version = "2.0.0" }
|
||||
dirs = { version = "4.0.0" }
|
||||
fern = { version = "0.6.1" }
|
||||
|
|
|
@ -233,3 +233,76 @@ pub(crate) enum Specificity {
|
|||
Code4Chars,
|
||||
Code5Chars,
|
||||
}
|
||||
|
||||
mod clap_completion {
|
||||
use clap::builder::{PossibleValue, TypedValueParser, ValueParserFactory};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::{
|
||||
codes::RuleCodePrefix,
|
||||
registry::{Linter, RuleNamespace},
|
||||
RuleSelector,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RuleSelectorParser;
|
||||
|
||||
impl ValueParserFactory for RuleSelector {
|
||||
type Parser = RuleSelectorParser;
|
||||
|
||||
fn value_parser() -> Self::Parser {
|
||||
RuleSelectorParser
|
||||
}
|
||||
}
|
||||
|
||||
impl TypedValueParser for RuleSelectorParser {
|
||||
type Value = RuleSelector;
|
||||
|
||||
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))?;
|
||||
|
||||
value
|
||||
.parse()
|
||||
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::InvalidValue, e))
|
||||
}
|
||||
|
||||
fn possible_values(
|
||||
&self,
|
||||
) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
|
||||
Some(Box::new(
|
||||
std::iter::once(PossibleValue::new("ALL").help("all rules")).chain(
|
||||
Linter::iter()
|
||||
.filter_map(|l| {
|
||||
let prefix = l.common_prefix();
|
||||
(!prefix.is_empty()).then(|| PossibleValue::new(prefix).help(l.name()))
|
||||
})
|
||||
.chain(RuleCodePrefix::iter().map(|p| {
|
||||
let prefix = p.linter().common_prefix();
|
||||
let code = p.short_code();
|
||||
|
||||
let mut rules_iter = p.into_iter();
|
||||
let rule1 = rules_iter.next();
|
||||
let rule2 = rules_iter.next();
|
||||
|
||||
let value = PossibleValue::new(format!("{prefix}{code}"));
|
||||
|
||||
if rule2.is_none() {
|
||||
let rule1 = rule1.unwrap();
|
||||
let name: &'static str = rule1.into();
|
||||
value.help(name)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
})),
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,8 @@ pub struct CheckArgs {
|
|||
long,
|
||||
value_delimiter = ',',
|
||||
value_name = "RULE_CODE",
|
||||
help_heading = "Rule selection"
|
||||
help_heading = "Rule selection",
|
||||
hide_possible_values = true
|
||||
)]
|
||||
pub select: Option<Vec<RuleSelector>>,
|
||||
/// Comma-separated list of rule codes to disable.
|
||||
|
@ -117,7 +118,8 @@ pub struct CheckArgs {
|
|||
long,
|
||||
value_delimiter = ',',
|
||||
value_name = "RULE_CODE",
|
||||
help_heading = "Rule selection"
|
||||
help_heading = "Rule selection",
|
||||
hide_possible_values = true
|
||||
)]
|
||||
pub ignore: Option<Vec<RuleSelector>>,
|
||||
/// Like --select, but adds additional rule codes on top of the selected
|
||||
|
@ -126,7 +128,8 @@ pub struct CheckArgs {
|
|||
long,
|
||||
value_delimiter = ',',
|
||||
value_name = "RULE_CODE",
|
||||
help_heading = "Rule selection"
|
||||
help_heading = "Rule selection",
|
||||
hide_possible_values = true
|
||||
)]
|
||||
pub extend_select: Option<Vec<RuleSelector>>,
|
||||
/// Like --ignore. (Deprecated: You can just use --ignore instead.)
|
||||
|
@ -164,7 +167,8 @@ pub struct CheckArgs {
|
|||
long,
|
||||
value_delimiter = ',',
|
||||
value_name = "RULE_CODE",
|
||||
help_heading = "Rule selection"
|
||||
help_heading = "Rule selection",
|
||||
hide_possible_values = true
|
||||
)]
|
||||
pub fixable: Option<Vec<RuleSelector>>,
|
||||
/// List of rule codes to treat as ineligible for autofix. Only applicable
|
||||
|
@ -173,7 +177,8 @@ pub struct CheckArgs {
|
|||
long,
|
||||
value_delimiter = ',',
|
||||
value_name = "RULE_CODE",
|
||||
help_heading = "Rule selection"
|
||||
help_heading = "Rule selection",
|
||||
hide_possible_values = true
|
||||
)]
|
||||
pub unfixable: Option<Vec<RuleSelector>>,
|
||||
/// Respect file exclusions via `.gitignore` and other standard ignore
|
||||
|
|
|
@ -57,6 +57,7 @@ pub fn register_rules(input: &Input) -> proc_macro2::TokenStream {
|
|||
PartialOrd,
|
||||
Ord,
|
||||
AsRefStr,
|
||||
::strum_macros::IntoStaticStr,
|
||||
)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Rule { #rule_variants }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue