-
Notifications
You must be signed in to change notification settings - Fork 878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement shell autocompletion for rule codes #2906
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -233,3 +233,76 @@ pub(crate) enum Specificity { | |
Code4Chars, | ||
Code5Chars, | ||
} | ||
|
||
mod clap_completion { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I put it in a submodule so that we can easily feature gate it in the future (since we'll probably want to turn |
||
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 | ||
} | ||
})), | ||
), | ||
)) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,15 +109,17 @@ pub struct CheckArgs { | |
long, | ||
value_delimiter = ',', | ||
value_name = "RULE_CODE", | ||
help_heading = "Rule selection" | ||
help_heading = "Rule selection", | ||
hide_possible_values = true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added |
||
)] | ||
pub select: Option<Vec<RuleSelector>>, | ||
/// Comma-separated list of rule codes to disable. | ||
#[arg( | ||
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is related to
hide_possible_values
, but I'm trying to wrap my head around what it's saying, when it would show up, and what would change by adding--help
-- isn't this message printed when the user runs--help
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah ... this also confused me quite a bit. As it turns out this is a Clap bug. I submitted a fix to upstream with clap-rs/clap#4710.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing that!