Add --no-syntax option

When using plain output, calls to `highlight_regions_for_line()`
 may cause a lot of overhead for little gain.

 So add a new option `--no-syntax` that skips syntax highlighting.
 It only has effect for plain output.

 This change is made in a way that preserves backwards compatibility and
 doesn't break any tests.

 Here is a test-case.

 Without `--no-syntax`

 ```
 Benchmark 1: seq 10000000 | ./target/release/bat -pf
  Time (mean ± σ):      7.899 s ±  0.195 s    [User: 7.962 s, System: 0.076 s]
  Range (min … max):    7.587 s …  8.095 s    10 runs
 ```

 With `--no-syntax`

 ```
 Benchmark 1: seq 10000000 | ./target/release/bat -pf --no-syntax
  Time (mean ± σ):     636.7 ms ±  42.9 ms    [User: 696.8 ms, System: 41.2 ms]
  Range (min … max):   603.5 ms … 715.5 ms    10 runs
 ```

Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This commit is contained in:
Mohammad AlSaleh 2024-10-09 07:09:42 +03:00
parent 7dd093ae3b
commit dd2d8909ed
7 changed files with 66 additions and 2 deletions

View File

@ -45,6 +45,7 @@
- Support 'statically linked binary' for aarch64 in 'Release' page, see #2992 (@tzq0301)
- Update options in shell completions and the man page of `bat`, see #2995 (@akinomyoga)
- Significantly improve performance by using a buffered writer, see #3101 (@MoSal)
- Add --no-syntax option, see #3102 (@MoSal)
## Syntaxes

View File

@ -87,6 +87,9 @@ Options:
Alias for '--decorations=always --color=always'. This is useful if the output of bat is
piped to another program, but you want to keep the colorization/decorations.
--no-syntax
Don't pass text to the syntax highlighter in plain mode.
--paging <when>
Specify when to use the pager. To disable the pager, use --paging=never' or its
alias,'-P'. To disable the pager permanently, set BAT_PAGING to 'never'. To control which

View File

@ -417,6 +417,11 @@ impl App {
)),
};
// Add syntax.
if !self.matches.get_flag("no-syntax") {
styled_components.0.insert(StyleComponent::Syntax);
}
// 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) {
bat_warning!("Style 'rule' is a subset of style 'grid', 'rule' will not be visible.");

View File

@ -301,6 +301,14 @@ pub fn build_app(interactive_output: bool) -> Command {
if the output of bat is piped to another program, but you want \
to keep the colorization/decorations.")
)
.arg(
Arg::new("no-syntax")
.long("no-syntax")
.action(ArgAction::SetTrue)
.overrides_with("no-syntax")
.hide_short_help(true)
.long_help("Don't pass text to the syntax highlighter in plain mode.")
)
.arg(
Arg::new("paging")
.long("paging")

View File

@ -639,6 +639,10 @@ impl<'a, W: io::Write> Printer<W> for InteractivePrinter<'a> {
line
};
if self.config.style_components.plain() && !self.config.style_components.syntax() {
return write!(handle, "{line}");
}
let regions = self.highlight_regions_for_line(&line)?;
if out_of_range {
return Ok(());

View File

@ -15,6 +15,7 @@ pub enum StyleComponent {
HeaderFilename,
HeaderFilesize,
LineNumbers,
Syntax,
Snip,
Full,
Default,
@ -39,6 +40,7 @@ impl StyleComponent {
StyleComponent::HeaderFilename => &[StyleComponent::HeaderFilename],
StyleComponent::HeaderFilesize => &[StyleComponent::HeaderFilesize],
StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
StyleComponent::Syntax => &[StyleComponent::Syntax],
StyleComponent::Snip => &[StyleComponent::Snip],
StyleComponent::Full => &[
#[cfg(feature = "git")]
@ -47,6 +49,7 @@ impl StyleComponent {
StyleComponent::HeaderFilename,
StyleComponent::HeaderFilesize,
StyleComponent::LineNumbers,
StyleComponent::Syntax,
StyleComponent::Snip,
],
StyleComponent::Default => &[
@ -55,6 +58,7 @@ impl StyleComponent {
StyleComponent::Grid,
StyleComponent::HeaderFilename,
StyleComponent::LineNumbers,
StyleComponent::Syntax,
StyleComponent::Snip,
],
StyleComponent::Plain => &[],
@ -76,6 +80,7 @@ impl FromStr for StyleComponent {
"header-filename" => Ok(StyleComponent::HeaderFilename),
"header-filesize" => Ok(StyleComponent::HeaderFilesize),
"numbers" => Ok(StyleComponent::LineNumbers),
"syntax" => Ok(StyleComponent::Syntax),
"snip" => Ok(StyleComponent::Snip),
"full" => Ok(StyleComponent::Full),
"default" => Ok(StyleComponent::Default),
@ -122,12 +127,18 @@ impl StyleComponents {
self.0.contains(&StyleComponent::LineNumbers)
}
pub fn syntax(&self) -> bool {
self.0.contains(&StyleComponent::Syntax)
}
pub fn snip(&self) -> bool {
self.0.contains(&StyleComponent::Snip)
}
pub fn plain(&self) -> bool {
self.0.iter().all(|c| c == &StyleComponent::Plain)
self.0
.iter()
.all(|c| c == &StyleComponent::Plain || c == &StyleComponent::Syntax)
}
pub fn insert(&mut self, component: StyleComponent) {
@ -245,7 +256,7 @@ mod test {
#[test]
pub fn style_component_list_parse() {
assert_eq!(
StyleComponentList::from_str("grid,+numbers,snip,-snip,header")
StyleComponentList::from_str("grid,+numbers,snip,-snip,header,-syntax")
.expect("no error")
.0,
vec![
@ -254,6 +265,7 @@ mod test {
(Override, Snip),
(Remove, Snip),
(Override, Header),
(Remove, Syntax),
]
);

View File

@ -2888,3 +2888,34 @@ fn style_components_will_merge_with_env_var() {
.stdout(" STDIN\n 1 test\n")
.stderr("");
}
#[test]
fn skip_syntax() {
macro_rules! bat {
([$($extra_arg:expr)*], out=$out:expr) => {
bat()
.arg("--paging=never")
.arg("--terminal-width=80")
.arg("--decorations=always")
.arg("--theme=ansi")
.arg("--style=plain")
.arg("--highlight-line=1")
$(.arg($extra_arg))*
.write_stdin("Ansi Underscore Test\nAnother Line")
.assert()
.success()
.stdout($out)
.stderr("");
};
}
// without --no-syntax
bat! {
[],
out = "\x1B[4mAnsi Underscore Test\n\x1B[24mAnother Line"
};
// with --no-syntax
bat! {
["--no-syntax"],
out = "Ansi Underscore Test\nAnother Line"
};
}