1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-09-01 10:52:24 +01:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Keith Hall
6a6041c72c make further improvements to docs relating to sponsors 2022-02-09 22:41:59 +02:00
Keith Hall
0d93abde67 create separate sponsors.md file 2022-02-09 22:34:46 +02:00
Keith Hall
1cc39a790f improve sponsor section in readme 2022-02-09 22:26:12 +02:00
Keith Hall
2d93da1869 Add WorkOS sponsor to readme 2022-02-09 22:22:34 +02:00
99 changed files with 613 additions and 2117 deletions

View File

@@ -7,26 +7,9 @@ assignees: ''
--- ---
<!-- <!-- Hey there, thank you for creating an issue! -->
Hey there, thank you for reporting a bug! **Describe the bug you encountered:**
Please note that the following bugs have already been reported:
* dpkg: error processing archive /some/path/some-program.deb (--unpack):
trying to overwrite '/usr/.crates2.json'
See https://github.com/sharkdp/bat/issues/938
-->
**What steps will reproduce the bug?**
1. step 1
2. step 2
3. ...
**What happens?**
... ...

View File

@@ -7,5 +7,3 @@ assignees: ''
--- ---
<!-- Using a normal ticket is still fine, but feel free to ask your
questions about bat on https://github.com/sharkdp/bat/discussions instead. -->

View File

@@ -1,7 +1,7 @@
name: CICD name: CICD
env: env:
MIN_SUPPORTED_RUST_VERSION: "1.60.0" MIN_SUPPORTED_RUST_VERSION: "1.51.0"
CICD_INTERMEDIATES_DIR: "_cicd-intermediates" CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
on: on:
@@ -39,8 +39,6 @@ jobs:
min_version: min_version:
name: Minimum supported rust version name: Minimum supported rust version
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
env:
MSRV_FEATURES: --no-default-features --features minimal-application,bugreport,build-assets
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: actions/checkout@v2 uses: actions/checkout@v2
@@ -56,12 +54,12 @@ jobs:
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: clippy command: clippy
args: --locked --all-targets ${{ env.MSRV_FEATURES }} args: --locked --all-targets --all-features
- name: Run tests - name: Run tests
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: test command: test
args: --locked ${{ env.MSRV_FEATURES }} args: --locked
test_with_new_syntaxes_and_themes: test_with_new_syntaxes_and_themes:
name: Run tests with updated syntaxes and themes name: Run tests with updated syntaxes and themes
@@ -98,7 +96,7 @@ jobs:
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: test command: test
args: --locked --release --test assets -- --ignored args: --locked --release -- --ignored
- name: Syntax highlighting regression test - name: Syntax highlighting regression test
run: tests/syntax-tests/regression_test.sh run: tests/syntax-tests/regression_test.sh
- name: List of languages - name: List of languages
@@ -108,32 +106,6 @@ jobs:
- name: Test custom assets - name: Test custom assets
run: tests/syntax-tests/test_custom_assets.sh run: tests/syntax-tests/test_custom_assets.sh
test_with_system_config:
name: Run tests with system wide configuration
runs-on: ubuntu-20.04
steps:
- name: Git checkout
uses: actions/checkout@v2
- name: Prepare environment variables
run: |
echo "BAT_SYSTEM_CONFIG_PREFIX=$GITHUB_WORKSPACE/tests/examples/system_config" >> $GITHUB_ENV
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
default: true
profile: minimal
- name: Build and install bat
uses: actions-rs/cargo@v1
with:
command: install
args: --locked --path .
- name: Run unit tests
uses: actions-rs/cargo@v1
with:
command: test
args: --locked --test system_wide_config -- --ignored
documentation: documentation:
name: Documentation name: Documentation
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
@@ -146,18 +118,6 @@ jobs:
toolchain: stable toolchain: stable
default: true default: true
profile: minimal profile: minimal
- name: Print -h
uses: actions-rs/cargo@v1
with:
command: run
args: --locked -- -h
- name: Print --help
uses: actions-rs/cargo@v1
with:
command: run
args: --locked -- --help
- name: Show man page
run: man $(find . -name bat.1)
- name: Check documentation - name: Check documentation
env: env:
RUSTDOCFLAGS: -D warnings RUSTDOCFLAGS: -D warnings
@@ -182,7 +142,7 @@ jobs:
- { target: x86_64-apple-darwin , os: macos-10.15 } - { target: x86_64-apple-darwin , os: macos-10.15 }
- { target: x86_64-pc-windows-gnu , os: windows-2019 } - { target: x86_64-pc-windows-gnu , os: windows-2019 }
- { target: x86_64-pc-windows-msvc , os: windows-2019 } - { target: x86_64-pc-windows-msvc , os: windows-2019 }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04 }
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
steps: steps:
- name: Checkout source code - name: Checkout source code

8
.gitmodules vendored
View File

@@ -236,11 +236,3 @@
[submodule "assets/syntaxes/02_Extra/Dart"] [submodule "assets/syntaxes/02_Extra/Dart"]
path = assets/syntaxes/02_Extra/Dart path = assets/syntaxes/02_Extra/Dart
url = https://github.com/elMuso/Dartlight.git url = https://github.com/elMuso/Dartlight.git
[submodule "assets/syntaxes/02_Extra/SublimeJQ"]
path = assets/syntaxes/02_Extra/SublimeJQ
url = https://github.com/zogwarg/SublimeJQ.git
[submodule "assets/syntaxes/02_Extra/cmd-help"]
path = assets/syntaxes/02_Extra/cmd-help
url = https://github.com/victor-gp/cmd-help-sublime-syntax.git
branch = main
shallow = true

View File

