mirror of
https://github.com/sharkdp/bat
synced 2026-07-30 18:11:44 +00:00
Support merging --style arguments
The `overrides_with` clap builder option was removed because it interfered with the matcher's ability to retain all occurrences of `--style`. The behavior it covered is expressed within the new `forced_style_components` function.
This commit is contained in:
+50
-26
@@ -2,11 +2,13 @@ use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::io::IsTerminal;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::{
|
||||
clap_app,
|
||||
config::{get_args_from_config_file, get_args_from_env_opts_var, get_args_from_env_vars},
|
||||
};
|
||||
use bat::style::StyleComponentList;
|
||||
use bat::StripAnsiMode;
|
||||
use clap::ArgMatches;
|
||||
|
||||
@@ -86,7 +88,6 @@ impl App {
|
||||
|
||||
// .. and the rest at the end
|
||||
cli_args.for_each(|a| args.push(a));
|
||||
|
||||
args
|
||||
};
|
||||
|
||||
@@ -364,34 +365,57 @@ impl App {
|
||||
Ok(file_input)
|
||||
}
|
||||
|
||||
fn forced_style_components(&self) -> Option<StyleComponents> {
|
||||
// No components if `--decorations=never``.
|
||||
if self
|
||||
.matches
|
||||
.get_one::<String>("decorations")
|
||||
.map(|s| s.as_str())
|
||||
== Some("never")
|
||||
{
|
||||
return Some(StyleComponents(HashSet::new()));
|
||||
}
|
||||
|
||||
// Only line numbers if `--number`.
|
||||
if self.matches.get_flag("number") {
|
||||
return Some(StyleComponents(HashSet::from([
|
||||
StyleComponent::LineNumbers,
|
||||
])));
|
||||
}
|
||||
|
||||
// Plain if `--plain` is specified at least once.
|
||||
if self.matches.get_count("plain") > 0 {
|
||||
return Some(StyleComponents(HashSet::from([StyleComponent::Plain])));
|
||||
}
|
||||
|
||||
// Default behavior.
|
||||
None
|
||||
}
|
||||
|
||||
fn style_components(&self) -> Result<StyleComponents> {
|
||||
let matches = &self.matches;
|
||||
let mut styled_components = StyleComponents(
|
||||
if matches.get_one::<String>("decorations").map(|s| s.as_str()) == Some("never") {
|
||||
HashSet::new()
|
||||
} else if matches.get_flag("number") {
|
||||
[StyleComponent::LineNumbers].iter().cloned().collect()
|
||||
} else if 0 < matches.get_count("plain") {
|
||||
[StyleComponent::Plain].iter().cloned().collect()
|
||||
} else {
|
||||
matches
|
||||
.get_one::<String>("style")
|
||||
.map(|styles| {
|
||||
styles
|
||||
.split(',')
|
||||
.map(|style| style.parse::<StyleComponent>())
|
||||
.filter_map(|style| style.ok())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_else(|| vec![StyleComponent::Default])
|
||||
let mut styled_components = match self.forced_style_components() {
|
||||
Some(forced_components) => forced_components,
|
||||
|
||||
// Parse the `--style` arguments and merge them.
|
||||
None if matches.contains_id("style") => {
|
||||
let lists = matches
|
||||
.get_many::<String>("style")
|
||||
.expect("styles present")
|
||||
.map(|v| StyleComponentList::from_str(v))
|
||||
.collect::<Result<Vec<StyleComponentList>>>()?;
|
||||
|
||||
StyleComponentList::to_components(lists, self.interactive_output)
|
||||
}
|
||||
|
||||
// Use the default.
|
||||
None => StyleComponents(HashSet::from_iter(
|
||||
StyleComponent::Default
|
||||
.components(self.interactive_output)
|
||||
.into_iter()
|
||||
.map(|style| style.components(self.interactive_output))
|
||||
.fold(HashSet::new(), |mut acc, components| {
|
||||
acc.extend(components.iter().cloned());
|
||||
acc
|
||||
})
|
||||
},
|
||||
);
|
||||
.cloned(),
|
||||
)),
|
||||
};
|
||||
|
||||
// If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning.
|
||||
if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) {
|
||||
|
||||
+6
-25
@@ -1,9 +1,11 @@
|
||||
use bat::style::StyleComponentList;
|
||||
use clap::{
|
||||
crate_name, crate_version, value_parser, Arg, ArgAction, ArgGroup, ColorChoice, Command,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
static VERSION: Lazy<String> = Lazy::new(|| {
|
||||
#[cfg(feature = "bugreport")]
|
||||
@@ -419,34 +421,13 @@ pub fn build_app(interactive_output: bool) -> Command {
|
||||
.arg(
|
||||
Arg::new("style")
|
||||
.long("style")
|
||||
.action(ArgAction::Append)
|
||||
.value_name("components")
|
||||
.overrides_with("style")
|
||||
.overrides_with("plain")
|
||||
.overrides_with("number")
|
||||
// Cannot use claps built in validation because we have to turn off clap's delimiters
|
||||
.value_parser(|val: &str| {
|
||||
let mut invalid_vals = val.split(',').filter(|style| {
|
||||
!&[
|
||||
"auto",
|
||||
"full",
|
||||
"default",
|
||||
"plain",
|
||||
"header",
|
||||
"header-filename",
|
||||
"header-filesize",
|
||||
"grid",
|
||||
"rule",
|
||||
"numbers",
|
||||
"snip",
|
||||
#[cfg(feature = "git")]
|
||||
"changes",
|
||||
].contains(style)
|
||||
});
|
||||
|
||||
if let Some(invalid) = invalid_vals.next() {
|
||||
Err(format!("Unknown style, '{invalid}'"))
|
||||
} else {
|
||||
Ok(val.to_owned())
|
||||
match StyleComponentList::from_str(val) {
|
||||
Err(err) => Err(err),
|
||||
Ok(_) => Ok(val.to_owned()),
|
||||
}
|
||||
})
|
||||
.help(
|
||||
|
||||
Reference in New Issue
Block a user