1
0
mirror of https://github.com/sharkdp/bat synced 2026-08-04 19:01:44 +00:00

Compare commits

...

77 Commits

Author SHA1 Message Date
Keith Hall 979ba22628 Merge pull request #3510 from sharkdp/prepare_release
Prepare for next release
2025-12-02 22:44:14 +02:00
Keith Hall 19ab724a73 Prepare for next release 2025-12-02 22:33:02 +02:00
Keith Hall def49e19a7 Merge pull request #3509 from sharkdp/ksh
Add syntax detection for files with ksh shebang lines
2025-12-02 22:15:48 +02:00
Keith Hall 1fb269a0fb Add syntax detection for files with ksh shebang lines 2025-12-02 22:06:21 +02:00
Keith Hall 0e469634a3 return None for get_pager_executable when builtin pager is used (#3498) 2025-12-01 20:02:55 +00:00
Keith Hall 6dfe471686 Merge pull request #3507 from sharkdp/help_read_theme_from_config
Ensure --help respects valid config file
2025-12-01 21:36:58 +02:00
Keith Hall 2c7fc5f926 update changelog 2025-12-01 06:51:04 +02:00
Keith Hall 579d371378 Ensure --help respects valid config file
While still ignoring ignoring invalid arguments in the config
2025-12-01 05:30:05 +02:00
auto-merge-dependabot-prs[bot] c74ca27075 Merge pull request #3500 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/Idris2-bbfe50e
build(deps): bump assets/syntaxes/02_Extra/Idris2 from `2874f20` to `bbfe50e`
2025-12-01 03:21:57 +00:00
dependabot[bot] e8f7b12bb1 build(deps): bump assets/syntaxes/02_Extra/Idris2
Bumps [assets/syntaxes/02_Extra/Idris2](https://github.com/buzden/sublime-syntax-idris2) from `2874f20` to `bbfe50e`.
- [Commits](https://github.com/buzden/sublime-syntax-idris2/compare/2874f206f56c588a29fd76b88043129471d1454a...bbfe50e023e0edc74f5e0c003eb946528d49279f)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/Idris2
  dependency-version: bbfe50e023e0edc74f5e0c003eb946528d49279f
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 03:06:08 +00:00
Keith Hall e7006b53e3 Merge pull request #3497 from xduugu/quadlet
Add syntax mapping for podman's `artifact` quadlet files
2025-11-30 14:26:53 +02:00
Cedric Staniewski a6e0057c12 Add syntax mapping for podman's artifact quadlet files 2025-11-30 14:18:12 +02:00
Keith Hall 1ffed0c039 Merge pull request #3496 from sharkdp/decorations_auto
Restore expected behavior when piping output with styles configured and auto decorations
2025-11-30 05:14:01 +02:00
Keith Hall 602df893de Add additional test cases for -n in loop through mode 2025-11-30 05:02:13 +02:00
Keith Hall 3755f788ca Improve -n detection to handle combined flags correctly
Updated the logic to correctly handle combined short flags like -pn and -np.
The -n flag is only honored when it's either:
1. A standalone flag (-n or --number)
2. The last flag in a combined form that includes -p (e.g., -pn), or
3. In a combined form without -p (e.g., -An)

This ensures that -np (where -p overrides -n) correctly produces plain output,
while -pn (where -n overrides -p) produces line numbers.
2025-11-30 05:02:13 +02:00
Keith Hall abc7261488 Fix -n flag to show line numbers in loop-through mode
When the -n/--number flag is passed on the command line, bat now shows
line numbers even when piping output to another process (loop-through
mode), similar to how `cat -n` behaves.

This change detects if -n or --number was passed on the CLI (before
merging with config file and environment variables) and disables
loop-through mode in that case, allowing the InteractivePrinter to
add line numbers.

The existing behavior is preserved:
- Styles from config/env are still ignored when piping (unless --decorations=always is set)
- Only the -n flag from CLI enables line numbers in piped mode
- -p and --style options from CLI do not disable loop-through mode
2025-11-30 05:02:13 +02:00
Keith Hall f9c33971d9 Update readme to mention decorations 2025-11-30 05:02:13 +02:00
Keith Hall 7d37325c19 Fix to not show style decorations in auto mode when piping 2025-11-30 05:02:13 +02:00
Keith Hall d17481575a Merge pull request #3495 from sharkdp/powershell_completions
Update PowerShell completions for compatibility with PowerShell v5.1
2025-11-28 22:49:44 +02:00
Keith Hall 1ee1d8fdff update changelog 2025-11-27 21:57:47 +02:00
Keith Hall af8f0626ac Update PowerShell completions for compatibility with PowerShell v5.1
Modified the PowerShell completion script to replace the null-coalescing operator (`??` - a v7 feature) with a conditional statement compatible with PowerShell v5.1. The script now uses an if-else check for null descriptions in the language completion section.
2025-11-27 21:50:17 +02:00
Keith Hall c88353b386 Merge pull request #3476 from sharkdp/docker_syntax_fix
Revert "Bump assets/syntaxes/02_Extra/Docker from `0f6b7bc` to `c001fb2` (#3024)"
2025-11-26 22:19:06 +02:00
Keith Hall 961f367ca8 use newer MacOS runner images
otherwise CI fails due to the brownout https://github.com/actions/runner-images/issues/13046
2025-11-26 22:07:06 +02:00
Keith Hall 8bf3be5e61 Revert "Patch Dockerfile to replace reference to non-existent context"
This reverts commit a4212e99b0.

No longer needed because we reverted the Docker submodule.
2025-11-25 22:43:58 +02:00
Keith Hall f8b6a009cb commit syntax dump to get integration tests to pass 2025-11-24 22:30:34 +02:00
Keith Hall efa9f0e63d add integration test to prove that building the cache finds all contexts 2025-11-24 22:20:44 +02:00
Keith Hall a4212e99b0 Patch Dockerfile to replace reference to non-existent context 2025-11-24 22:05:31 +02:00
Keith Hall 6884a8e7e0 Update changelog 2025-11-24 21:56:05 +02:00
Keith Hall a1b1feb247 Revert "Bump assets/syntaxes/02_Extra/Docker from 0f6b7bc to c001fb2 (#3024)"
This reverts commit 3838766dd4.
2025-11-24 21:56:05 +02:00
Muntasir Mahmud 70ec3fc24e feat: add paging to '-h' and '--help' (#3478)
* feat: add paging to '-h' and '--help'

Fixes #1587
2025-11-23 20:10:56 +00:00
Keith Hall 1e4a4b765f Merge pull request #3457 from abhinavcool42/fix/list-themes-pager-hang
fix: `--list-themes` pagination
2025-11-15 15:49:40 +02:00
Keith Hall cfe49779fa Merge branch 'master' into fix/list-themes-pager-hang 2025-11-15 15:41:07 +02:00
Keith Hall c51cff8961 Merge pull request #3481 from AldanTanneo/master
update Ada syntax gitmodule
2025-11-14 19:46:22 +02:00
AldanTanneo 1abecd2c93 update Ada syntax gitmodule 2025-11-14 11:41:08 +01:00
Keith Hall 3217a7e667 Merge pull request #3484 from cyqsimon/quadlet-update
Update quadlet syntax mapping to include `*.{build,pod}` files
2025-11-13 19:15:28 +02:00
cyqsimon 015cafdbdc Write changelog 2025-11-13 13:50:53 +08:00
cyqsimon f5a934c213 Update quadlet syntax mapping to include *.{build,pod} files 2025-11-13 13:44:24 +08:00
Abhinav Diwakar 24813db49f Merge branch 'master' into fix/list-themes-pager-hang 2025-11-06 23:26:06 +05:30
Benjamin A. Beasley ce856dbba7 Update etcetera to 0.11; no longer depend on home; MSRV 1.87
Release 0.11 of `etcetera` requires MSRV 1.87, in which
`std::env::home_dir` is no longer deprecated,
https://github.com/rust-lang/rust/pull/137327.

Update to that MSRV and to `etcetera`, and drop the dependency on the
`home` crate just as `etcetera` 0.11 did.
2025-11-03 19:06:33 +01:00
abhinavcool42 8b09724420 change imports 2025-11-02 11:55:30 +05:30
abhinavcool42 2af7be1b65 fix prefix 2025-11-02 11:51:00 +05:30
Abhinav Diwakar dac98da526 Merge branch 'master' into fix/list-themes-pager-hang 2025-11-02 11:35:27 +05:30
abhinavcool42 9456f7d8cd list-themes buffer added 2025-11-02 11:31:07 +05:30
auto-merge-dependabot-prs[bot] 3ecbd18e56 Merge pull request #3469 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/typst-syntax-highlight-363f0e7
build(deps): bump assets/syntaxes/02_Extra/typst-syntax-highlight from `4e2e68b` to `363f0e7`
2025-11-01 10:41:09 +00:00
dependabot[bot] 61fbc3fc0c build(deps): bump assets/syntaxes/02_Extra/typst-syntax-highlight
Bumps [assets/syntaxes/02_Extra/typst-syntax-highlight](https://github.com/hyrious/typst-syntax-highlight) from `4e2e68b` to `363f0e7`.
- [Release notes](https://github.com/hyrious/typst-syntax-highlight/releases)
- [Commits](https://github.com/hyrious/typst-syntax-highlight/compare/4e2e68b0a13555720a5ff0c4b32db98ddf490ed1...363f0e767c938c615a14912c302db7936f025fc2)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/typst-syntax-highlight
  dependency-version: 363f0e767c938c615a14912c302db7936f025fc2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 10:24:37 +00:00
auto-merge-dependabot-prs[bot] 5bcbd91943 Merge pull request #3472 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/Zig-c16d871
build(deps): bump assets/syntaxes/02_Extra/Zig from `8a4a3fe` to `c16d871`
2025-11-01 10:21:28 +00:00
dependabot[bot] cfe32fa219 build(deps): bump assets/syntaxes/02_Extra/Zig
Bumps [assets/syntaxes/02_Extra/Zig](https://github.com/ziglang/sublime-zig-language) from `8a4a3fe` to `c16d871`.
- [Release notes](https://github.com/ziglang/sublime-zig-language/releases)
- [Commits](https://github.com/ziglang/sublime-zig-language/compare/8a4a3fe4a051f85c4752b82f586d395cab843c06...c16d871ccccb3749f5a4b824f3fd44b143114565)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/Zig
  dependency-version: c16d871ccccb3749f5a4b824f3fd44b143114565
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 10:05:25 +00:00
auto-merge-dependabot-prs[bot] f0f4af864a Merge pull request #3470 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/cmd-help-273cb98
build(deps): bump assets/syntaxes/02_Extra/cmd-help from `c71ba41` to `273cb98`
2025-11-01 10:01:27 +00:00
dependabot[bot] 8bace0e808 build(deps): bump assets/syntaxes/02_Extra/cmd-help
Bumps [assets/syntaxes/02_Extra/cmd-help](https://github.com/victor-gp/cmd-help-sublime-syntax) from `c71ba41` to `273cb98`.
- [Commits](https://github.com/victor-gp/cmd-help-sublime-syntax/compare/c71ba410bdfcc8f627df3219f14e3f2be4fe68ba...273cb988177e96f4187e06008b13fa72ad22ae4d)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/cmd-help
  dependency-version: 273cb988177e96f4187e06008b13fa72ad22ae4d
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 09:40:14 +00:00
auto-merge-dependabot-prs[bot] 2f5cba7f8f Merge pull request #3473 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/SystemVerilog-b340f1c
build(deps): bump assets/syntaxes/02_Extra/SystemVerilog from `7eca705` to `b340f1c`
2025-11-01 09:37:25 +00:00
dependabot[bot] 528aa4fedd build(deps): bump assets/syntaxes/02_Extra/SystemVerilog
Bumps [assets/syntaxes/02_Extra/SystemVerilog](https://github.com/TheClams/SystemVerilog) from `7eca705` to `b340f1c`.
- [Commits](https://github.com/TheClams/SystemVerilog/compare/7eca705e87f87b94478fe222fc91d54d488cc8e3...b340f1c7f6a38d4da9f77be5abd6d455e5da7641)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/SystemVerilog
  dependency-version: b340f1c7f6a38d4da9f77be5abd6d455e5da7641
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 09:27:44 +00:00
auto-merge-dependabot-prs[bot] 490e1580ad Merge pull request #3471 from sharkdp/dependabot/cargo/serde_with-3.15.1
build(deps): bump serde_with from 3.12.0 to 3.15.1
2025-11-01 05:15:10 +00:00
dependabot[bot] cbfbfc8ff3 build(deps): bump serde_with from 3.12.0 to 3.15.1
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.12.0 to 3.15.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.12.0...v3.15.1)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 05:03:16 +00:00
auto-merge-dependabot-prs[bot] b6edf7ab0b Merge pull request #3468 from sharkdp/dependabot/cargo/prettyplease-0.2.37
build(deps): bump prettyplease from 0.2.35 to 0.2.37
2025-11-01 05:00:21 +00:00
dependabot[bot] 65e6b4de69 build(deps): bump prettyplease from 0.2.35 to 0.2.37
Bumps [prettyplease](https://github.com/dtolnay/prettyplease) from 0.2.35 to 0.2.37.
- [Release notes](https://github.com/dtolnay/prettyplease/releases)
- [Commits](https://github.com/dtolnay/prettyplease/compare/0.2.35...0.2.37)

---
updated-dependencies:
- dependency-name: prettyplease
  dependency-version: 0.2.37
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 04:42:58 +00:00
auto-merge-dependabot-prs[bot] 2ca62e25f1 Merge pull request #3474 from sharkdp/dependabot/cargo/git2-0.20.2
build(deps): bump git2 from 0.20.0 to 0.20.2
2025-11-01 04:39:53 +00:00
dependabot[bot] 1b2a814478 build(deps): bump git2 from 0.20.0 to 0.20.2
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.20.0 to 0.20.2.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.20.0...git2-0.20.2)

---
updated-dependencies:
- dependency-name: git2
  dependency-version: 0.20.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 04:22:33 +00:00
auto-merge-dependabot-prs[bot] e33967aa39 Merge pull request #3467 from sharkdp/dependabot/cargo/regex-1.12.2
build(deps): bump regex from 1.11.1 to 1.12.2
2025-11-01 04:17:04 +00:00
dependabot[bot] a1adefce36 build(deps): bump regex from 1.11.1 to 1.12.2
Bumps [regex](https://github.com/rust-lang/regex) from 1.11.1 to 1.12.2.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.11.1...1.12.2)

---
updated-dependencies:
- dependency-name: regex
  dependency-version: 1.12.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 03:40:47 +00:00
auto-merge-dependabot-prs[bot] 6e87e02e96 Merge pull request #3465 from sharkdp/dependabot/cargo/terminal-colorsaurus-1.0.1
build(deps): bump terminal-colorsaurus from 1.0.0 to 1.0.1
2025-11-01 03:37:12 +00:00
dependabot[bot] ab9cc674d5 build(deps): bump terminal-colorsaurus from 1.0.0 to 1.0.1
Bumps [terminal-colorsaurus](https://github.com/bash/terminal-colorsaurus) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/bash/terminal-colorsaurus/releases)
- [Changelog](https://github.com/bash/terminal-colorsaurus/blob/main/changelog.md)
- [Commits](https://github.com/bash/terminal-colorsaurus/compare/1.0.0...1.0.1)

---
updated-dependencies:
- dependency-name: terminal-colorsaurus
  dependency-version: 1.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 03:02:09 +00:00
Abhinav Diwakar 8e0e13a899 Merge branch 'master' into fix/list-themes-pager-hang 2025-11-01 00:59:59 +05:30
Jack Haden-Enneking 5371426588 alternatives.md: fix emoji & formatting
Could replace all emoji shortcodes (`✔️` & ``) in source with actual emoji. Erred on the side of least change.
2025-10-31 19:32:29 +01:00
abhinavcool42 1852dea96a Fix --list-themes pager init so less stays interactive 2025-10-30 18:42:35 +05:30
abhinavcool42 a8140f91cc changelog 2025-10-28 17:25:43 +05:30
abhinavcool42 2fac9b2740 added changelog 2025-10-28 17:07:12 +05:30
abhinavcool42 6a99915afe fix --list-themes hang 2025-10-28 16:10:32 +05:30
Justin Su 4e13c3eb5b Update CHANGELOG.md
Also fix a typo from the previous release
2025-10-20 19:23:26 +02:00
Justin Su 7e55608975 docs: Clarify that -X/--no-init is not added on modern versions of less 2025-10-20 19:23:26 +02:00
Justin Su 4bd5cbca8e docs: Mention less options by short+long names 2025-10-20 19:23:26 +02:00
Keith Hall 7c3fa7e1ce Merge pull request #3448 from akinomyoga/bash-fullquote
Use `-o fullquote` and `-o noquote` for more robust escaping in Bash completions
2025-10-20 19:55:56 +03:00
Koichi Murase 3188a147d8 Use "-o fullquote" and "-o noquote" to escape Bash completions 2025-10-20 19:38:54 +09:00
Koichi Murase 926fbc4b13 Fix indentation of the Bash completion file 2025-10-20 17:59:48 +09:00
Keith Hall 006d77fa39 Merge pull request #3442 from lmmx/patch-1
fix: allow hyphen values to `-r`/`--line-range`
2025-10-19 23:44:25 +03:00
Louis Maddox 52a792d46f fix: allow hyphen values to -r/--line-range
via #2944
2025-10-19 21:24:59 +01:00
Keith Hall 20db989fb1 Merge pull request #3441 from sharkdp/prepare_changelog
Prepare changelog for future changes
2025-10-19 21:40:50 +03:00
Keith Hall 2c63d3c792 Prepare changelog for future changes 2025-10-19 21:24:54 +03:00
33 changed files with 752 additions and 209 deletions
+13 -13
View File
@@ -161,19 +161,19 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
job: job:
- { target: aarch64-unknown-linux-musl , os: ubuntu-latest, dpkg_arch: arm64, use-cross: true } - { target: aarch64-unknown-linux-musl , os: ubuntu-latest , dpkg_arch: arm64, use-cross: true }
- { target: aarch64-unknown-linux-gnu , os: ubuntu-latest, dpkg_arch: arm64, use-cross: true } - { target: aarch64-unknown-linux-gnu , os: ubuntu-latest , dpkg_arch: arm64, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-latest, dpkg_arch: armhf, use-cross: true } - { target: arm-unknown-linux-gnueabihf , os: ubuntu-latest , dpkg_arch: armhf, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-latest, dpkg_arch: musl-linux-armhf, use-cross: true } - { target: arm-unknown-linux-musleabihf, os: ubuntu-latest , dpkg_arch: musl-linux-armhf, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2025, } - { target: i686-pc-windows-msvc , os: windows-2025 , }
- { target: i686-unknown-linux-gnu , os: ubuntu-latest, dpkg_arch: i686, use-cross: true } - { target: i686-unknown-linux-gnu , os: ubuntu-latest , dpkg_arch: i686, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-latest, dpkg_arch: musl-linux-i686, use-cross: true } - { target: i686-unknown-linux-musl , os: ubuntu-latest , dpkg_arch: musl-linux-i686, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-13, } - { target: x86_64-apple-darwin , os: macos-15-intel, }
- { target: aarch64-apple-darwin , os: macos-14, } - { target: aarch64-apple-darwin , os: macos-latest , }
- { target: x86_64-pc-windows-msvc , os: windows-2025, } - { target: x86_64-pc-windows-msvc , os: windows-2025 , }
- { target: aarch64-pc-windows-msvc , os: windows-11-arm, } - { target: aarch64-pc-windows-msvc , os: windows-11-arm, }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-latest, dpkg_arch: amd64, use-cross: true } - { target: x86_64-unknown-linux-gnu , os: ubuntu-latest , dpkg_arch: amd64, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-latest, dpkg_arch: musl-linux-amd64, use-cross: true } - { target: x86_64-unknown-linux-musl , os: ubuntu-latest , dpkg_arch: musl-linux-amd64, use-cross: true }
env: env:
BUILD_CMD: cargo BUILD_CMD: cargo
steps: steps:
+1 -1
View File
@@ -243,7 +243,7 @@
url = https://github.com/dertuxmalwieder/SublimeTodoTxt url = https://github.com/dertuxmalwieder/SublimeTodoTxt
[submodule "assets/syntaxes/02_Extra/Ada"] [submodule "assets/syntaxes/02_Extra/Ada"]
path = assets/syntaxes/02_Extra/Ada path = assets/syntaxes/02_Extra/Ada
url = https://github.com/wiremoons/ada-sublime-syntax url = https://github.com/AldanTanneo/ada-sublime-syntax
[submodule "assets/syntaxes/02_Extra/Crontab"] [submodule "assets/syntaxes/02_Extra/Crontab"]
path = assets/syntaxes/02_Extra/Crontab path = assets/syntaxes/02_Extra/Crontab
+32 -1
View File
@@ -1,3 +1,34 @@
# v0.26.1
## Features
- Add paging to '-h' and '--help' see PR #3478 (@MuntasirSZN)
## Bugfixes
- Fix hang when using `--list-themes` with an explicit pager, see #3457 (@abhinavcool42)
- Fix negative values of N not being parsed in <N:M> line ranges without `=` flag value separator, see #3442 (@lmmx)
- Fix broken Docker syntax preventing use of custom assets, see #3476 (@keith-hall)
- Fix decorations being applied unexpectedly when piping. Now only line numbers explicitly required on the command line should be applied in auto decorations mode for `cat` compatibility. See #3496 (@keith-hall)
- Fix diagnostics attempting to find the version of an executable named builtin when builtin pager is used. See #3498 (@keith-hall)
- `--help` now correctly reads the config file for theme information etc. See #3507 (@keith-hall)
## Other
- Improve README documentation on pager options passed to less, see #3443 (@injust)
- Make PowerShell completions compatible with PowerShell v5.1, see #3495 (@keith-hall)
- Use more robust approach to escaping in Bash completions, see #3448 (@akinomyoga)
## Syntaxes
- Update quadlet syntax mapping to include *.{build,pod} files #3484 (@cyqsimon)
- Fix inconsistencies in Ada syntax, see #3481 (@AldanTanneo)
- Add syntax mapping for podman's `artifact` quadlet files, see #3497 (@xduugu)
- Highlight Korn Shell scripts (i.e. with a shebang of ...`ksh`) using Bash syntax, see #3509 (@keith-hall)
## Themes
## `bat` as a library
# v0.26.0 # v0.26.0
## Features ## Features
@@ -29,7 +60,7 @@
- Update base16 README links to community driven base16 work #2871 (@JamyGolden) - Update base16 README links to community driven base16 work #2871 (@JamyGolden)
- Work around build failures when building `bat` from vendored sources #3179 (@dtolnay) - Work around build failures when building `bat` from vendored sources #3179 (@dtolnay)
- CICD: Stop building for x86_64-pc-windows-gnu which fails #3261 (Enselic) - CICD: Stop building for x86_64-pc-windows-gnu which fails #3261 (Enselic)
- CICD: CICD: replace windows-2019 runners with windows-2025 #3339 (@cyqsimon) - CICD: replace windows-2019 runners with windows-2025 #3339 (@cyqsimon)
- Build script: replace string-based codegen with quote-based codegen #3340 (@cyqsimon) - Build script: replace string-based codegen with quote-based codegen #3340 (@cyqsimon)
- Improve code coverage of `--list-languages` parameter #2942 (@sblondon) - Improve code coverage of `--list-languages` parameter #2942 (@sblondon)
- Only start offload worker thread when there's more than 1 core #2956 (@cyqsimon) - Only start offload worker thread when there's more than 1 core #2956 (@cyqsimon)
Generated
+67 -54
View File
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "adler2" name = "adler2"
@@ -111,7 +111,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bat" name = "bat"
version = "0.26.0" version = "0.26.1"
dependencies = [ dependencies = [
"ansi_colours", "ansi_colours",
"anyhow", "anyhow",
@@ -131,7 +131,6 @@ dependencies = [
"git2", "git2",
"globset", "globset",
"grep-cli", "grep-cli",
"home",
"indexmap", "indexmap",
"itertools", "itertools",
"minus", "minus",
@@ -394,9 +393,9 @@ dependencies = [
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.20.10" version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"darling_macro", "darling_macro",
@@ -404,9 +403,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.20.10" version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
@@ -418,9 +417,9 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.20.10" version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
@@ -517,13 +516,12 @@ dependencies = [
[[package]] [[package]]
name = "etcetera" name = "etcetera"
version = "0.10.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 = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6" checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"home", "windows-sys 0.61.2",
"windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -667,9 +665,9 @@ dependencies = [
[[package]] [[package]]
name = "git2" name = "git2"
version = "0.20.0" version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff" checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
@@ -723,15 +721,6 @@ version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "icu_collections" name = "icu_collections"
version = "1.5.0" version = "1.5.0"
@@ -932,9 +921,9 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]] [[package]]
name = "libgit2-sys" name = "libgit2-sys"
version = "0.18.0+1.9.0" version = "0.18.2+1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1a117465e7e1597e8febea8bb0c410f1c7fb93b1e1cddf34363f8390367ffec" checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@@ -1032,13 +1021,13 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.0.3" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
dependencies = [ dependencies = [
"libc", "libc",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -1218,9 +1207,9 @@ dependencies = [
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.2.35" version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn", "syn",
@@ -1284,9 +1273,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.11.1" version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1296,9 +1285,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.9" version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1362,18 +1351,28 @@ checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.217" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.217" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1403,20 +1402,19 @@ dependencies = [
[[package]] [[package]]
name = "serde_with" name = "serde_with"
version = "3.12.0" version = "3.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04"
dependencies = [ dependencies = [
"serde", "serde_core",
"serde_derive",
"serde_with_macros", "serde_with_macros",
] ]
[[package]] [[package]]
name = "serde_with_macros" name = "serde_with_macros"
version = "3.12.0" version = "3.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955"
dependencies = [ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
@@ -1534,9 +1532,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.104" version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1615,28 +1613,28 @@ dependencies = [
[[package]] [[package]]
name = "terminal-colorsaurus" name = "terminal-colorsaurus"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f7226dad4b1817567c1e2f5d453897ef36abe79def7783af3fa241a694e30b3" checksum = "8909f33134da34b43f69145e748790de650a6abd84faf1f82e773444dd293ec8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"memchr", "memchr",
"mio 1.0.3", "mio 1.1.0",
"terminal-trx", "terminal-trx",
"windows-sys 0.59.0", "windows-sys 0.61.2",
"xterm-color", "xterm-color",
] ]
[[package]] [[package]]
name = "terminal-trx" name = "terminal-trx"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "975b4233aefa1b02456d5e53b22c61653c743e308c51cf4181191d8ce41753ab" checksum = "662a3cd5ca570df622e848ef18b50c151e65c9835257465417242243b0bce783"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@@ -2011,6 +2009,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]] [[package]]
name = "windows-result" name = "windows-result"
version = "0.1.2" version = "0.1.2"
@@ -2056,6 +2060,15 @@ dependencies = [
"windows-targets 0.53.2", "windows-targets 0.53.2",
] ]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.48.5" version = "0.48.5"
+7 -8
View File
@@ -6,12 +6,12 @@ homepage = "https://github.com/sharkdp/bat"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
name = "bat" name = "bat"
repository = "https://github.com/sharkdp/bat" repository = "https://github.com/sharkdp/bat"
version = "0.26.0" version = "0.26.1"
exclude = ["assets/syntaxes/*", "assets/themes/*"] exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build/main.rs" build = "build/main.rs"
edition = '2021' edition = '2021'
# You are free to bump MSRV as soon as a reason for bumping emerges. # You are free to bump MSRV as soon as a reason for bumping emerges.
rust-version = "1.79" rust-version = "1.87"
[features] [features]
default = ["application", "git"] default = ["application", "git"]
@@ -65,9 +65,9 @@ semver = "1.0"
path_abs = { version = "0.5", default-features = false } path_abs = { version = "0.5", default-features = false }
clircle = { version = "0.6.1", default-features = false } clircle = { version = "0.6.1", default-features = false }
bugreport = { version = "0.5.0", optional = true } bugreport = { version = "0.5.0", optional = true }
etcetera = { version = "0.10.0", optional = true } etcetera = { version = "0.11.0", optional = true }
grep-cli = { version = "0.1.11", optional = true } grep-cli = { version = "0.1.11", optional = true }
regex = { version = "1.10.6", optional = true } regex = { version = "1.12.2", optional = true }
walkdir = { version = "2.5", optional = true } walkdir = { version = "2.5", optional = true }
bytesize = { version = "1.3.0" } bytesize = { version = "1.3.0" }
encoding_rs = "0.8.35" encoding_rs = "0.8.35"
@@ -92,7 +92,6 @@ optional = true
features = ["wrap_help", "cargo"] features = ["wrap_help", "cargo"]
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
home = "0.5.9"
plist = "1.7.0" plist = "1.7.0"
[dev-dependencies] [dev-dependencies]
@@ -112,13 +111,13 @@ anyhow = "1.0.97"
indexmap = { version = "2.8.0", features = ["serde"] } indexmap = { version = "2.8.0", features = ["serde"] }
itertools = "0.14.0" itertools = "0.14.0"
once_cell = "1.20" once_cell = "1.20"
prettyplease = "0.2.35" prettyplease = "0.2.37"
proc-macro2 = "1.0.95" proc-macro2 = "1.0.95"
quote = "1.0.40" quote = "1.0.40"
regex = "1.10.6" regex = "1.12.2"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_with = { version = "3.12.0", default-features = false, features = ["macros"] } serde_with = { version = "3.15.1", default-features = false, features = ["macros"] }
syn = { version = "2.0.104", features = ["full"] } syn = { version = "2.0.104", features = ["full"] }
toml = { version = "0.9.1", features = ["preserve_order"] } toml = { version = "0.9.1", features = ["preserve_order"] }
walkdir = "2.5" walkdir = "2.5"
+12 -6
View File
@@ -540,6 +540,12 @@ variable to make these changes permanent or use `bat`'s
> Or, if you want to override the styles completely, you use `--style=numbers` to > Or, if you want to override the styles completely, you use `--style=numbers` to
> only show the line numbers. > only show the line numbers.
### Decorations
By default, `bat` only shows decorations (such as line numbers, file headers, grid borders, etc.) when outputting to an interactive terminal. You can control this behavior with the `--decorations` option. Use `--decorations=always` to show decorations even when piping output to another command, or `--decorations=never` to disable them entirely. Possible values are `auto` (default), `never`, and `always`.
There is also the `--force-colorization` option, which is an alias for `--decorations=always --color=always`. This is useful if you want to keep colorization and decorations when piping `bat`'s output to another program.
### Adding new syntaxes / language definitions ### Adding new syntaxes / language definitions
Should you find that a particular syntax is not available within `bat`, you can follow these Should you find that a particular syntax is not available within `bat`, you can follow these
@@ -670,22 +676,22 @@ to improve the experience. Specifically, `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--qui
> - The `--paging=always` argument is used. > - The `--paging=always` argument is used.
> - The `BAT_PAGING` environment is set to `always`. > - The `BAT_PAGING` environment is set to `always`.
The `-R` option is needed to interpret ANSI colors correctly. The `-R`/`--RAW-CONTROL-CHARS` option is needed to interpret ANSI colors correctly.
The `-F` option instructs `less` to exit immediately if the output size is smaller than The `-F`/`--quit-if-one-screen` option instructs `less` to exit immediately if the output size is smaller than
the vertical size of the terminal. This is convenient for small files because you do not the vertical size of the terminal. This is convenient for small files because you do not
have to press `q` to quit the pager. have to press `q` to quit the pager.
The `-K` option instructs `less` to exit immediately when an interrupt signal is received. The `-K`/`--quit-on-intr` option instructs `less` to exit immediately when an interrupt signal is received.
This is useful to ensure that `less` quits together with `bat` on SIGINT. This is useful to ensure that `less` quits together with `bat` on SIGINT.
The `-X` option is needed to fix a bug with the `--quit-if-one-screen` feature in versions The `-X`/`--no-init` option is added to versions of `less` older than version 530 (older than 558 on Windows) to
of `less` older than version 530. Unfortunately, it also breaks mouse-wheel support in `less`. fix a bug with the `-F`/`--quit-if-one-screen` feature. Unfortunately, it also breaks mouse-wheel support in `less`.
If you want to enable mouse-wheel scrolling on older versions of `less` and do not mind losing If you want to enable mouse-wheel scrolling on older versions of `less` and do not mind losing
the quit-if-one-screen feature, you can set the pager (via `--pager` or `BAT_PAGER`) to `less -R`. the quit-if-one-screen feature, you can set the pager (via `--pager` or `BAT_PAGER`) to `less -R`.
For `less` 530 or newer, it should work out of the box. For `less` 530 or newer, it should work out of the box.
The `-S` option is added when `bat`'s `-S`/`--chop-long-lines` option is used. This tells `less` The `-S`/`--chop-long-lines` option is added when `bat`'s `-S`/`--chop-long-lines` option is used. This tells `less`
to truncate any lines larger than the terminal width. to truncate any lines larger than the terminal width.
### Indentation ### Indentation
BIN
View File
Binary file not shown.
+4 -1
View File
@@ -49,7 +49,10 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
} }
'*;--language' { '*;--language' {
Get-MyLanguages | Get-MyLanguages |
ForEach-Object {[CompletionResult]::new(($_.MyParameter -replace "^(.*)$", '''$1'''), $_.MyParameter, [CompletionResultType]::ParameterName, $_.MyDescription ?? '_no value_')} ForEach-Object {
$desc = if ($null -eq $_.MyDescription) { '_no value_' } else { $_.MyDescription }
[CompletionResult]::new(($_.MyParameter -replace "^(.*)$", '''$1'''), $_.MyParameter, [CompletionResultType]::ParameterName, $desc)
}
break break
} }
'*;--theme' { '*;--theme' {
+30 -12
View File
@@ -14,18 +14,36 @@ __bat_escape_completions()
{ {
# Do not escape if completing a quoted value. # Do not escape if completing a quoted value.
[[ $cur == [\"\']* ]] && return 0 [[ $cur == [\"\']* ]] && return 0
# printf -v to an array index is available in bash >= 4.1.
# Use it if available, as -o filenames is semantically incorrect if
# we are not actually completing filenames, and it has side effects
# (e.g. adds trailing slash to candidates matching present dirs).
if (( if ((
BASH_VERSINFO[0] > 5 || \
BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3
)); then
# bash >= 5.3 has "compopt -o fullquote", which exactly does
# what this function tries to do.
compopt -o fullquote
elif ((
BASH_VERSINFO[0] > 4 || \ BASH_VERSINFO[0] > 4 || \
BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] > 0 BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] > 0
)); then )); then
# printf -v to an array index is available in bash >= 4.1.
# Use it if available, as -o filenames is semantically
# incorrect if we are not actually completing filenames, and it
# has side effects (e.g. adds trailing slash to candidates
# matching present dirs).
local i local i
for i in ${!COMPREPLY[*]}; do for i in ${!COMPREPLY[*]}; do
printf -v "COMPREPLY[i]" %q "${COMPREPLY[i]}" printf -v "COMPREPLY[i]" %q "${COMPREPLY[i]}"
done done
# We can use "compopt -o noquote" available in bash >= 4.3 to
# prevent further quoting by the shell, which would be
# unexpectedly applied when a quoted result matches a filename.
if ((
BASH_VERSINFO[0] > 4 || \
BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3
)); then
compopt -o noquote
fi
else else
compopt -o filenames compopt -o filenames
fi fi
@@ -66,7 +84,7 @@ _bat() {
printf "%s\n" "$lang" printf "%s\n" "$lang"
done done
)" -- "$cur")) )" -- "$cur"))
__bat_escape_completions __bat_escape_completions
return 0 return 0
;; ;;
-H | --highlight-line | \ -H | --highlight-line | \
@@ -130,16 +148,16 @@ _bat() {
return 0 return 0
;; ;;
--theme) --theme)
local IFS=$'\n' local IFS=$'\n'
COMPREPLY=($(compgen -W "auto${IFS}auto:always${IFS}auto:system${IFS}dark${IFS}light${IFS}$("$1" --list-themes)" -- "$cur")) COMPREPLY=($(compgen -W "auto${IFS}auto:always${IFS}auto:system${IFS}dark${IFS}light${IFS}$("$1" --list-themes)" -- "$cur"))
__bat_escape_completions __bat_escape_completions
return 0 return 0
;; ;;
--theme-dark | \ --theme-dark | \
--theme-light) --theme-light)
local IFS=$'\n' local IFS=$'\n'
COMPREPLY=($(compgen -W "$("$1" --list-themes)" -- "$cur")) COMPREPLY=($(compgen -W "$("$1" --list-themes)" -- "$cur"))
__bat_escape_completions __bat_escape_completions
return 0 return 0
;; ;;
--style) --style)
@@ -158,7 +176,7 @@ _bat() {
numbers numbers
snip snip
) )
# shellcheck disable=SC2016 # shellcheck disable=SC2016
if declare -F _comp_delimited >/dev/null 2>&1; then if declare -F _comp_delimited >/dev/null 2>&1; then
# bash-completion > 2.11 # bash-completion > 2.11
_comp_delimited , -W '"${styles[@]}"' _comp_delimited , -W '"${styles[@]}"'
+1 -1
View File
@@ -14,7 +14,7 @@ index e973e319..07c170a7 100644
first_line_match: | first_line_match: |
(?x) (?x)
- ^\#! .* \b(bash|zsh|sh|tcsh|ash)\b - ^\#! .* \b(bash|zsh|sh|tcsh|ash)\b
+ ^\#! .* \b(bash|zsh|sh|tcsh|ash|dash)\b + ^\#! .* \b(bash|zsh|sh|tcsh|ash|dash|ksh)\b
| ^\# \s* -\*- [^*]* mode: \s* shell-script [^*]* -\*- | ^\# \s* -\*- [^*]* mode: \s* shell-script [^*]* -\*-
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -6,12 +6,12 @@ if you are not looking for a program like `bat`, this comparison might not be fo
| | 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) | [clp](https://github.com/jpe90/clp) |
|----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------| |----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|
| 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:&nbsp;[*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (✔️) | :x: | :x:&nbsp;[*](https://github.com/rstacruz/hicat/issues/6) | :x: | :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: | :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: | :x: |
| Languages (circa) | 150 | 300 | 200 | 7 | 80 | 130 | 30 | 130 | 150 | | Languages (circa) | 150 | 300 | 200 | 7 | 80 | 130 | 30 | 130 | 150 |
| 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: | (✔️) | (✔️) | :x: | (✔️) | :x: | :x: | :x: | :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: | :heavy_check_mark: | | Advanced highlighting (e.g. nested syntaxes) | :heavy_check_mark: | :heavy_check_mark: | (✔️) ? | :x: | :heavy_check_mark: | :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`) | 422 | 455 | 299 | 39 | 208 | 287 | 128 | 740 | 22 |
| Execution time [ms] (`miniz.c`) | 27 | 169 | 19 | 4 | 36 | 131 | 58 | 231 | 4 | | Execution time [ms] (`miniz.c`) | 27 | 169 | 19 | 4 | 36 | 131 | 58 | 231 | 4 |
| Execution time [ms] (957 kB XML file) | 215 | 296 | 236 | 165 | 83 | 412 | 135 | 386 | 127 | | Execution time [ms] (957 kB XML file) | 215 | 296 | 236 | 165 | 83 | 412 | 135 | 386 | 127 |
+1
View File
@@ -194,6 +194,7 @@ Options:
'--line-range :40' prints lines 1 to 40 '--line-range :40' prints lines 1 to 40
'--line-range 40:' prints lines 40 to the end of the file '--line-range 40:' prints lines 40 to the end of the file
'--line-range 40' only prints line 40 '--line-range 40' only prints line 40
'--line-range -10:' prints the last 10 lines
'--line-range 30:+10' prints lines 30 to 40 '--line-range 30:+10' prints lines 30 to 40
'--line-range 35::5' prints lines 30 to 40 (line 35 with 5 lines of context) '--line-range 35::5' prints lines 30 to 40 (line 35 with 5 lines of context)
'--line-range 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context) '--line-range 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context)
+207 -47
View File
@@ -38,9 +38,18 @@ pub fn env_no_color() -> bool {
env::var_os("NO_COLOR").is_some_and(|x| !x.is_empty()) env::var_os("NO_COLOR").is_some_and(|x| !x.is_empty())
} }
enum HelpType {
Short,
Long,
}
pub struct App { pub struct App {
pub matches: ArgMatches, pub matches: ArgMatches,
interactive_output: bool, interactive_output: bool,
/// True if -n / --number was passed on the command line
/// (not from config file or environment variables).
/// This is used to honor the flag when piping output, similar to `cat -n`.
number_from_cli: bool,
} }
impl App { impl App {
@@ -50,65 +59,216 @@ impl App {
let interactive_output = std::io::stdout().is_terminal(); let interactive_output = std::io::stdout().is_terminal();
// Check if the -n / --number option was passed on the command line
// (before merging with config file and environment variables).
// This is needed to honor the -n flag when piping output, similar to `cat -n`.
// We need to handle both standalone (-n, --number) and combined short flags (-pn, -An, etc.)
// Note: We only check if -n appears and is not overridden by -p in the same combined flag.
// For combined flags like -np, -p comes after -n and overrides it, so we don't count it.
// For combined flags like -pn, -n comes after -p and takes effect.
let number_from_cli = wild::args_os().any(|arg| {
let arg_str = arg.to_string_lossy();
if arg_str == "-n" || arg_str == "--number" {
return true;
}
// Handle combined short flags
// Only count -n if it's the LAST flag in the combined form (so -p doesn't override it)
// or if -p is not present in the combined form
if arg_str.starts_with('-') && !arg_str.starts_with("--") && arg_str.len() > 2 {
let chars: Vec<char> = arg_str.chars().skip(1).collect();
let n_pos = chars.iter().position(|&c| c == 'n');
let p_pos = chars.iter().position(|&c| c == 'p');
// -n is in the combined flag and either:
// - -p is not present, OR
// - -n comes after -p (so -n takes effect)
if let Some(n) = n_pos {
if p_pos.is_none() || n > p_pos.unwrap() {
return true;
}
}
}
false
});
let matches = Self::matches(interactive_output)?;
if matches.get_flag("help") {
let help_type = if wild::args_os().any(|arg| arg == "--help") {
HelpType::Long
} else {
HelpType::Short
};
let use_pager = match matches.get_one::<String>("paging").map(|s| s.as_str()) {
Some("never") => false,
_ => !matches.get_flag("no-paging"),
};
let use_color = match matches.get_one::<String>("color").map(|s| s.as_str()) {
Some("always") => true,
Some("never") => false,
_ => interactive_output, // auto: use color if interactive
};
let custom_pager = matches.get_one::<String>("pager").map(|s| s.to_string());
let theme_options = Self::theme_options_from_matches(&matches);
Self::display_help(
interactive_output,
help_type,
use_pager,
use_color,
custom_pager,
theme_options,
)?;
std::process::exit(0);
}
Ok(App { Ok(App {
matches: Self::matches(interactive_output)?, matches,
interactive_output, interactive_output,
number_from_cli,
}) })
} }
fn display_help(
interactive_output: bool,
help_type: HelpType,
use_pager: bool,
use_color: bool,
custom_pager: Option<String>,
theme_options: ThemeOptions,
) -> Result<()> {
use crate::assets::assets_from_cache_or_binary;
use crate::directories::PROJECT_DIRS;
use bat::{
config::Config,
controller::Controller,
input::Input,
style::{StyleComponent, StyleComponents},
theme::theme,
PagingMode,
};
let mut cmd = clap_app::build_app(interactive_output);
let help_text = match help_type {
HelpType::Short => cmd.render_help().to_string(),
HelpType::Long => cmd.render_long_help().to_string(),
};
let inputs: Vec<Input> = vec![Input::from_reader(Box::new(help_text.as_bytes()))];
let paging_mode = if use_pager {
PagingMode::QuitIfOneScreen
} else {
PagingMode::Never
};
let pager = bat::config::get_pager_executable(custom_pager.as_deref());
let help_config = Config {
style_components: StyleComponents::new(StyleComponent::Plain.components(false)),
paging_mode,
pager: pager.as_deref(),
colored_output: use_color,
true_color: use_color,
language: if use_color { Some("help") } else { None },
theme: theme(theme_options).to_string(),
..Default::default()
};
let cache_dir = PROJECT_DIRS.cache_dir();
let assets = assets_from_cache_or_binary(false, cache_dir)?;
Controller::new(&help_config, &assets)
.run(inputs, None)
.ok();
Ok(())
}
/// Build argument list with env vars and CLI args (without config file)
fn build_args_without_config() -> Vec<std::ffi::OsString> {
let mut cli_args = wild::args_os();
let mut args = get_args_from_env_vars();
// Put the zero-th CLI argument (program name) first
args.insert(0, cli_args.next().unwrap());
// .. and the rest at the end
cli_args.for_each(|a| args.push(a));
args
}
fn matches(interactive_output: bool) -> Result<ArgMatches> { fn matches(interactive_output: bool) -> Result<ArgMatches> {
// Check if we should skip config file processing for special arguments // Check if we should skip config file processing for special arguments
// that don't require full application setup (help, version, diagnostic) // that don't require full application setup (version, diagnostic)
let should_skip_config = wild::args_os().any(|arg| { let should_skip_config = wild::args_os().any(|arg| {
matches!( matches!(
arg.to_str(), arg.to_str(),
Some("-h" | "--help" | "-V" | "--version" | "--diagnostic" | "--diagnostics") Some("-V" | "--version" | "--diagnostic" | "--diagnostics")
) )
}); });
let args = if wild::args_os().nth(1) == Some("cache".into()) { // Check if help was requested - help should read the config file but be
// forgiving of invalid arguments (so configured theme etc. can be used)
let help_requested =
wild::args_os().any(|arg| matches!(arg.to_str(), Some("-h" | "--help")));
if wild::args_os().nth(1) == Some("cache".into()) {
// Skip the config file and env vars // Skip the config file and env vars
let args = wild::args_os().collect::<Vec<_>>();
return Ok(clap_app::build_app(interactive_output).get_matches_from(args));
}
wild::args_os().collect::<Vec<_>>() if wild::args_os().any(|arg| arg == "--no-config") || should_skip_config {
} else if wild::args_os().any(|arg| arg == "--no-config") || should_skip_config {
// Skip the arguments in bats config file when --no-config is present // Skip the arguments in bats config file when --no-config is present
// or when user requests help, version, or diagnostic information // or when user requests version or diagnostic information
let args = Self::build_args_without_config();
return Ok(clap_app::build_app(interactive_output).get_matches_from(args));
}
let mut cli_args = wild::args_os(); // Build arguments with config file
let mut args = if should_skip_config { let mut cli_args = wild::args_os();
// For special commands, don't even try to load env vars that might fail
vec![]
} else {
get_args_from_env_vars()
};
// Put the zero-th CLI argument (program name) first // Read arguments from bats config file
args.insert(0, cli_args.next().unwrap()); let config_args = match get_args_from_env_opts_var() {
Some(result) => result,
// .. and the rest at the end None => get_args_from_config_file(),
cli_args.for_each(|a| args.push(a));
args
} else {
let mut cli_args = wild::args_os();
// Read arguments from bats config file
let mut args = get_args_from_env_opts_var()
.unwrap_or_else(get_args_from_config_file)
.map_err(|_| "Could not parse configuration file")?;
// Selected env vars supersede config vars
args.extend(get_args_from_env_vars());
// Put the zero-th CLI argument (program name) first
args.insert(0, cli_args.next().unwrap());
// .. and the rest at the end
cli_args.for_each(|a| args.push(a));
args
}; };
Ok(clap_app::build_app(interactive_output).get_matches_from(args)) // For help, ignore config file parse errors (use empty config instead)
// For non-help, propagate the error
let mut args = if help_requested {
config_args.unwrap_or_default()
} else {
config_args.map_err(|_| "Could not parse configuration file")?
};
// Selected env vars supersede config vars
args.extend(get_args_from_env_vars());
// Put the zero-th CLI argument (program name) first
args.insert(0, cli_args.next().unwrap());
// .. and the rest at the end
cli_args.for_each(|a| args.push(a));
// For help, try parsing with config, and if clap fails (e.g., invalid
// argument in config), fall back to parsing without config file args
if help_requested {
let app = clap_app::build_app(interactive_output);
match app.try_get_matches_from(args) {
Ok(matches) => Ok(matches),
Err(_) => {
// Config has invalid arguments, fall back to just env vars + CLI args
let fallback_args = Self::build_args_without_config();
Ok(clap_app::build_app(interactive_output).get_matches_from(fallback_args))
}
}
} else {
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
}
} }
pub fn config(&self, inputs: &[Input]) -> Result<Config<'_>> { pub fn config(&self, inputs: &[Input]) -> Result<Config<'_>> {
@@ -277,8 +437,7 @@ impl App {
.map(|s| s.as_str()) .map(|s| s.as_str())
== Some("always") == Some("always")
|| self.matches.get_flag("force-colorization") || self.matches.get_flag("force-colorization")
|| self.matches.get_flag("number") || self.number_from_cli),
|| self.matches.contains_id("style") && !style_components.plain()),
tab_width: self tab_width: self
.matches .matches
.get_one::<String>("tabs") .get_one::<String>("tabs")
@@ -462,17 +621,18 @@ impl App {
} }
fn theme_options(&self) -> ThemeOptions { fn theme_options(&self) -> ThemeOptions {
let theme = self Self::theme_options_from_matches(&self.matches)
.matches }
fn theme_options_from_matches(matches: &ArgMatches) -> ThemeOptions {
let theme = matches
.get_one::<String>("theme") .get_one::<String>("theme")
.map(|t| ThemePreference::from_str(t).unwrap()) .map(|t| ThemePreference::from_str(t).unwrap())
.unwrap_or_default(); .unwrap_or_default();
let theme_dark = self let theme_dark = matches
.matches
.get_one::<String>("theme-dark") .get_one::<String>("theme-dark")
.map(|t| ThemeName::from_str(t).unwrap()); .map(|t| ThemeName::from_str(t).unwrap());
let theme_light = self let theme_light = matches
.matches
.get_one::<String>("theme-light") .get_one::<String>("theme-light")
.map(|t| ThemeName::from_str(t).unwrap()); .map(|t| ThemeName::from_str(t).unwrap());
ThemeOptions { ThemeOptions {
+19
View File
@@ -34,6 +34,8 @@ pub fn build_app(interactive_output: bool) -> Command {
.args_conflicts_with_subcommands(true) .args_conflicts_with_subcommands(true)
.allow_external_subcommands(true) .allow_external_subcommands(true)
.disable_help_subcommand(true) .disable_help_subcommand(true)
.disable_help_flag(true)
.disable_version_flag(true)
.max_term_width(100) .max_term_width(100)
.about("A cat(1) clone with wings.") .about("A cat(1) clone with wings.")
.long_about("A cat(1) clone with syntax highlighting and Git integration.") .long_about("A cat(1) clone with syntax highlighting and Git integration.")
@@ -519,6 +521,7 @@ pub fn build_app(interactive_output: bool) -> Command {
.short('r') .short('r')
.action(ArgAction::Append) .action(ArgAction::Append)
.value_name("N:M") .value_name("N:M")
.allow_hyphen_values(true)
.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. \
@@ -527,6 +530,7 @@ pub fn build_app(interactive_output: bool) -> Command {
'--line-range :40' prints lines 1 to 40\n \ '--line-range :40' prints lines 1 to 40\n \
'--line-range 40:' prints lines 40 to the end of the file\n \ '--line-range 40:' prints lines 40 to the end of the file\n \
'--line-range 40' only prints line 40\n \ '--line-range 40' only prints line 40\n \
'--line-range -10:' prints the last 10 lines\n \
'--line-range 30:+10' prints lines 30 to 40\n \ '--line-range 30:+10' prints lines 30 to 40\n \
'--line-range 35::5' prints lines 30 to 40 (line 35 with 5 lines of context)\n \ '--line-range 35::5' prints lines 30 to 40 (line 35 with 5 lines of context)\n \
'--line-range 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context)", '--line-range 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context)",
@@ -652,6 +656,21 @@ pub fn build_app(interactive_output: bool) -> Command {
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.hide_short_help(true) .hide_short_help(true)
.help("Sets terminal title to filenames when using a pager."), .help("Sets terminal title to filenames when using a pager."),
)
.arg(
Arg::new("help")
.short('h')
.long("help")
.action(ArgAction::SetTrue)
.help("Print help (see more with '--help')")
.long_help("Print help (see a summary with '-h')"),
)
.arg(
Arg::new("version")
.long("version")
.short('V')
.action(ArgAction::Version)
.help("Print version"),
); );
// Check if the current directory contains a file name cache. Otherwise, // Check if the current directory contains a file name cache. Otherwise,
+19 -16
View File
@@ -16,7 +16,7 @@ use std::io::{BufReader, Write};
use std::path::Path; use std::path::Path;
use std::process; use std::process;
use bat::output::OutputType; use bat::output::{OutputHandle, OutputType};
use bat::theme::DetectColorScheme; use bat::theme::DetectColorScheme;
use nu_ansi_term::Color::Green; use nu_ansi_term::Color::Green;
use nu_ansi_term::Style; use nu_ansi_term::Style;
@@ -206,11 +206,10 @@ pub fn list_themes(
config.language = Some("Rust"); config.language = Some("Rust");
config.style_components = StyleComponents(style); config.style_components = StyleComponents(style);
let mut output_type =
OutputType::from_mode(config.paging_mode, config.wrapping_mode, config.pager)?;
let mut writer = output_type.handle()?;
let default_theme_name = default_theme(color_scheme(detect_color_scheme).unwrap_or_default()); let default_theme_name = default_theme(color_scheme(detect_color_scheme).unwrap_or_default());
let mut buf = String::new();
let mut handle = OutputHandle::FmtWrite(&mut buf);
for theme in assets.themes() { for theme in assets.themes() {
let default_theme_info = if default_theme_name == theme { let default_theme_info = if default_theme_name == theme {
" (default)" " (default)"
@@ -221,35 +220,39 @@ pub fn list_themes(
} else { } else {
"" ""
}; };
if config.colored_output { if config.colored_output {
writeln!( handle.write_fmt(format_args!(
writer, "{}{default_theme_info}\n\n",
"Theme: {}{default_theme_info}\n",
Style::new().bold().paint(theme.to_string()), Style::new().bold().paint(theme.to_string()),
)?; ))?;
config.theme = theme.to_string(); config.theme = theme.to_string();
Controller::new(&config, &assets) Controller::new(&config, &assets)
.run(vec![theme_preview_file()], Some(&mut writer)) .run(vec![theme_preview_file()], Some(&mut handle))
.ok(); .ok();
writeln!(writer)?; handle.write_fmt(format_args!("\n"))?;
} else if config.loop_through { } else if config.loop_through {
writeln!(writer, "{theme}")?; handle.write_fmt(format_args!("{theme}\n"))?;
} else { } else {
writeln!(writer, "{theme}{default_theme_info}")?; handle.write_fmt(format_args!("{theme}{default_theme_info}\n"))?;
} }
} }
if config.colored_output { if config.colored_output {
writeln!( handle.write_fmt(format_args!(
writer,
"Further themes can be installed to '{}', \ "Further themes can be installed to '{}', \
and are added to the cache with `bat cache --build`. \ and are added to the cache with `bat cache --build`. \
For more information, see:\n\n \ For more information, see:\n\n \
https://github.com/sharkdp/bat#adding-new-themes", https://github.com/sharkdp/bat#adding-new-themes",
config_dir.join("themes").to_string_lossy() config_dir.join("themes").to_string_lossy()
)?; ))?;
} }
let mut output_type =
OutputType::from_mode(config.paging_mode, config.wrapping_mode, config.pager)?;
let mut writer = output_type.handle()?;
writer.write_fmt(format_args!("{buf}"))?;
Ok(()) Ok(())
} }
+84 -1
View File
@@ -114,7 +114,13 @@ pub fn get_pager_executable(config_pager: Option<&str>) -> Option<String> {
crate::pager::get_pager(config_pager) crate::pager::get_pager(config_pager)
.ok() .ok()
.flatten() .flatten()
.map(|pager| pager.bin) .and_then(|pager| {
if pager.kind != crate::pager::PagerKind::Builtin {
Some(pager.bin)
} else {
None
}
})
} }
#[test] #[test]
@@ -141,3 +147,80 @@ fn default_config_should_highlight_no_lines() {
RangeCheckResult::InRange RangeCheckResult::InRange
); );
} }
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_with_config_pager_less() {
let result = get_pager_executable(Some("less"));
assert_eq!(result, Some("less".to_string()));
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_with_config_pager_builtin() {
let result = get_pager_executable(Some("builtin"));
assert_eq!(result, None);
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_with_config_pager_more() {
let result = get_pager_executable(Some("more"));
assert_eq!(result, Some("more".to_string()));
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_with_bat_pager() {
std::env::set_var("BAT_PAGER", "most");
let result = get_pager_executable(None);
assert_eq!(result, Some("most".to_string()));
std::env::remove_var("BAT_PAGER");
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_with_pager_more_switches_to_less() {
std::env::set_var("PAGER", "more");
let result = get_pager_executable(None);
assert_eq!(result, Some("less".to_string()));
std::env::remove_var("PAGER");
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_default() {
// Ensure no env vars
std::env::remove_var("BAT_PAGER");
std::env::remove_var("PAGER");
let result = get_pager_executable(None);
assert_eq!(result, Some("less".to_string()));
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_name_ignoring_arguments() {
let result = get_pager_executable(Some("foo --bar"));
assert_eq!(result, Some("foo".to_string()));
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_name_ignoring_path() {
let result = get_pager_executable(Some("/bin/foo test"));
assert_eq!(result, Some("/bin/foo".to_string()));
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_invalid_command() {
let result = get_pager_executable(Some("invalid ' command"));
assert_eq!(result, None);
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]
#[test]
fn get_pager_executable_empty_config() {
let result = get_pager_executable(Some(""));
assert_eq!(result, None);
}
+22 -10
View File
@@ -50,10 +50,12 @@ impl Controller<'_> {
output_handle: Option<&mut OutputHandle<'_>>, output_handle: Option<&mut OutputHandle<'_>>,
mut handle_error: impl FnMut(&Error, &mut dyn Write), mut handle_error: impl FnMut(&Error, &mut dyn Write),
) -> Result<bool> { ) -> Result<bool> {
let mut output_type; // only create our own OutputType if no output handle was provided.
#[allow(unused_mut)]
let mut output_type_opt: Option<OutputType> = None;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
{ if output_handle.is_none() {
use crate::input::InputKind; use crate::input::InputKind;
use std::path::Path; use std::path::Path;
@@ -74,25 +76,35 @@ impl Controller<'_> {
let wrapping_mode = self.config.wrapping_mode; let wrapping_mode = self.config.wrapping_mode;
output_type = OutputType::from_mode(paging_mode, wrapping_mode, self.config.pager)?; output_type_opt = Some(OutputType::from_mode(
paging_mode,
wrapping_mode,
self.config.pager,
)?);
} }
#[cfg(not(feature = "paging"))] #[cfg(not(feature = "paging"))]
{ if output_handle.is_none() {
output_type = OutputType::stdout(); output_type_opt = Some(OutputType::stdout());
} }
let attached_to_pager = output_type.is_pager(); let attached_to_pager = match (&output_handle, &output_type_opt) {
(Some(_), _) => true,
(None, Some(ot)) => ot.is_pager(),
(None, None) => false,
};
let stdout_identifier = if cfg!(windows) || attached_to_pager { let stdout_identifier = if cfg!(windows) || attached_to_pager {
None None
} else { } else {
clircle::Identifier::stdout() clircle::Identifier::stdout()
}; };
let mut writer = match output_handle { let mut writer = match (output_handle, &mut output_type_opt) {
Some(OutputHandle::FmtWrite(w)) => OutputHandle::FmtWrite(w), (Some(OutputHandle::FmtWrite(w)), _) => OutputHandle::FmtWrite(w),
Some(OutputHandle::IoWrite(w)) => OutputHandle::IoWrite(w), (Some(OutputHandle::IoWrite(w)), _) => OutputHandle::IoWrite(w),
None => output_type.handle()?, (None, Some(ot)) => ot.handle()?,
(None, None) => unreachable!("No output handle and no output type available"),
}; };
let mut no_errors: bool = true; let mut no_errors: bool = true;
let stderr = io::stderr(); let stderr = io::stderr();
+11 -9
View File
@@ -141,16 +141,18 @@ impl OutputType {
// //
// For newer versions (530 or 558 on Windows), we omit '--no-init' as it // For newer versions (530 or 558 on Windows), we omit '--no-init' as it
// is not needed anymore. // is not needed anymore.
match retrieve_less_version(&pager.bin) { if single_screen_action == SingleScreenAction::Quit {
None => { match retrieve_less_version(&pager.bin) {
p.arg("--no-init"); None => {
p.arg("--no-init");
}
Some(LessVersion::Less(version))
if (version < 530 || (cfg!(windows) && version < 558)) =>
{
p.arg("--no-init");
}
_ => {}
} }
Some(LessVersion::Less(version))
if (version < 530 || (cfg!(windows) && version < 558)) =>
{
p.arg("--no-init");
}
_ => {}
} }
} else { } else {
p.args(args); p.args(args);
@@ -1,5 +1,5 @@
# see `man quadlet` # see `man quadlet`
[mappings] [mappings]
"INI" = [ "INI" = [
"**/containers/systemd/**/*.{container,volume,network,kube,image}", "**/containers/systemd/**/*.{container,volume,network,kube,image,build,pod,artifact}",
] ]
+1 -1
View File
@@ -288,7 +288,7 @@ fn color_scheme_from_system() -> Option<ColorScheme> {
const PREFERENCES_FILE: &str = "Library/Preferences/.GlobalPreferences.plist"; const PREFERENCES_FILE: &str = "Library/Preferences/.GlobalPreferences.plist";
const STYLE_KEY: &str = "AppleInterfaceStyle"; const STYLE_KEY: &str = "AppleInterfaceStyle";
let preferences_file = home::home_dir() let preferences_file = std::env::home_dir()
.map(|home| home.join(PREFERENCES_FILE)) .map(|home| home.join(PREFERENCES_FILE))
.expect("Could not get home directory"); .expect("Could not get home directory");
+168 -13
View File
@@ -166,6 +166,53 @@ fn line_numbers() {
.stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n 5 line 5\n 6 line 6\n 7 line 7\n 8 line 8\n 9 line 9\n 10 line 10\n"); .stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n 5 line 5\n 6 line 6\n 7 line 7\n 8 line 8\n 9 line 9\n 10 line 10\n");
} }
// Test that -n on command line shows line numbers even when piping (similar to `cat -n`)
#[test]
fn line_numbers_from_cli_in_loop_through_mode() {
bat()
.arg("multiline.txt")
.arg("-n")
.assert()
.success()
.stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n 5 line 5\n 6 line 6\n 7 line 7\n 8 line 8\n 9 line 9\n 10 line 10\n");
}
#[test]
fn style_from_env_var_ignored_and_line_numbers_from_cli_in_loop_through_mode() {
bat()
.env("BAT_STYLE", "full")
.arg("multiline.txt")
.arg("-n")
.arg("--decorations=auto")
.assert()
.success()
.stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n 5 line 5\n 6 line 6\n 7 line 7\n 8 line 8\n 9 line 9\n 10 line 10\n");
}
#[test]
fn numbers_ignored_from_cli_when_followed_by_plain_in_loop_through_mode() {
bat()
.arg("multiline.txt")
.arg("-np")
.arg("--decorations=auto")
.assert()
.success()
.stdout(
"line 1\nline 2\nline 3\nline 4\nline 5\nline 6\nline 7\nline 8\nline 9\nline 10\n",
);
}
#[test]
fn numbers_honored_from_cli_when_preceeded_by_plain_in_loop_through_mode() {
bat()
.arg("multiline.txt")
.arg("-pn")
.arg("--decorations=auto")
.assert()
.success()
.stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n 5 line 5\n 6 line 6\n 7 line 7\n 8 line 8\n 9 line 9\n 10 line 10\n");
}
#[test] #[test]
fn line_range_2_3() { fn line_range_2_3() {
bat() bat()
@@ -207,7 +254,7 @@ fn line_range_from_back_last_two() {
} }
#[test] #[test]
fn line_range_from_back_last_two_single_line() { fn line_range_from_back_last_two_single_line_eq_sep() {
bat() bat()
.arg("single-line.txt") .arg("single-line.txt")
.arg("--line-range=-2:") .arg("--line-range=-2:")
@@ -216,6 +263,17 @@ fn line_range_from_back_last_two_single_line() {
.stdout("Single Line"); .stdout("Single Line");
} }
#[test]
fn line_range_from_back_last_two_single_line_no_sep() {
bat()
.arg("single-line.txt")
.arg("--line-range")
.arg("-2:")
.assert()
.success()
.stdout("Single Line");
}
#[test] #[test]
fn line_range_first_two() { fn line_range_first_two() {
bat() bat()
@@ -404,26 +462,18 @@ fn piped_output_with_line_numbers_style_flag() {
.write_stdin("hello\nworld\n") .write_stdin("hello\nworld\n")
.assert() .assert()
.success() .success()
.stdout(" 1 hello\n 2 world\n"); .stdout("hello\nworld\n");
} }
#[test] #[test]
#[cfg(not(target_os = "windows"))]
fn piped_output_with_line_numbers_with_header_grid_style_flag() { fn piped_output_with_line_numbers_with_header_grid_style_flag() {
// style ignored because non-interactive
bat() bat()
.arg("--style=header,grid,numbers") .arg("--style=header,grid,numbers")
.write_stdin("hello\nworld\n") .write_stdin("hello\nworld\n")
.assert() .assert()
.success() .success()
.stdout( .stdout("hello\nworld\n");
"─────┬──────────────────────────────────────────────────────────────────────────
STDIN
1 hello
2 world
",
);
} }
#[test] #[test]
@@ -441,6 +491,7 @@ fn piped_output_with_auto_style() {
fn piped_output_with_default_style_flag() { fn piped_output_with_default_style_flag() {
bat() bat()
.arg("--style=default") .arg("--style=default")
.arg("--decorations=always")
.write_stdin("hello\nworld\n") .write_stdin("hello\nworld\n")
.assert() .assert()
.success() .success()
@@ -594,6 +645,44 @@ fn test_help(arg: &str, expect_file: &str) {
.assert_eq(&String::from_utf8_lossy(&assert.get_output().stdout)); .assert_eq(&String::from_utf8_lossy(&assert.get_output().stdout));
} }
#[test]
fn short_help_with_highlighting() {
bat()
.arg("-h")
.arg("--paging=never")
.arg("--color=always")
.assert()
.success()
.stdout(predicate::str::contains("\x1B["))
.stdout(predicate::str::contains("Usage:"))
.stdout(predicate::str::contains("Options:"));
}
#[test]
fn long_help_with_highlighting() {
bat()
.arg("--help")
.arg("--paging=never")
.arg("--color=always")
.assert()
.success()
.stdout(predicate::str::contains("\x1B["))
.stdout(predicate::str::contains("Usage:"))
.stdout(predicate::str::contains("Options:"));
}
#[test]
fn help_with_color_never() {
bat()
.arg("--help")
.arg("--color=never")
.arg("--paging=never")
.assert()
.success()
.stdout(predicate::str::contains("\x1B[").not())
.stdout(predicate::str::contains("Usage:"));
}
#[cfg(unix)] #[cfg(unix)]
fn setup_temp_file(content: &[u8]) -> io::Result<(PathBuf, tempfile::TempDir)> { fn setup_temp_file(content: &[u8]) -> io::Result<(PathBuf, tempfile::TempDir)> {
let dir = tempfile::tempdir().expect("Couldn't create tempdir"); let dir = tempfile::tempdir().expect("Couldn't create tempdir");
@@ -1390,6 +1479,28 @@ fn help_works_with_invalid_config() {
.stdout(predicate::str::contains("A cat(1) clone with wings")); .stdout(predicate::str::contains("A cat(1) clone with wings"));
} }
#[test]
fn help_uses_valid_config() {
let tmp_dir = tempdir().expect("can create temporary directory");
let tmp_config_path = tmp_dir.path().join("valid-config.conf");
// Write a valid config file with an invalid theme (so we can see a warning)
std::fs::write(&tmp_config_path, "--theme=NonExistentThemeName123")
.expect("can write config file");
// --help should read the config file and try to use the theme
// (we'll see a warning about unknown theme. This is the easiest way to prove the theme is read from config.)
bat_with_config()
.env("BAT_CONFIG_PATH", tmp_config_path.to_str().unwrap())
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains(
"A cat(1) clone with syntax highlighting",
))
.stderr(predicate::str::contains("Unknown theme"));
}
#[test] #[test]
fn version_works_with_invalid_config() { fn version_works_with_invalid_config() {
let tmp_dir = tempdir().expect("can create temporary directory"); let tmp_dir = tempdir().expect("can create temporary directory");
@@ -1550,7 +1661,7 @@ Clearing metadata file ... okay",
#[cfg(unix)] #[cfg(unix)]
#[test] #[test]
fn cache_build() { fn cache_build_blank() {
let src_dir = "cache_source"; let src_dir = "cache_source";
let tmp_dir = tempdir().expect("can create temporary directory"); let tmp_dir = tempdir().expect("can create temporary directory");
let tmp_themes_path = tmp_dir.path().join("themes.bin"); let tmp_themes_path = tmp_dir.path().join("themes.bin");
@@ -1593,6 +1704,50 @@ Writing metadata to folder .* ... okay",
assert!(tmp_metadata_path.exists()); assert!(tmp_metadata_path.exists());
} }
#[cfg(unix)]
#[test]
fn cache_build() {
let src_dir = "cache_source";
let tmp_dir = tempdir().expect("can create temporary directory");
let tmp_themes_path = tmp_dir.path().join("themes.bin");
let tmp_syntaxes_path = tmp_dir.path().join("syntaxes.bin");
let tmp_acknowledgements_path = tmp_dir.path().join("acknowledgements.bin");
let tmp_metadata_path = tmp_dir.path().join("metadata.yaml");
// Build the cache
// Include the BAT_CONFIG_PATH and BAT_THEME environment variables to ensure that
// options loaded from a config or the environment are not inserted
// before the cache subcommand, which would break it.
bat_with_config()
.current_dir(Path::new(EXAMPLES_DIR).join(src_dir))
.env("BAT_CONFIG_PATH", "bat.conf")
.env("BAT_THEME", "1337")
.arg("cache")
.arg("--build")
// removed --blank
.arg("--source")
.arg(".")
.arg("--target")
.arg(tmp_dir.path().to_str().unwrap())
.arg("--acknowledgements")
.assert()
.success()
.stdout(
predicate::str::is_match(
"Writing theme set to .*/themes.bin ... okay\nWriting syntax set to .*/syntaxes.bin ... okay\nWriting acknowledgements to .*/acknowledgements.bin ... okay\nWriting metadata to folder .* ... okay",
)
.unwrap(),
)
.stdout(predicate::str::contains("Some referenced contexts could not be found!").not())
;
// Now we expect the files to exist. If they exist, we assume contents are correct
assert!(tmp_themes_path.exists());
assert!(tmp_syntaxes_path.exists());
assert!(tmp_acknowledgements_path.exists());
assert!(tmp_metadata_path.exists());
}
#[test] #[test]
fn utf16() { fn utf16() {
// The output will be converted to UTF-8 with the leading UTF-16 // The output will be converted to UTF-8 with the leading UTF-16
+2 -2
View File
@@ -1,5 +1,5 @@
with Chests.Ring_Buffers; with Chests.Ring_Buffers;
with USB.Device.HID.Keyboard; with USB.Device.HID.Keyboard;
package body Click is package body Click is
 ----------------  ----------------
+2 -2
View File
@@ -1,5 +1,5 @@
with HAL.GPIO; with HAL.GPIO;
with USB.Device.HID.Keyboard; with USB.Device.HID.Keyboard;
generic generic
 Nb_Bounce : Natural;  Nb_Bounce : Natural;
@@ -0,0 +1,19 @@
#!/bin/ksh
#
# https://www.qnx.com/developers/docs/6.4.0/neutrino/user_guide/scripts.html
# tfind:
# script to look for strings in various files and dump to less
case $# in
1)
 find . -name '*.[ch]' | xargs grep $1 | less
 exit 0 # good status
esac
echo "Use tfind stuff_to_find "
echo " where : stuff_to_find = search string "
echo " "
echo "e.g. tfind console_state looks through all files in " 
echo " the current directory and below and displays all "
echo " instances of console_state."
exit 1 # bad status
+19
View File
@@ -0,0 +1,19 @@
#!/bin/ksh
#
# https://www.qnx.com/developers/docs/6.4.0/neutrino/user_guide/scripts.html
# tfind:
# script to look for strings in various files and dump to less
case $# in
1)
find . -name '*.[ch]' | xargs grep $1 | less
exit 0 # good status
esac
echo "Use tfind stuff_to_find "
echo " where : stuff_to_find = search string "
echo " "
echo "e.g. tfind console_state looks through all files in "
echo " the current directory and below and displays all "
echo " instances of console_state."
exit 1 # bad status