@@ -1,97 +1,12 @@
# v0.22.1 # unreleased
## Bugfixes
- Bring back pre-processing of ANSI escape characters to so that some common `bat` use cases starts working again. See #2308 (@Enselic)
# v0.22.0
## Features
- Make the default macOS theme depend on Dark Mode. See #2197, #1746 (@Enselic)
- Support for separate system and user config files. See #668 (@patrickpichler)
## Bugfixes
- Prevent fork nightmare with `PAGER=batcat`. See #2235 (@johnmatthiggins)
- Make `--no-paging`/`-P` override `--paging=...` if passed as a later arg, see #2201 (@themkat)
- `--map-syntax` and `--ignored-suffix` now works together, see #2093 (@czzrr)
- Strips byte order mark from output when in non-loop-through mode. See #1922 (@dag-h)
## Other
- Relaxed glibc requirements on amd64, see #2106 and #2194 (@sharkdp)
- Improved fish completions. See #2275 (@zgracem)
- Stop pre-processing ANSI escape characters. Syntax highlighting on ANSI escaped input is not supported. See #2185 and #2189 (@Enselic)
## Syntaxes
- NSE (Nmap Scripting Engine) is mapped to Lua, see #2151 (@Cre3per)
- Correctly color `fstab` dump and pass fields, see #2246 (@yuvalmo)
- Update `Command Help` syntax, see #2255
- `Julia`: Fix syntax highlighting for function name starting with `struct`, see #2230
- Minor update to `LiveScript`, see #2291
- Associate `.mts` and `.cts` files with the `TypeScript` syntax. See #2236 (@kidonng)
- Fish history is mapped to YAML. See #2237 (@kidonng)
## `bat` as a library
- Make `bat::PrettyPrinter::syntaxes()` iterate over new `bat::Syntax` struct instead of `&syntect::parsing::SyntaxReference`. See #2222 (@Enselic)
- Clear highlights after printing, see #1919 and #1920 (@rhysd)
# v0.21.0
## Features
- Correctly render tab stops in `--show-all`, see #2038 (@Synthetica9)
- Add a `--style=default` option and make it the default. It is less verbose than `full`, see #2061 (@IsaacHorvath)
- Enable BusyBox `less` as pager, see #2162 (@nfisher1226)
- File extensions are now matched case-insensitively. See #1854, #2181 (@Enselic)
## Bugfixes
- Bump `regex` dependency from 1.5.4 to 1.5.5 to fix [CVE-2022-24713](https://blog.rust-lang.org/2022/03/08/cve-2022-24713.html), see #2145, #2139 (@Enselic)
- `bat` no longer crashes when encountering files that references missing syntaxes. See #915, #2181 (@Enselic)
## Performance
- Skip syntax highlighting on long lines (> 16384 chars) to help improve performance. See #2165 (@keith-hall)
- Vastly improve startup time by lazy-loading syntaxes via syntect 5.0.0. This makes bat display small files ~75% faster than before. See #951, #2181 (@Enselic)
## Other
- Include info about custom assets in `--diagnostics` if used. See #2107, #2144 (@Enselic)
## Syntaxes
- Mapped clang-format config file (.clang-format) to YAML syntax (@TruncatedDinosour)
- log syntax: improved handling of escape characters in double quoted strings. See #2123 (@keith-hall)
- Associate `/var/spool/mail/*` and `/var/mail/*` with the `Email` syntax. See #2156 (@cyqsimon)
- Added cmd-help syntax to scope --help messages. See #2148 (@victor-gp)
- Slightly adjust Zig syntax. See #2136 (@Enselic)
- Associate `.inf` files with the `INI` syntax. See #2190 (@Enselic)
## `bat` as a library
- Allow configuration of `show_nonprintable` with `PrettyPrinter`, see #2142
- The binary format of syntaxes.bin has been changed due to syntaxes now being lazy-loaded via syntect 5.0.0. See #2181 (@Enselic)
- Mark `bat::error::Error` enum as `#[non_exhaustive]` to allow adding new variants without future semver breakage. See #2181 (@Enselic)
- Change `Error::SyntectError(syntect::LoadingError)` to `Error::SyntectError(syntect::Error)`. See #2181 (@Enselic)
- Add `Error::SyntectLoadingError(syntect::LoadingError)` enum variant. See #2181 (@Enselic)
# v0.20.0
## Features ## Features
- New style component `header-filesize` to show size of the displayed file in the header. See #1988 (@mdibaiee) - New style component `header-filesize` to show size of the displayed file in the header. See #1988 (@mdibaiee)
- Use underline for line highlighting on ANSI, see #1730 (@mdibaiee)
## Bugfixes ## Bugfixes
- Fix bash completion on bash 3.x and bash-completion 1.x. See #2066 (@joshpencheon) ## Other
## Syntaxes ## Syntaxes
@@ -99,14 +14,12 @@
- Associate `_vimrc` and `_gvimrc` files with the `VimL` syntax. See #2002 - Associate `_vimrc` and `_gvimrc` files with the `VimL` syntax. See #2002
- Associate `poetry.lock` files with the `TOML` syntax. See #2049 - Associate `poetry.lock` files with the `TOML` syntax. See #2049
- Associate `.mesh`, `.task`, `.rgen`, `.rint`, `.rahit`, `.rchit`, `.rmiss`, and `.rcall` with the `GLSL` syntax. See #2050 - Associate `.mesh`, `.task`, `.rgen`, `.rint`, `.rahit`, `.rchit`, `.rmiss`, and `.rcall` with the `GLSL` syntax. See #2050
- Added support for `JQ` syntax, see #2072
- Properly associate global git config files rooted in `$XDG_CONFIG_HOME/git/` or `$HOME/.config/git/`. See #2067 (@cyqsimon) ## Themes
## `bat` as a library ## `bat` as a library
- Exposed `get_syntax_set` and `get_theme` methods on `HighlightingAssets`. See #2030 (@dandavison) - Exposed `get_syntax_set` and `get_theme` methods on `HighlightingAssets`. See #2030 (@dandavison)
- Added `HeaderFilename` and `HeaderFilesize` to `StyleComponent` enum, and mark it `#[non_exhaustive]`. See #1988 (@mdibaiee)
# v0.19.0 # v0.19.0

View File

@@ -46,25 +46,3 @@ If you really think that a particular syntax or theme should be added for all
users, please read the corresponding users, please read the corresponding
[documentation](https://github.com/sharkdp/bat/blob/master/doc/assets.md) [documentation](https://github.com/sharkdp/bat/blob/master/doc/assets.md)
first. first.
## Regression tests
You are strongly encouraged to add regression tests. Regression tests are great,
not least because they:
* ensure that your contribution will never completely stop working,
* makes code review easier, because it becomes very clear what the code is
supposed to do.
For functional changes, you most likely want to add a test to
[`tests/integration_tests.rs`](https://github.com/sharkdp/bat/blob/master/tests/integration_tests.rs).
Look at existing tests to know how to write a new test. In short, you will
invoke the `bat` binary with a certain set of arguments, and then assert on
stdout/stderr.
To learn how to write regression tests for theme and syntax changes, read the
[Syntax
tests](https://github.com/sharkdp/bat/blob/master/doc/assets.md#syntax-tests)
section in `assets.md`.

237
Cargo.lock generated
View File

@@ -74,7 +74,7 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]] [[package]]
name = "bat" name = "bat"
version = "0.22.1" version = "0.19.0"
dependencies = [ dependencies = [
"ansi_colours", "ansi_colours",
"ansi_term", "ansi_term",
@@ -155,9 +155,9 @@ dependencies = [
[[package]] [[package]]
name = "bugreport" name = "bugreport"
version = "0.5.0" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "535120b8182547808081a66f1f77a64533c780b23da26763e0ee34dfb94f98c9" checksum = "0014b4b2b4f63bfe69c3838470121290cc437fdc79785d408a761a21e8b2404c"
dependencies = [ dependencies = [
"git-version", "git-version",
"shell-escape", "shell-escape",
@@ -193,28 +193,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.2.20" version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [ dependencies = [
"ansi_term",
"atty", "atty",
"bitflags", "bitflags",
"clap_lex",
"indexmap",
"once_cell",
"strsim", "strsim",
"termcolor", "term_size",
"terminal_size",
"textwrap", "textwrap",
] "unicode-width",
"vec_map",
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
] ]
[[package]] [[package]]
@@ -231,13 +221,14 @@ dependencies = [
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.1" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode",
"libc", "libc",
"once_cell", "once_cell",
"regex",
"terminal_size", "terminal_size",
"unicode-width", "unicode-width",
"winapi", "winapi",
@@ -391,11 +382,13 @@ dependencies = [
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.24" version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
dependencies = [ dependencies = [
"cfg-if",
"crc32fast", "crc32fast",
"libc",
"miniz_oxide", "miniz_oxide",
] ]
@@ -459,9 +452,9 @@ dependencies = [
[[package]] [[package]]
name = "git2" name = "git2"
version = "0.15.0" version = "0.13.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1" checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
@@ -478,9 +471,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]] [[package]]
name = "globset" name = "globset"
version = "0.4.9" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"bstr", "bstr",
@@ -588,16 +581,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "lazycell"
version = "0.2.125" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]] [[package]]
name = "libgit2-sys" name = "libgit2-sys"
version = "0.14.0+1.5.0" version = "0.12.26+1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b" checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@@ -663,23 +662,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "miniz_oxide" name = "memoffset"
version = "0.5.1" version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [ dependencies = [
"adler", "adler",
"autocfg",
] ]
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.24.2" version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cc",
"cfg-if", "cfg-if",
"libc", "libc",
"memoffset",
] ]
[[package]] [[package]]
@@ -699,9 +710,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.1" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]] [[package]]
name = "onig" name = "onig"
@@ -725,12 +736,6 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "os_str_bytes"
version = "6.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@@ -793,9 +798,9 @@ dependencies = [
[[package]] [[package]]
name = "predicates" name = "predicates"
version = "2.1.1" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" checksum = "95e5a7689e456ab905c22c2b48225bb921aba7c8dfa58440d68ba13f6222a715"
dependencies = [ dependencies = [
"difflib", "difflib",
"float-cmp", "float-cmp",
@@ -821,30 +826,6 @@ dependencies = [
"termtree", "termtree",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"
@@ -853,11 +834,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.39" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-ident", "unicode-xid",
] ]
[[package]] [[package]]
@@ -890,9 +871,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.6.0" version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -907,9 +888,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.27" version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
@@ -929,12 +910,6 @@ dependencies = [
"bytemuck", "bytemuck",
] ]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.9" version = "1.0.9"
@@ -964,24 +939,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.13" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.144" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.144" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1001,9 +976,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_yaml" name = "serde_yaml"
version = "0.8.24" version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc" checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"ryu", "ryu",
@@ -1013,9 +988,9 @@ dependencies = [
[[package]] [[package]]
name = "serial_test" name = "serial_test"
version = "0.6.0" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5bcc41d18f7a1d50525d080fd3e953be87c4f9f1a974f3c21798ca00d54ec15" checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"parking_lot", "parking_lot",
@@ -1024,14 +999,12 @@ dependencies = [
[[package]] [[package]]
name = "serial_test_derive" name = "serial_test_derive"
version = "0.6.0" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2881bccd7d60fb32dfa3d7b3136385312f8ad75e2674aab2852867a09790cae8" checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5"
dependencies = [ dependencies = [
"proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustversion",
"syn", "syn",
] ]
@@ -1043,9 +1016,9 @@ checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
[[package]] [[package]]
name = "shell-words" name = "shell-words"
version = "1.1.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" checksum = "b6fa3938c99da4914afedd13bf3d79bcb6c277d1b2c398d23257a304d9e1b074"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
@@ -1061,26 +1034,26 @@ checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.95" version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-ident", "unicode-xid",
] ]
[[package]] [[package]]
name = "syntect" name = "syntect"
version = "5.0.0" version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8" checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
dependencies = [ dependencies = [
"bincode", "bincode",
"bitflags", "bitflags",
@@ -1088,14 +1061,13 @@ dependencies = [
"flate2", "flate2",
"fnv", "fnv",
"lazy_static", "lazy_static",
"once_cell", "lazycell",
"onig", "onig",
"plist", "plist",
"regex-syntax", "regex-syntax",
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"thiserror",
"walkdir", "walkdir",
"yaml-rust", "yaml-rust",
] ]
@@ -1124,6 +1096,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "termcolor" name = "termcolor"
version = "1.1.2" version = "1.1.2"
@@ -1151,27 +1133,28 @@ checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16"
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.15.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [ dependencies = [
"terminal_size", "term_size",
"unicode-width",
] ]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.33" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57" checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.33" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1209,12 +1192,6 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]]
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.19" version = "0.1.19"
@@ -1230,6 +1207,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "url" name = "url"
version = "2.2.2" version = "2.2.2"
@@ -1249,10 +1232,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "vec_map"
version = "0.9.4" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "wait-timeout" name = "wait-timeout"
@@ -1282,9 +1265,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "wild" name = "wild"
version = "2.1.0" version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74" checksum = "035793abb854745033f01a07647a79831eba29ec0be377205f2a25b0aa830020"
dependencies = [ dependencies = [
"glob", "glob",
] ]

View File

@@ -6,7 +6,7 @@ homepage = "https://github.com/sharkdp/bat"
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
name = "bat" name = "bat"
repository = "https://github.com/sharkdp/bat" repository = "https://github.com/sharkdp/bat"
version = "0.22.1" version = "0.19.0"
exclude = ["assets/syntaxes/*", "assets/themes/*"] exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build.rs" build = "build.rs"
edition = '2018' edition = '2018'
@@ -33,7 +33,8 @@ minimal-application = [
] ]
git = ["git2"] # Support indicating git modifications git = ["git2"] # Support indicating git modifications
paging = ["shell-words", "grep-cli"] # Support applying a pager on the output paging = ["shell-words", "grep-cli"] # Support applying a pager on the output
build-assets = ["syntect/yaml-load", "syntect/plist-load", "regex", "walkdir"] # Add "syntect/plist-load" when https://github.com/trishume/syntect/pull/345 reaches us
build-assets = ["syntect/yaml-load", "syntect/dump-create", "regex", "walkdir"]
# You need to use one of these if you depend on bat as a library: # You need to use one of these if you depend on bat as a library:
regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine
@@ -44,14 +45,14 @@ atty = { version = "0.2.14", optional = true }
ansi_term = "^0.12.1" ansi_term = "^0.12.1"
ansi_colours = "^1.1" ansi_colours = "^1.1"
bincode = "1.0" bincode = "1.0"
console = "0.15.1" console = "0.15.0"
flate2 = "1.0" flate2 = "1.0"
once_cell = "1.13" once_cell = "1.9"
thiserror = "1.0" thiserror = "1.0"
wild = { version = "2.1", optional = true } wild = { version = "2.0", optional = true }
content_inspector = "0.2.4" content_inspector = "0.2.4"
encoding = "0.2" encoding = "0.2"
shell-words = { version = "1.1.0", optional = true } shell-words = { version = "1.0.0", optional = true }
unicode-width = "0.1.9" unicode-width = "0.1.9"
globset = "0.4" globset = "0.4"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
@@ -59,41 +60,41 @@ serde_yaml = "0.8"
semver = "1.0" semver = "1.0"
path_abs = { version = "0.5", default-features = false } path_abs = { version = "0.5", default-features = false }
clircle = "0.3" clircle = "0.3"
bugreport = { version = "0.5.0", optional = true } bugreport = { version = "0.4", optional = true }
dirs-next = { version = "2.0.0", optional = true } dirs-next = { version = "2.0.0", optional = true }
grep-cli = { version = "0.1.6", optional = true } grep-cli = { version = "0.1.6", optional = true }
regex = { version = "1.6.0", optional = true } regex = { version = "1.0", optional = true }
walkdir = { version = "2.0", optional = true } walkdir = { version = "2.0", optional = true }
bytesize = { version = "1.1.0" } bytesize = { version = "1.1.0" }
[dependencies.git2] [dependencies.git2]
version = "0.15" version = "0.13"
optional = true optional = true
default-features = false default-features = false
[dependencies.syntect] [dependencies.syntect]
version = "5.0.0" version = "4.6.0"
default-features = false default-features = false
features = ["parsing"] features = ["parsing"]
[dependencies.clap] [dependencies.clap]
version = "3.2.20" version = "2.34"
optional = true optional = true
default-features = false default-features = false
features = ["std", "suggestions", "color", "wrap_help", "cargo"] features = ["suggestions", "color", "wrap_help"]
[dev-dependencies] [dev-dependencies]
assert_cmd = "2.0.4" assert_cmd = "2.0.4"
serial_test = "0.6.0" serial_test = "0.5.1"
predicates = "2.1.1" predicates = "2.1.0"
wait-timeout = "0.2.0" wait-timeout = "0.2.0"
tempfile = "3.3.0" tempfile = "3.3.0"
[target.'cfg(unix)'.dev-dependencies] [target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.24.2", default-features = false, features = ["term"] } nix = "0.23.1"
[build-dependencies] [build-dependencies]
clap = { version = "3.2.20", optional = true } clap = { version = "2.34", optional = true }
[profile.release] [profile.release]
lto = true lto = true

View File

@@ -21,7 +21,7 @@
### Sponsors ### Sponsors
A special *thank you* goes to our biggest <a href="doc/sponsors.md">sponsors</a>:<br> a special thank you goes to our biggest <a href="doc/sponsors.md">sponsors</a>:<br>
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=bat&utm_source=github"> <a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=bat&utm_source=github">
<img src="doc/sponsors/workos-logo-white-bg.svg" width="200" alt="WorkOS"> <img src="doc/sponsors/workos-logo-white-bg.svg" width="200" alt="WorkOS">
<br> <br>
@@ -171,7 +171,7 @@ You can combine `bat` with `git diff` to view lines around code changes with pro
highlighting: highlighting:
```bash ```bash
batdiff() { batdiff() {
git diff --name-only --relative --diff-filter=d | xargs bat --diff git diff --name-only --diff-filter=d | xargs bat --diff
} }
``` ```
If you prefer to use this as a separate tool, check out `batdiff` in [`bat-extras`](https://github.com/eth-p/bat-extras). If you prefer to use this as a separate tool, check out `batdiff` in [`bat-extras`](https://github.com/eth-p/bat-extras).
@@ -212,24 +212,6 @@ Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145)
The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) script is a wrapper that will format code and print it with `bat`. The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) script is a wrapper that will format code and print it with `bat`.
#### Highlighting `--help` messages
You can use `bat` to colorize help text: `$ cp --help | bat -plhelp`
You can also use a wrapper around this:
```bash
# in your .bashrc/.zshrc/*rc
alias bathelp='bat --plain --language=help'
help() {
"$@" --help 2>&1 | bathelp
}
```
Then you can do `$ help cp` or `$ help git commit`.
Please report any issues with the help syntax in [this repository](https://github.com/victor-gp/cmd-help-sublime-syntax).
## Installation ## Installation
@@ -418,7 +400,7 @@ binaries are also available: look for archives with `musl` in the file name.
### From source ### From source
If you want to build `bat` from source, you need Rust 1.60.0 or If you want to build `bat` from source, you need Rust 1.51 or
higher. You can then use `cargo` to build everything: higher. You can then use `cargo` to build everything:
```bash ```bash
@@ -639,10 +621,6 @@ A default configuration file can be created with the `--generate-config-file` op
bat --generate-config-file bat --generate-config-file
``` ```
There is also now a systemwide configuration file, which is located under `/etc/bat/config` on
Linux and Mac OS and `C:\ProgramData\bat\config` on windows. If the system wide configuration
file is present, the content of the user configuration will simply be appended to it.
### Format ### Format
The configuration file is a simple list of command line arguments. Use `bat --help` to see a full list of possible options and values. In addition, you can add comments by prepending a line with the `#` character. The configuration file is a simple list of command line arguments. Use `bat --help` to see a full list of possible options and values. In addition, you can add comments by prepending a line with the `#` character.

Binary file not shown.

View File

@@ -37,7 +37,7 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
[CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').') [CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').')
[CompletionResult]::new('--map-syntax', 'map-syntax', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').') [CompletionResult]::new('--map-syntax', 'map-syntax', [CompletionResultType]::ParameterName, 'Use the specified syntax for files matching the glob pattern (''*.cpp:C++'').')
[CompletionResult]::new('--theme', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting.') [CompletionResult]::new('--theme', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting.')
[CompletionResult]::new('--style', 'style', [CompletionResultType]::ParameterName, 'Comma-separated list of style elements to display (*default*, auto, full, plain, changes, header, header-filename, header-filesize, grid, rule, numbers, snip).') [CompletionResult]::new('--style', 'style', [CompletionResultType]::ParameterName, 'Comma-separated list of style elements to display (*auto*, full, plain, changes, header, grid, rule, numbers, snip).')
[CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.') [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.')
[CompletionResult]::new('--line-range', 'line-range', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.') [CompletionResult]::new('--line-range', 'line-range', [CompletionResultType]::ParameterName, 'Only print the lines from N to M.')
[CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).') [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')

View File

@@ -2,22 +2,9 @@
# Requires https://github.com/scop/bash-completion # Requires https://github.com/scop/bash-completion
# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
__bat_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
}
_bat() { _bat() {
local cur prev words cword split=false local cur prev words cword split
if declare -F _init_completion >/dev/null 2>&1; then _init_completion -s || return 0
_init_completion -s || return 0
else
__bat_init_completion -n "=" || return 0
_split_longopt && split=true
fi
if [[ ${words[1]-} == cache ]]; then if [[ ${words[1]-} == cache ]]; then
case $prev in case $prev in

View File

@@ -1,219 +1,78 @@
# Fish Shell Completions # Fish Shell Completions
# Copy or symlink to $XDG_CONFIG_HOME/fish/completions/{{PROJECT_EXECUTABLE}}.fish # Place or symlink to $XDG_CONFIG_HOME/fish/completions/{{PROJECT_EXECUTABLE}}.fish ($XDG_CONFIG_HOME is usually set to ~/.config)
# ($XDG_CONFIG_HOME is usually set to ~/.config)
# `bat` is `batcat` on Debian and Ubuntu # Helper function:
set bat {{PROJECT_EXECUTABLE}} function __{{PROJECT_EXECUTABLE}}_autocomplete_languages --description "A helper function used by "(status filename)
{{PROJECT_EXECUTABLE}} --list-languages | awk -F':' '
{
lang=$1
split($2, exts, ",")
# Helper functions: for (i in exts) {
ext=exts[i]
function __bat_complete_files -a token if (ext !~ /[A-Z].*/ && ext !~ /^\..*rc$/) {
# Cheat to complete files by calling `complete -C` on a fake command name, print ext"\t"lang
# like `__fish_complete_directories` does. }
set -l fake_command aaabccccdeeeeefffffffffgghhhhhhiiiii }
complete -C"$fake_command $token" }
' | sort
end end
function __bat_complete_one_language -a comp
command $bat --list-languages | string split -f1 : | string match -e "$comp"
end
function __bat_complete_list_languages
for spec in (command $bat --list-languages)
set -l name (string split -f1 : $spec)
for ext in (string split -f2 : $spec | string split ,)
test -n "$ext"; or continue
string match -rq '[/*]' $ext; and continue
printf "%s\t%s\n" $ext $name
end
printf "%s\t\n" $name
end
end
function __bat_complete_map_syntax
set -l token (commandline -ct)
if string match -qr '(?<glob>.+):(?<syntax>.*)' -- $token
# If token ends with a colon, complete with the list of language names.
set -f comps $glob:(__bat_complete_one_language $syntax)
else if string match -qr '\*' -- $token
# If token contains a globbing character (`*`), complete only possible
# globs in the current directory
set -f comps (__bat_complete_files $token | string match -er '[*]'):
else
# Complete files (and globs).
set -f comps (__bat_complete_files $token | string match -erv '/$'):
end
if set -q comps[1]
printf "%s\t\n" $comps
end
end
function __bat_cache_subcommand
__fish_seen_subcommand_from cache
end
# Returns true if no exclusive arguments seen.
function __bat_no_excl_args
not __bat_cache_subcommand; and not __fish_seen_argument \
-s h -l help \
-s V -l version \
-l acknowledgements \
-l config-dir -l config-file \
-l diagnostic \
-l list-languages -l list-themes
end
# Returns true if the 'cache' subcommand is seen without any exclusive arguments.
function __bat_cache_no_excl
__bat_cache_subcommand; and not __fish_seen_argument \
-s h -l help \
-l acknowledgements -l build -l clear
end
function __bat_style_opts
set -l style_opts \
"default,recommended components" \
"auto,same as 'default' unless piped" \
"full,all components" \
"plain,no components" \
"changes,Git change markers" \
"header,alias for header-filename" \
"header-filename,filename above content" \
"header-filesize,filesize above content" \
"grid,lines b/w sidebar/header/content" \
"numbers,line numbers in sidebar" \
"rule,separate files" \
"snip,separate ranges"
string replace , \t $style_opts
end
# Use option argument descriptions to indicate which is the default, saving
# horizontal space and making sure the option description isn't truncated.
set -l color_opts '
auto\tdefault
never\t
always\t
'
set -l decorations_opts $color_opts
set -l paging_opts $color_opts
# Include some examples so we can indicate the default.
set -l pager_opts '
less\tdefault
less\ -FR\t
more\t
vimpager\t
'
set -l italic_text_opts '
always\t
never\tdefault
'
set -l wrap_opts '
auto\tdefault
never\t
character\t
'
# While --tabs theoretically takes any number, most people should be OK with these.
# Specifying a list lets us explain what 0 does.
set -l tabs_opts '
0\tpass\ tabs\ through\ directly
1\t
2\t
4\t
8\t
'
# Completions: # Completions:
complete -c $bat -l acknowledgements -d "Print acknowledgements" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -l color -xka "auto never always" -d "Specify when to use colored output (default: auto)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l color -x -a "$color_opts" -d "When to use colored output" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l config-dir -d "Display location of '{{PROJECT_EXECUTABLE}}' configuration directory" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l config-dir -f -d "Display location of configuration directory" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -l config-file -d "Display location of '{{PROJECT_EXECUTABLE}}' configuration file" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l config-file -f -d "Display location of configuration file" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -l decorations -xka "auto never always" -d "Specify when to use the decorations specified with '--style' (default: auto)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l decorations -x -a "$decorations_opts" -d "When to use --style decorations" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s h -l help -d "Print help message" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l diagnostic -d "Print diagnostic info for bug reports" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -s H -l highlight-line -x -d "<N> Highlight the N-th line with a different background color" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s d -l diff -d "Only show lines with Git changes" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l italic-text -xka "always never" -d "Specify when to use ANSI sequences for italic text (default: never)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l diff-context -x -d "Show N context lines around Git changes" -n "__fish_seen_argument -s d -l diff" complete -c {{PROJECT_EXECUTABLE}} -s l -l language -d "Set the language for syntax highlighting" -n "not __fish_seen_subcommand_from cache" -xa "(__{{PROJECT_EXECUTABLE}}_autocomplete_languages)"
complete -c $bat -l file-name -x -d "Specify the display name" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s r -l line-range -x -d "<N:M> Only print the specified range of lines for each file" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s f -l force-colorization -d "Force color and decorations" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l list-languages -d "Display list of supported languages for syntax highlighting" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s h -d "Print a concise overview" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -l list-themes -d "Display a list of supported themes for syntax highlighting" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l help -f -d "Print all help information" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -s m -l map-syntax -x -d "<from:to> Map a file extension or file name to an existing syntax" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s H -l highlight-line -x -d "Highlight line(s) N[:M]" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s n -l number -d "Only show line numbers, no other decorations. Alias for '--style=numbers'" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l ignored-suffix -x -d "Ignore extension" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l pager -x -d "<command> Specify which pager program to use (default: less)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l italic-text -x -a "$italic_text_opts" -d "When to use italic text in the output" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l paging -xka "auto never always" -d "Specify when to use the pager (default: auto)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s l -l language -x -k -a "(__bat_complete_list_languages)" -d "Set the syntax highlighting language" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s p -l plain -d "Only show plain style, no decorations. Alias for '--style=plain'" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s r -l line-range -x -d "Only print lines [M]:[N] (either optional)" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s P -d "Disable paging. Alias for '--paging=never'" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l list-languages -f -d "List syntax highlighting languages" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -s A -l show-all -d "Show non-printable characters like space/tab/newline" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l list-themes -f -d "List syntax highlighting themes" -n __fish_is_first_arg complete -c {{PROJECT_EXECUTABLE}} -l style -xka "auto full plain changes header grid rule numbers snip" -d "Comma-separated list of style elements or presets to display with file contents" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s m -l map-syntax -x -a "(__bat_complete_map_syntax)" -d "Map <glob pattern>:<language syntax>" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l tabs -x -d "<T> Set the tab width to T spaces (width of 0 passes tabs through directly)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s n -l number -d "Only show line numbers, no other decorations" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l terminal-width -x -d "<width> Explicitly set terminal width; Prefix with '+' or '-' to offset (default width is auto determined)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l pager -x -a "$pager_opts" -d "Which pager to use" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l theme -xka "({{PROJECT_EXECUTABLE}} --list-themes | cat)" -d "Set the theme for syntax highlighting" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l paging -x -a "$paging_opts" -d "When to use the pager" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s u -l unbuffered -d "POSIX-compliant unbuffered output. Option is ignored" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s p -l plain -d "Disable decorations" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -s V -l version -d "Show version information" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -o pp -d "Disable decorations and paging" -n __bat_no_excl_args complete -c {{PROJECT_EXECUTABLE}} -l wrap -xka "auto never character" -d "<mode> Specify the text-wrapping mode (default: auto)" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -s P -d "Disable paging" -n __bat_no_excl_args
complete -c $bat -s A -l show-all -d "Show non-printable characters" -n __bat_no_excl_args
complete -c $bat -l style -x -k -a "(__fish_complete_list , __bat_style_opts)" -d "Specify which non-content elements to display" -n __bat_no_excl_args
complete -c $bat -l tabs -x -a "$tabs_opts" -d "Set tab width" -n __bat_no_excl_args
complete -c $bat -l terminal-width -x -d "Set terminal <width>, +<offset>, or -<offset>" -n __bat_no_excl_args
complete -c $bat -l theme -x -a "(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme" -n __bat_no_excl_args
complete -c $bat -s V -l version -f -d "Show version information" -n __fish_is_first_arg
complete -c $bat -l wrap -x -a "$wrap_opts" -d "Text-wrapping mode" -n __bat_no_excl_args
# Sub-command 'cache' completions # Sub-command 'cache' completions
complete -c $bat -a cache -d "Modify the syntax/language definition cache" -n __fish_use_subcommand complete -c {{PROJECT_EXECUTABLE}} -a "cache" -d "Modify the syntax/language definition cache" -n "not __fish_seen_subcommand_from cache"
complete -c $bat -l build -f -d "Parse new definitions into cache" -n __bat_cache_no_excl complete -c {{PROJECT_EXECUTABLE}} -l build -f -d "Parse syntaxes/language definitions into cache" -n "__fish_seen_subcommand_from cache"
complete -c $bat -l clear -f -d "Reset definitions to defaults" -n __bat_cache_no_excl complete -c {{PROJECT_EXECUTABLE}} -l clear -f -d "Reset syntaxes/language definitions to default settings" -n "__fish_seen_subcommand_from cache"
complete -c $bat -l blank -f -d "Create new data instead of appending" -n "__bat_cache_subcommand; and not __fish_seen_argument -l clear"
complete -c $bat -l source -x -a "(__fish_complete_directories)" -d "Load syntaxes and themes from DIR" -n "__bat_cache_subcommand; and not __fish_seen_argument -l clear"
complete -c $bat -l target -x -a "(__fish_complete_directories)" -d "Store cache in DIR" -n __bat_cache_subcommand
complete -c $bat -l acknowledgements -d "Build acknowledgements.bin" -n __bat_cache_no_excl
complete -c $bat -s h -d "Print a concise overview of $bat-cache help" -n __bat_cache_no_excl
complete -c $bat -l help -f -d "Print all $bat-cache help" -n __bat_cache_no_excl
# vim:ft=fish

View File

@@ -75,7 +75,7 @@ _{{PROJECT_EXECUTABLE}}_main() {
;; ;;
style) style)
_values -s , 'style' default auto full plain changes header header-filename header-filesize grid rule numbers snip _values -s , 'style' auto full plain changes header grid rule numbers snip
;; ;;
esac esac
} }

View File

@@ -29,7 +29,7 @@ control the width of the tab\-placeholders.
.IP .IP
Only show plain style, no decorations. This is an alias for Only show plain style, no decorations. This is an alias for
\&'\-\-style=plain'. When '\-p' is used twice ('\-pp'), it also disables \&'\-\-style=plain'. When '\-p' is used twice ('\-pp'), it also disables
automatic paging (alias for '\-\-style=plain \fB\-\-paging\fR=\fI\,never\/\fR'). automatic paging (alias for '\-\-style=plain \fB\-\-pager\fR=\fI\,never\/\fR').
.HP .HP
\fB\-l\fR, \fB\-\-language\fR <language> \fB\-l\fR, \fB\-\-language\fR <language>
.IP .IP
@@ -146,8 +146,7 @@ Configure which elements (line numbers, file headers, grid borders, Git modifica
of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full'). of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full').
To set a default style, add the '\-\-style=".."' option to the configuration file or To set a default style, add the '\-\-style=".."' option to the configuration file or
export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
values: *default*, full, auto, plain, changes, header, header-filename, header-filesize, grid, values: *full*, auto, plain, changes, header, grid, rule, numbers, snip.
rule, numbers, snip.
.HP .HP
\fB\-r\fR, \fB\-\-line\-range\fR <N:M>... \fB\-r\fR, \fB\-\-line\-range\fR <N:M>...
.IP .IP

BIN
assets/syntaxes.bin vendored

Binary file not shown.

View File

@@ -95,7 +95,7 @@ contexts:
fstab_dump: fstab_dump:
- include: comment - include: comment
- match: '\s*[012]\s*' - match: '\s*[01]\s*'
comment: dump field comment: dump field
scope: constant.numeric scope: constant.numeric
set: fstab_pass set: fstab_pass
@@ -107,7 +107,7 @@ contexts:
fstab_pass: fstab_pass:
- include: comment - include: comment
- match: '\s*[012]\s*' - match: '\s*[01]\s*'
comment: pass field comment: pass field
scope: constant.numeric scope: constant.numeric
set: expected_eol set: expected_eol

View File

@@ -5,8 +5,8 @@ name: INI
file_extensions: file_extensions:
- ini - ini
- INI - INI
- "inf" - inf
- "INF" - INF
- reg - reg
- REG - REG
- lng - lng

View File

@@ -4,8 +4,6 @@
name: TypeScript name: TypeScript
file_extensions: file_extensions:
- ts - ts
- mts
- cts
scope: source.ts scope: source.ts
contexts: contexts:
main: main:

View File

