Skip to content

Commit

Permalink
Show rule codes in shell tab completion
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Sep 14, 2023
1 parent 71450ff commit 556da38
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 37 deletions.
2 changes: 2 additions & 0 deletions crates/ruff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//!
//! [Ruff]: https://github.com/astral-sh/ruff

#[cfg(feature = "clap")]
pub use rule_selector::clap_completion::RuleSelectorParser;
pub use rule_selector::RuleSelector;
pub use rules::pycodestyle::rules::{IOError, SyntaxError};

Expand Down
50 changes: 29 additions & 21 deletions crates/ruff/src/rule_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,14 @@ pub enum Specificity {
}

#[cfg(feature = "clap")]
mod clap_completion {
pub mod clap_completion {
use clap::builder::{PossibleValue, TypedValueParser, ValueParserFactory};
use strum::IntoEnumIterator;

use crate::{
codes::RuleCodePrefix,
registry::{Linter, RuleNamespace},
rule_selector::is_single_rule_selector,
RuleSelector,
};

Expand Down Expand Up @@ -381,7 +382,7 @@ mod clap_completion {

value
.parse()
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::InvalidValue, e))
.map_err(|err| clap::Error::raw(clap::error::ErrorKind::InvalidValue, err))
}

fn possible_values(&self) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> {
Expand All @@ -404,27 +405,34 @@ mod clap_completion {
RuleCodePrefix::iter()
// Filter out rule gated behind `#[cfg(feature = "unreachable-code")]`, which is
// off-by-default
.filter(|p| {
format!("{}{}", p.linter().common_prefix(), p.short_code())
!= "RUF014"
.filter(|prefix| {
format!(
"{}{}",
prefix.linter().common_prefix(),
prefix.short_code()
) != "RUF014"
})
.map(|p| {
let prefix = p.linter().common_prefix();
let code = p.short_code();

let mut rules_iter = p.rules();
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
.filter_map(|prefix| {
// Ex) `UP`
if prefix.short_code().is_empty() {
let code = prefix.linter().common_prefix();
let name = prefix.linter().name();
return Some(PossibleValue::new(code).help(name));
}

// Ex) `UP004`
if is_single_rule_selector(&prefix) {
let rule = prefix.rules().next()?;
let code = format!(
"{}{}",
prefix.linter().common_prefix(),
prefix.short_code()
);
let name: &'static str = rule.into();
return Some(PossibleValue::new(code).help(name));
}

None
}),
),
),
Expand Down
25 changes: 10 additions & 15 deletions crates/ruff_cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use std::str::FromStr;

use clap::{command, Parser};
use regex::Regex;
use ruff::line_width::LineLength;
use rustc_hash::FxHashMap;

use ruff::line_width::LineLength;
use ruff::logging::LogLevel;
use ruff::registry::Rule;
use ruff::settings::types::{
FilePattern, PatternPrefixPair, PerFileIgnore, PreviewMode, PythonVersion, SerializationFormat,
};
use ruff::RuleSelector;
use ruff::{RuleSelector, RuleSelectorParser};
use ruff_workspace::configuration::{Configuration, RuleSelection};
use ruff_workspace::resolver::ConfigProcessor;

Expand Down Expand Up @@ -129,7 +129,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -139,7 +139,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -149,7 +149,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -159,7 +159,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide = true
)]
Expand Down Expand Up @@ -191,7 +191,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -201,7 +201,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -211,7 +211,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide_possible_values = true
)]
Expand All @@ -221,7 +221,7 @@ pub struct CheckCommand {
long,
value_delimiter = ',',
value_name = "RULE_CODE",
value_parser = parse_rule_selector,
value_parser = RuleSelectorParser,
help_heading = "Rule selection",
hide = true
)]
Expand Down Expand Up @@ -511,11 +511,6 @@ impl FormatCommand {
}
}

fn parse_rule_selector(env: &str) -> Result<RuleSelector, std::io::Error> {
RuleSelector::from_str(env)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
}

fn resolve_bool_arg(yes: bool, no: bool) -> Option<bool> {
match (yes, no) {
(true, false) => Some(true),
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ Ruff supports two command-line flags that alter its exit code behavior:
`--exit-non-zero-on-fix` can result in a non-zero exit code even if no violations remain after
autofixing.

## Autocompletion
## Shell autocompletion

Ruff supports autocompletion for most shells. A shell-specific completion script can be generated
by `ruff generate-shell-completion <SHELL>`, where `<SHELL>` is one of `bash`, `elvish`, `fig`, `fish`,
Expand Down

0 comments on commit 556da38

Please sign in to comment.