mirror of
https://github.com/sharkdp/bat.git
synced 2024-11-21 23:33:26 +01:00
Merge branch 'master' into add-pipe-delimter-to-csv-syntax
This commit is contained in:
commit
d725443116
@ -9,6 +9,7 @@
|
||||
- Syntax highlighting for JavaScript files that start with `#!/usr/bin/env bun` #2913 (@sharunkumar)
|
||||
- `bat --strip-ansi={never,always,auto}` to remove ANSI escape sequences from bat's input, see #2999 (@eth-p)
|
||||
- Add or remove individual style components without replacing all styles #2929 (@eth-p)
|
||||
- Add option `--binary=as-text` for printing binary content, see issue #2974 and PR #2976 (@einfachIrgendwer0815)
|
||||
|
||||
## Bugfixes
|
||||
|
||||
@ -18,6 +19,7 @@
|
||||
- Fix handling of inputs with combined ANSI color and attribute sequences, see #2185 and #2856 (@eth-p)
|
||||
- Fix panel width when line 10000 wraps, see #2854 (@eth-p)
|
||||
- Fix compile issue of `time` dependency caused by standard library regression #3045 (@cyqsimon)
|
||||
- Fix override behavior of --plain and --paging, see issue #2731 and PR #3108 (@einfachIrgendwer0815)
|
||||
|
||||
## Other
|
||||
|
||||
@ -63,6 +65,7 @@
|
||||
- Map `*.mkd` files to `Markdown` syntax, see issue #3060 and PR #3061 (@einfachIrgendwer0815)
|
||||
- Add syntax mapping for kubernetes config files #3049 (@cyqsimon)
|
||||
- Adds support for pipe delimiter for CSV #3115 (@pratik-m)
|
||||
- Add syntax mapping for `/etc/pacman.conf` #2961 (@cyqsimon)
|
||||
|
||||
## Themes
|
||||
|
||||
@ -112,6 +115,7 @@
|
||||
- Update `Julia` syntax, see #2553 (@dependabot)
|
||||
- add `NSIS` support, see #2577 (@idleberg)
|
||||
- Update `ssh-config`, see #2697 (@mrmeszaros)
|
||||
- Add syntax mapping `*.debdiff` => `diff`, see #2947 (@jacg)
|
||||
|
||||
## `bat` as a library
|
||||
|
||||
|
33
Cargo.lock
generated
33
Cargo.lock
generated
@ -279,12 +279,11 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
||||
|
||||
[[package]]
|
||||
name = "clircle"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0b92245ea62a7a751db4b0e4a583f8978e508077ef6de24fcc0d0dc5311a8d"
|
||||
checksum = "e136d50bd652710f1d86259a8977263d46bef0ab782a8bfc3887e44338517015"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"winapi",
|
||||
@ -422,9 +421,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.34"
|
||||
version = "0.8.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
|
||||
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
@ -602,9 +601,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "grep-cli"
|
||||
version = "0.1.10"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea40788c059ab8b622c4d074732750bfb3bd2912e2dd58eabc11798a4d5ad725"
|
||||
checksum = "47f1288f0e06f279f84926fa4c17e3fcd2a22b357927a82f2777f7be26e4cec0"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"globset",
|
||||
@ -1147,9 +1146,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -1393,9 +1392,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.9"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@ -1406,18 +1405,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.1"
|
||||
version = "0.22.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@ -1747,9 +1746,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.18"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "176b6138793677221d420fd2f0aeeced263f197688b36484660da767bca2fa32"
|
||||
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -58,14 +58,14 @@ serde_derive = "1.0"
|
||||
serde_yaml = "0.9.28"
|
||||
semver = "1.0"
|
||||
path_abs = { version = "0.5", default-features = false }
|
||||
clircle = "0.5"
|
||||
clircle = "0.6"
|
||||
bugreport = { version = "0.5.0", optional = true }
|
||||
etcetera = { version = "0.8.0", optional = true }
|
||||
grep-cli = { version = "0.1.10", optional = true }
|
||||
grep-cli = { version = "0.1.11", optional = true }
|
||||
regex = { version = "1.10.2", optional = true }
|
||||
walkdir = { version = "2.5", optional = true }
|
||||
bytesize = { version = "1.3.0" }
|
||||
encoding_rs = "0.8.34"
|
||||
encoding_rs = "0.8.35"
|
||||
os_str_bytes = { version = "~7.0", optional = true }
|
||||
run_script = { version = "^0.10.1", optional = true}
|
||||
|
||||
@ -109,7 +109,7 @@ regex = "1.10.2"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_with = { version = "3.8.1", default-features = false, features = ["macros"] }
|
||||
toml = { version = "0.8.9", features = ["preserve_order"] }
|
||||
toml = { version = "0.8.19", features = ["preserve_order"] }
|
||||
walkdir = "2.5"
|
||||
|
||||
[build-dependencies.clap]
|
||||
|
@ -20,6 +20,13 @@ Options:
|
||||
* unicode (␇, ␊, ␀, ..)
|
||||
* caret (^G, ^J, ^@, ..)
|
||||
|
||||
--binary <behavior>
|
||||
How to treat binary content. (default: no-printing)
|
||||
|
||||
Possible values:
|
||||
* no-printing: do not print any binary content
|
||||
* as-text: treat binary content as normal text
|
||||
|
||||
-p, --plain...
|
||||
Only show plain style, no decorations. This is an alias for '--style=plain'. When '-p' is
|
||||
used twice ('-pp'), it also disables automatic paging (alias for '--style=plain
|
||||
|
@ -11,6 +11,8 @@ Options:
|
||||
Show non-printable characters (space, tab, newline, ..).
|
||||
--nonprintable-notation <notation>
|
||||
Set notation for non-printable characters.
|
||||
--binary <behavior>
|
||||
How to treat binary content. (default: no-printing)
|
||||
-p, --plain...
|
||||
Show plain style (alias for '--style=plain').
|
||||
-l, --language <language>
|
||||
|
@ -9,6 +9,7 @@ use crate::{
|
||||
config::{get_args_from_config_file, get_args_from_env_opts_var, get_args_from_env_vars},
|
||||
};
|
||||
use bat::style::StyleComponentList;
|
||||
use bat::BinaryBehavior;
|
||||
use bat::StripAnsiMode;
|
||||
use clap::ArgMatches;
|
||||
|
||||
@ -97,12 +98,30 @@ impl App {
|
||||
pub fn config(&self, inputs: &[Input]) -> Result<Config> {
|
||||
let style_components = self.style_components()?;
|
||||
|
||||
let extra_plain = self.matches.get_count("plain") > 1;
|
||||
let plain_last_index = self
|
||||
.matches
|
||||
.indices_of("plain")
|
||||
.and_then(Iterator::max)
|
||||
.unwrap_or_default();
|
||||
let paging_last_index = self
|
||||
.matches
|
||||
.indices_of("paging")
|
||||
.and_then(Iterator::max)
|
||||
.unwrap_or_default();
|
||||
|
||||
let paging_mode = match self.matches.get_one::<String>("paging").map(|s| s.as_str()) {
|
||||
Some("always") => PagingMode::Always,
|
||||
Some("always") => {
|
||||
// Disable paging if the second -p (or -pp) is specified after --paging=always
|
||||
if extra_plain && plain_last_index > paging_last_index {
|
||||
PagingMode::Never
|
||||
} else {
|
||||
PagingMode::Always
|
||||
}
|
||||
}
|
||||
Some("never") => PagingMode::Never,
|
||||
Some("auto") | None => {
|
||||
// If we have -pp as an option when in auto mode, the pager should be disabled.
|
||||
let extra_plain = self.matches.get_count("plain") > 1;
|
||||
if extra_plain || self.matches.get_flag("no-paging") {
|
||||
PagingMode::Never
|
||||
} else if inputs.iter().any(Input::is_stdin) {
|
||||
@ -193,6 +212,11 @@ impl App {
|
||||
Some("caret") => NonprintableNotation::Caret,
|
||||
_ => unreachable!("other values for --nonprintable-notation are not allowed"),
|
||||
},
|
||||
binary: match self.matches.get_one::<String>("binary").map(|s| s.as_str()) {
|
||||
Some("as-text") => BinaryBehavior::AsText,
|
||||
Some("no-printing") => BinaryBehavior::NoPrinting,
|
||||
_ => unreachable!("other values for --binary are not allowed"),
|
||||
},
|
||||
wrapping_mode: if self.interactive_output || maybe_term_width.is_some() {
|
||||
if !self.matches.get_flag("chop-long-lines") {
|
||||
match self.matches.get_one::<String>("wrap").map(|s| s.as_str()) {
|
||||
|
@ -77,11 +77,26 @@ pub fn build_app(interactive_output: bool) -> Command {
|
||||
* caret (^G, ^J, ^@, ..)",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("binary")
|
||||
.long("binary")
|
||||
.action(ArgAction::Set)
|
||||
.default_value("no-printing")
|
||||
.value_parser(["no-printing", "as-text"])
|
||||
.value_name("behavior")
|
||||
.hide_default_value(true)
|
||||
.help("How to treat binary content. (default: no-printing)")
|
||||
.long_help(
|
||||
"How to treat binary content. (default: no-printing)\n\n\
|
||||
Possible values:\n \
|
||||
* no-printing: do not print any binary content\n \
|
||||
* as-text: treat binary content as normal text",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("plain")
|
||||
.overrides_with("plain")
|
||||
.overrides_with("number")
|
||||
.overrides_with("paging")
|
||||
.short('p')
|
||||
.long("plain")
|
||||
.action(ArgAction::Count)
|
||||
@ -306,7 +321,6 @@ pub fn build_app(interactive_output: bool) -> Command {
|
||||
.long("paging")
|
||||
.overrides_with("paging")
|
||||
.overrides_with("no-paging")
|
||||
.overrides_with("plain")
|
||||
.value_name("when")
|
||||
.value_parser(["auto", "never", "always"])
|
||||
.default_value("auto")
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::line_range::{HighlightedLineRanges, LineRanges};
|
||||
use crate::nonprintable_notation::NonprintableNotation;
|
||||
use crate::nonprintable_notation::{BinaryBehavior, NonprintableNotation};
|
||||
#[cfg(feature = "paging")]
|
||||
use crate::paging::PagingMode;
|
||||
use crate::style::StyleComponents;
|
||||
@ -44,6 +44,9 @@ pub struct Config<'a> {
|
||||
/// The configured notation for non-printable characters
|
||||
pub nonprintable_notation: NonprintableNotation,
|
||||
|
||||
/// How to treat binary content
|
||||
pub binary: BinaryBehavior,
|
||||
|
||||
/// The character width of the terminal
|
||||
pub term_width: usize,
|
||||
|
||||
|
@ -52,7 +52,7 @@ mod terminal;
|
||||
mod vscreen;
|
||||
pub(crate) mod wrapping;
|
||||
|
||||
pub use nonprintable_notation::NonprintableNotation;
|
||||
pub use nonprintable_notation::{BinaryBehavior, NonprintableNotation};
|
||||
pub use preprocessor::StripAnsiMode;
|
||||
pub use pretty_printer::{Input, PrettyPrinter, Syntax};
|
||||
pub use syntax_mapping::{MappingTarget, SyntaxMapping};
|
||||
|
@ -10,3 +10,15 @@ pub enum NonprintableNotation {
|
||||
#[default]
|
||||
Unicode,
|
||||
}
|
||||
|
||||
/// How to treat binary content
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum BinaryBehavior {
|
||||
/// Do not print any binary content
|
||||
#[default]
|
||||
NoPrinting,
|
||||
|
||||
/// Treat binary content as normal text
|
||||
AsText,
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ use crate::style::StyleComponent;
|
||||
use crate::terminal::{as_terminal_escaped, to_ansi_color};
|
||||
use crate::vscreen::{AnsiStyle, EscapeSequence, EscapeSequenceIterator};
|
||||
use crate::wrapping::WrappingMode;
|
||||
use crate::BinaryBehavior;
|
||||
use crate::StripAnsiMode;
|
||||
|
||||
const ANSI_UNDERLINE_ENABLE: EscapeSequence = EscapeSequence::CSI {
|
||||
@ -268,7 +269,8 @@ impl<'a> InteractivePrinter<'a> {
|
||||
.content_type
|
||||
.map_or(false, |c| c.is_binary() && !config.show_nonprintable);
|
||||
|
||||
let needs_to_match_syntax = !is_printing_binary
|
||||
let needs_to_match_syntax = (!is_printing_binary
|
||||
|| matches!(config.binary, BinaryBehavior::AsText))
|
||||
&& (config.colored_output || config.strip_ansi == StripAnsiMode::Auto);
|
||||
|
||||
let (is_plain_text, highlighter_from_set) = if needs_to_match_syntax {
|
||||
@ -458,7 +460,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
}
|
||||
|
||||
if !self.config.style_components.header() {
|
||||
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
|
||||
if Some(ContentType::BINARY) == self.content_type
|
||||
&& !self.config.show_nonprintable
|
||||
&& !matches!(self.config.binary, BinaryBehavior::AsText)
|
||||
{
|
||||
writeln!(
|
||||
handle,
|
||||
"{}: Binary content from {} will not be printed to the terminal \
|
||||
@ -539,7 +544,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
})?;
|
||||
|
||||
if self.config.style_components.grid() {
|
||||
if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
|
||||
if self.content_type.map_or(false, |c| c.is_text())
|
||||
|| self.config.show_nonprintable
|
||||
|| matches!(self.config.binary, BinaryBehavior::AsText)
|
||||
{
|
||||
self.print_horizontal_line(handle, '┼')?;
|
||||
} else {
|
||||
self.print_horizontal_line(handle, '┴')?;
|
||||
@ -551,7 +559,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
|
||||
fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
|
||||
if self.config.style_components.grid()
|
||||
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
|
||||
&& (self.content_type.map_or(false, |c| c.is_text())
|
||||
|| self.config.show_nonprintable
|
||||
|| matches!(self.config.binary, BinaryBehavior::AsText))
|
||||
{
|
||||
self.print_horizontal_line(handle, '┴')
|
||||
} else {
|
||||
@ -599,7 +609,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
.into()
|
||||
} else {
|
||||
let mut line = match self.content_type {
|
||||
Some(ContentType::BINARY) | None => {
|
||||
Some(ContentType::BINARY) | None
|
||||
if !matches!(self.config.binary, BinaryBehavior::AsText) =>
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
Some(ContentType::UTF_16LE) => UTF_16LE.decode_with_bom_removal(line_buffer).0,
|
||||
|
3
src/syntax_mapping/builtins/common/50-diff.toml
Normal file
3
src/syntax_mapping/builtins/common/50-diff.toml
Normal file
@ -0,0 +1,3 @@
|
||||
# .debdiff is the extension used for diffs in Debian packaging
|
||||
[mappings]
|
||||
"Diff" = ["*.debdiff"]
|
@ -1,3 +1,8 @@
|
||||
[mappings]
|
||||
# pacman hooks
|
||||
"INI" = ["/usr/share/libalpm/hooks/*.hook", "/etc/pacman.d/hooks/*.hook"]
|
||||
"INI" = [
|
||||
# config
|
||||
"/etc/pacman.conf",
|
||||
# hooks
|
||||
"/usr/share/libalpm/hooks/*.hook",
|
||||
"/etc/pacman.d/hooks/*.hook",
|
||||
]
|
||||
|
@ -1019,6 +1019,31 @@ fn enable_pager_if_pp_flag_comes_before_paging() {
|
||||
.stdout(predicate::eq("pager-output\n").normalize());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paging_does_not_override_simple_plain() {
|
||||
bat()
|
||||
.env("PAGER", "echo pager-output")
|
||||
.arg("--decorations=always")
|
||||
.arg("--plain")
|
||||
.arg("--paging=never")
|
||||
.arg("test.txt")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::eq("hello world\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_plain_does_not_override_paging() {
|
||||
bat()
|
||||
.env("PAGER", "echo pager-output")
|
||||
.arg("--paging=always")
|
||||
.arg("--plain")
|
||||
.arg("test.txt")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::eq("pager-output\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pager_failed_to_parse() {
|
||||
bat()
|
||||
@ -1938,6 +1963,16 @@ fn show_all_with_unicode() {
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binary_as_text() {
|
||||
bat()
|
||||
.arg("--binary=as-text")
|
||||
.arg("control_characters.txt")
|
||||
.assert()
|
||||
.stdout("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F")
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_paging_arg() {
|
||||
bat()
|
||||
|
Loading…
Reference in New Issue
Block a user