@@ -6,16 +6,8 @@ file_extensions:
scope: text.log scope: text.log
variables: variables:
ipv4_part: (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) ipv4_part: (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
hours_minutes_seconds: (?:[01]\d|2[0-3]):(?:[0-5]\d):(?:[0-5]\d)
error: \b(?i:fail(?:ure|ed)?|error|exception|fatal|critical)\b
warning: \b(?i:warn(?:ing)?)\b
info: \b(?i:info)\b
debug: \b(?i:debug)\b
contexts: contexts:
main: main:
- include: log_level_lines
- include: main_without_log_level_line
main_without_log_level_line:
- match: (\w+)(=) - match: (\w+)(=)
captures: captures:
1: variable.parameter.log 1: variable.parameter.log
@@ -25,85 +17,31 @@ contexts:
captures: captures:
1: punctuation.definition.string.begin.log 1: punctuation.definition.string.begin.log
3: punctuation.definition.string.end.log 3: punctuation.definition.string.end.log
- match: \" - match: (")([^"]*)(")
scope: string.quoted.double.log
captures: captures:
1: punctuation.definition.string.begin.log 1: punctuation.definition.string.begin.log
push: double_quoted_string 3: punctuation.definition.string.end.log
- include: dates - include: dates
- include: ip_addresses - include: ip_addresses
- include: numbers - include: numbers
- include: log_levels - match: \b(?i:fail(?:ure|ed)?|error|exception)\b
scope: markup.error.log
- match: \b(?i:warn(?:ing)?)\b
scope: markup.warning.log
#- include: scope:text.html.markdown#autolink-inet #- include: scope:text.html.markdown#autolink-inet
- match: \b\w+:/{2,3} - match: \b\w+:/{2,3}
scope: markup.underline.link.scheme.log scope: markup.underline.link.scheme.log
push: url-host push: url-host
log_level_lines:
- match: ^(?=.*{{error}})
push:
- error_line
- main_pop_at_eol
- match: ^(?=.*{{warning}})
push:
- warning_line
- main_pop_at_eol
- match: ^(?=.*{{info}})
push:
- info_line
- main_pop_at_eol
- match: ^(?=.*{{debug}})
push:
- debug_line
- main_pop_at_eol
log_levels:
- match: '{{error}}'
scope: markup.error.log
- match: '{{warning}}'
scope: markup.warning.log
- match: '{{info}}'
scope: markup.info.log
- match: '{{debug}}'
scope: markup.info.log
error_line:
- meta_scope: meta.annotation.error-line.log
- include: immediately_pop
warning_line:
- meta_scope: meta.annotation.warning-line.log
- include: immediately_pop
info_line:
- meta_scope: meta.annotation.info-line.log
- include: immediately_pop
debug_line:
- meta_scope: meta.annotation.debug-line.log
- include: immediately_pop
immediately_pop:
- match: ''
pop: true
pop_at_eol:
- match: $
pop: true
main_pop_at_eol:
- include: main_without_log_level_line
- include: pop_at_eol
dates: dates:
- match: \b\d{4}-\d{2}-\d{2}(?=\b|T) - match: \b\d{4}-\d{2}-\d{2}\b
scope: meta.date.log meta.number.integer.decimal.log constant.numeric.value.log scope: meta.date.log meta.number.integer.decimal.log constant.numeric.value.log
push: maybe_date_time_separator - match: \b\d{4}/\d{2}/\d{2}\b
- match: \b\d{4}/\d{2}/\d{2}(?=\b|T)
scope: meta.date.log meta.number.integer.decimal.log constant.numeric.value.log scope: meta.date.log meta.number.integer.decimal.log constant.numeric.value.log
push: maybe_date_time_separator - match: \b(?:[01]\d|2[0-3]):(?:[0-5]\d):(?:[0-5]\d)(?:(\.)\d{3})?\b
- match: \b(?={{hours_minutes_seconds}})
push: time
time:
- match: (?:{{hours_minutes_seconds}})(?:(\.)\d{3})?\b
scope: meta.time.log meta.number.integer.decimal.log constant.numeric.value.log scope: meta.time.log meta.number.integer.decimal.log constant.numeric.value.log
captures: captures:
1: punctuation.separator.decimal.log 1: punctuation.separator.decimal.log
- include: immediately_pop
maybe_date_time_separator:
- match: T(?={{hours_minutes_seconds}})
scope: meta.date.log meta.time.log keyword.other.log
set: time
- include: immediately_pop
ip_addresses: ip_addresses:
- match: \b(?=(?:{{ipv4_part}}\.){3}{{ipv4_part}}\b) - match: \b(?=(?:{{ipv4_part}}\.){3}{{ipv4_part}}\b)
push: push:
@@ -112,7 +50,8 @@ contexts:
scope: constant.numeric.value.log scope: constant.numeric.value.log
- match: \. - match: \.
scope: punctuation.separator.sequence.log scope: punctuation.separator.sequence.log
- include: immediately_pop - match: ''
pop: true
- match: (?=(?:\h{0,4}:){2,6}\h{1,4}\b) - match: (?=(?:\h{0,4}:){2,6}\h{1,4}\b)
push: push:
- meta_scope: meta.ipaddress.v6.log meta.number.integer.hexadecimal.log - meta_scope: meta.ipaddress.v6.log meta.number.integer.hexadecimal.log
@@ -120,7 +59,8 @@ contexts:
scope: constant.numeric.value.log scope: constant.numeric.value.log
- match: ':' - match: ':'
scope: punctuation.separator.sequence.log scope: punctuation.separator.sequence.log
- include: immediately_pop - match: ''
pop: true
numbers: numbers:
- match: \b(0x)(\h+)(?:(\.)(\h+))?\b - match: \b(0x)(\h+)(?:(\.)(\h+))?\b
scope: meta.number.float.hexadecimal.log scope: meta.number.float.hexadecimal.log
@@ -172,13 +112,5 @@ contexts:
pop: true pop: true
- match: '[^?!.,:*_~\s<&()%]+|\S' - match: '[^?!.,:*_~\s<&()%]+|\S'
scope: markup.underline.link.path.log scope: markup.underline.link.path.log
- include: immediately_pop - match: ''
double_quoted_string:
- meta_scope: string.quoted.double.log
- match: \\"
scope: constant.character.escape.log
- match: \\n
scope: constant.character.escape.log
- match: \"
scope: punctuation.definition.string.end.log
pop: true pop: true

BIN
assets/themes.bin vendored

Binary file not shown.

View File

@@ -181,7 +181,7 @@ man 2 select
## インストール ## インストール
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) [![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### On Ubuntu (`apt` を使用) ### On Ubuntu (`apt` を使用)
*... や他のDebianベースのLinuxディストリビューション* *... や他のDebianベースのLinuxディストリビューション*
@@ -366,7 +366,7 @@ ansible-galaxy install aeimer.install_bat
### From source ### From source
`bat` をソースからビルドしたいならば、Rust 1.60.0 以上の環境が必要です。 `bat` をソースからビルドしたいならば、Rust 1.51 以上の環境が必要です。
`cargo` を使用してビルドすることができます: `cargo` を使用してビルドすることができます:
```bash ```bash

View File

@@ -416,7 +416,7 @@ scoop install bat
### 소스에서 ### 소스에서
`bat`의 소스를 빌드하기 위해서는, Rust 1.60.0 이상이 필요합니다. `bat`의 소스를 빌드하기 위해서는, Rust 1.51 이상이 필요합니다.
`cargo`를 이용해 전부 빌드할 수 있습니다: `cargo`를 이용해 전부 빌드할 수 있습니다:
```bash ```bash

View File

@@ -160,7 +160,7 @@ man 2 select
## Установка ## Установка
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions) [![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### Ubuntu (с помощью `apt`) ### Ubuntu (с помощью `apt`)
*... и другие дистрибутивы основанные на Debian.* *... и другие дистрибутивы основанные на Debian.*
@@ -344,7 +344,7 @@ ansible-galaxy install aeimer.install_bat
### Из исходников ### Из исходников
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.60.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать: Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.51 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
```bash ```bash
cargo install --locked bat cargo install --locked bat

View File

@@ -372,7 +372,7 @@ scoop install bat
### 从源码编译 ### 从源码编译
如果你想要自己构建`bat`那么你需要安装有高于1.58.0版本的 Rust。 如果你想要自己构建`bat`那么你需要安装有高于1.51版本的 Rust。
使用以下命令编译。 使用以下命令编译。
@@ -550,7 +550,7 @@ bat --generate-config-file
# 在终端中以斜体输出文本(不是所有终端都支持) # 在终端中以斜体输出文本(不是所有终端都支持)
--italic-text=always --italic-text=always
# 使用 C++ 语法来给 Arduino 的 .ino 文件提供高亮 # 使用 C++ 语法来给 Ardiuno 的 .ino 文件提供高亮
--map-syntax "*.ino:C++" --map-syntax "*.ino:C++"
``` ```

View File

@@ -4,17 +4,17 @@ The following table tries to give an overview *from `bat`s perspective*, i.e. we
categories which are relevant for `bat`. Some of these projects have completely different goals and categories which are relevant for `bat`. Some of these projects have completely different goals and
if you are not looking for a program like `bat`, this comparison might not be for you. if you are not looking for a program like `bat`, this comparison might not be for you.
| | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) | [clp](https://github.com/jpe90/clp) | | | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) |
|----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------| |----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|
| Drop-in `cat` replacement | :heavy_check_mark: [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: | :x: | | Drop-in `cat` replacement | :heavy_check_mark: [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: |
| Git integration | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | | Git integration | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
| Automatic paging | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: | :x: | :x: | :x: | | Automatic paging | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: | :x: | :x: |
| Languages (circa) | 150 | 300 | 200 | 7 | 80 | 130 | 30 | 130 | 150 | | Languages (circa) | 150 | 300 | 200 | 7 | 80 | 130 | 30 | 130 |
| Extensible (languages, themes) | :heavy_check_mark: | (:heavy_check_mark:) | (:heavy_check_mark:) | :x: | (:heavy_check_mark:) | :x: | :x: | :x: | :heavy_check_mark: | | Extensible (languages, themes) | :heavy_check_mark: | (:heavy_check_mark:) | (:heavy_check_mark:) | :x: | (:heavy_check_mark:) | :x: | :x: | :x: |
| Advanced highlighting (e.g. nested syntaxes) | :heavy_check_mark: | :heavy_check_mark: | (:heavy_check_mark:) ? | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Advanced highlighting (e.g. nested syntaxes) | :heavy_check_mark: | :heavy_check_mark: | (:heavy_check_mark:) ? | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| Execution time [ms] (`jquery-3.3.1.js`) | 422 | 455 | 299 | 39 | 208 | 287 | 128 | 740 | 22 | | Execution time [ms] (`jquery-3.3.1.js`) | 624 | 789 | 400 | 80 | 300 | 316 | 157 | 695 |
| Execution time [ms] (`miniz.c`) | 27 | 169 | 19 | 4 | 36 | 131 | 58 | 231 | 4 | | Execution time [ms] (`miniz.c`) | 66 | 656 | 26 | 8 | 53 | 141 | 75 | 254 |
| Execution time [ms] (957 kB XML file) | 215 | 296 | 236 | 165 | 83 | 412 | 135 | 386 | 127 | | Execution time [ms] (370 kB XML file) | 238 | 487 | 129 | 111 | 110 | 339 | 147 | 359 |
If you think that some entries in this table are outdated or wrong, please open a ticket or pull If you think that some entries in this table are outdated or wrong, please open a ticket or pull
request. request.
@@ -49,7 +49,6 @@ cmd_source_highlight="source-highlight --failsafe --infer-lang -f esc -i '$SRC'"
cmd_hicat="hicat '$SRC'" cmd_hicat="hicat '$SRC'"
cmd_coderay="coderay '$SRC'" cmd_coderay="coderay '$SRC'"
cmd_rouge="rougify '$SRC'" cmd_rouge="rougify '$SRC'"
cmd_clp="clp '$SRC'"
hyperfine --warmup 3 \ hyperfine --warmup 3 \
"$cmd_bat" \ "$cmd_bat" \
@@ -61,5 +60,4 @@ hyperfine --warmup 3 \
"$cmd_hicat" \ "$cmd_hicat" \
"$cmd_coderay" \ "$cmd_coderay" \
"$cmd_rouge" \ "$cmd_rouge" \
"$cmd_clp" \
``` ```

View File

@@ -1,5 +1,16 @@
# Release checklist # Release checklist
## Dependencies
See this page for a good overview: https://deps.rs/repo/github/sharkdp/bat
- [ ] Optional: update dependencies with `cargo update`. This is also done by
dependabot, so it is not strictly necessary.
- [ ] Install [cargo-outdated](https://crates.io/crates/cargo-outdated). Check
for outdated dependencies with `cargo outdated --root-deps-only` and
decide for each of them whether we want to (manually) upgrade. This will
require changes to `Cargo.toml`.
## Version bump ## Version bump
- [ ] Update version in `Cargo.toml`. Run `cargo build` to update `Cargo.lock`. - [ ] Update version in `Cargo.toml`. Run `cargo build` to update `Cargo.lock`.
@@ -7,22 +18,21 @@
- [ ] Find the current min. supported Rust version by running - [ ] Find the current min. supported Rust version by running
`grep '^\s*MIN_SUPPORTED_RUST_VERSION' .github/workflows/CICD.yml`. `grep '^\s*MIN_SUPPORTED_RUST_VERSION' .github/workflows/CICD.yml`.
- [ ] Update the version and the min. supported Rust version in `README.md` and - [ ] Update the version and the min. supported Rust version in `README.md` and
`doc/README-*.md`. Check with `doc/README-*.md`. Check with `git grep -i 'rust.*1\.'` and
`git grep -i -e 'rust.*1\.' -e '1\..*rust' | grep README | grep -v tests/`. `git grep -i '1\..*rust'`.
- [ ] Update `CHANGELOG.md`. Introduce a section for the new release. - [ ] Update `CHANGELOG.md`. Introduce a section for the new release.
## Update syntaxes and themes (build assets) ## Update syntaxes and themes (build assets)
- [ ] Install the latest master version (`cargo clean && cargo install --locked -f --path .`) and make - [ ] Install the latest master version (`cargo install -f --path .`) and make
sure that it is available on the `PATH` (`bat --version` should show the sure that it is available on the `PATH` (`bat --version` should show the
new version). new version).
- [ ] Run `assets/create.sh` and check in the binary asset files. - [ ] Run `assets/create.sh` and check in the binary asset files.
## Documentation ## Documentation
- [ ] Review `-h`, `--help`, and the `man` page. All of these are shown in - [ ] Review the `-h` and `--help` texts
the output of the CI job called *Documentation*, so look there. - [ ] Review the `man` page
The CI workflow corresponding to the tip of the master branch is a good place to look.
## Pre-release checks ## Pre-release checks
@@ -31,14 +41,13 @@
- [ ] Optional: manually test the new features and command-line options. To do - [ ] Optional: manually test the new features and command-line options. To do
this, install the latest `bat` version again (to include the new syntaxes this, install the latest `bat` version again (to include the new syntaxes
and themes). and themes).
- [ ] Run `cargo publish --dry-run` to make sure that it will - [ ] Run `cargo publish --dry-run --allow-dirty` to make sure that it will
succeed later (after creating the GitHub release). succeed later (after creating the GitHub release).
## Release ## Release
- [ ] Create a tag and push it: `git tag vX.Y.Z; git push origin tag vX.Y.Z`. - [ ] Create a tag and push it: `git tag vX.Y.Z; git push origin tag vX.Y.Z`.
This will trigger the deployment via GitHub Actions. This will trigger the deployment via GitHub Actions.
REMINDER: If your `origin` is a fork, don't forget to push to e.g. `upstream` instead!
- [ ] Go to https://github.com/sharkdp/bat/releases/new to create the new - [ ] Go to https://github.com/sharkdp/bat/releases/new to create the new
release. Select the new tag and also use it as the release title. For the release. Select the new tag and also use it as the release title. For the
release notes, copy the corresponding section from `CHANGELOG.md` and release notes, copy the corresponding section from `CHANGELOG.md` and
@@ -51,23 +60,4 @@
## Post-release ## Post-release
- [ ] Prepare a new "unreleased" section at the top of `CHANGELOG.md`. - [ ] Prepare a new (empty) "unreleased" section at the top of `CHANGELOG.md`.
Put this at the top:
```
# unreleased
## Features
## Bugfixes
## Other
## Syntaxes
## Themes
## `bat` as a library
```

View File

@@ -1,7 +1,5 @@
## Sponsors ## Sponsors
`bat` development is sponsored by many individuals and companies. Thank you very much!
Please note, that being sponsored does not affect the individuality of the `bat` Please note, that being sponsored does not affect the individuality of the `bat`
project or affect the maintainers' actions in any way. project or affect the maintainers' actions in any way.
We remain impartial and continue to assess pull requests solely on merit - the We remain impartial and continue to assess pull requests solely on merit - the

View File

@@ -1,4 +1,4 @@
/// A simple program that lists all supported syntaxes and themes. /// A simple program that prints its own source code using the bat library
use bat::PrettyPrinter; use bat::PrettyPrinter;
fn main() { fn main() {

View File

@@ -1 +0,0 @@
# Defaults are used

View File

@@ -43,9 +43,8 @@ pub struct SyntaxReferenceInSet<'a> {
pub syntax_set: &'a SyntaxSet, pub syntax_set: &'a SyntaxSet,
} }
/// Lazy-loaded syntaxes are already compressed, and we don't want to compress /// Compress for size of ~700 kB instead of ~4600 kB at the cost of ~30% longer deserialization time
/// already compressed data. pub(crate) const COMPRESS_SYNTAXES: bool = true;
pub(crate) const COMPRESS_SYNTAXES: bool = false;
/// We don't want to compress our [LazyThemeSet] since the lazy-loaded themes /// We don't want to compress our [LazyThemeSet] since the lazy-loaded themes
/// within it are already compressed, and compressing another time just makes /// within it are already compressed, and compressing another time just makes
@@ -69,57 +68,10 @@ impl HighlightingAssets {
} }
} }
/// The default theme.
///
/// ### Windows and Linux
///
/// Windows and most Linux distributions has a dark terminal theme by
/// default. On these platforms, this function always returns a theme that
/// looks good on a dark background.
///
/// ### macOS
///
/// On macOS the default terminal background is light, but it is common that
/// Dark Mode is active, which makes the terminal background dark. On this
/// platform, the default theme depends on
/// ```bash
/// defaults read -globalDomain AppleInterfaceStyle
/// ````
/// To avoid the overhead of the check on macOS, simply specify a theme
/// explicitly via `--theme`, `BAT_THEME`, or `~/.config/bat`.
///
/// See <https://github.com/sharkdp/bat/issues/1746> and
/// <https://github.com/sharkdp/bat/issues/1928> for more context.
pub fn default_theme() -> &'static str { pub fn default_theme() -> &'static str {
#[cfg(not(target_os = "macos"))]
{
Self::default_dark_theme()
}
#[cfg(target_os = "macos")]
{
if macos_dark_mode_active() {
Self::default_dark_theme()
} else {
Self::default_light_theme()
}
}
}
/**
* The default theme that looks good on a dark background.
*/
fn default_dark_theme() -> &'static str {
"Monokai Extended" "Monokai Extended"
} }
/**
* The default theme that looks good on a light background.
*/
#[cfg(target_os = "macos")]
fn default_light_theme() -> &'static str {
"Monokai Extended Light"
}
pub fn from_cache(cache_path: &Path) -> Result<Self> { pub fn from_cache(cache_path: &Path) -> Result<Self> {
Ok(HighlightingAssets::new( Ok(HighlightingAssets::new(
SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")), SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")),
@@ -399,16 +351,6 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
.map_err(|_| format!("Could not parse cached {}", description).into()) .map_err(|_| format!("Could not parse cached {}", description).into())
} }
#[cfg(target_os = "macos")]
fn macos_dark_mode_active() -> bool {
let mut defaults_cmd = std::process::Command::new("defaults");
defaults_cmd.args(&["read", "-globalDomain", "AppleInterfaceStyle"]);
match defaults_cmd.output() {
Ok(output) => output.stdout == b"Dark\n",
Err(_) => true,
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -639,22 +581,13 @@ mod tests {
} }
#[test] #[test]
fn syntax_detection_is_case_insensitive() { fn syntax_detection_is_case_sensitive() {
let mut test = SyntaxDetectionTest::new(); let mut test = SyntaxDetectionTest::new();
assert_eq!(test.syntax_for_file("README.md"), "Markdown"); assert_ne!(test.syntax_for_file("README.MD"), "Markdown");
assert_eq!(test.syntax_for_file("README.mD"), "Markdown");
assert_eq!(test.syntax_for_file("README.Md"), "Markdown");
assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
// Adding a mapping for "MD" in addition to "md" should not break the mapping
test.syntax_mapping test.syntax_mapping
.insert("*.MD", MappingTarget::MapTo("Markdown")) .insert("*.MD", MappingTarget::MapTo("Markdown"))
.ok(); .ok();
assert_eq!(test.syntax_for_file("README.md"), "Markdown");
assert_eq!(test.syntax_for_file("README.mD"), "Markdown");
assert_eq!(test.syntax_for_file("README.Md"), "Markdown");
assert_eq!(test.syntax_for_file("README.MD"), "Markdown"); assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
} }

View File

@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::error::*; use crate::error::*;
#[derive(Debug, PartialEq, Eq, Default, Serialize, Deserialize)] #[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct AssetsMetadata { pub struct AssetsMetadata {
bat_version: Option<String>, bat_version: Option<String>,
creation_time: Option<SystemTime>, creation_time: Option<SystemTime>,

View File

@@ -1,4 +1,3 @@
use std::fmt::Write;
use std::fs::read_to_string; use std::fs::read_to_string;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@@ -125,7 +124,7 @@ fn append_to_acknowledgements(
relative_path: &str, relative_path: &str,
license_text: &str, license_text: &str,
) { ) {
write!(acknowledgements, "## {}\n\n{}", relative_path, license_text).ok(); acknowledgements.push_str(&format!("## {}\n\n{}", relative_path, license_text));
// Make sure the last char is a newline to not mess up formatting later // Make sure the last char is a newline to not mess up formatting later
if acknowledgements if acknowledgements

View File

@@ -1,6 +1,6 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::env; use std::env;
use std::path::{Path, PathBuf}; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use atty::{self, Stream}; use atty::{self, Stream};
@@ -32,7 +32,7 @@ fn is_truecolor_terminal() -> bool {
} }
pub struct App { pub struct App {
pub matches: ArgMatches, pub matches: ArgMatches<'static>,
interactive_output: bool, interactive_output: bool,
} }
@@ -49,7 +49,7 @@ impl App {
}) })
} }
fn matches(interactive_output: bool) -> Result<ArgMatches> { fn matches(interactive_output: bool) -> Result<ArgMatches<'static>> {
let args = if wild::args_os().nth(1) == Some("cache".into()) let args = if wild::args_os().nth(1) == Some("cache".into())
|| wild::args_os().any(|arg| arg == "--no-config") || wild::args_os().any(|arg| arg == "--no-config")
{ {
@@ -79,13 +79,13 @@ impl App {
pub fn config(&self, inputs: &[Input]) -> Result<Config> { pub fn config(&self, inputs: &[Input]) -> Result<Config> {
let style_components = self.style_components()?; let style_components = self.style_components()?;
let paging_mode = match self.matches.get_one::<String>("paging").map(|s| s.as_str()) { let paging_mode = match self.matches.value_of("paging") {
Some("always") => PagingMode::Always, Some("always") => PagingMode::Always,
Some("never") => PagingMode::Never, Some("never") => PagingMode::Never,
Some("auto") | None => { Some("auto") | None => {
// If we have -pp as an option when in auto mode, the pager should be disabled. // 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; let extra_plain = self.matches.occurrences_of("plain") > 1;
if extra_plain || self.matches.get_flag("no-paging") { if extra_plain || self.matches.is_present("no-paging") {
PagingMode::Never PagingMode::Never
} else if inputs.iter().any(Input::is_stdin) { } else if inputs.iter().any(Input::is_stdin) {
// If we are reading from stdin, only enable paging if we write to an // If we are reading from stdin, only enable paging if we write to an
@@ -107,13 +107,13 @@ impl App {
let mut syntax_mapping = SyntaxMapping::builtin(); let mut syntax_mapping = SyntaxMapping::builtin();
if let Some(values) = self.matches.get_many::<String>("ignored-suffix") { if let Some(values) = self.matches.values_of("ignored-suffix") {
for suffix in values { for suffix in values {
syntax_mapping.insert_ignored_suffix(suffix); syntax_mapping.insert_ignored_suffix(suffix);
} }
} }
if let Some(values) = self.matches.get_many::<String>("map-syntax") { if let Some(values) = self.matches.values_of("map-syntax") {
for from_to in values { for from_to in values {
let parts: Vec<_> = from_to.split(':').collect(); let parts: Vec<_> = from_to.split(':').collect();
@@ -125,43 +125,36 @@ impl App {
} }
} }
let maybe_term_width = self let maybe_term_width = self.matches.value_of("terminal-width").and_then(|w| {
.matches if w.starts_with('+') || w.starts_with('-') {
.get_one::<String>("terminal-width") // Treat argument as a delta to the current terminal width
.and_then(|w| { w.parse().ok().map(|delta: i16| {
if w.starts_with('+') || w.starts_with('-') { let old_width: u16 = Term::stdout().size().1;
// Treat argument as a delta to the current terminal width let new_width: i32 = i32::from(old_width) + i32::from(delta);
w.parse().ok().map(|delta: i16| {
let old_width: u16 = Term::stdout().size().1;
let new_width: i32 = i32::from(old_width) + i32::from(delta);
if new_width <= 0 { if new_width <= 0 {
old_width as usize old_width as usize
} else { } else {
new_width as usize new_width as usize
} }
}) })
} else { } else {
w.parse().ok() w.parse().ok()
} }
}); });
Ok(Config { Ok(Config {
true_color: is_truecolor_terminal(), true_color: is_truecolor_terminal(),
language: self language: self.matches.value_of("language").or_else(|| {
.matches if self.matches.is_present("show-all") {
.get_one::<String>("language") Some("show-nonprintable")
.map(|s| s.as_str()) } else {
.or_else(|| { None
if self.matches.get_flag("show-all") { }
Some("show-nonprintable") }),
} else { show_nonprintable: self.matches.is_present("show-all"),
None
}
}),
show_nonprintable: self.matches.get_flag("show-all"),
wrapping_mode: if self.interactive_output || maybe_term_width.is_some() { wrapping_mode: if self.interactive_output || maybe_term_width.is_some() {
match self.matches.get_one::<String>("wrap").map(|s| s.as_str()) { match self.matches.value_of("wrap") {
Some("character") => WrappingMode::Character, Some("character") => WrappingMode::Character,
Some("never") => WrappingMode::NoWrapping(true), Some("never") => WrappingMode::NoWrapping(true),
Some("auto") | None => { Some("auto") | None => {
@@ -178,8 +171,8 @@ impl App {
// There's no point in wrapping when this is the case. // There's no point in wrapping when this is the case.
WrappingMode::NoWrapping(false) WrappingMode::NoWrapping(false)
}, },
colored_output: self.matches.get_flag("force-colorization") colored_output: self.matches.is_present("force-colorization")
|| match self.matches.get_one::<String>("color").map(|s| s.as_str()) { || match self.matches.value_of("color") {
Some("always") => true, Some("always") => true,
Some("never") => false, Some("never") => false,
Some("auto") => env::var_os("NO_COLOR").is_none() && self.interactive_output, Some("auto") => env::var_os("NO_COLOR").is_none() && self.interactive_output,
@@ -188,16 +181,12 @@ impl App {
paging_mode, paging_mode,
term_width: maybe_term_width.unwrap_or(Term::stdout().size().1 as usize), term_width: maybe_term_width.unwrap_or(Term::stdout().size().1 as usize),
loop_through: !(self.interactive_output loop_through: !(self.interactive_output
|| self.matches.get_one::<String>("color").map(|s| s.as_str()) == Some("always") || self.matches.value_of("color") == Some("always")
|| self || self.matches.value_of("decorations") == Some("always")
.matches || self.matches.is_present("force-colorization")),
.get_one::<String>("decorations")
.map(|s| s.as_str())
== Some("always")
|| self.matches.get_flag("force-colorization")),
tab_width: self tab_width: self
.matches .matches
.get_one::<String>("tabs") .value_of("tabs")
.map(String::from) .map(String::from)
.or_else(|| env::var("BAT_TABS").ok()) .or_else(|| env::var("BAT_TABS").ok())
.and_then(|t| t.parse().ok()) .and_then(|t| t.parse().ok())
@@ -210,7 +199,7 @@ impl App {
), ),
theme: self theme: self
.matches .matches
.get_one::<String>("theme") .value_of("theme")
.map(String::from) .map(String::from)
.or_else(|| env::var("BAT_THEME").ok()) .or_else(|| env::var("BAT_THEME").ok())
.map(|s| { .map(|s| {
@@ -221,19 +210,19 @@ impl App {
} }
}) })
.unwrap_or_else(|| String::from(HighlightingAssets::default_theme())), .unwrap_or_else(|| String::from(HighlightingAssets::default_theme())),
visible_lines: match self.matches.contains_id("diff") && self.matches.get_flag("diff") { visible_lines: match self.matches.is_present("diff") {
#[cfg(feature = "git")] #[cfg(feature = "git")]
true => VisibleLines::DiffContext( true => VisibleLines::DiffContext(
self.matches self.matches
.get_one::<String>("diff-context") .value_of("diff-context")
.and_then(|t| t.parse().ok()) .and_then(|t| t.parse().ok())
.unwrap_or(2), .unwrap_or(2),
), ),
_ => VisibleLines::Ranges( _ => VisibleLines::Ranges(
self.matches self.matches
.get_many::<String>("line-range") .values_of("line-range")
.map(|vs| vs.map(|s| LineRange::from(s.as_str())).collect()) .map(|vs| vs.map(LineRange::from).collect())
.transpose()? .transpose()?
.map(LineRanges::from) .map(LineRanges::from)
.unwrap_or_default(), .unwrap_or_default(),
@@ -241,47 +230,45 @@ impl App {
}, },
style_components, style_components,
syntax_mapping, syntax_mapping,
pager: self.matches.get_one::<String>("pager").map(|s| s.as_str()), pager: self.matches.value_of("pager"),
use_italic_text: self use_italic_text: self.matches.value_of("italic-text") == Some("always"),
.matches
.get_one::<String>("italic-text")
.map(|s| s.as_str())
== Some("always"),
highlighted_lines: self highlighted_lines: self
.matches .matches
.get_many::<String>("highlight-line") .values_of("highlight-line")
.map(|ws| ws.map(|s| LineRange::from(s.as_str())).collect()) .map(|ws| ws.map(LineRange::from).collect())
.transpose()? .transpose()?
.map(LineRanges::from) .map(LineRanges::from)
.map(HighlightedLineRanges) .map(HighlightedLineRanges)
.unwrap_or_default(), .unwrap_or_default(),
use_custom_assets: !self.matches.get_flag("no-custom-assets"), use_custom_assets: !self.matches.is_present("no-custom-assets"),
}) })
} }
pub fn inputs(&self) -> Result<Vec<Input>> { pub fn inputs(&self) -> Result<Vec<Input>> {
// verify equal length of file-names and input FILEs
match self.matches.values_of("file-name") {
Some(ref filenames)
if self.matches.values_of_os("FILE").is_some()
&& filenames.len() != self.matches.values_of_os("FILE").unwrap().len() =>
{
return Err("Must be one file name per input type.".into());
}
_ => {}
}
let filenames: Option<Vec<&Path>> = self let filenames: Option<Vec<&Path>> = self
.matches .matches
.get_many::<PathBuf>("file-name") .values_of_os("file-name")
.map(|vs| vs.map(|p| p.as_path()).collect::<Vec<_>>()); .map(|values| values.map(Path::new).collect());
let files: Option<Vec<&Path>> = self
.matches
.get_many::<PathBuf>("FILE")
.map(|vs| vs.map(|p| p.as_path()).collect::<Vec<_>>());
// verify equal length of file-names and input FILEs
if filenames.is_some()
&& files.is_some()
&& filenames.as_ref().map(|v| v.len()) != files.as_ref().map(|v| v.len())
{
return Err("Must be one file name per input type.".into());
}
let mut filenames_or_none: Box<dyn Iterator<Item = Option<&Path>>> = match filenames { let mut filenames_or_none: Box<dyn Iterator<Item = Option<&Path>>> = match filenames {
Some(filenames) => Box::new(filenames.into_iter().map(Some)), Some(filenames) => Box::new(filenames.into_iter().map(Some)),
None => Box::new(std::iter::repeat(None)), None => Box::new(std::iter::repeat(None)),
}; };
let files: Option<Vec<&Path>> = self
.matches
.values_of_os("FILE")
.map(|vs| vs.map(Path::new).collect());
if files.is_none() { if files.is_none() {
return Ok(vec![new_stdin_input( return Ok(vec![new_stdin_input(
filenames_or_none.next().unwrap_or(None), filenames_or_none.next().unwrap_or(None),
@@ -307,12 +294,12 @@ impl App {
fn style_components(&self) -> Result<StyleComponents> { fn style_components(&self) -> Result<StyleComponents> {
let matches = &self.matches; let matches = &self.matches;
let mut styled_components = StyleComponents( let mut styled_components =
if matches.get_one::<String>("decorations").map(|s| s.as_str()) == Some("never") { StyleComponents(if matches.value_of("decorations") == Some("never") {
HashSet::new() HashSet::new()
} else if matches.get_flag("number") { } else if matches.is_present("number") {
[StyleComponent::LineNumbers].iter().cloned().collect() [StyleComponent::LineNumbers].iter().cloned().collect()
} else if 0 < matches.get_count("plain") { } else if matches.is_present("plain") {
[StyleComponent::Plain].iter().cloned().collect() [StyleComponent::Plain].iter().cloned().collect()
} else { } else {
let env_style_components: Option<Vec<StyleComponent>> = env::var("BAT_STYLE") let env_style_components: Option<Vec<StyleComponent>> = env::var("BAT_STYLE")
@@ -326,7 +313,7 @@ impl App {
.transpose()?; .transpose()?;
matches matches
.get_one::<String>("style") .value_of("style")
.map(|styles| { .map(|styles| {
styles styles
.split(',') .split(',')
@@ -335,15 +322,14 @@ impl App {
.collect::<Vec<_>>() .collect::<Vec<_>>()
}) })
.or(env_style_components) .or(env_style_components)
.unwrap_or_else(|| vec![StyleComponent::Default]) .unwrap_or_else(|| vec![StyleComponent::Full])
.into_iter() .into_iter()
.map(|style| style.components(self.interactive_output)) .map(|style| style.components(self.interactive_output))
.fold(HashSet::new(), |mut acc, components| { .fold(HashSet::new(), |mut acc, components| {
acc.extend(components.iter().cloned()); acc.extend(components.iter().cloned());
acc acc
}) })
}, });
);
// If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning. // 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) { if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) {

View File

@@ -1,10 +1,7 @@
use clap::{ use clap::{crate_name, crate_version, App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
crate_name, crate_version, value_parser, AppSettings, Arg, ArgAction, ArgGroup, ColorChoice,
Command,
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::env; use std::env;
use std::path::{Path, PathBuf}; use std::path::Path;
static VERSION: Lazy<String> = Lazy::new(|| { static VERSION: Lazy<String> = Lazy::new(|| {
#[cfg(feature = "bugreport")] #[cfg(feature = "bugreport")]
@@ -19,21 +16,23 @@ static VERSION: Lazy<String> = Lazy::new(|| {
} }
}); });
pub fn build_app(interactive_output: bool) -> Command<'static> { pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
let color_when = if interactive_output && env::var_os("NO_COLOR").is_none() { let clap_color_setting = if interactive_output && env::var_os("NO_COLOR").is_none() {
ColorChoice::Auto AppSettings::ColoredHelp
} else { } else {
ColorChoice::Never AppSettings::ColorNever
}; };
let mut app = Command::new(crate_name!()) let mut app = ClapApp::new(crate_name!())
.version(VERSION.as_str()) .version(VERSION.as_str())
.color(color_when) .global_setting(clap_color_setting)
.global_setting(AppSettings::DeriveDisplayOrder) .global_setting(AppSettings::DeriveDisplayOrder)
.hide_possible_values(true) .global_setting(AppSettings::UnifiedHelpMessage)
.args_conflicts_with_subcommands(true) .global_setting(AppSettings::HidePossibleValuesInHelp)
.allow_external_subcommands(true) .setting(AppSettings::ArgsNegateSubcommands)
.disable_help_subcommand(true) .setting(AppSettings::AllowExternalSubcommands)
.setting(AppSettings::DisableHelpSubcommand)
.setting(AppSettings::VersionlessSubcommands)
.max_term_width(100) .max_term_width(100)
.about( .about(
"A cat(1) clone with wings.\n\n\ "A cat(1) clone with wings.\n\n\
@@ -45,22 +44,20 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
) )
.long_about("A cat(1) clone with syntax highlighting and Git integration.") .long_about("A cat(1) clone with syntax highlighting and Git integration.")
.arg( .arg(
Arg::new("FILE") Arg::with_name("FILE")
.help("File(s) to print / concatenate. Use '-' for standard input.") .help("File(s) to print / concatenate. Use '-' for standard input.")
.long_help( .long_help(
"File(s) to print / concatenate. Use a dash ('-') or no argument at all \ "File(s) to print / concatenate. Use a dash ('-') or no argument at all \
to read from standard input.", to read from standard input.",
) )
.takes_value(true) .multiple(true)
.multiple_values(true) .empty_values(false),
.value_parser(value_parser!(PathBuf)),
) )
.arg( .arg(
Arg::new("show-all") Arg::with_name("show-all")
.long("show-all") .long("show-all")
.alias("show-nonprintable") .alias("show-nonprintable")
.short('A') .short("A")
.action(ArgAction::SetTrue)
.conflicts_with("language") .conflicts_with("language")
.help("Show non-printable characters (space, tab, newline, ..).") .help("Show non-printable characters (space, tab, newline, ..).")
.long_help( .long_help(
@@ -70,22 +67,22 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("plain") Arg::with_name("plain")
.overrides_with("plain") .overrides_with("plain")
.overrides_with("number") .overrides_with("number")
.short('p') .short("p")
.long("plain") .long("plain")
.action(ArgAction::Count) .multiple(true)
.help("Show plain style (alias for '--style=plain').") .help("Show plain style (alias for '--style=plain').")
.long_help( .long_help(
"Only show plain style, no decorations. This is an alias for \ "Only show plain style, no decorations. This is an alias for \
'--style=plain'. When '-p' is used twice ('-pp'), it also disables \ '--style=plain'. When '-p' is used twice ('-pp'), it also disables \
automatic paging (alias for '--style=plain --paging=never').", automatic paging (alias for '--style=plain --pager=never').",
), ),
) )
.arg( .arg(
Arg::new("language") Arg::with_name("language")
.short('l') .short("l")
.long("language") .long("language")
.overrides_with("language") .overrides_with("language")
.help("Set the language for syntax highlighting.") .help("Set the language for syntax highlighting.")
@@ -98,11 +95,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
.takes_value(true), .takes_value(true),
) )
.arg( .arg(
Arg::new("highlight-line") Arg::with_name("highlight-line")
.long("highlight-line") .long("highlight-line")
.short('H') .short("H")
.takes_value(true) .takes_value(true)
.action(ArgAction::Append) .number_of_values(1)
.multiple(true)
.value_name("N:M") .value_name("N:M")
.help("Highlight lines N through M.") .help("Highlight lines N through M.")
.long_help( .long_help(
@@ -116,12 +114,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("file-name") Arg::with_name("file-name")
.long("file-name") .long("file-name")
.takes_value(true) .takes_value(true)
.action(ArgAction::Append) .number_of_values(1)
.multiple(true)
.value_name("name") .value_name("name")
.value_parser(value_parser!(PathBuf))
.help("Specify the name to display for a file.") .help("Specify the name to display for a file.")
.long_help( .long_help(
"Specify the name to display for a file. Useful when piping \ "Specify the name to display for a file. Useful when piping \
@@ -135,11 +133,9 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
{ {
app = app app = app
.arg( .arg(
Arg::new("diff") Arg::with_name("diff")
.long("diff") .long("diff")
.short('d') .short("d")
.action(ArgAction::SetTrue)
.conflicts_with("line-range")
.help("Only show lines that have been added/removed/modified.") .help("Only show lines that have been added/removed/modified.")
.long_help( .long_help(
"Only show lines that have been added/removed/modified with respect \ "Only show lines that have been added/removed/modified with respect \
@@ -147,20 +143,20 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("diff-context") Arg::with_name("diff-context")
.long("diff-context") .long("diff-context")
.overrides_with("diff-context") .overrides_with("diff-context")
.takes_value(true) .takes_value(true)
.value_name("N") .value_name("N")
.value_parser( .validator(
|n: &str| { |n| {
n.parse::<usize>() n.parse::<usize>()
.map_err(|_| "must be a number") .map_err(|_| "must be a number")
.map(|_| n.to_owned()) // Convert to Result<String, &str> .map(|_| ()) // Convert to Result<(), &str>
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
}, // Convert to Result<(), String> }, // Convert to Result<(), String>
) )
.hide_short_help(true) .hidden_short_help(true)
.long_help( .long_help(
"Include N lines of context around added/removed/modified lines when using '--diff'.", "Include N lines of context around added/removed/modified lines when using '--diff'.",
), ),
@@ -168,16 +164,16 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
} }
app = app.arg( app = app.arg(
Arg::new("tabs") Arg::with_name("tabs")
.long("tabs") .long("tabs")
.overrides_with("tabs") .overrides_with("tabs")
.takes_value(true) .takes_value(true)
.value_name("T") .value_name("T")
.value_parser( .validator(
|t: &str| { |t| {
t.parse::<u32>() t.parse::<u32>()
.map_err(|_t| "must be a number") .map_err(|_t| "must be a number")
.map(|_t| t.to_owned()) // Convert to Result<String, &str> .map(|_t| ()) // Convert to Result<(), &str>
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
}, // Convert to Result<(), String> }, // Convert to Result<(), String>
) )
@@ -188,12 +184,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("wrap") Arg::with_name("wrap")
.long("wrap") .long("wrap")
.overrides_with("wrap") .overrides_with("wrap")
.takes_value(true) .takes_value(true)
.value_name("mode") .value_name("mode")
.value_parser(["auto", "never", "character"]) .possible_values(&["auto", "never", "character"])
.default_value("auto") .default_value("auto")
.hide_default_value(true) .hide_default_value(true)
.help("Specify the text-wrapping mode (*auto*, never, character).") .help("Specify the text-wrapping mode (*auto*, never, character).")
@@ -202,21 +198,21 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
control the output width."), control the output width."),
) )
.arg( .arg(
Arg::new("terminal-width") Arg::with_name("terminal-width")
.long("terminal-width") .long("terminal-width")
.takes_value(true) .takes_value(true)
.value_name("width") .value_name("width")
.hide_short_help(true) .hidden_short_help(true)
.allow_hyphen_values(true) .allow_hyphen_values(true)
.value_parser( .validator(
|t: &str| { |t| {
let is_offset = t.starts_with('+') || t.starts_with('-'); let is_offset = t.starts_with('+') || t.starts_with('-');
t.parse::<i32>() t.parse::<i32>()
.map_err(|_e| "must be an offset or number") .map_err(|_e| "must be an offset or number")
.and_then(|v| if v == 0 && !is_offset { .and_then(|v| if v == 0 && !is_offset {
Err("terminal width cannot be zero") Err("terminal width cannot be zero")
} else { } else {
Ok(t.to_owned()) Ok(())
}) })
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
}) })
@@ -227,11 +223,10 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("number") Arg::with_name("number")
.long("number") .long("number")
.overrides_with("number") .overrides_with("number")
.short('n') .short("n")
.action(ArgAction::SetTrue)
.help("Show line numbers (alias for '--style=numbers').") .help("Show line numbers (alias for '--style=numbers').")
.long_help( .long_help(
"Only show line numbers, no other decorations. This is an alias for \ "Only show line numbers, no other decorations. This is an alias for \
@@ -239,12 +234,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("color") Arg::with_name("color")
.long("color") .long("color")
.overrides_with("color") .overrides_with("color")
.takes_value(true) .takes_value(true)
.value_name("when") .value_name("when")
.value_parser(["auto", "never", "always"]) .possible_values(&["auto", "never", "always"])
.hide_default_value(true) .hide_default_value(true)
.default_value("auto") .default_value("auto")
.help("When to use colors (*auto*, never, always).") .help("When to use colors (*auto*, never, always).")
@@ -256,23 +251,23 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("italic-text") Arg::with_name("italic-text")
.long("italic-text") .long("italic-text")
.takes_value(true) .takes_value(true)
.value_name("when") .value_name("when")
.value_parser(["always", "never"]) .possible_values(&["always", "never"])
.default_value("never") .default_value("never")
.hide_default_value(true) .hide_default_value(true)
.help("Use italics in output (always, *never*)") .help("Use italics in output (always, *never*)")
.long_help("Specify when to use ANSI sequences for italic text in the output. Possible values: always, *never*."), .long_help("Specify when to use ANSI sequences for italic text in the output. Possible values: always, *never*."),
) )
.arg( .arg(
Arg::new("decorations") Arg::with_name("decorations")
.long("decorations") .long("decorations")
.overrides_with("decorations") .overrides_with("decorations")
.takes_value(true) .takes_value(true)
.value_name("when") .value_name("when")
.value_parser(["auto", "never", "always"]) .possible_values(&["auto", "never", "always"])
.default_value("auto") .default_value("auto")
.hide_default_value(true) .hide_default_value(true)
.help("When to show the decorations (*auto*, never, always).") .help("When to show the decorations (*auto*, never, always).")
@@ -283,26 +278,24 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("force-colorization") Arg::with_name("force-colorization")
.long("force-colorization") .long("force-colorization")
.short('f') .short("f")
.action(ArgAction::SetTrue)
.conflicts_with("color") .conflicts_with("color")
.conflicts_with("decorations") .conflicts_with("decorations")
.overrides_with("force-colorization") .overrides_with("force-colorization")
.hide_short_help(true) .hidden_short_help(true)
.long_help("Alias for '--decorations=always --color=always'. This is useful \ .long_help("Alias for '--decorations=always --color=always'. This is useful \
if the output of bat is piped to another program, but you want \ if the output of bat is piped to another program, but you want \
to keep the colorization/decorations.") to keep the colorization/decorations.")
) )
.arg( .arg(
Arg::new("paging") Arg::with_name("paging")
.long("paging") .long("paging")
.overrides_with("paging") .overrides_with("paging")
.overrides_with("no-paging")
.takes_value(true) .takes_value(true)
.value_name("when") .value_name("when")
.value_parser(["auto", "never", "always"]) .possible_values(&["auto", "never", "always"])
.default_value("auto") .default_value("auto")
.hide_default_value(true) .hide_default_value(true)
.help("Specify when to use the pager, or use `-P` to disable (*auto*, never, always).") .help("Specify when to use the pager, or use `-P` to disable (*auto*, never, always).")
@@ -314,23 +307,22 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("no-paging") Arg::with_name("no-paging")
.short('P') .short("P")
.long("no-paging") .long("no-paging")
.alias("no-pager") .alias("no-pager")
.action(ArgAction::SetTrue)
.overrides_with("no-paging") .overrides_with("no-paging")
.hide(true) .hidden(true)
.hide_short_help(true) .hidden_short_help(true)
.help("Alias for '--paging=never'") .help("Alias for '--paging=never'")
) )
.arg( .arg(
Arg::new("pager") Arg::with_name("pager")
.long("pager") .long("pager")
.overrides_with("pager") .overrides_with("pager")
.takes_value(true) .takes_value(true)
.value_name("command") .value_name("command")
.hide_short_help(true) .hidden_short_help(true)
.help("Determine which pager to use.") .help("Determine which pager to use.")
.long_help( .long_help(
"Determine which pager is used. This option will override the \ "Determine which pager is used. This option will override the \
@@ -340,11 +332,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("map-syntax") Arg::with_name("map-syntax")
.short('m') .short("m")
.long("map-syntax") .long("map-syntax")
.action(ArgAction::Append) .multiple(true)
.takes_value(true) .takes_value(true)
.number_of_values(1)
.value_name("glob:syntax") .value_name("glob:syntax")
.help("Use the specified syntax for files matching the glob pattern ('*.cpp:C++').") .help("Use the specified syntax for files matching the glob pattern ('*.cpp:C++').")
.long_help( .long_help(
@@ -357,18 +350,19 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
.takes_value(true), .takes_value(true),
) )
.arg( .arg(
Arg::new("ignored-suffix") Arg::with_name("ignored-suffix")
.action(ArgAction::Append) .number_of_values(1)
.multiple(true)
.takes_value(true) .takes_value(true)
.long("ignored-suffix") .long("ignored-suffix")
.hide_short_help(true) .hidden_short_help(true)
.help( .help(
"Ignore extension. For example:\n \ "Ignore extension. For example:\n \
'bat --ignored-suffix \".dev\" my_file.json.dev' will use JSON syntax, and ignore '.dev'" 'bat --ignored-suffix \".dev\" my_file.json.dev' will use JSON syntax, and ignore '.dev'"
) )
) )
.arg( .arg(
Arg::new("theme") Arg::with_name("theme")
.long("theme") .long("theme")
.overrides_with("theme") .overrides_with("theme")
.takes_value(true) .takes_value(true)
@@ -382,30 +376,28 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("list-themes") Arg::with_name("list-themes")
.long("list-themes") .long("list-themes")
.action(ArgAction::SetTrue)
.help("Display all supported highlighting themes.") .help("Display all supported highlighting themes.")
.long_help("Display a list of supported themes for syntax highlighting."), .long_help("Display a list of supported themes for syntax highlighting."),
) )
.arg( .arg(
Arg::new("style") Arg::with_name("style")
.long("style") .long("style")
.value_name("components") .value_name("components")
// Need to turn this off for overrides_with to work as we want. See the bottom most // Need to turn this off for overrides_with to work as we want. See the bottom most
// example at https://docs.rs/clap/2.32.0/clap/struct.Arg.html#method.overrides_with // example at https://docs.rs/clap/2.32.0/clap/struct.Arg.html#method.overrides_with
.use_value_delimiter(false) .use_delimiter(false)
.takes_value(true) .takes_value(true)
.overrides_with("style") .overrides_with("style")
.overrides_with("plain") .overrides_with("plain")
.overrides_with("number") .overrides_with("number")
// Cannot use claps built in validation because we have to turn off clap's delimiters // Cannot use claps built in validation because we have to turn off clap's delimiters
.value_parser(|val: &str| { .validator(|val| {
let mut invalid_vals = val.split(',').filter(|style| { let mut invalid_vals = val.split(',').filter(|style| {
!&[ !&[
"auto", "auto",
"full", "full",
"default",
"plain", "plain",
"header", "header",
"header-filename", "header-filename",
@@ -422,12 +414,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
if let Some(invalid) = invalid_vals.next() { if let Some(invalid) = invalid_vals.next() {
Err(format!("Unknown style, '{}'", invalid)) Err(format!("Unknown style, '{}'", invalid))
} else { } else {
Ok(val.to_owned()) Ok(())
} }
}) })
.help( .help(
"Comma-separated list of style elements to display \ "Comma-separated list of style elements to display \
(*default*, auto, full, plain, changes, header, header-filename, header-filesize, grid, rule, numbers, snip).", (*auto*, full, plain, changes, header, grid, rule, numbers, snip).",
) )
.long_help( .long_help(
"Configure which elements (line numbers, file headers, grid \ "Configure which elements (line numbers, file headers, grid \
@@ -438,9 +430,8 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
'--style=\"..\"' option to the configuration file or export the \ '--style=\"..\"' option to the configuration file or export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\ BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\
Possible values:\n\n \ Possible values:\n\n \
* default: enables recommended style components (default).\n \ * full: enables all available components (default).\n \
* full: enables all available components.\n \ * auto: same as 'full', unless the output is piped.\n \
* auto: same as 'default', unless the output is piped.\n \
* plain: disables all available components.\n \ * plain: disables all available components.\n \
* changes: show Git modification markers.\n \ * changes: show Git modification markers.\n \
* header: alias for 'header-filename'.\n \ * header: alias for 'header-filename'.\n \
@@ -454,12 +445,14 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("line-range") Arg::with_name("line-range")
.long("line-range") .long("line-range")
.short('r') .short("r")
.action(ArgAction::Append) .multiple(true)
.takes_value(true) .takes_value(true)
.number_of_values(1)
.value_name("N:M") .value_name("N:M")
.conflicts_with("diff")
.help("Only print the lines from N to M.") .help("Only print the lines from N to M.")
.long_help( .long_help(
"Only print the specified range of lines for each file. \ "Only print the specified range of lines for each file. \
@@ -472,19 +465,18 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("list-languages") Arg::with_name("list-languages")
.long("list-languages") .long("list-languages")
.short('L') .short("L")
.action(ArgAction::SetTrue)
.conflicts_with("list-themes") .conflicts_with("list-themes")
.help("Display all supported languages.") .help("Display all supported languages.")
.long_help("Display a list of supported languages for syntax highlighting."), .long_help("Display a list of supported languages for syntax highlighting."),
) )
.arg( .arg(
Arg::new("unbuffered") Arg::with_name("unbuffered")
.short('u') .short("u")
.long("unbuffered") .long("unbuffered")
.hide_short_help(true) .hidden_short_help(true)
.long_help( .long_help(
"This option exists for POSIX-compliance reasons ('u' is for \ "This option exists for POSIX-compliance reasons ('u' is for \
'unbuffered'). The output is always unbuffered - this option \ 'unbuffered'). The output is always unbuffered - this option \
@@ -492,66 +484,60 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("no-config") Arg::with_name("no-config")
.long("no-config") .long("no-config")
.hide(true) .hidden(true)
.help("Do not use the configuration file"), .help("Do not use the configuration file"),
) )
.arg( .arg(
Arg::new("no-custom-assets") Arg::with_name("no-custom-assets")
.long("no-custom-assets") .long("no-custom-assets")
.action(ArgAction::SetTrue) .hidden(true)
.hide(true)
.help("Do not load custom assets"), .help("Do not load custom assets"),
) )
.arg( .arg(
Arg::new("config-file") Arg::with_name("config-file")
.long("config-file") .long("config-file")
.action(ArgAction::SetTrue)
.conflicts_with("list-languages") .conflicts_with("list-languages")
.conflicts_with("list-themes") .conflicts_with("list-themes")
.hide(true) .hidden(true)
.help("Show path to the configuration file."), .help("Show path to the configuration file."),
) )
.arg( .arg(
Arg::new("generate-config-file") Arg::with_name("generate-config-file")
.long("generate-config-file") .long("generate-config-file")
.action(ArgAction::SetTrue)
.conflicts_with("list-languages") .conflicts_with("list-languages")
.conflicts_with("list-themes") .conflicts_with("list-themes")
.hide(true) .hidden(true)
.help("Generates a default configuration file."), .help("Generates a default configuration file."),
) )
.arg( .arg(
Arg::new("config-dir") Arg::with_name("config-dir")
.long("config-dir") .long("config-dir")
.action(ArgAction::SetTrue) .hidden(true)
.hide(true)
.help("Show bat's configuration directory."), .help("Show bat's configuration directory."),
) )
.arg( .arg(
Arg::new("cache-dir") Arg::with_name("cache-dir")
.long("cache-dir") .long("cache-dir")
.action(ArgAction::SetTrue) .hidden(true)
.hide(true)
.help("Show bat's cache directory."), .help("Show bat's cache directory."),
) )
.arg( .arg(
Arg::new("diagnostic") Arg::with_name("diagnostic")
.long("diagnostic") .long("diagnostic")
.alias("diagnostics") .alias("diagnostics")
.action(ArgAction::SetTrue) .hidden_short_help(true)
.hide_short_help(true)
.help("Show diagnostic information for bug reports.") .help("Show diagnostic information for bug reports.")
) )
.arg( .arg(
Arg::new("acknowledgements") Arg::with_name("acknowledgements")
.long("acknowledgements") .long("acknowledgements")
.action(ArgAction::SetTrue) .hidden_short_help(true)
.hide_short_help(true)
.help("Show acknowledgements."), .help("Show acknowledgements."),
) )
.mut_arg("help", |arg| arg.help("Print this help message.")); .help_message("Print this help message.")
.version_message("Show version information.");
// Check if the current directory contains a file name cache. Otherwise, // Check if the current directory contains a file name cache. Otherwise,
// enable the 'bat cache' subcommand. // enable the 'bat cache' subcommand.
@@ -559,13 +545,12 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
app app
} else { } else {
app.subcommand( app.subcommand(
Command::new("cache") SubCommand::with_name("cache")
.about("Modify the syntax-definition and theme cache") .about("Modify the syntax-definition and theme cache")
.arg( .arg(
Arg::new("build") Arg::with_name("build")
.long("build") .long("build")
.short('b') .short("b")
.action(ArgAction::SetTrue)
.help("Initialize (or update) the syntax/theme cache.") .help("Initialize (or update) the syntax/theme cache.")
.long_help( .long_help(
"Initialize (or update) the syntax/theme cache by loading from \ "Initialize (or update) the syntax/theme cache by loading from \
@@ -573,19 +558,18 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("clear") Arg::with_name("clear")
.long("clear") .long("clear")
.short('c') .short("c")
.action(ArgAction::SetTrue)
.help("Remove the cached syntax definitions and themes."), .help("Remove the cached syntax definitions and themes."),
) )
.group( .group(
ArgGroup::new("cache-actions") ArgGroup::with_name("cache-actions")
.args(&["build", "clear"]) .args(&["build", "clear"])
.required(true), .required(true),
) )
.arg( .arg(
Arg::new("source") Arg::with_name("source")
.long("source") .long("source")
.requires("build") .requires("build")
.takes_value(true) .takes_value(true)
@@ -593,7 +577,7 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
.help("Use a different directory to load syntaxes and themes from."), .help("Use a different directory to load syntaxes and themes from."),
) )
.arg( .arg(
Arg::new("target") Arg::with_name("target")
.long("target") .long("target")
.requires("build") .requires("build")
.takes_value(true) .takes_value(true)
@@ -603,9 +587,8 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("blank") Arg::with_name("blank")
.long("blank") .long("blank")
.action(ArgAction::SetTrue)
.requires("build") .requires("build")
.help( .help(
"Create completely new syntax and theme sets \ "Create completely new syntax and theme sets \
@@ -613,17 +596,11 @@ pub fn build_app(interactive_output: bool) -> Command<'static> {
), ),
) )
.arg( .arg(
Arg::new("acknowledgements") Arg::with_name("acknowledgements")
.long("acknowledgements") .long("acknowledgements")
.action(ArgAction::SetTrue)
.requires("build") .requires("build")
.help("Build acknowledgements.bin."), .help("Build acknowledgements.bin."),
), ),
) )
} }
} }
#[test]
fn verify_app() {
build_app(false).debug_assert();
}

View File

@@ -6,22 +6,6 @@ use std::path::PathBuf;
use crate::directories::PROJECT_DIRS; use crate::directories::PROJECT_DIRS;
#[cfg(not(target_os = "windows"))]
const DEFAULT_SYSTEM_CONFIG_PREFIX: &str = "/etc";
#[cfg(target_os = "windows")]
const DEFAULT_SYSTEM_CONFIG_PREFIX: &str = "C:\\ProgramData";
pub fn system_config_file() -> PathBuf {
let folder = option_env!("BAT_SYSTEM_CONFIG_PREFIX").unwrap_or(DEFAULT_SYSTEM_CONFIG_PREFIX);
let mut path = PathBuf::from(folder);
path.push("bat");
path.push("config");
path
}
pub fn config_file() -> PathBuf { pub fn config_file() -> PathBuf {
env::var("BAT_CONFIG_PATH") env::var("BAT_CONFIG_PATH")
.ok() .ok()
@@ -103,18 +87,11 @@ pub fn generate_config_file() -> bat::error::Result<()> {
} }
pub fn get_args_from_config_file() -> Result<Vec<OsString>, shell_words::ParseError> { pub fn get_args_from_config_file() -> Result<Vec<OsString>, shell_words::ParseError> {
let mut config = String::new(); Ok(fs::read_to_string(config_file())
.ok()
if let Ok(c) = fs::read_to_string(system_config_file()) { .map(|content| get_args_from_str(&content))
config.push_str(&c); .transpose()?
config.push('\n'); .unwrap_or_else(Vec::new))
}
if let Ok(c) = fs::read_to_string(config_file()) {
config.push_str(&c);
}
get_args_from_str(&config)
} }
pub fn get_args_from_env_var() -> Option<Result<Vec<OsString>, shell_words::ParseError>> { pub fn get_args_from_env_var() -> Option<Result<Vec<OsString>, shell_words::ParseError>> {

View File

@@ -8,7 +8,6 @@ mod directories;
mod input; mod input;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fmt::Write as _;
use std::io; use std::io;
use std::io::{BufReader, Write}; use std::io::{BufReader, Write};
use std::path::Path; use std::path::Path;
@@ -22,9 +21,6 @@ use crate::{
config::{config_file, generate_config_file}, config::{config_file, generate_config_file},
}; };
#[cfg(feature = "bugreport")]
use crate::config::system_config_file;
use assets::{assets_from_cache_or_binary, cache_dir, clear_assets, config_dir}; use assets::{assets_from_cache_or_binary, cache_dir, clear_assets, config_dir};
use directories::PROJECT_DIRS; use directories::PROJECT_DIRS;
use globset::GlobMatcher; use globset::GlobMatcher;
@@ -43,30 +39,30 @@ const THEME_PREVIEW_DATA: &[u8] = include_bytes!("../../../assets/theme_preview.
#[cfg(feature = "build-assets")] #[cfg(feature = "build-assets")]
fn build_assets(matches: &clap::ArgMatches) -> Result<()> { fn build_assets(matches: &clap::ArgMatches) -> Result<()> {
let source_dir = matches let source_dir = matches
.get_one::<String>("source") .value_of("source")
.map(Path::new) .map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.config_dir()); .unwrap_or_else(|| PROJECT_DIRS.config_dir());
let target_dir = matches let target_dir = matches
.get_one::<String>("target") .value_of("target")
.map(Path::new) .map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.cache_dir()); .unwrap_or_else(|| PROJECT_DIRS.cache_dir());
bat::assets::build( bat::assets::build(
source_dir, source_dir,
!matches.get_flag("blank"), !matches.is_present("blank"),
matches.get_flag("acknowledgements"), matches.is_present("acknowledgements"),
target_dir, target_dir,
clap::crate_version!(), clap::crate_version!(),
) )
} }
fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> { fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
if matches.get_flag("build") { if matches.is_present("build") {
#[cfg(feature = "build-assets")] #[cfg(feature = "build-assets")]
build_assets(matches)?; build_assets(matches)?;
#[cfg(not(feature = "build-assets"))] #[cfg(not(feature = "build-assets"))]
println!("bat has been built without the 'build-assets' feature. The 'cache --build' option is not available."); println!("bat has been built without the 'build-assets' feature. The 'cache --build' option is not available.");
} else if matches.get_flag("clear") { } else if matches.is_present("clear") {
clear_assets(); clear_assets();
} }
@@ -129,7 +125,7 @@ pub fn get_languages(config: &Config) -> Result<String> {
if config.loop_through { if config.loop_through {
for lang in languages { for lang in languages {
writeln!(result, "{}:{}", lang.name, lang.file_extensions.join(",")).ok(); result += &format!("{}:{}\n", lang.name, lang.file_extensions.join(","));
} }
} else { } else {
let longest = languages let longest = languages
@@ -150,7 +146,7 @@ pub fn get_languages(config: &Config) -> Result<String> {
}; };
for lang in languages { for lang in languages {
write!(result, "{:width$}{}", lang.name, separator, width = longest).ok(); result += &format!("{:width$}{}", lang.name, separator, width = longest);
// Number of characters on this line so far, wrap before `desired_width` // Number of characters on this line so far, wrap before `desired_width`
let mut num_chars = 0; let mut num_chars = 0;
@@ -161,11 +157,11 @@ pub fn get_languages(config: &Config) -> Result<String> {
let new_chars = word.len() + comma_separator.len(); let new_chars = word.len() + comma_separator.len();
if num_chars + new_chars >= desired_width { if num_chars + new_chars >= desired_width {
num_chars = 0; num_chars = 0;
write!(result, "\n{:width$}{}", "", separator, width = longest).ok(); result += &format!("\n{:width$}{}", "", separator, width = longest);
} }
num_chars += new_chars; num_chars += new_chars;
write!(result, "{}", style.paint(&word[..])).ok(); result += &format!("{}", style.paint(&word[..]));
if extension.peek().is_some() { if extension.peek().is_some() {
result += comma_separator; result += comma_separator;
} }
@@ -231,13 +227,8 @@ fn run_controller(inputs: Vec<Input>, config: &Config) -> Result<bool> {
#[cfg(feature = "bugreport")] #[cfg(feature = "bugreport")]
fn invoke_bugreport(app: &App) { fn invoke_bugreport(app: &App) {
use bugreport::{bugreport, collector::*, format::Markdown}; use bugreport::{bugreport, collector::*, format::Markdown};
let pager = bat::config::get_pager_executable( let pager = bat::config::get_pager_executable(app.matches.value_of("pager"))
app.matches.get_one::<String>("pager").map(|s| s.as_str()), .unwrap_or_else(|| "less".to_owned()); // FIXME: Avoid non-canonical path to "less".
)
.unwrap_or_else(|| "less".to_owned()); // FIXME: Avoid non-canonical path to "less".
let mut custom_assets_metadata = PROJECT_DIRS.cache_dir().to_path_buf();
custom_assets_metadata.push("metadata.yaml");
let mut report = bugreport!() let mut report = bugreport!()
.info(SoftwareVersion::default()) .info(SoftwareVersion::default())
@@ -262,16 +253,7 @@ fn invoke_bugreport(app: &App) {
"NO_COLOR", "NO_COLOR",
"MANPAGER", "MANPAGER",
])) ]))
.info(FileContent::new("System Config file", system_config_file()))
.info(FileContent::new("Config file", config_file())) .info(FileContent::new("Config file", config_file()))
.info(FileContent::new(
"Custom assets metadata",
custom_assets_metadata,
))
.info(DirectoryEntries::new(
"Custom assets",
PROJECT_DIRS.cache_dir(),
))
.info(CompileTimeInformation::default()); .info(CompileTimeInformation::default());
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
@@ -291,7 +273,7 @@ fn invoke_bugreport(app: &App) {
fn run() -> Result<bool> { fn run() -> Result<bool> {
let app = App::new()?; let app = App::new()?;
if app.matches.get_flag("diagnostic") { if app.matches.is_present("diagnostic") {
#[cfg(feature = "bugreport")] #[cfg(feature = "bugreport")]
invoke_bugreport(&app); invoke_bugreport(&app);
#[cfg(not(feature = "bugreport"))] #[cfg(not(feature = "bugreport"))]
@@ -300,11 +282,11 @@ fn run() -> Result<bool> {
} }
match app.matches.subcommand() { match app.matches.subcommand() {
Some(("cache", cache_matches)) => { ("cache", Some(cache_matches)) => {
// If there is a file named 'cache' in the current working directory, // If there is a file named 'cache' in the current working directory,
// arguments for subcommand 'cache' are not mandatory. // arguments for subcommand 'cache' are not mandatory.
// If there are non-zero arguments, execute the subcommand cache, else, open the file cache. // If there are non-zero arguments, execute the subcommand cache, else, open the file cache.
if cache_matches.args_present() { if !cache_matches.args.is_empty() {
run_cache_subcommand(cache_matches)?; run_cache_subcommand(cache_matches)?;
Ok(true) Ok(true)
} else { } else {
@@ -318,7 +300,7 @@ fn run() -> Result<bool> {
let inputs = app.inputs()?; let inputs = app.inputs()?;
let config = app.config(&inputs)?; let config = app.config(&inputs)?;
if app.matches.get_flag("list-languages") { if app.matches.is_present("list-languages") {
let languages: String = get_languages(&config)?; let languages: String = get_languages(&config)?;
let inputs: Vec<Input> = vec![Input::from_reader(Box::new(languages.as_bytes()))]; let inputs: Vec<Input> = vec![Input::from_reader(Box::new(languages.as_bytes()))];
let plain_config = Config { let plain_config = Config {
@@ -327,22 +309,22 @@ fn run() -> Result<bool> {
..Default::default() ..Default::default()
}; };
run_controller(inputs, &plain_config) run_controller(inputs, &plain_config)
} else if app.matches.get_flag("list-themes") { } else if app.matches.is_present("list-themes") {
list_themes(&config)?; list_themes(&config)?;
Ok(true) Ok(true)
} else if app.matches.get_flag("config-file") { } else if app.matches.is_present("config-file") {
println!("{}", config_file().to_string_lossy()); println!("{}", config_file().to_string_lossy());
Ok(true) Ok(true)
} else if app.matches.get_flag("generate-config-file") { } else if app.matches.is_present("generate-config-file") {
generate_config_file()?; generate_config_file()?;
Ok(true) Ok(true)
} else if app.matches.get_flag("config-dir") { } else if app.matches.is_present("config-dir") {
writeln!(io::stdout(), "{}", config_dir())?; writeln!(io::stdout(), "{}", config_dir())?;
Ok(true) Ok(true)
} else if app.matches.get_flag("cache-dir") { } else if app.matches.is_present("cache-dir") {
writeln!(io::stdout(), "{}", cache_dir())?; writeln!(io::stdout(), "{}", cache_dir())?;
Ok(true) Ok(true)
} else if app.matches.get_flag("acknowledgements") { } else if app.matches.is_present("acknowledgements") {
writeln!(io::stdout(), "{}", bat::assets::get_acknowledgements())?; writeln!(io::stdout(), "{}", bat::assets::get_acknowledgements())?;
Ok(true) Ok(true)
} else { } else {

View File

@@ -2,14 +2,11 @@ use std::io::Write;
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error { pub enum Error {
#[error(transparent)] #[error(transparent)]
Io(#[from] ::std::io::Error), Io(#[from] ::std::io::Error),
#[error(transparent)] #[error(transparent)]
SyntectError(#[from] ::syntect::Error), SyntectError(#[from] ::syntect::LoadingError),
#[error(transparent)]
SyntectLoadingError(#[from] ::syntect::LoadingError),
#[error(transparent)] #[error(transparent)]
ParseIntError(#[from] ::std::num::ParseIntError), ParseIntError(#[from] ::std::num::ParseIntError),
#[error(transparent)] #[error(transparent)]

View File

@@ -118,7 +118,7 @@ impl OpenedInput<'_> {
self.metadata self.metadata
.user_provided_name .user_provided_name
.as_ref() .as_ref()
.or(match self.kind { .or_else(|| match self.kind {
OpenedInputKind::OrdinaryFile(ref path) => Some(path), OpenedInputKind::OrdinaryFile(ref path) => Some(path),
_ => None, _ => None,
}) })

View File

@@ -3,38 +3,21 @@
use std::ffi::OsStr; use std::ffi::OsStr;
use std::process::Command; use std::process::Command;
#[derive(Debug, PartialEq, Eq)] pub fn retrieve_less_version(less_path: &dyn AsRef<OsStr>) -> Option<usize> {
pub enum LessVersion {
Less(usize),
BusyBox,
}
pub fn retrieve_less_version(less_path: &dyn AsRef<OsStr>) -> Option<LessVersion> {
let resolved_path = grep_cli::resolve_binary(less_path.as_ref()).ok()?; let resolved_path = grep_cli::resolve_binary(less_path.as_ref()).ok()?;
let cmd = Command::new(resolved_path).arg("--version").output().ok()?; let cmd = Command::new(resolved_path).arg("--version").output().ok()?;
if cmd.status.success() { parse_less_version(&cmd.stdout)
parse_less_version(&cmd.stdout)
} else {
parse_less_version_busybox(&cmd.stderr)
}
} }
fn parse_less_version(output: &[u8]) -> Option<LessVersion> { fn parse_less_version(output: &[u8]) -> Option<usize> {
if !output.starts_with(b"less ") { if !output.starts_with(b"less ") {
return None; return None;
} }
let version = std::str::from_utf8(&output[5..]).ok()?; let version = std::str::from_utf8(&output[5..]).ok()?;
let end = version.find(|c: char| !c.is_ascii_digit())?; let end = version.find(|c: char| !c.is_ascii_digit())?;
Some(LessVersion::Less(version[..end].parse::<usize>().ok()?)) version[..end].parse::<usize>().ok()
}
fn parse_less_version_busybox(output: &[u8]) -> Option<LessVersion> {
match std::str::from_utf8(output) {
Ok(version) if version.contains("BusyBox ") => Some(LessVersion::BusyBox),
_ => None,
}
} }
#[test] #[test]
@@ -47,7 +30,7 @@ For information about the terms of redistribution,
see the file named README in the less distribution. see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less"; Homepage: http://www.greenwoodsoftware.com/less";
assert_eq!(Some(LessVersion::Less(487)), parse_less_version(output)); assert_eq!(Some(487), parse_less_version(output));
} }
#[test] #[test]
@@ -60,7 +43,7 @@ For information about the terms of redistribution,
see the file named README in the less distribution. see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less"; Homepage: http://www.greenwoodsoftware.com/less";
assert_eq!(Some(LessVersion::Less(529)), parse_less_version(output)); assert_eq!(Some(529), parse_less_version(output));
} }
#[test] #[test]
@@ -73,7 +56,7 @@ For information about the terms of redistribution,
see the file named README in the less distribution. see the file named README in the less distribution.
Home page: http://www.greenwoodsoftware.com/less"; Home page: http://www.greenwoodsoftware.com/less";
assert_eq!(Some(LessVersion::Less(551)), parse_less_version(output)); assert_eq!(Some(551), parse_less_version(output));
} }
#[test] #[test]
@@ -86,7 +69,7 @@ For information about the terms of redistribution,
see the file named README in the less distribution. see the file named README in the less distribution.
Home page: https://greenwoodsoftware.com/less"; Home page: https://greenwoodsoftware.com/less";
assert_eq!(Some(LessVersion::Less(581)), parse_less_version(output)); assert_eq!(Some(581), parse_less_version(output));
} }
#[test] #[test]
@@ -94,38 +77,4 @@ fn test_parse_less_version_wrong_program() {
let output = b"more from util-linux 2.34"; let output = b"more from util-linux 2.34";
assert_eq!(None, parse_less_version(output)); assert_eq!(None, parse_less_version(output));
assert_eq!(None, parse_less_version_busybox(output));
}
#[test]
fn test_parse_less_version_busybox() {
let output = b"pkg/less: unrecognized option '--version'
BusyBox v1.35.0 (2022-04-21 10:38:11 EDT) multi-call binary.
Usage: less [-EFIMmNSRh~] [FILE]...
View FILE (or stdin) one screenful at a time
-E Quit once the end of a file is reached
-F Quit if entire file fits on first screen
-I Ignore case in all searches
-M,-m Display status line with line numbers
and percentage through the file
-N Prefix line number to each line
-S Truncate long lines
-R Remove color escape codes in input
-~ Suppress ~s displayed past EOF";
assert_eq!(
Some(LessVersion::BusyBox),
parse_less_version_busybox(output)
);
}
#[test]
fn test_parse_less_version_invalid_utf_8() {
let output = b"\xff";
assert_eq!(None, parse_less_version(output));
assert_eq!(None, parse_less_version_busybox(output));
} }

View File

@@ -49,7 +49,7 @@ mod terminal;
mod vscreen; mod vscreen;
pub(crate) mod wrapping; pub(crate) mod wrapping;
pub use pretty_printer::{Input, PrettyPrinter, Syntax}; pub use pretty_printer::{Input, PrettyPrinter};
pub use syntax_mapping::{MappingTarget, SyntaxMapping}; pub use syntax_mapping::{MappingTarget, SyntaxMapping};
pub use wrapping::WrappingMode; pub use wrapping::WrappingMode;

View File

@@ -168,7 +168,7 @@ fn test_parse_minus_fail() {
assert!(range.is_err()); assert!(range.is_err());
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub enum RangeCheckResult { pub enum RangeCheckResult {
// Within one of the given ranges // Within one of the given ranges
InRange, InRange,

View File

@@ -4,7 +4,7 @@ use std::process::Child;
use crate::error::*; use crate::error::*;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
use crate::less::{retrieve_less_version, LessVersion}; use crate::less::retrieve_less_version;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
use crate::paging::PagingMode; use crate::paging::PagingMode;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
@@ -83,13 +83,13 @@ impl OutputType {
let replace_arguments_to_less = pager.source == PagerSource::EnvVarPager; let replace_arguments_to_less = pager.source == PagerSource::EnvVarPager;
if args.is_empty() || replace_arguments_to_less { if args.is_empty() || replace_arguments_to_less {
p.arg("-R"); // Short version of --RAW-CONTROL-CHARS for maximum compatibility p.arg("--RAW-CONTROL-CHARS");
if single_screen_action == SingleScreenAction::Quit { if single_screen_action == SingleScreenAction::Quit {
p.arg("-F"); // Short version of --quit-if-one-screen for compatibility p.arg("--quit-if-one-screen");
} }
if wrapping_mode == WrappingMode::NoWrapping(true) { if wrapping_mode == WrappingMode::NoWrapping(true) {
p.arg("-S"); // Short version of --chop-long-lines for compatibility p.arg("--chop-long-lines");
} }
// Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older // Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older
@@ -103,9 +103,7 @@ impl OutputType {
None => { None => {
p.arg("--no-init"); p.arg("--no-init");
} }
Some(LessVersion::Less(version)) Some(version) if (version < 530 || (cfg!(windows) && version < 558)) => {
if (version < 530 || (cfg!(windows) && version < 558)) =>
{
p.arg("--no-init"); p.arg("--no-init");
} }
_ => {} _ => {}

View File

@@ -40,23 +40,15 @@ impl PagerKind {
fn from_bin(bin: &str) -> PagerKind { fn from_bin(bin: &str) -> PagerKind {
use std::path::Path; use std::path::Path;
// Set to `less` by default on most Linux distros. match Path::new(bin)
let pager_bin = Path::new(bin).file_stem(); .file_stem()
.map(|s| s.to_string_lossy())
// The name of the current running binary. Normally `bat` but sometimes .as_deref()
// `batcat` for compatibility reasons. {
let current_bin = env::args_os().next(); Some("bat") => PagerKind::Bat,
// Check if the current running binary is set to be our pager.
let is_current_bin_pager = current_bin
.map(|s| Path::new(&s).file_stem() == pager_bin)
.unwrap_or(false);
match pager_bin.map(|s| s.to_string_lossy()).as_deref() {
Some("less") => PagerKind::Less, Some("less") => PagerKind::Less,
Some("more") => PagerKind::More, Some("more") => PagerKind::More,
Some("most") => PagerKind::Most, Some("most") => PagerKind::Most,
_ if is_current_bin_pager => PagerKind::Bat,
_ => PagerKind::Unknown, _ => PagerKind::Unknown,
} }
} }

View File

@@ -1,4 +1,4 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum PagingMode { pub enum PagingMode {
Always, Always,
QuitIfOneScreen, QuitIfOneScreen,

View File

@@ -1,5 +1,3 @@
use std::fmt::Write;
use console::AnsiCodeIterator; use console::AnsiCodeIterator;
/// Expand tabs like an ANSI-enabled expand(1). /// Expand tabs like an ANSI-enabled expand(1).
@@ -55,33 +53,26 @@ pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String {
let tab_width = if tab_width == 0 { 4 } else { tab_width }; let tab_width = if tab_width == 0 { 4 } else { tab_width };
let mut idx = 0; let mut idx = 0;
let mut line_idx = 0;
let len = input.len(); let len = input.len();
while idx < len { while idx < len {
if let Some((chr, skip_ahead)) = try_parse_utf8_char(&input[idx..]) { if let Some((chr, skip_ahead)) = try_parse_utf8_char(&input[idx..]) {
idx += skip_ahead; idx += skip_ahead;
line_idx += 1;
match chr { match chr {
// space // space
' ' => output.push('·'), ' ' => output.push('·'),
// tab // tab
'\t' => { '\t' => {
let tab_stop = tab_width - ((line_idx - 1) % tab_width); if tab_width == 1 {
line_idx = 0;
if tab_stop == 1 {
output.push('↹'); output.push('↹');
} else { } else {
output.push('├'); output.push('├');
output.push_str(&"".repeat(tab_stop - 2)); output.push_str(&"".repeat(tab_width - 2));
output.push('┤'); output.push('┤');
} }
} }
// line feed // line feed
'\x0A' => { '\x0A' => output.push_str("\x0A"),
output.push_str("\x0A");
line_idx = 0;
}
// carriage return // carriage return
'\x0D' => output.push('␍'), '\x0D' => output.push('␍'),
// null // null
@@ -103,7 +94,7 @@ pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String {
c => output.push_str(&c.escape_unicode().collect::<String>()), c => output.push_str(&c.escape_unicode().collect::<String>()),
} }
} else { } else {
write!(output, "\\x{:02X}", input[idx]).ok(); output.push_str(&format!("\\x{:02X}", input[idx]));
idx += 1; idx += 1;
} }
} }

View File

@@ -2,6 +2,7 @@ use std::io::Read;
use std::path::Path; use std::path::Path;
use console::Term; use console::Term;
use syntect::parsing::SyntaxReference;
use crate::{ use crate::{
assets::HighlightingAssets, assets::HighlightingAssets,
@@ -27,12 +28,6 @@ struct ActiveStyleComponents {
snip: bool, snip: bool,
} }
#[non_exhaustive]
pub struct Syntax {
pub name: String,
pub file_extensions: Vec<String>,
}
pub struct PrettyPrinter<'a> { pub struct PrettyPrinter<'a> {
inputs: Vec<Input<'a>>, inputs: Vec<Input<'a>>,
config: Config<'a>, config: Config<'a>,
@@ -169,12 +164,6 @@ impl<'a> PrettyPrinter<'a> {
self self
} }
/// Whether to print binary content or nonprintable characters (default: no)
pub fn show_nonprintable(&mut self, yes: bool) -> &mut Self {
self.config.show_nonprintable = yes;
self
}
/// Whether to show "snip" markers between visible line ranges (default: no) /// Whether to show "snip" markers between visible line ranges (default: no)
pub fn snip(&mut self, yes: bool) -> &mut Self { pub fn snip(&mut self, yes: bool) -> &mut Self {
self.active_style_components.snip = yes; self.active_style_components.snip = yes;
@@ -245,26 +234,18 @@ impl<'a> PrettyPrinter<'a> {
self.assets.themes() self.assets.themes()
} }
pub fn syntaxes(&self) -> impl Iterator<Item = Syntax> + '_ { pub fn syntaxes(&self) -> impl Iterator<Item = &SyntaxReference> {
// We always use assets from the binary, which are guaranteed to always // We always use assets from the binary, which are guaranteed to always
// be valid, so get_syntaxes() can never fail here // be valid, so get_syntaxes() can never fail here
self.assets self.assets.get_syntaxes().unwrap().iter()
.get_syntaxes()
.unwrap()
.iter()
.filter(|s| !s.hidden)
.map(|s| Syntax {
name: s.name.clone(),
file_extensions: s.file_extensions.clone(),
})
} }
/// Pretty-print all specified inputs. This method will "use" all stored inputs. /// Pretty-print all specified inputs. This method will "use" all stored inputs.
/// If you want to call 'print' multiple times, you have to call the appropriate /// If you want to call 'print' multiple times, you have to call the appropriate
/// input_* methods again. /// input_* methods again.
pub fn print(&mut self) -> Result<bool> { pub fn print(&mut self) -> Result<bool> {
let highlight_lines = std::mem::take(&mut self.highlighted_lines); self.config.highlighted_lines =
self.config.highlighted_lines = HighlightedLineRanges(LineRanges::from(highlight_lines)); HighlightedLineRanges(LineRanges::from(self.highlighted_lines.clone()));
self.config.term_width = self self.config.term_width = self
.term_width .term_width
.unwrap_or_else(|| Term::stdout().size().1 as usize); .unwrap_or_else(|| Term::stdout().size().1 as usize);

View File

@@ -424,7 +424,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
let line = if self.config.show_nonprintable { let line = if self.config.show_nonprintable {
replace_nonprintable(line_buffer, self.config.tab_width) replace_nonprintable(line_buffer, self.config.tab_width)
} else { } else {
let line = match self.content_type { match self.content_type {
Some(ContentType::BINARY) | None => { Some(ContentType::BINARY) | None => {
return Ok(()); return Ok(());
} }
@@ -435,15 +435,6 @@ impl<'a> Printer for InteractivePrinter<'a> {
.decode(line_buffer, DecoderTrap::Replace) .decode(line_buffer, DecoderTrap::Replace)
.map_err(|_| "Invalid UTF-16BE")?, .map_err(|_| "Invalid UTF-16BE")?,
_ => String::from_utf8_lossy(line_buffer).to_string(), _ => String::from_utf8_lossy(line_buffer).to_string(),
};
// Remove byte order mark from the first line if it exists
if line_number == 1 {
match line.strip_prefix('\u{feff}') {
Some(stripped) => stripped.to_string(),
None => line,
}
} else {
line
} }
}; };
@@ -454,21 +445,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
return Ok(()); return Ok(());
} }
}; };
highlighter_from_set
// skip syntax highlighting on long lines
let too_long = line.len() > 1024 * 16;
let for_highlighting: &str = if too_long { "\n" } else { &line };
let mut highlighted_line = highlighter_from_set
.highlighter .highlighter
.highlight_line(for_highlighting, highlighter_from_set.syntax_set)?; .highlight(&line, highlighter_from_set.syntax_set)
if too_long {
highlighted_line[0].1 = &line;
}
highlighted_line
}; };
if out_of_range { if out_of_range {
@@ -484,10 +463,6 @@ impl<'a> Printer for InteractivePrinter<'a> {
let highlight_this_line = let highlight_this_line =
self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange; self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange;
if highlight_this_line && self.config.theme == "ansi" {
self.ansi_style.update("^[4m");
}
let background_color = self let background_color = self
.background_color_highlight .background_color_highlight
.filter(|_| highlight_this_line); .filter(|_| highlight_this_line);
@@ -674,11 +649,6 @@ impl<'a> Printer for InteractivePrinter<'a> {
writeln!(handle)?; writeln!(handle)?;
} }
if highlight_this_line && self.config.theme == "ansi" {
self.ansi_style.update("^[24m");
write!(handle, "\x1B[24m")?;
}
Ok(()) Ok(())
} }
} }

View File

@@ -17,7 +17,6 @@ pub enum StyleComponent {
LineNumbers, LineNumbers,
Snip, Snip,
Full, Full,
Default,
Plain, Plain,
} }
@@ -26,7 +25,7 @@ impl StyleComponent {
match self { match self {
StyleComponent::Auto => { StyleComponent::Auto => {
if interactive_terminal { if interactive_terminal {
StyleComponent::Default.components(interactive_terminal) StyleComponent::Full.components(interactive_terminal)
} else { } else {
StyleComponent::Plain.components(interactive_terminal) StyleComponent::Plain.components(interactive_terminal)
} }
@@ -49,14 +48,6 @@ impl StyleComponent {
StyleComponent::LineNumbers, StyleComponent::LineNumbers,
StyleComponent::Snip, StyleComponent::Snip,
], ],
StyleComponent::Default => &[
#[cfg(feature = "git")]
StyleComponent::Changes,
StyleComponent::Grid,
StyleComponent::HeaderFilename,
StyleComponent::LineNumbers,
StyleComponent::Snip,
],
StyleComponent::Plain => &[], StyleComponent::Plain => &[],
} }
} }
@@ -78,7 +69,6 @@ impl FromStr for StyleComponent {
"numbers" => Ok(StyleComponent::LineNumbers), "numbers" => Ok(StyleComponent::LineNumbers),
"snip" => Ok(StyleComponent::Snip), "snip" => Ok(StyleComponent::Snip),
"full" => Ok(StyleComponent::Full), "full" => Ok(StyleComponent::Full),
"default" => Ok(StyleComponent::Default),
"plain" => Ok(StyleComponent::Plain), "plain" => Ok(StyleComponent::Plain),
_ => Err(format!("Unknown style '{}'", s).into()), _ => Err(format!("Unknown style '{}'", s).into()),
} }

View File

@@ -7,7 +7,7 @@ use globset::{Candidate, GlobBuilder, GlobMatcher};
pub mod ignored_suffixes; pub mod ignored_suffixes;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive] #[non_exhaustive]
pub enum MappingTarget<'a> { pub enum MappingTarget<'a> {
/// For mapping a path to a specific syntax. /// For mapping a path to a specific syntax.
@@ -41,9 +41,6 @@ impl<'a> SyntaxMapping<'a> {
pub fn builtin() -> SyntaxMapping<'a> { pub fn builtin() -> SyntaxMapping<'a> {
let mut mapping = Self::empty(); let mut mapping = Self::empty();
mapping.insert("*.h", MappingTarget::MapTo("C++")).unwrap(); mapping.insert("*.h", MappingTarget::MapTo("C++")).unwrap();
mapping
.insert(".clang-format", MappingTarget::MapTo("YAML"))
.unwrap();
mapping.insert("*.fs", MappingTarget::MapTo("F#")).unwrap(); mapping.insert("*.fs", MappingTarget::MapTo("F#")).unwrap();
mapping mapping
.insert("build", MappingTarget::MapToUnknown) .insert("build", MappingTarget::MapToUnknown)
@@ -66,14 +63,6 @@ impl<'a> SyntaxMapping<'a> {
mapping mapping
.insert("*.pac", MappingTarget::MapTo("JavaScript (Babel)")) .insert("*.pac", MappingTarget::MapTo("JavaScript (Babel)"))
.unwrap(); .unwrap();
mapping
.insert("fish_history", MappingTarget::MapTo("YAML"))
.unwrap();
// See #2151, https://nmap.org/book/nse-language.html
mapping
.insert("*.nse", MappingTarget::MapTo("Lua"))
.unwrap();
// See #1008 // See #1008
mapping mapping
@@ -128,32 +117,13 @@ impl<'a> SyntaxMapping<'a> {
mapping.insert(glob, MappingTarget::MapTo("INI")).unwrap(); mapping.insert(glob, MappingTarget::MapTo("INI")).unwrap();
} }
// unix mail spool
for glob in &["/var/spool/mail/*", "/var/mail/*"] {
mapping.insert(glob, MappingTarget::MapTo("Email")).unwrap()
}
// pacman hooks // pacman hooks
mapping mapping
.insert("*.hook", MappingTarget::MapTo("INI")) .insert("*.hook", MappingTarget::MapTo("INI"))
.unwrap(); .unwrap();
// Global git config files rooted in `$XDG_CONFIG_HOME/git/` or `$HOME/.config/git/` if let Some(xdg_config_home) = std::env::var_os("XDG_CONFIG_HOME") {
// See e.g. https://git-scm.com/docs/git-config#FILES let git_config_path = Path::new(&xdg_config_home).join("git");
if let Some(xdg_config_home) =
std::env::var_os("XDG_CONFIG_HOME").filter(|val| !val.is_empty())
{
insert_git_config_global(&mut mapping, &xdg_config_home);
}
if let Some(default_config_home) = std::env::var_os("HOME")
.filter(|val| !val.is_empty())
.map(|home| Path::new(&home).join(".config"))
{
insert_git_config_global(&mut mapping, &default_config_home);
}
fn insert_git_config_global(mapping: &mut SyntaxMapping, config_home: impl AsRef<Path>) {
let git_config_path = config_home.as_ref().join("git");
mapping mapping
.insert( .insert(
@@ -194,7 +164,6 @@ impl<'a> SyntaxMapping<'a> {
} }
pub(crate) fn get_syntax_for(&self, path: impl AsRef<Path>) -> Option<MappingTarget<'a>> { pub(crate) fn get_syntax_for(&self, path: impl AsRef<Path>) -> Option<MappingTarget<'a>> {
// Try matching on the file name as-is.
let candidate = Candidate::new(&path); let candidate = Candidate::new(&path);
let candidate_filename = path.as_ref().file_name().map(Candidate::new); let candidate_filename = path.as_ref().file_name().map(Candidate::new);
for (ref glob, ref syntax) in self.mappings.iter().rev() { for (ref glob, ref syntax) in self.mappings.iter().rev() {
@@ -206,13 +175,7 @@ impl<'a> SyntaxMapping<'a> {
return Some(*syntax); return Some(*syntax);
} }
} }
// Try matching on the file name after removing an ignored suffix. None
let file_name = path.as_ref().file_name()?;
self.ignored_suffixes
.try_with_stripped_suffix(file_name, |stripped_file_name| {
Ok(self.get_syntax_for(stripped_file_name))
})
.ok()?
} }
pub fn insert_ignored_suffix(&mut self, suffix: &'a str) { pub fn insert_ignored_suffix(&mut self, suffix: &'a str) {

View File

@@ -1,5 +1,5 @@
# Make sure that the pager gets executed # Make sure that the pager gets executed
--paging=always --paging=always
# Output a dummy message for the integration test and system wide config test. # Output a dummy message for the integration test.
--pager="echo dummy-pager-from-config" --pager="echo dummy-pager-from-config"

View File

@@ -1,3 +0,0 @@
[user]
email = foo@bar.net
name = foobar

View File

@@ -1,3 +0,0 @@
[user]
email = foo@bar.net
name = foobar

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
# Make sure that the pager gets executed
--paging=always
# Output a dummy message for the integration test.
--pager="echo dummy-pager-from-system-config"

View File

@@ -1 +0,0 @@
{"test": "value"}

View File

@@ -1 +0,0 @@
{"test": "value"}

View File

@@ -1 +0,0 @@
hello world

File diff suppressed because one or more lines are too long

View File

@@ -18,7 +18,7 @@ gpl_occurances=$(git grep --recurse-submodules "${gpl_term}" -- "${gpl_excludes[
if [ -z "${gpl_occurances}" ]; then if [ -z "${gpl_occurances}" ]; then
echo "PASS: No files under GPL were found" echo "PASS: No files under GPL were found"
else else
echo "FAIL: GPL:ed code is not compatible with bat, but occurrences of '${gpl_term}' were found:" echo "FAIL: GPL:ed code is not compatible with bat, but occurances of '${gpl_term}' were found:"
echo "${gpl_occurances}" echo "${gpl_occurances}"
exit 1 exit 1
fi fi

View File

@@ -1,13 +1,13 @@
#[cfg(feature = "git")]
mod tester; mod tester;
use crate::tester::BatTester;
macro_rules! snapshot_tests { macro_rules! snapshot_tests {
($($test_name: ident: $style: expr,)*) => { ($($test_name: ident: $style: expr,)*) => {
$( $(
#[test] #[test]
#[cfg(feature = "git")]
fn $test_name() { fn $test_name() {
let bat_tester = tester::BatTester::default(); let bat_tester = BatTester::default();
bat_tester.test_snapshot(stringify!($test_name), $style); bat_tester.test_snapshot(stringify!($test_name), $style);
} }
)* )*

View File

@@ -3,6 +3,5 @@
# <file system> <dir> <type> <options> <dump> <pass> # <file system> <dir> <type> <options> <dump> <pass>
UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 0 0 UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 0 1
UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 1 1 UUID=62F8-2047 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2
UUID=62F8-2047 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 2 2

View File

@@ -1,5 +0,0 @@
[section]
key=value
# This file is just for testing that the INI syntax is registered to handle
# the .inf file extension, it is not testing the syntax highlighting capabilities
# of the INI syntax itself

View File

@@ -1,60 +0,0 @@
import "../imported-file" ;
# With Comments !
def weird($a; $b; $c):
 [ $a, $b, $c ] | transpose | reduce .[][] as $item (
 [];
 . + $item.property
 )
;
. | weird (.a; .b; .c) |
(
if (. | contains("never") ) then
 "Why yes"
else
 12.23
end
) as $never |
{
 hello,
 why: "because",
 hello: ( weird | ascii_upcase ),
 format_eg: ( . | @json "My json string \( . | this | part | just | white | ascii_upcase | transpose)" ),
 never: $never,
 "literal_key": literal_value,
 "this": 12.1e12,
 "part": "almost"
 "like": [
 12,
 2
 "json"
 {
 "quite": {
 similar: "but not quite"
 }
 }
 ],
} | (
 
 # And with very basic brace matching
 
 # Invalid End
 ] 
 
 # Other invalid ends
 ( [ } ] )
 # A "valid" sequence
 ( [ { key: () , other_key:( [ [] [[]] ] ), gaga } ] )
 # A "invalid" sequence
 ( [ { key: () , other_key:( [ [] [[] ] ), gaga } ] )
 "A string\n whith escaped characters \" because we can"
)

View File

@@ -1,3 +1,2 @@
2021-03-06 23:22:21.392 https://[2001:db8:4006:812::200e]:8080/path/the%20page.html 2021-03-06 23:22:21.392 https://[2001:db8:4006:812::200e]:8080/path/the%20page.html
2021-03-06 23:22:21 https://example.com:8080/path/the%20page(with_parens).html 2021-03-06 23:22:21 https://example.com:8080/path/the%20page(with_parens).html
2022-03-16T17:41:02.519 helix_term::application [WARN] unhandled window/showMessage: ShowMessageParams { typ: Error, message: "rust-analyzer failed to load workspace: Failed to read Cargo metadata from Cargo.toml file /home/zeta/dev/raytracer/Cargo.toml, cargo 1.61.0-nightly (65c8266 2022-03-09): Failed to run `\"cargo\" \"metadata\" \"--format-version\" \"1\" \"--manifest-path\" \"/home/zeta/dev/raytracer/Cargo.toml\" \"--filter-platform\" \"wasm32-unknown-unknown\"`: `cargo metadata` exited with an error: Updating crates.io index\nerror: failed to select a version for `parking_lot`.\n ... required by package `raytracer v0.1.0 (/home/zeta/dev/raytracer)`\nversions that meet the requirements `^0.12.0` are: 0.12.0\n\nthe package `raytracer` depends on `parking_lot`, with features: `wasm-bindgen` but `parking_lot` does not have these features.\n\n\nfailed to select a version for `parking_lot` which could resolve this conflict\n" }

View File

@@ -1,34 +0,0 @@
--- Finds factorial of a number.
-- @param value Number to find factorial.
-- @return Factorial of number.
local function factorial(value)
 if value <= 1 then
 return 1
 else
 return value * factorial(value - 1)
 end
end
--- Joins a table of strings into a new string.
-- @param table Table of strings.
-- @param separator Separator character.
-- @return Joined string.
local function join(table, separator)
 local data = ""
 
 for index, value in ipairs(table) do
 data = data .. value .. separator
 end
 
 data = data:sub(1, data:len() - 1)
 
 return data
end
local a = factorial(5)
print(a)
local b = join({ "l", "u", "a" }, ",")
print(b)

View File

@@ -1,4 +1,4 @@
# PowerShell script for testing syntax highlighting # PowerShell script for testing syntax highlighting
function Get-FutureTime { function Get-FutureTime {
 param (  param (

View File

@@ -27,13 +27,9 @@
</script> </script>
<script type="text/livescript"> <script type="text/livescript">
 // This block is a regression test for a bat panic when a LiveScript syntax definition is missing  // This block is a regression test for a bat panic when a LiveScript syntax definition is missing
</script> </script>
<style lang="text/postcss">
 /* This block is a regression test for a bat panic when a PostCSS syntax definition is missing */
</style>
<style> <style>
 main {  main {
 position: relative;  position: relative;

View File

@@ -1,7 +1,7 @@
Apr 4 00:00:01 hostname-here systemd[1]: logrotate.service: Succeeded. Apr 4 00:00:01 hostname-here systemd[1]: logrotate.service: Succeeded.
Apr 4 00:00:01 hostname-here systemd[1]: Finished Rotate log files. Apr 4 00:00:01 hostname-here systemd[1]: Finished Rotate log files.
Apr 4 00:00:01 hostname-here colord[920]: failed to get session [pid 137485]: No data available Apr 4 00:00:01 hostname-here colord[920]: failed to get session [pid 137485]: No data available
Apr 4 00:00:21 hostname-here kernel: [55604.908232] audit: type=1400 audit(1617483621.094:28): apparmor="DENIED" operation="capable" profile="/usr/sbin/cups-browsed" pid=59311 comm="cups-browsed" capability=23 capname="sys_nice" Apr 4 00:00:21 hostname-here kernel: [55604.908232] audit: type=1400 audit(1617483621.094:28): apparmor="DENIED" operation="capable" profile="/usr/sbin/cups-browsed" pid=59311 comm="cups-browsed" capability=23 capname="sys_nice"
Apr 4 00:01:38 hostname-here systemd-resolved[721]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP. Apr 4 00:01:38 hostname-here systemd-resolved[721]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.
Apr 4 00:04:46 hostname-here ntpd[952]: Soliciting pool server 255.76.59.37 Apr 4 00:04:46 hostname-here ntpd[952]: Soliciting pool server 255.76.59.37
Apr 4 00:05:21 hostname-here ntpd[952]: ::1 local addr 0:0:0:0:0:0:0:1 -> <null> Apr 4 00:05:21 hostname-here ntpd[952]: ::1 local addr 0:0:0:0:0:0:0:1 -> <null>
@@ -10,7 +10,7 @@
Apr 4 16:32:07 hostname-here NetworkManager[740]: <info> [1617629527.1101] manager: NetworkManager state is now CONNECTED_GLOBAL Apr 4 16:32:07 hostname-here NetworkManager[740]: <info> [1617629527.1101] manager: NetworkManager state is now CONNECTED_GLOBAL
Apr 4 22:00:45 hostname-here dbus-daemon[1094]: [session uid=1000 pid=1094] Successfully activated service 'io.github.celluloid_player.Celluloid' Apr 4 22:00:45 hostname-here dbus-daemon[1094]: [session uid=1000 pid=1094] Successfully activated service 'io.github.celluloid_player.Celluloid'
Aug 11 13:29:06 hostname-here insomnia_insomnia.desktop[142666]: 13:29:06.316 [updater] Updater not running platform=linux dev=false Aug 11 13:29:06 hostname-here insomnia_insomnia.desktop[142666]: 13:29:06.316 [updater] Updater not running platform=linux dev=false
Aug 11 13:36:34 192.168.220.5 nginx: 2021/08/11 13:36:34 [debug] 2031#2031: epoll add event: fd:6 op:1 ev:00002001 Aug 11 13:36:34 192.168.220.5 nginx: 2021/08/11 13:36:34 [debug] 2031#2031: epoll add event: fd:6 op:1 ev:00002001
Aug 11 21:31:08 ::1 nginx: 2021/08/11 21:31:08 [debug] 760831#760831: epoll add event: fd:6 op:1 ev:10000001 Aug 11 21:31:08 ::1 nginx: 2021/08/11 21:31:08 [debug] 760831#760831: epoll add event: fd:6 op:1 ev:10000001
Aug 11 21:40:31 hostname-here scop hello Aug 11 21:40:31 hostname-here scop hello
Aug 16 21:38:21 hostname-here systemd[1]: Finished Cleanup of Temporary Directories. Aug 16 21:38:21 hostname-here systemd[1]: Finished Cleanup of Temporary Directories.

View File

@@ -1 +0,0 @@
const dummy: string = "Regression test for https://github.com/sharkdp/bat/pull/2236";

View File

@@ -8,11 +8,6 @@
 </div>  </div>
</template> </template>
<template lang='pug'>
 #container.col
 p This shall be formatted as Plain Text as long as a Pug syntax definition is missing
</template>
<script> <script>
import AppHeader from "@/components/AppHeader"; import AppHeader from "@/components/AppHeader";
import AppLoadingIndicator from "@/components/AppLoadingIndicator"; import AppLoadingIndicator from "@/components/AppLoadingIndicator";

View File

@@ -1,18 +1,18 @@
//! this is a top level doc, starts with "//!" //! this is a top level doc, starts with "//!"
const std = @import("std"); const std = @import("std");
pub fn main() anyerror!void { pub fn main() anyerror!void {
 const stdout = std.io.getStdOut().writer();  const stdout = std.io.getStdOut().writer();
 try stdout.print("Hello, {}!\n", .{"world"});  try stdout.print("Hello, {}!\n", .{"world"});
} }
const expect = std.testing.expect; const expect = std.testing.expect;
test "comments" { test "comments" {
 // comments start with "//" until newline  // comments start with "//" until newline
 // foo bar baz  // foo bar baz
 const x = true; // another comment  const x = true; // another comment
 expect(x);  expect(x);
} }
@@ -25,26 +25,26 @@
 /// number of nanoseconds past the second  /// number of nanoseconds past the second
 nano: u32,  nano: u32,
 const Self = @This();  const Self = @This();
 pub fn unixEpoch() Self {  pub fn unixEpoch() Self {
 return Self{  return Self{
 .seconds = 0,  .seconds = 0,
 .nanos = 0,  .nanos = 0,
 };  };
 }  }
}; };
const my_val = switch (std.Target.current.os.tag) { const my_val = switch (std.Target.current.os.tag) {
 .linux => "Linux",  .linux => "Linux",
 else => "not Linux",  else => "not Linux",
}; };
const Book = enum { const Book = enum {
 paperback,  paperback,
 hardcover,  hardcover,
 ebook,  ebook,
 pdf,  pdf,
}; };
const TokenType = union(enum) { const TokenType = union(enum) {
@@ -54,54 +54,54 @@
}; };
const array_lit: [4]u8 = .{ 11, 22, 33, 44 }; const array_lit: [4]u8 = .{ 11, 22, 33, 44 };
const sentinal_lit = [_:0]u8{ 1, 2, 3, 4 }; const sentinal_lit = [_:0]u8{ 1, 2, 3, 4 };
test "address of syntax" { test "address of syntax" {
 // Get the address of a variable:  // Get the address of a variable:
 const x: i32 = 1234;  const x: i32 = 1234;
 const x_ptr = &x;  const x_ptr = &x;
 // Dereference a pointer:  // Dereference a pointer:
 expect(x_ptr.* == 1234);  expect(x_ptr.* == 1234);
 // When you get the address of a const variable, you get a const pointer to a single item.  // When you get the address of a const variable, you get a const pointer to a single item.
 expect(@TypeOf(x_ptr) == *const i32);  expect(@TypeOf(x_ptr) == *const i32);
 // If you want to mutate the value, you'd need an address of a mutable variable:  // If you want to mutate the value, you'd need an address of a mutable variable:
 var y: i32 = 5678;  var y: i32 = 5678;
 const y_ptr = &y;  const y_ptr = &y;
 expect(@TypeOf(y_ptr) == *i32);  expect(@TypeOf(y_ptr) == *i32);
 y_ptr.* += 1;  y_ptr.* += 1;
 expect(y_ptr.* == 5679);  expect(y_ptr.* == 5679);
} }
// integer literals // integer literals
const decimal_int = 98222; const decimal_int = 98222;
const hex_int = 0xff; const hex_int = 0xff;
const another_hex_int = 0xFF; const another_hex_int = 0xFF;
const octal_int = 0o755; const octal_int = 0o755;
const binary_int = 0b11110000; const binary_int = 0b11110000;
// underscores may be placed between two digits as a visual separator // underscores may be placed between two digits as a visual separator
const one_billion = 1_000_000_000; const one_billion = 1_000_000_000;
const binary_mask = 0b1_1111_1111; const binary_mask = 0b1_1111_1111;
const permissions = 0o7_5_5; const permissions = 0o7_5_5;
const big_address = 0xFF80_0000_0000_0000; const big_address = 0xFF80_0000_0000_0000;
// float literals // float literals
const floating_point = 123.0E+77; const floating_point = 123.0E+77;
const another_float = 123.0; const another_float = 123.0;
const yet_another = 123.0e+77; const yet_another = 123.0e+77;
const hex_floating_point = 0x103.70p-5; const hex_floating_point = 0x103.70p-5;
const another_hex_float = 0x103.70; const another_hex_float = 0x103.70;
const yet_another_hex_float = 0x103.70P-5; const yet_another_hex_float = 0x103.70P-5;
// underscores may be placed between two digits as a visual separator // underscores may be placed between two digits as a visual separator
const lightspeed = 299_792_458.000_000; const lightspeed = 299_792_458.000_000;
const nanosecond = 0.000_000_001; const nanosecond = 0.000_000_001;
const more_hex = 0x1234_5678.9ABC_CDEFp-10; const more_hex = 0x1234_5678.9ABC_CDEFp-10;
fn max(comptime T: type, a: T, b: T) T { fn max(comptime T: type, a: T, b: T) T {
 return if (a > b) a else b;  return if (a > b) a else b;
} }

View File

@@ -1,54 +0,0 @@
bat 0.20.0 (e735562-modified)
A cat(1) clone with syntax highlighting and Git integration.
USAGE:
 bat [OPTIONS] [FILE]...
 bat <SUBCOMMAND>
OPTIONS:
 -A, --show-all
 Show non-printable characters (space, tab, newline, ..).
 -p, --plain Show plain style (alias for '--style=plain').
 -l, --language <language> Set the language for syntax highlighting.
 -H, --highlight-line <N:M>... Highlight lines N through M.
 --file-name <name>... Specify the name to display for a file.
 -d, --diff
 Only show lines that have been added/removed/modified.
 --tabs <T> Set the tab width to T spaces.
 --wrap <mode>
 Specify the text-wrapping mode (*auto*, never, character).
 -n, --number
 Show line numbers (alias for '--style=numbers').
 --color <when> When to use colors (*auto*, never, always).
 --italic-text <when> Use italics in output (always, *never*)
 --decorations <when>
 When to show the decorations (*auto*, never, always).
 --paging <when>
 Specify when to use the pager, or use `-P` to disable (*auto*, never,
 always).
 -m, --map-syntax <glob:syntax>...
 Use the specified syntax for files matching the glob pattern
 ('*.cpp:C++').
 --theme <theme> Set the color theme for syntax highlighting.
 --list-themes Display all supported highlighting themes.
 --style <components>
 Comma-separated list of style elements to display (*auto*, full, plain,
 changes, header, grid, rule, numbers, snip).
 -r, --line-range <N:M>... Only print the lines from N to M.
 -L, --list-languages Display all supported languages.
 -h, --help Print this help message.
 -V, --version Show version information.
ARGS:
 <FILE>... File(s) to print / concatenate. Use '-' for standard input.
SUBCOMMANDS:
 cache Modify the syntax-definition and theme cache
Note: `bat -h` prints a short and concise overview while `bat --help` gives all
details.

View File

@@ -1,11 +0,0 @@
- cmd: echo "hello world"
 when: 1656950812
- cmd: ls /tmp
 when: 1656950818
 paths:
 - /tmp
- cmd: cp .local/share/fish/fish_history .
 when: 1656950833
 paths:
 - .local/share/fish/fish_history
 - .

View File

@@ -3,6 +3,5 @@
# <file system> <dir> <type> <options> <dump> <pass> # <file system> <dir> <type> <options> <dump> <pass>
UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 0 0 UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 0 1
UUID=9e6faddf-31ab-3f3e-9b50-2ad4fbc2ea8b / ext4 rw,relatime,data=ordered 1 1 UUID=62F8-2047 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2
UUID=62F8-2047 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 2 2

View File

@@ -1,5 +0,0 @@
[section]
key=value
# This file is just for testing that the INI syntax is registered to handle
# the .inf file extension, it is not testing the syntax highlighting capabilities
# of the INI syntax itself

View File

@@ -1,25 +0,0 @@
The `sample.jq` file was taken from [SublimeJQ] under the following license:
[SublimeJQ]: https://github.com/zogwarg/SublimeJQ
MIT License
Copyright (c) 2017 Thomas Buick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,60 +0,0 @@
import "../imported-file" ;
# With Comments !
def weird($a; $b; $c):
[ $a, $b, $c ] | transpose | reduce .[][] as $item (
[];
. + $item.property
)
;
. | weird (.a; .b; .c) |
(
if (. | contains("never") ) then
"Why yes"
else
12.23
end
) as $never |
{
hello,
why: "because",
hello: ( weird | ascii_upcase ),
format_eg: ( . | @json "My json string \( . | this | part | just | white | ascii_upcase | transpose)" ),
never: $never,
"literal_key": literal_value,
"this": 12.1e12,
"part": "almost"
"like": [
12,
2
"json"
{
"quite": {
similar: "but not quite"
}
}
],
} | (
# And with very basic brace matching
# Invalid End
]
# Other invalid ends
( [ } ] )
# A "valid" sequence
( [ { key: () , other_key:( [ [] [[]] ] ), gaga } ] )
# A "invalid" sequence
( [ { key: () , other_key:( [ [] [[] ] ), gaga } ] )
"A string\n whith escaped characters \" because we can"
)

View File

@@ -1,3 +1,2 @@
2021-03-06 23:22:21.392 https://[2001:db8:4006:812::200e]:8080/path/the%20page.html 2021-03-06 23:22:21.392 https://[2001:db8:4006:812::200e]:8080/path/the%20page.html
2021-03-06 23:22:21 https://example.com:8080/path/the%20page(with_parens).html 2021-03-06 23:22:21 https://example.com:8080/path/the%20page(with_parens).html
2022-03-16T17:41:02.519 helix_term::application [WARN] unhandled window/showMessage: ShowMessageParams { typ: Error, message: "rust-analyzer failed to load workspace: Failed to read Cargo metadata from Cargo.toml file /home/zeta/dev/raytracer/Cargo.toml, cargo 1.61.0-nightly (65c8266 2022-03-09): Failed to run `\"cargo\" \"metadata\" \"--format-version\" \"1\" \"--manifest-path\" \"/home/zeta/dev/raytracer/Cargo.toml\" \"--filter-platform\" \"wasm32-unknown-unknown\"`: `cargo metadata` exited with an error: Updating crates.io index\nerror: failed to select a version for `parking_lot`.\n ... required by package `raytracer v0.1.0 (/home/zeta/dev/raytracer)`\nversions that meet the requirements `^0.12.0` are: 0.12.0\n\nthe package `raytracer` depends on `parking_lot`, with features: `wasm-bindgen` but `parking_lot` does not have these features.\n\n\nfailed to select a version for `parking_lot` which could resolve this conflict\n" }

View File

@@ -1,34 +0,0 @@
--- Finds factorial of a number.
-- @param value Number to find factorial.
-- @return Factorial of number.
local function factorial(value)
if value <= 1 then
return 1
else
return value * factorial(value - 1)
end
end
--- Joins a table of strings into a new string.
-- @param table Table of strings.
-- @param separator Separator character.
-- @return Joined string.
local function join(table, separator)
local data = ""
for index, value in ipairs(table) do
data = data .. value .. separator
end
data = data:sub(1, data:len() - 1)
return data
end
local a = factorial(5)
print(a)
local b = join({ "l", "u", "a" }, ",")
print(b)

View File

@@ -27,13 +27,9 @@
</script> </script>
<script type="text/livescript"> <script type="text/livescript">
// This block is a regression test for a bat panic when a LiveScript syntax definition is missing // This block is a regression test for a bat panic when a LiveScript syntax definition is missing
</script> </script>
<style lang="text/postcss">
/* This block is a regression test for a bat panic when a PostCSS syntax definition is missing */
</style>
<style> <style>
main { main {
position: relative; position: relative;

View File

@@ -1 +0,0 @@
const dummy: string = "Regression test for https://github.com/sharkdp/bat/pull/2236";

View File

@@ -8,11 +8,6 @@
</div> </div>
</template> </template>
<template lang='pug'>
#container.col
p This shall be formatted as Plain Text as long as a Pug syntax definition is missing
</template>
<script> <script>
import AppHeader from "@/components/AppHeader"; import AppHeader from "@/components/AppHeader";
import AppLoadingIndicator from "@/components/AppLoadingIndicator"; import AppLoadingIndicator from "@/components/AppLoadingIndicator";

View File

@@ -1,54 +0,0 @@
bat 0.20.0 (e735562-modified)
A cat(1) clone with syntax highlighting and Git integration.
USAGE:
bat [OPTIONS] [FILE]...
bat <SUBCOMMAND>
OPTIONS:
-A, --show-all
Show non-printable characters (space, tab, newline, ..).
-p, --plain Show plain style (alias for '--style=plain').
-l, --language <language> Set the language for syntax highlighting.
-H, --highlight-line <N:M>... Highlight lines N through M.
--file-name <name>... Specify the name to display for a file.
-d, --diff
Only show lines that have been added/removed/modified.
--tabs <T> Set the tab width to T spaces.
--wrap <mode>
Specify the text-wrapping mode (*auto*, never, character).
-n, --number
Show line numbers (alias for '--style=numbers').
--color <when> When to use colors (*auto*, never, always).
--italic-text <when> Use italics in output (always, *never*)
--decorations <when>
When to show the decorations (*auto*, never, always).
--paging <when>
Specify when to use the pager, or use `-P` to disable (*auto*, never,
always).
-m, --map-syntax <glob:syntax>...
Use the specified syntax for files matching the glob pattern
('*.cpp:C++').
--theme <theme> Set the color theme for syntax highlighting.
--list-themes Display all supported highlighting themes.
--style <components>
Comma-separated list of style elements to display (*auto*, full, plain,
changes, header, grid, rule, numbers, snip).
-r, --line-range <N:M>... Only print the lines from N to M.
-L, --list-languages Display all supported languages.
-h, --help Print this help message.
-V, --version Show version information.
ARGS:
<FILE>... File(s) to print / concatenate. Use '-' for standard input.
SUBCOMMANDS:
cache Modify the syntax-definition and theme cache
Note: `bat -h` prints a short and concise overview while `bat --help` gives all
details.

View File

@@ -1,11 +0,0 @@
- cmd: echo "hello world"
when: 1656950812
- cmd: ls /tmp
when: 1656950818
paths:
- /tmp
- cmd: cp .local/share/fish/fish_history .
when: 1656950833
paths:
- .local/share/fish/fish_history
- .

View File

@@ -1,29 +0,0 @@
use predicates::{prelude::predicate, str::PredicateStrExt};
mod utils;
use utils::command::bat_with_config;
// This test is ignored, as it needs a special system wide config put into place.
// In order to run this tests, use `cargo test --test system_wide_config -- --ignored`
#[test]
#[ignore]
fn use_systemwide_config() {
bat_with_config()
.arg("test.txt")
.assert()
.success()
.stdout(predicate::eq("dummy-pager-from-system-config\n").normalize());
}
// This test is ignored, as it needs a special system wide config put into place
// In order to run this tests, use `cargo test --test system_wide_config -- --ignored`
#[test]
#[ignore]
fn config_overrides_system_config() {
bat_with_config()
.env("BAT_CONFIG_PATH", "bat.conf")
.arg("test.txt")
.assert()
.success()
.stdout(predicate::eq("dummy-pager-from-config\n").normalize());
}

View File

@@ -1,16 +0,0 @@
use bat::PrettyPrinter;
#[test]
fn syntaxes() {
let printer = PrettyPrinter::new();
let syntaxes: Vec<String> = printer.syntaxes().map(|s| s.name).collect();
// Just do some sanity checking
assert!(syntaxes.contains(&"Rust".to_string()));
assert!(syntaxes.contains(&"Java".to_string()));
assert!(!syntaxes.contains(&"this-language-does-not-exist".to_string()));
// This language exists but is hidden, so we should not see it; it shall
// have been filtered out before getting to us
assert!(!syntaxes.contains(&"Git Common".to_string()));
}

View File

@@ -1,38 +0,0 @@
#![allow(unused)] // Because indirectly included by e.g.integration_tests.rs, but not everything inside is used
use assert_cmd::cargo::CommandCargoExt;
use std::process::Command;
pub fn bat_raw_command_with_config() -> Command {
let mut cmd = Command::cargo_bin("bat").unwrap();
cmd.current_dir("tests/examples");
cmd.env_remove("BAT_CACHE_PATH");
cmd.env_remove("BAT_CONFIG_DIR");
cmd.env_remove("BAT_CONFIG_PATH");
cmd.env_remove("BAT_OPTS");
cmd.env_remove("BAT_PAGER");
cmd.env_remove("BAT_STYLE");
cmd.env_remove("BAT_TABS");
cmd.env_remove("BAT_THEME");
cmd.env_remove("COLORTERM");
cmd.env_remove("NO_COLOR");
cmd.env_remove("PAGER");
cmd
}
#[cfg(test)]
pub fn bat_raw_command() -> Command {
let mut cmd = bat_raw_command_with_config();
cmd.arg("--no-config");
cmd
}
#[cfg(test)]
pub fn bat_with_config() -> assert_cmd::Command {
assert_cmd::Command::from_std(bat_raw_command_with_config())
}
#[cfg(test)]
pub fn bat() -> assert_cmd::Command {
assert_cmd::Command::from_std(bat_raw_command())
}

View File

@@ -1,5 +1,3 @@
#![allow(unused)] // Because indirectly included by e.g. system_wide_config.rs, but not used
use assert_cmd::Command; use assert_cmd::Command;
use predicates::prelude::predicate; use predicates::prelude::predicate;
use std::env; use std::env;

View File

@@ -1,2 +1 @@
pub mod command;
pub mod mocked_pagers; pub mod mocked_pagers;