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

Compare commits

...

267 Commits

Author SHA1 Message Date
dependabot[bot]
869deabcc9 build(deps): bump unicode-width from 0.2.0 to 0.2.1
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.2.0 to 0.2.1.
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.2.0...v0.2.1)

---
updated-dependencies:
- dependency-name: unicode-width
  dependency-version: 0.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 04:53:18 +00:00
Sorin Sbarnea
d291b3e5fa chore: Fix some typos (#3244) 2025-08-28 17:30:50 +00:00
Josef Andersson
6772225477 docs(security): add initial security policy (#3290) 2025-08-27 18:33:50 +00:00
Vedant Mohan Goyal
339e7df0bc Update winget-releaser to latest (#3012) 2025-08-25 05:29:04 +00:00
Keith Hall
297e8280d9 Merge pull request #3376 from eric-menne/fix/ctrl-c_fails_in_powershell
Fix ctrl-c fails in powershell
2025-08-22 17:59:35 +03:00
Eric Menne
d397bea6dc Fix typo and clarify description 2025-08-22 17:49:53 +03:00
Eric Menne
3d174b8c09 Updated README.md to include -K option for less 2025-08-22 17:49:53 +03:00
Eric Menne
d9dd9729b8 Add flag to less to enable quitting on Ctrl-C 2025-08-22 17:49:53 +03:00
Martin Nordholts
c657b18efd README.md: Put some requirements on installation instructions
Adding new installation methods increases risk of supply chain exploits
and increases burden of maintainers. Let's put some requirements on what
installation methods to have in the README.md
2025-08-22 06:24:51 +02:00
Keith Hall
c9b41b1df7 Merge pull request #3381 from CalebLarsen/update-docs
docs: added minor theming documentation notes
2025-08-22 07:12:17 +03:00
Caleb Larsen
45efc4117e docs: added minor theming documentation notes
.
2025-08-22 06:04:22 +02:00
Keith Hall
6a74283289 Merge pull request #3382 from CosmicHorrorDev/update-github-theme
deps: Bump assets/themes/github-sublime-theme from `508740b` to `59e525f`
2025-08-20 08:04:30 +03:00
Cosmic Horror
120c39429f deps: Bump assets/themes/github-sublime-theme from 508740b to 59e525f 2025-08-19 21:53:01 -06:00
Keith Hall
1c6ad4d514 Merge pull request #3345 from cavanaug/master
Support context in line ranges
2025-08-20 06:43:36 +03:00
John Cavanaugh
36d25c8642 Merge branch 'master' into master 2025-08-19 20:34:08 -07:00
Yuri Astrakhan
caf6fa369f chore: add CI linting
* ensure `cargo clippy` treats all suggestions as errors in CI
* ensure `cargo clippy` runs with the latest stable Rust because Clippy is MSRV-aware, so it will not suggest anything unapplicable. Also note that whenever new release comes out, Clippy might temporarily show new errors - I think this is  better than forgetting to update the version somewhere, and keep running older tools.
* Update actions/checkout to the latest v5
2025-08-19 18:26:24 +02:00
Yuri Astrakhan
503c50b1ec chore: address all cargo clippy lints
* also do a bit of a doc cleanup for the `load_from_folder` fn
2025-08-19 05:22:47 +02:00
Yuri Astrakhan
d9fbd18541 inline format arguments
In a few cases, removed the unneeded `&` - this causes a minor slowdown because compiler cannot eliminate those (yet).
2025-08-19 05:07:54 +02:00
Keith Hall
9824090654 Merge pull request #3369 from forkeith/utf16le
Fix the read_line method for utf16le/be input
2025-08-16 15:49:16 +03:00
Keith Hall
bdaf25793d cargo fmt 2025-08-16 15:36:45 +03:00
Keith Hall
96ce80d0e2 Apply same fix and tests for UTF16BE 2025-08-16 15:36:45 +03:00
Keith Hall
40c4c8e542 More thorough tests for UTF16LE 2025-08-16 15:35:57 +03:00
Keith Hall
6675153460 Fix the read_line method for utf16le input
to determine the end of the line, instead of reading until \n (0x0A) and then reading until 0x00 and calling it done, read until we find 0x00 preceded by 0x0A.
2025-08-16 15:35:57 +03:00
dependabot[bot]
76e6a49a2e Bump assets/syntaxes/02_Extra/Fish from 98316d4 to ef510fd
Bumps [assets/syntaxes/02_Extra/Fish](https://github.com/Phidica/sublime-fish) from `98316d4` to `ef510fd`.
- [Release notes](https://github.com/Phidica/sublime-fish/releases)
- [Commits](98316d4332...ef510fd759)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-16 08:26:08 +02:00
joshua!
1bcf760d90 docs: Include GNOME bash script for Dark Mode
Title.  I developed this on Fedora 39 with GNOME. Tested and works on my setup as expected.
2025-08-16 07:52:18 +02:00
dependabot[bot]
94f1035c08 Bump nix from 0.29.0 to 0.30.1
Bumps [nix](https://github.com/nix-rust/nix) from 0.29.0 to 0.30.1.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.29.0...v0.30.1)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.30.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-16 07:33:52 +02:00
John Cavanaugh
3516a3311a Merge branch 'master' into master 2025-08-15 06:34:33 -07:00
John Cavanaugh
f79adaf607 test: 🚨 update tests for truncated multiline.txt
test(tests/examples/multiline.txt): 🚨 trim sample file to 10 lines to match new behavior
test(tests/integration_tests.rs): 🚨 adjust line ranges and expected outputs for 10-line sample; add multi-range context test
2025-08-15 05:57:41 -07:00
alcroito
d9ac757b6a Add CI build for windows/ARM64
Fixes: #2644
2025-08-14 17:56:00 +02:00
John Cavanaugh
58bfcd9051 style: 🎨 reformat predicate assertions
style(integration_tests.rs): 🎨 doh, run cargo fmt
2025-08-13 23:31:17 -07:00
John Cavanaugh
67e3e42531 test: 🚨 extend line-range tests
test(tests/examples/multiline.txt): 🚨 add lines 5-20 to sample file for expanded line-range tests
test(tests/integration_tests.rs): 🚨 update expected outputs and add comprehensive context and error tests for line-range feature
2025-08-13 23:29:58 -07:00
John Cavanaugh
3fd3f1def8 Merge branch 'master' into master 2025-08-13 23:27:26 -07:00
Keith Hall
6d849e53d2 Merge pull request #3373 from wcampbell0x2a/add-name-to-x86-asm-sublime-syntax
Add x86_64 Assembly to x86 sublime syntax file
2025-08-13 09:44:13 +03:00
Keith Hall
7fc3d6b588 Update assets/syntaxes/02_Extra/Assembly (x86_64).sublime-syntax 2025-08-13 09:34:59 +03:00
wcampbell
1a931224eb Add x86_64 Assembly to x86 sublime syntax file
* Using ARM Assembly with the bat library works with .language("ARM Assembly"),
  while x86 has no name. Add name to sublime syntax file.
2025-08-13 00:09:31 -04:00
Keith Hall
60833ae5ec Merge pull request #3372 from Nicholas42/master
update gruvbox theme
2025-08-10 19:12:53 +03:00
Nicholas Schwab
183def9569 docs(changelog): update gruvbox theme 2025-08-10 17:52:30 +02:00
Nicholas Schwab
77cfca1aff update gruvbox theme
This fixes https://github.com/sharkdp/bat/issues/2115 for this theme
2025-08-10 17:37:56 +02:00
Keith Hall
d9cc01b50c Merge pull request #3370 from qianbinbin/fix/manpager
Make MANPAGER more portable
2025-08-10 06:17:17 +03:00
Binbin Qian
466087156f Update man usage for Chinese docs 2025-08-09 13:53:00 +08:00
Binbin Qian
a8d610c6e8 Make MANPAGER more portable 2025-08-09 13:52:34 +08:00
Keith Hall
30b42149aa Merge pull request #3200 from forkeith/add_missing_switches_to_manpage
Add missing command line switches to manpage
2025-08-08 06:35:31 +03:00
Keith Hall
c25e005c87 Add missing command line switches to manpage
- `--binary`
- `--completion`
- `--strip-ansi`
2025-08-08 06:21:41 +03:00
Keith Hall
c4d7451841 Merge pull request #3365 from deflektor/update/CompletionPwsh
Update ps1 completion
2025-08-08 06:19:29 +03:00
deflektor
d4fc07a347 Update _bat.ps1.in 2025-08-08 06:11:04 +03:00
deflektor
0238473868 Update assets/completions/_bat.ps1.in
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-08 06:11:04 +03:00
deflektor
4363ddf0fb Update assets/completions/_bat.ps1.in
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-08 06:11:04 +03:00
deflektor
43c5fef70a Update assets/completions/_bat.ps1.in
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-08 06:11:04 +03:00
deflektor
7e436e307d Update assets/completions/_bat.ps1.in
changed back to Template

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-08 06:11:04 +03:00
deflektor
b4d529402a Update ps1 completion;removed shortcuts from completion;added completion for language, theme and options 2025-08-08 06:11:04 +03:00
Keith Hall
b47338ec75 Merge pull request #3362 from qianbinbin/fix/batdiff
Make batdiff more portable
2025-08-08 05:51:24 +03:00
Binbin Qian
bd782ab228 Make batdiff more portable 2025-08-08 05:43:49 +03:00
Keith Hall
4c2b20fedd Merge pull request #3368 from forkeith/fix_missing_assets
Replace missing asset submodules
2025-08-07 22:55:30 +03:00
Keith Hall
9d3245eebe Replace missing asset submodules 2025-08-07 22:45:22 +03:00
Keith Hall
369ea67ad3 Merge pull request #3359 from sharkdp/dependabot/submodules/assets/syntaxes/02_Extra/typst-syntax-highlight-4e2e68b
Bump assets/syntaxes/02_Extra/typst-syntax-highlight from `3f2561d` to `4e2e68b`
2025-08-01 06:23:46 +03:00
dependabot[bot]
c56ce6ad36 Bump assets/syntaxes/02_Extra/typst-syntax-highlight
Bumps [assets/syntaxes/02_Extra/typst-syntax-highlight](https://github.com/hyrious/typst-syntax-highlight) from `3f2561d` to `4e2e68b`.
- [Commits](3f2561d4d8...4e2e68b0a1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 02:53:17 +00:00
Keith Hall
4f0a3f5766 Merge pull request #3353 from Ferenc-/linux-ini-formats
Add syntax mapping for flatpakref
2025-07-31 20:26:08 +03:00
Ferenc Géczi
bac58be1ee Add entry to CHANGELOG.md
Signed-off-by: Ferenc Géczi <ferenc.gm@gmail.com>
2025-07-31 00:00:00 +00:00
Ferenc Géczi
20caaf26c8 Add syntax mapping for flatpakrepo
Signed-off-by: Ferenc Géczi <ferenc.gm@gmail.com>
2025-07-31 00:00:00 +00:00
Ferenc Géczi
3574118e17 Add syntax mapping for flatpakref
Signed-off-by: Ferenc Géczi <ferenc.gm@gmail.com>
2025-07-31 00:00:00 +00:00
Keith Hall
847b717cdf Merge pull request #3351 from musicinmybrain/console-0.16
Update console dependency from 0.15.10 to 0.16.0
2025-07-23 15:19:11 +03:00
Benjamin A. Beasley
3dfb51b25d Add changelog entry for PR#3351 2025-07-23 08:04:24 -04:00
Benjamin A. Beasley
d0b5dd8977 Update Cargo.lock for console 0.16.0 2025-07-23 07:57:07 -04:00
Benjamin A. Beasley
23d97eb4a8 Update console dependency to 0.16.0 2025-07-23 07:56:46 -04:00
Keith Hall
8bc4e76e47 Merge pull request #3347 from bash/terminal-colorsaurus-1.0
Update terminal-colorsaurus to 1.0
2025-07-22 21:19:24 +03:00
Tau Gärtli
38762724f5 Add changelog entry 2025-07-22 07:28:16 +02:00
Tau Gärtli
feb0bc1ae6 Update terminal-colorsaurus to 1.0 2025-07-22 07:15:52 +02:00
Keith Hall
872d0baafb Merge pull request #3206 from sharkdp/make_map_syntax_case_insensitive
Make map-syntax target case insensitive
2025-07-17 22:31:54 +03:00
Keith Hall
35c3f065a3 Update changelog 2025-07-17 22:20:42 +03:00
Keith Hall
8b12191bda Make map-syntax target case insensitive 2025-07-17 22:19:54 +03:00
Martin Nordholts
90b2c57951 Stop auto-merge dependabot PRs
Our CI runs a fair amount of unaudited third party code. I'd like to
stop using my Personal Access Token until we have had time to security
harden our CI.
2025-07-17 19:42:34 +02:00
John Cavanaugh
f484a9dfce Merge branch 'master' into master 2025-07-16 16:53:14 -07:00
John Cavanaugh
b97c275de5 Restore original formatting that my editor decided to "autocorrect" 2025-07-16 16:40:43 -07:00
dependabot[bot]
91c95d8ba7 Bump unicode-width from 0.1.14 to 0.2.0 (#3225)
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.14 to 0.2.0.
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.14...v0.2.0)

---
updated-dependencies:
- dependency-name: unicode-width
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-16 17:01:06 +00:00
TR Staake
2015c99e65 Update README.md
Added note about escaping alias when using help aliasing in zsh
2025-07-16 18:44:42 +02:00
John Cavanaugh
eadf15d9c0 docs: 📚 correct changelog PR reference
docs(CHANGELOG.md): 📚 correct PR number for context in line ranges entry from #3344 to #3345
2025-07-15 16:43:11 -07:00
John Cavanaugh
bb8c5657e1 fix: 🐛 allow three-part range parsing
fix(src/line_range.rs): 🐛 support three-part (start🔚context) syntax, clamp lower at zero and extend upper, and add tests for invalid formats
2025-07-15 16:36:58 -07:00
John Cavanaugh
dc2eae08a6 docs: 📚 update changelog for range context support
docs(CHANGELOG.md): 📚 add entry for context in line ranges and normalize list formatting
style(src/line_range.rs): 🎨 trim trailing whitespace in context parsing code
2025-07-15 16:25:28 -07:00
John Cavanaugh
6c13a98f01 feat: add context support to line-range syntax
docs(long-help.txt): 📚 add examples for N::C and N:M:C context syntax
docs(clap_app.rs): 📚 update CLI help text with context syntax examples
feat(line_range.rs):  implement N::C and N:M:C parsing and add tests
2025-07-15 16:17:09 -07:00
Justin Su
1ad294dcd3 Add missing apostrophe in "bats" 2025-07-15 17:30:50 +02:00
Justin Su
806df574e7 Use relative links in README.md 2025-07-15 17:30:50 +02:00
HE7086
9b580c7a98 Update documentation for git diff 2025-07-15 07:49:46 +02:00
anand-dragon
7c8e2324ab [3040]: Add Alias hint on README 2025-07-15 07:04:14 +02:00
cyqsimon
555933315d Only start offload worker thread when there's more than 1 core (#2956)
* Only start offload worker thread when there's more than 1 core

* Write changelog
2025-07-15 05:21:00 +02:00
Stéphane Blondon
9121746f05 test: code coverage for list-languages parameter 2025-07-14 16:40:14 +02:00
Keith Hall
f1d45da676 Merge pull request #3333 from SchweGELBin/catppuccin-update
Bump Catppuccin from 19c4453 to ccf194f
2025-07-11 20:41:39 +03:00
SchweGELBin
cf147a440e docs(changelog): update catppuccin theme 2025-07-11 20:29:29 +03:00
SchweGELBin
a3a23e5759 binary: update to support newer Catppuccin theme 2025-07-11 20:29:29 +03:00
SchweGELBin
bc7d1cd44a theme: bump Catppuccin from 19c4453 to ccf194f 2025-07-11 20:29:29 +03:00
Keith Hall
735fb7be0e Merge pull request #3322 from YDX-2147483647/lean
Update Lean.sublime-syntax from Lean 3 to Lean 4
2025-07-11 20:28:18 +03:00
Y.D.X.
4661f22e81 Merge remote-tracking branch 'upstream/master' into lean 2025-07-11 13:03:06 +08:00
Y.D.X. (Gitpod)
bfd8776042 chore: Follow Lean upstream 2025-07-11 12:56:46 +08:00
dependabot[bot]
e8ff13cd53 Bump toml from 0.8.19 to 0.8.23 (#3332)
---
updated-dependencies:
- dependency-name: toml
  dependency-version: 0.8.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 21:18:15 +00:00
dependabot[bot]
1771f6da8d Bump flate2 from 1.0.35 to 1.1.2 (#3331)
---
updated-dependencies:
- dependency-name: flate2
  dependency-version: 1.1.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 21:02:31 +00:00
Keith Hall
e888e968b6 Merge pull request #3340 from cyqsimon/syntax-mapping-build-script-use-quote
Build script: replace string-based codegen with `quote`-based codegen
2025-07-10 23:46:54 +03:00
cyqsimon
68df079c0e Add improvement note on parse + unparse 2025-07-10 23:31:12 +03:00
cyqsimon
563c4c290d Consistent spaces in quote! invocations 2025-07-10 23:31:12 +03:00
cyqsimon
ffbcfd53f9 Write changelog 2025-07-10 23:31:12 +03:00
cyqsimon
fd12328293 Build script: replace string-based codegen with quote-based codegen 2025-07-10 23:31:12 +03:00
Keith Hall
b387abea6b Merge pull request #3342 from krikera/master
docs(man): update --style documentation with priority rules
2025-07-10 23:30:05 +03:00
Krishna Ketan Rai
efdd038fa4 docs(man): update --style documentation with priority rules 2025-07-10 02:11:35 +05:30
dependabot[bot]
94b699d8df Bump assets/syntaxes/02_Extra/typst-syntax-highlight (#3330)
Bumps [assets/syntaxes/02_Extra/typst-syntax-highlight](https://github.com/hyrious/typst-syntax-highlight) from `1bde1ea` to `3f2561d`.
- [Commits](1bde1ea511...3f2561d4d8)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-09 19:47:43 +00:00
Keith Hall
226efecdd6 Merge pull request #3337 from JerryImMouse/syntax-vhdl
Add syntax highlighting for VHDL language
2025-07-09 22:31:26 +03:00
Jerry
a0b4397ddf Merge branch 'master' into syntax-vhdl 2025-07-09 04:33:36 +05:00
Keith Hall
c18f5e054e Merge pull request #3338 from cyqsimon/certbot
Add syntax mapping for certbot certificate configuration
2025-07-08 23:44:37 +03:00
cyqsimon
360d43dd4d Write changelog 2025-07-08 23:33:41 +03:00
cyqsimon
e0165a2d6a Add syntax mapping for certbot certificate configuration 2025-07-08 23:33:41 +03:00
Jerry
9776ebfa0f Send errors to stderr (#3336)
* fix: send errors to stderr by default (#2561)

Closes #2561

* chore: add changelog entry

* chore: change PR id

* chore: add github username

* chore: cargo fmt...

* chore: move changelog line to bugfixes
2025-07-08 20:42:22 +02:00
Jerry
eda3ecb0b3 Merge branch 'master' into syntax-vhdl 2025-07-08 17:48:10 +05:00
cyqsimon
cf7631d469 CICD: replace windows-2019 runners with windows-2025 (#3339)
* CICD: replace windows-2019 runners with windows-2025

See https://github.com/actions/runner-images/issues/12045

* Write changelog
2025-07-08 12:37:06 +02:00
JerryImMouse
185a2f3437 chore: update pr number in changelog 2025-07-07 19:37:06 +05:00
JerryImMouse
bdc971eca3 feat(syntax): add syntax highlighting for VHDL 2025-07-07 19:20:23 +05:00
Y.D.X.
288b7e9ca3 docs: Add Lean/LICENSE.md
> Jeremy Avigad:
> Patrick and I decided that it makes sense to release the text of MIL under CC BY 4.0 and the repository code (exercises, solutions, etc.) under Apache 2.0. We'll put the Apache license in the repo and figure out where to at the CC BY notice, but in the meantime, you can take this message as a declaration.

https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/License.20of.20Mathematics.20in.20Lean.3F/near/523527618
2025-06-11 22:06:52 +08:00
Y.D.X.
a9d5880dc8 docs: Update CHANGELOG, allow CC BY 4.0 license, and fix a markdown backquote 2025-06-10 17:44:10 +08:00
Y.D.X.
0918984249 Update Lean.sublime-syntax from Lean 3 to Lean 4
Resolves #3286

1. `lean4.json` → `lean4.tmLanguage`

    1. Download `vscode-lean4/syntaxes/lean4.json` from https://github.com/leanprover/vscode-lean4/pull/623 (now merged).
    2. Install the VS Code extension [TextMate Languages (pedro-w)](https://marketplace.visualstudio.com/items?itemName=pedro-w.tmlanguage).
    3. Open `lean4.json` in VS Code, <kbd>F1</kbd>, and “Convert to tmLanguage PLIST File”.

2. `lean4.tmLanguage` → `lean4.sublime-syntax`

    Open `lean4.tmLanguage` in Sublime text, “Tools → Developer → New Syntax from lean4.tmLanguage…”.
2025-06-10 17:41:33 +08:00
Keith Hall
e2aa4bc33c Merge pull request #3320 from krikera/add-mill-syntax-mapping
Add syntax mapping for Mill build tool files to use Scala syntax
2025-06-02 19:50:38 +03:00
krikera
9d3db318e3 Add syntax mapping for Mill build tool files to use Scala syntax 2025-06-01 22:03:54 +05:30
dependabot[bot]
5aa123b4f0 Bump assets/syntaxes/02_Extra/Apache from cf6cefc to c438c35 (#3318)
Bumps [assets/syntaxes/02_Extra/Apache](https://github.com/colinta/ApacheConf.tmLanguage) from `cf6cefc` to `c438c35`.
- [Commits](cf6cefc51e...c438c352db)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-01 02:13:57 +00:00
Keith Hall
f11d34997a Merge pull request #3317 from SchweGELBin/catppuccin
Themes: Add Catppuccin
2025-05-31 16:50:34 +03:00
SchweGELBin
510814410c docs(changelog): add catppuccin theme 2025-05-31 15:05:44 +02:00
SchweGELBin
e4bae61393 binary: update to support Catppuccin 2025-05-31 14:57:44 +02:00
SchweGELBin
4cfc50c358 theme: add Catppuccin 2025-05-31 14:56:10 +02:00
Keith Hall
6886cdaace Merge pull request #3315 from krikera/fix-utf8-bom-syntax-detection
Fix UTF-8 BOM file type detection for first-line syntax patterns
2025-05-31 14:45:50 +03:00
krikera
17e6952ab8 Fix UTF-8 BOM file type detection for first-line syntax patterns - Fixes #3314 2025-05-31 02:58:47 +05:30
Keith Hall
0da4084064 Merge pull request #3300 from cskeeters/syntax_typst
Adds Typst syntax from hyrious/typst-syntax-highlight
2025-05-21 05:47:26 +03:00
Chad Skeeters
4c9a51990c Corrects spelling mistake in syntax-test for Typst 2025-05-20 16:35:47 -05:00
Chad Skeeters
36a86d34e8 Adds changelog entry 2025-05-20 14:50:53 -05:00
Chad Skeeters
fb514ca90f Adds Typst syntax from hyrious/typst-syntax-highlight 2025-05-20 14:43:21 -05:00
Keith Hall
aa5e28bef5 Merge pull request #3299 from cyqsimon/quadlet
Update quadlet syntax mapping rules to cover quadlets in subdirectories
2025-05-20 21:40:43 +03:00
cyqsimon
5dc3d8c936 Write changelog 2025-05-20 15:33:57 +08:00
cyqsimon
a4ffe2fdbf Update quadlet syntax mapping rules to cover quadlets in subdirectories 2025-05-20 15:22:55 +08:00
Keith Hall
c32fa662d5 Merge pull request #3298 from ZaneErebos/patch-2
Clarify situation in which man page and shell completions will be accessible when building from source
2025-05-19 04:42:28 +03:00
Zane
0a9588a866 Clarify situation in which man page and shell completions will be accessible when building from source 2025-05-18 21:00:59 -04:00
Jamy Golden
861b868416 Update base16 urls to link to community run version 2025-05-14 19:01:50 +02:00
David Peter
b7f9662097 Update README.md 2025-05-05 08:46:01 +02:00
Keith Hall
79ecb11ce2 Add new sponsor Graphite to Readme (#3270)
* Add new sponsor Graphite to Readme

* hide bullet points in sponsors section of readme

* remove bullet points
2025-05-05 08:44:24 +02:00
Integral
4e9bb610b3 docs(README): fix broken link of Visual C++ Redistributable 2025-05-01 13:33:43 +02:00
dependabot[bot]
c88faf8cfa Bump assets/themes/zenburn from 9c588eb to 4f21745 (#3277)
Bumps [assets/themes/zenburn](https://github.com/colinta/zenburn) from `9c588eb` to `4f21745`.
- [Commits](9c588ebc11...4f21745723)

---
updated-dependencies:
- dependency-name: assets/themes/zenburn
  dependency-version: 4f217457230ff5f31d594b0e20474b69294988d4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 03:10:48 +00:00
Keith Hall
0b48eab7a6 Merge pull request #3276 from forkeith/livescript_fix
remove LiveScript submodule
2025-04-30 22:42:30 +03:00
Keith Hall
ccfbd1ee31 remove LiveScript submodule
the repo has gone away, causing all our CI etc. to break

we can keep the highlighting though because we have a .sublime-syntax file
2025-04-30 22:32:48 +03:00
Keith Hall
98c9a5d948 Merge pull request #3263 from gthb/patch-1
Fix copy-paste mistake in bat.1.in
2025-04-15 21:55:35 +03:00
Keith Hall
96ea42e5f4 Merge branch 'master' into patch-1 2025-04-15 21:25:32 +03:00
Keith Hall
2ff2a818ef Merge pull request #3068 from ajesipow/read-from-tail
Support relative negative line ranges
2025-04-15 21:16:39 +03:00
Keith Hall
dd694c266e Merge branch 'master' into patch-1 2025-04-15 21:00:19 +03:00
Keith Hall
c4461f7d78 Merge branch 'master' into read-from-tail 2025-04-15 20:59:51 +03:00
Keith Hall
77de5160ac Merge pull request #3266 from sharkdp/fix_ci
use latest Ubuntu for CI jobs now that GitHub deprecated 20.04
2025-04-15 20:59:14 +03:00
Keith Hall
b9fcc5ae2d use latest Ubuntu for CI jobs now that GitHub deprecated 20.04 2025-04-15 20:30:56 +03:00
Keith Hall
e42883bf2c Merge branch 'master' into read-from-tail 2025-04-15 20:27:26 +03:00
Keith Hall
5c41a45931 Merge branch 'master' into patch-1 2025-04-15 20:09:50 +03:00
dependabot[bot]
ba49ba0acd Bump assets/themes/zenburn from 86d4ee7 to 9c588eb (#3251)
Bumps [assets/themes/zenburn](https://github.com/colinta/zenburn) from `86d4ee7` to `9c588eb`.
- [Commits](86d4ee7a1f...9c588ebc11)

---
updated-dependencies:
- dependency-name: assets/themes/zenburn
  dependency-version: 9c588ebc11c3e6487b081bd54528af08baa8a09a
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 10:36:54 +00:00
dependabot[bot]
5d75632c8e Bump assets/syntaxes/02_Extra/PowerShell from c0372a1 to a08b55b (#3252)
Bumps [assets/syntaxes/02_Extra/PowerShell](https://github.com/PowerShell/EditorSyntax) from `c0372a1` to `a08b55b`.
- [Commits](c0372a1d2d...a08b55bf11)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 10:14:09 +00:00
dependabot[bot]
e202a33ea1 Bump assets/syntaxes/02_Extra/Apache from 163bc03 to cf6cefc (#3253)
Bumps [assets/syntaxes/02_Extra/Apache](https://github.com/colinta/ApacheConf.tmLanguage) from `163bc03` to `cf6cefc`.
- [Commits](163bc03ae8...cf6cefc51e)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 09:50:51 +00:00
Keith Hall
93be82ebc9 Merge pull request #3236 from chetanjangir0/add-gdscript-support
Add GDScript Syntax Support (#3233)
2025-04-13 12:31:26 +03:00
Chetan Jangir
0bf4753ff1 Update CHANGELOG.md
Co-authored-by: Keith Hall <keith-hall@users.noreply.github.com>
2025-04-13 14:51:53 +05:30
Chetan Jangir
fbb07a1494 Merge branch 'master' into add-gdscript-support 2025-04-13 10:00:58 +05:30
Keith Hall
debb66f8b0 Merge pull request #3262 from AdamGaskins/bash-zsh
Fix syntax highlighting for bash/zsh
2025-04-12 18:21:01 +03:00
Adam Gaskins
45185b36fb Merge branch 'master' into bash-zsh 2025-04-12 11:09:33 -04:00
Adam Gaskins
e761d79512 Update CHANGELOG.md
Co-authored-by: Keith Hall <keith-hall@users.noreply.github.com>
2025-04-12 11:08:57 -04:00
chetanjangir0
14064dd987 regenerated the highlighted file 2025-04-12 19:14:15 +05:30
chetanjangir0
3eef8590f4 genereated highlighted syntax test file 2025-04-12 18:00:43 +05:30
chetanjangir0
3e7ad18fe3 fixed merge conflicts 2025-04-12 17:22:18 +05:30
Keith Hall
80a38590b8 Merge pull request #3245 from HSM95/fix/multibyte-chars
Fix for multibyte characters in file path
2025-04-12 11:30:28 +03:00
Keith Hall
44a6e29da7 Merge branch 'master' into fix/multibyte-chars 2025-04-12 11:20:48 +03:00
Gunnlaugur Thor Briem
a6e847e267 Fix copy-paste mistake in bat.1.in
The `--theme-light` documentation says “dark” in two places where it should say “light” (presumably copy-pasted from the `--theme-dark` documentation)
2025-04-10 10:56:19 +00:00
Martin Nordholts
2f70906665 Cargo.toml: Document that MSRV can be bumped if there is a reason for it
To the best of my knowledge our current MSRV rule is that we can bump
MSRV whenever there is a reason for it. Let's document it.
2025-04-08 05:00:00 +02:00
Adam Gaskins
c4c919aa31 Update CHANGELOG.md 2025-04-07 17:43:56 -04:00
Adam Gaskins
51491c3c08 Fix syntax highlighting for bash/zsh 2025-04-07 17:43:56 -04:00
Martin Nordholts
ea17f6ad28 Make mention (@ in front of name) in CHANGELOG entry optional 2025-04-07 17:31:12 +02:00
Martin Nordholts
3691c9945a CICD: Stop building for x86_64-pc-windows-gnu which fails
Let's not build for platforms that are broken. If someone fixes the
build we can of course add it back.
2025-04-07 17:31:12 +02:00
Keith Hall
57629bcaca Merge pull request #3239 from einfachIrgendwer0815/feature/page_list_themes
Add paging to `--list-themes`
2025-04-05 09:08:35 +03:00
HSM95
b38ee77628 Merge branch 'master' into fix/multibyte-chars 2025-04-03 00:49:55 -07:00
Haris Mohamedy
b5413cc015 Do not split into graphemes if not necessary 2025-04-03 00:49:14 -07:00
einfachIrgendwer0815
5edaa96164 Update CHANGELOG 2025-04-02 11:27:37 +02:00
einfachIrgendwer0815
12a2a451b4 Add paging to --list-themes 2025-04-02 11:27:37 +02:00
Keith Hall
fc7dff50b0 Merge pull request #3255 from dan-hipschman/fix-syntax-test-compare-script
Make highlight tests fail when new syntaxes don't have fixtures
2025-04-02 05:21:30 +03:00
Dan Hipschman
9272e09058 Make highlight tests fail when new syntaxes don't have fixtures 2025-04-01 13:08:19 -07:00
dependabot[bot]
b13c4d5f8d Bump indexmap from 2.7.0 to 2.8.0 (#3248)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.7.0 to 2.8.0.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.7.0...2.8.0)

---
updated-dependencies:
- dependency-name: indexmap
  dependency-version: 2.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 03:39:30 +00:00
dependabot[bot]
d7b10b4352 Bump etcetera from 0.8.0 to 0.10.0 (#3247)
Bumps [etcetera](https://github.com/lunacookies/etcetera) from 0.8.0 to 0.10.0.
- [Release notes](https://github.com/lunacookies/etcetera/releases)
- [Commits](https://github.com/lunacookies/etcetera/compare/v0.8.0...v0.10.0)

---
updated-dependencies:
- dependency-name: etcetera
  dependency-version: 0.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 03:11:49 +00:00
dependabot[bot]
05cddff72d Bump anyhow from 1.0.95 to 1.0.97 (#3246)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.95 to 1.0.97.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.95...1.0.97)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.97
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 02:44:03 +00:00
Haris Mohamedy
a55d23aaa4 Add PR to CHANGELOG 2025-03-31 17:50:23 -07:00
Haris Mohamedy
18b71743c8 Fix for multibyte characters in file path 2025-03-31 17:29:18 -07:00
dependabot[bot]
f761ff6824 Bump assets/syntaxes/02_Extra/Org_mode from 4976d8f to bb6e5d8 (#3221)
Bumps [assets/syntaxes/02_Extra/Org_mode](https://github.com/jezcope/Org.tmbundle) from `4976d8f` to `bb6e5d8`.
- [Release notes](https://github.com/jezcope/Org.tmbundle/releases)
- [Commits](4976d8f84e...bb6e5d8481)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/Org_mode
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-29 06:55:24 +00:00
dependabot[bot]
8e2d233445 Bump assets/syntaxes/02_Extra/Zig from 1a4a384 to 8a4a3fe (#3220)
Bumps [assets/syntaxes/02_Extra/Zig](https://github.com/ziglang/sublime-zig-language) from `1a4a384` to `8a4a3fe`.
- [Release notes](https://github.com/ziglang/sublime-zig-language/releases)
- [Commits](1a4a38445f...8a4a3fe4a0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-29 06:41:10 +00:00
Keith Hall
59b1f362f6 Merge pull request #3241 from chetanjangir0/add-odin-syntax
Add Odin Language Syntax Support
2025-03-29 08:23:52 +02:00
Chetan Jangir
a73c641a0f Update CHANGELOG.md
Co-authored-by: Keith Hall <keith-hall@users.noreply.github.com>
2025-03-29 11:43:36 +05:30
Chetan Jangir
3d4c72da0b Merge branch 'master' into add-gdscript-support 2025-03-29 09:44:48 +05:30
Chetan Jangir
71547b3fb3 Merge branch 'master' into add-odin-syntax 2025-03-29 09:44:11 +05:30
Keith Hall
ad8da94d2a Merge pull request #3243 from simono/patch-2
Use built-in detection for OS theme in Readme
2025-03-29 05:27:11 +02:00
Simon Olofsson
5ea762a46c Use built-in detection for OS theme in Readme 2025-03-29 05:15:38 +02:00
Keith Hall
bbb5829ad9 Merge pull request #3242 from simono/patch-1
Add abbreviations for fish to Readme
2025-03-29 05:13:14 +02:00
Simon Olofsson
c00b382f13 Add abbreviations for fish to Readme 2025-03-28 22:01:23 +01:00
Chetan
964e2bdac3 updated changelog for pr number 2025-03-28 12:23:34 +00:00
Chetan
2e7ab99099 Add Odin submodule and syntax test file 2025-03-28 12:17:45 +00:00
Chetan
4175f28979 Update changelog entry for GDScript support (#3233) 2025-03-23 13:53:32 +00:00
Chetan
207f90f01b Add GDScript submodule and syntax test file for GDScript support, see #XXX (@chetanjangir0) 2025-03-23 13:24:30 +00:00
dependabot[bot]
5c43ddb56c Bump assets/syntaxes/02_Extra/cmd-help from 209559b to 68e727b (#3222)
Bumps [assets/syntaxes/02_Extra/cmd-help](https://github.com/victor-gp/cmd-help-sublime-syntax) from `209559b` to `68e727b`.
- [Commits](209559b72f...68e727bad4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-18 17:23:30 +00:00
dependabot[bot]
3838766dd4 Bump assets/syntaxes/02_Extra/Docker from 0f6b7bc to c001fb2 (#3024)
Bumps [assets/syntaxes/02_Extra/Docker](https://github.com/asbjornenge/Docker.tmbundle) from `0f6b7bc` to `c001fb2`.
- [Release notes](https://github.com/asbjornenge/Docker.tmbundle/releases)
- [Commits](0f6b7bc87a...c001fb2805)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/Docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-18 16:13:59 +00:00
David Peter
a006457a72 Update Warp link 2025-03-09 19:20:02 +01:00
David Peter
0449107230 Update sponsors 2025-03-04 19:30:20 +01:00
dependabot[bot]
75313d886b Bump assets/syntaxes/02_Extra/Nix from 9032bd6 to 48c497c (#3219)
Bumps [assets/syntaxes/02_Extra/Nix](https://github.com/wmertens/sublime-nix) from `9032bd6` to `48c497c`.
- [Release notes](https://github.com/wmertens/sublime-nix/releases)
- [Commits](9032bd6137...48c497c709)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/Nix
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-01 03:25:07 +00:00
Keith Hall
4998f58847 Merge pull request #3215 from sharkdp/debsources
Add debsources syntax
2025-02-25 22:28:09 +02:00
Keith Hall
ffc094bd91 Add debsources syntax 2025-02-25 22:17:00 +02:00
Keith Hall
343326eacf Merge pull request #3213 from sharkdp/csproj_xml_mapping
Map various .NET file extensions to XML syntax
2025-02-25 05:09:12 +02:00
Keith Hall
d31bc4347a Map various .NET file extensions to XML syntax 2025-02-23 20:20:52 +02:00
Keith Hall
adfb951e51 Merge pull request #3209 from sharkdp/ndjson
Add mapping for ndjson file extension to JSON syntax
2025-02-15 12:16:52 +02:00
Keith Hall
2843a2c0e8 Add mapping for ndjson file extension to JSON syntax 2025-02-15 08:46:22 +02:00
Keith Hall
94d3dc254e Merge pull request #3205 from sharkdp/syslog_error_highlighting_fix
Syslog error highlighting fix
2025-02-10 20:46:54 +02:00
Keith Hall
915eb55779 Merge branch 'master' into syslog_error_highlighting_fix 2025-02-09 22:20:14 +02:00
Keith Hall
547bc38118 Merge pull request #3186 from sharkdp/csv_1977
Correctly handle CSV files with a single separator throughout
2025-02-09 20:49:14 +02:00
Keith Hall
93fd013aa1 Update changelog 2025-02-09 20:37:53 +02:00
Keith Hall
512bfde7ce Correctly handle CSV files with a single separator throughout
better auto-detection of CSV delimiter
- files with a tsv extension are automatically detected as tab delimited
- other files parsed as CSV go through the following steps:
  - if the first line contains at least 3 of the same separator, it uses that separator as a delimiter
  - if the first line contains only one supported separator character, it uses that separator as a delimiter
  - otherwise it falls back to treating all supported delimiters as the delimiter

 supported delimiters, in precedence order:
 - comma `,`
 - semi-colon `;`
 - tab `\t`
 - pipe `|`
2025-02-09 20:37:53 +02:00
Keith Hall
27ba45ded7 patch Monokai Extended theme for better Syslog error highlighting 2025-02-09 20:32:48 +02:00
Keith Hall
c0898dedb1 fix meta scope ordering to come before constant.numeric scope for times 2025-02-09 20:31:31 +02:00
Keith Hall
b82b920420 attempt to fix syslog error highlighting 2025-02-09 20:31:31 +02:00
Keith Hall
ac40f7cfd8 Merge pull request #3201 from victor-gp/fix-submodules-for-dependabot
Rename submodule paths to fix Dependabot submodule updates
2025-02-04 05:15:14 +02:00
Víctor González Prieto
330c51de9f Add Changelog entry 2025-02-04 00:15:45 +01:00
Víctor González Prieto
0ed527f0d1 Replace spaces in git submodule paths
To mitigate a bug in the GitHub API that broke the Dependabot action
that updates submodules. See sharkdp/bat#3198.
2025-02-03 22:01:33 +01:00
Keith Hall
7df1dec65c Merge pull request #3196 from odilf/master
Add syntax mapping for `nix`s `flake.lock`
2025-02-02 21:20:33 +02:00
odilf
61d42ee87b Add syntax mapping for nixs flake.lock 2025-02-02 21:10:03 +02:00
Keith Hall
a95e65eea1 Merge pull request #3197 from einfachIrgendwer0815/style/fix_lints
Fix clippy lint warnings
2025-02-02 21:05:43 +02:00
einfachIrgendwer0815
71dce0e7f3 Fix clippy::duplicated_attributes warnings 2025-02-02 15:08:16 +01:00
einfachIrgendwer0815
53af1dc32d Fix clippy::unnecessary_filter_map warnings 2025-02-02 15:08:15 +01:00
einfachIrgendwer0815
52252b15d6 Fix clippy::needless_lifetimes warnings 2025-02-02 15:08:15 +01:00
einfachIrgendwer0815
bc24ce9ad4 Fix clippy::needless_update warnings 2025-02-02 15:08:15 +01:00
einfachIrgendwer0815
625e986552 Fix clippy::manual_ignore_case_cmp warnings 2025-02-02 15:08:14 +01:00
einfachIrgendwer0815
095442191c Fix clippy::ptr_arg warnings 2025-02-02 15:08:14 +01:00
einfachIrgendwer0815
cc46282866 Fix clippy::into_iter_on_ref warnings 2025-02-02 15:08:13 +01:00
einfachIrgendwer0815
cbc9c3629d Fix clippy::manual_pattern_char_comparison warnings 2025-02-02 15:08:13 +01:00
einfachIrgendwer0815
2c49d905e4 Fix clippy::legacy_numeric_constants warnings 2025-02-02 15:08:12 +01:00
einfachIrgendwer0815
f0e2f642e0 Fix clippy::redundant_closure warnings 2025-02-02 15:08:12 +01:00
einfachIrgendwer0815
3d0f0c0565 Fix clippy::unnecessary_map_or warnings 2025-02-02 15:08:12 +01:00
einfachIrgendwer0815
3d442cdf98 Fix clippy::needless_borrow warnings 2025-02-02 15:08:11 +01:00
einfachIrgendwer0815
b009fee5ea Fix clippy::needless_return warnings 2025-02-02 15:08:11 +01:00
einfachIrgendwer0815
6cf747678c Fix clippy::needless_borrows_for_generic_args warnings 2025-02-02 15:08:11 +01:00
dependabot[bot]
db812e1179 Bump thiserror from 1.0.69 to 2.0.11 (#3195)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.69 to 2.0.11.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.69...2.0.11)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 04:35:19 +00:00
dependabot[bot]
995f23b58f Bump tempfile from 3.15.0 to 3.16.0 (#3192)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.15.0 to 3.16.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.15.0...v3.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 04:18:58 +00:00
dependabot[bot]
ef3830234d Bump itertools from 0.13.0 to 0.14.0 (#3193)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.13.0 to 0.14.0.
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.13.0...v0.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 03:53:27 +00:00
dependabot[bot]
4fc55cfcec Bump semver from 1.0.24 to 1.0.25 (#3191)
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.24 to 1.0.25.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.24...1.0.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-01 03:24:58 +00:00
Keith Hall
487ac3bc48 Merge pull request #3150 from buzden/add-idris-syntax
[ new ] Add support for Idris 2 programming language
2025-01-27 23:00:05 +02:00
Denis Buzdalov
d6cb3ba747 [ new ] Add support for Idris 2 programming language 2025-01-27 23:47:20 +03:00
Keith Hall
a9a2dceb72 Merge pull request #3146 from buzden/fix-readme-translation
Correct and update one readme's translation according to the main english one
2025-01-27 22:35:23 +02:00
Keith Hall
bee08e48ae Merge branch 'master' into fix-readme-translation 2025-01-27 22:20:35 +02:00
Keith Hall
b14fb9db24 Merge pull request #3189 from einfachIrgendwer0815/fix/list_themes_2
Fix: Don't output default theme info to piped stdout
2025-01-27 21:59:18 +02:00
Keith Hall
91acb0d16f update changelog to mention --list-themes bugfix when stdout is piped 2025-01-27 21:43:57 +02:00
einfachIrgendwer0815
4f161705a3 Fix: Don't output default theme info to piped stdout 2025-01-27 17:11:26 +01:00
Keith Hall
f8c6e90647 Merge pull request #3182 from cyqsimon/paru
Add syntax mapping for paru configuration files
2025-01-24 23:21:29 +02:00
cyqsimon
dd9dc4f76b Write changelog 2025-01-24 23:02:57 +02:00
cyqsimon
94f49fd99b Add syntax mapping for paru configuration 2025-01-24 23:02:57 +02:00
Keith Hall
498df11a50 Merge pull request #3179 from dtolnay-contrib/vendorbug
Work around `cargo vendor` losing syntax_mapping builtins directory
2025-01-18 09:31:35 +02:00
David Tolnay
db7da314e7 Work around cargo vendor losing syntax_mapping builtins directory 2025-01-17 21:30:37 -08:00
David Peter
33aabc696a Move section slightly further down 2025-01-15 08:34:52 +01:00
oliviajohnsto
648bedf290 Add Warp Pack sponsorship 2025-01-15 08:34:52 +01:00
Keith Hall
dd3d1b8cdb Merge pull request #3174 from philipp-tailor/patch-1
Fix tiny accidental repetition in README.md
2025-01-10 19:31:42 +02:00
Philipp Schneider
b39a156d57 Update README.md
Fixes copy and paste error, where same option was listed twice, instead of the 2 distinct options of `--theme` for different system appearances.
2025-01-10 17:45:26 +01:00
Keith Hall
b6158c09b4 Merge pull request #3168 from bash/fix-env-var-names
Fix name of BAT_THEME_{DARK,LIGHT} env vars
2025-01-09 18:50:02 +02:00
Tau Gärtli
8a11a46f66 Add integration tests 2025-01-09 08:20:36 +01:00
Tau Gärtli
4d73c1e511 Add changelog entry 2025-01-09 08:20:36 +01:00
Tau Gärtli
280f3eeb4e Fix name of BAT_THEME_{DARK,LIGHT} env vars 2025-01-09 08:20:36 +01:00
Keith Hall
1321160203 Merge pull request #3169 from branchvincent/git2
Bump git2 to 0.20
2025-01-08 06:52:03 +02:00
Branch Vincent
01680e444b Bump git2 to 0.20 2025-01-07 20:30:27 -08:00
Keith Hall
2435453c33 Merge pull request #3167 from sharkdp/keith-hall-patch-1
Post release steps
2025-01-07 21:51:03 +02:00
Keith Hall
6e466e5ab4 Post release steps
Add new unreleased section at top of change log
2025-01-07 21:30:39 +02:00
Denis Buzdalov
004d2d5122 [ readme ] Correct and update one readme's translation 2024-12-17 13:49:23 +03:00
Alex Jesipow
60b3428ad7 Fix lock file 2024-08-10 11:38:38 +02:00
Alex
571970f8ff Merge branch 'master' into read-from-tail 2024-08-10 11:34:45 +02:00
Alex Jesipow
18a0653ce8 Add changelog entry 2024-08-10 11:27:34 +02:00
Alex Jesipow
569286055c Support relative negative line ranges 2024-08-10 10:37:19 +02:00
145 changed files with 4382 additions and 1325 deletions

View File

@@ -1,23 +0,0 @@
# This workflow triggers auto-merge of any PR that dependabot creates so that
# PRs will be merged automatically without maintainer intervention if CI passes
name: Auto-merge dependabot PRs
on:
pull_request_target:
types: [opened]
jobs:
auto-merge:
if: github.repository == 'sharkdp/bat' && startsWith(github.head_ref, 'dependabot/')
runs-on: ubuntu-latest
environment:
name: auto-merge
url: https://github.com/sharkdp/bat/blob/main/.github/workflows/Auto-merge-dependabot-PRs.yml
env:
GITHUB_TOKEN: ${{ secrets.AUTO_MERGE_GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- run: |
gh pr review ${{ github.event.pull_request.number }} --comment --body "If CI passes, this dependabot PR will be [auto-merged](https://github.com/sharkdp/bat/blob/main/.github/workflows/Auto-merge-dependabot-PRs.yml) 🚀"
- run: |
gh pr merge --auto --squash ${{ github.event.pull_request.number }}

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
needs:
- crate_metadata
- ensure_cargo_fmt
- lint
- min_version
- license_checks
- test_with_new_syntaxes_and_themes
@@ -35,7 +35,7 @@ jobs:
name: Extract crate metadata
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Extract crate information
id: crate_metadata
run: |
@@ -51,49 +51,46 @@ jobs:
homepage: ${{ steps.crate_metadata.outputs.homepage }}
msrv: ${{ steps.crate_metadata.outputs.msrv }}
ensure_cargo_fmt:
name: Ensure 'cargo fmt' has been run
runs-on: ubuntu-20.04
lint:
name: Ensure code quality
runs-on: ubuntu-latest
steps:
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: actions/checkout@v4
components: rustfmt,clippy
- uses: actions/checkout@v5
- run: cargo fmt -- --check
- run: cargo clippy --locked --all-targets --all-features -- -D warnings
min_version:
name: Minimum supported rust version
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
needs: crate_metadata
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.crate_metadata.outputs.msrv }}
components: clippy
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
run: cargo clippy --locked --all-targets ${{ env.MSRV_FEATURES }}
- name: Run tests
run: cargo test --locked ${{ env.MSRV_FEATURES }}
license_checks:
name: License checks
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
submodules: true # we especially want to perform license checks on submodules
- run: tests/scripts/license-checks.sh
test_with_new_syntaxes_and_themes:
name: Run tests with updated syntaxes and themes
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: true # we need all syntax and theme submodules
- name: Install Rust toolchain
@@ -119,10 +116,10 @@ jobs:
test_with_system_config:
name: Run tests with system wide configuration
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Prepare environment variables
run: |
echo "BAT_SYSTEM_CONFIG_PREFIX=$GITHUB_WORKSPACE/tests/examples/system_config" >> $GITHUB_ENV
@@ -135,10 +132,10 @@ jobs:
documentation:
name: Documentation
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Check documentation
@@ -153,7 +150,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: cargo install cargo-audit --locked
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- run: cargo audit
build:
@@ -164,24 +161,24 @@ jobs:
fail-fast: false
matrix:
job:
- { target: aarch64-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: arm64, use-cross: true }
- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: arm64, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, dpkg_arch: armhf, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, dpkg_arch: musl-linux-armhf, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2019, }
- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: i686, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-i686, 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: 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: 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-musl , os: ubuntu-latest, dpkg_arch: musl-linux-i686, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-13, }
- { target: aarch64-apple-darwin , os: macos-14, }
- { target: x86_64-pc-windows-gnu , os: windows-2019, }
- { target: x86_64-pc-windows-msvc , os: windows-2019, }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: amd64, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-amd64, use-cross: true }
- { target: x86_64-pc-windows-msvc , os: windows-2025, }
- { 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-musl , os: ubuntu-latest, dpkg_arch: musl-linux-amd64, use-cross: true }
env:
BUILD_CMD: cargo
steps:
- name: Checkout source code
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install prerequisites
shell: bash
@@ -462,7 +459,7 @@ jobs:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
- uses: vedantmgoyal9/winget-releaser@19e706d4c9121098010096f9c495a70a7518b30f
with:
identifier: sharkdp.bat
installers-regex: '-pc-windows-msvc\.zip$'

View File

@@ -30,4 +30,4 @@ jobs:
echo "Added lines in CHANGELOG.md:"
echo "$ADDED"
echo "Grepping for PR info (see CONTRIBUTING.md):"
grep "#${PR_NUMBER}\\b.*@${PR_SUBMITTER}\\b" <<< "$ADDED"
grep "#${PR_NUMBER}\\b.*${PR_SUBMITTER}\\b" <<< "$ADDED"

39
.gitmodules vendored
View File

@@ -65,7 +65,7 @@
path = assets/themes/onehalf
url = https://github.com/sonph/onehalf
[submodule "assets/syntaxes/JavaScript (Babel)"]
path = assets/syntaxes/02_Extra/JavaScript (Babel)
path = assets/syntaxes/02_Extra/JavaScript_(Babel)
url = https://github.com/babel/babel-sublime
[submodule "assets/syntaxes/FSharp"]
path = assets/syntaxes/02_Extra/FSharp
@@ -89,7 +89,7 @@
path = assets/themes/sublime-snazzy
url = https://github.com/greggb/sublime-snazzy
[submodule "assets/syntaxes/Assembly (ARM)"]
path = assets/syntaxes/02_Extra/Assembly (ARM)
path = assets/syntaxes/02_Extra/Assembly_(ARM)
url = https://github.com/tvi/Sublime-ARM-Assembly
[submodule "assets/syntaxes/protobuf-syntax-highlighting"]
path = assets/syntaxes/02_Extra/Protobuf
@@ -108,14 +108,11 @@
path = assets/syntaxes/02_Extra/Fish
url = https://github.com/Phidica/sublime-fish.git
[submodule "assets/syntaxes/Org mode"]
path = assets/syntaxes/02_Extra/Org mode
path = assets/syntaxes/02_Extra/Org_mode
url = https://github.com/jezcope/Org.tmbundle.git
[submodule "assets/syntaxes/DotENV"]
path = assets/syntaxes/02_Extra/DotENV
url = https://github.com/zaynali53/DotENV
[submodule "assets/syntaxes/hosts"]
path = assets/syntaxes/02_Extra/hosts
url = https://github.com/brandonwamboldt/sublime-hosts
[submodule "assets/syntaxes/ssh-config"]
path = assets/syntaxes/02_Extra/ssh-config
url = https://github.com/robballou/sublimetext-sshconfig.git
@@ -142,7 +139,7 @@
path = assets/themes/dracula-sublime
url = https://github.com/dracula/sublime.git
[submodule "assets/syntaxes/HTML (Twig)"]
path = assets/syntaxes/02_Extra/HTML (Twig)
path = assets/syntaxes/02_Extra/HTML_(Twig)
url = https://github.com/Anomareh/PHP-Twig.tmbundle.git
[submodule "assets/themes/Nord-sublime"]
path = assets/themes/Nord-sublime
@@ -177,7 +174,7 @@
url = https://github.com/euler0/sublime-glsl
[submodule "assets/syntaxes/02_Extra/Nginx"]
path = assets/syntaxes/02_Extra/Nginx
url = https://github.com/brandonwamboldt/sublime-nginx
url = https://github.com/SublimeText/nginx
[submodule "assets/syntaxes/02_Extra/Apache"]
path = assets/syntaxes/02_Extra/Apache
url = https://github.com/colinta/ApacheConf.tmLanguage
@@ -196,10 +193,7 @@
branch = bat-source
[submodule "assets/syntaxes/02_Extra/Lean"]
path = assets/syntaxes/02_Extra/Lean
url = https://github.com/leanprover/vscode-lean.git
[submodule "assets/syntaxes/02_Extra/LiveScript"]
path = assets/syntaxes/02_Extra/LiveScript
url = https://github.com/paulmillr/LiveScript.tmbundle
url = https://github.com/leanprover/vscode-lean4.git
[submodule "assets/syntaxes/02_Extra/Zig"]
path = assets/syntaxes/02_Extra/Zig
url = https://github.com/ziglang/sublime-zig-language.git
@@ -263,3 +257,24 @@
[submodule "assets/syntaxes/02_Extra/CFML"]
path = assets/syntaxes/02_Extra/CFML
url = https://github.com/jcberquist/sublimetext-cfml.git
[submodule "assets/syntaxes/02_Extra/Idris2"]
path = assets/syntaxes/02_Extra/Idris2
url = https://github.com/buzden/sublime-syntax-idris2
[submodule "assets/syntaxes/02_Extra/GDScript-sublime"]
path = assets/syntaxes/02_Extra/GDScript-sublime
url = https://github.com/beefsack/GDScript-sublime
[submodule "assets/syntaxes/02_Extra/sublime-odin"]
path = assets/syntaxes/02_Extra/sublime-odin
url = https://github.com/odin-lang/sublime-odin
[submodule "assets/syntaxes/02_Extra/typst-syntax-highlight"]
path = assets/syntaxes/02_Extra/typst-syntax-highlight
url = https://github.com/hyrious/typst-syntax-highlight
[submodule "assets/themes/Catppuccin"]
path = assets/themes/Catppuccin
url = https://github.com/SchweGELBin/catppuccin-bat-sub.git
[submodule "assets/syntaxes/02_Extra/SmartVHDL"]
path = assets/syntaxes/02_Extra/SmartVHDL
url = https://github.com/TheClams/SmartVHDL
[submodule "assets/syntaxes/02_Extra/hosts"]
path = assets/syntaxes/02_Extra/hosts
url = https://github.com/tijn/hosts.tmLanguage

View File

@@ -1,3 +1,68 @@
# unreleased
## Features
- Add build for windows/ARM64 platform. #3190 (@alcroito)
- Add paging to `--list-themes`, see PR #3239 (@einfachIrgendwer0815)
- Support negative relative line ranges, e.g. `bat -r :-10` / `bat -r='-10:'`, see #3068 (@ajesipow)
- Support context in line ranges, e.g. `bat -r 30::5` / `bat -r 30:40:5`, see #3345 (@cavanaug)
## Bugfixes
- Fix UTF-8 BOM not being stripped for syntax detection, see #3314 (@krikera)
- Fix `BAT_THEME_DARK` and `BAT_THEME_LIGHT` being ignored, see issue #3171 and PR #3168 (@bash)
- Prevent `--list-themes` from outputting default theme info to stdout when it is piped, see #3189 (@einfachIrgendwer0815)
- Rename some submodules to fix Dependabot submodule updates, see issue #3198 and PR #3201 (@victor-gp)
- Make highlight tests fail when new syntaxes don't have fixtures PR #3255 (@dan-hipschman)
- Fix crash for multibyte characters in file path, see issue #3230 and PR #3245 (@HSM95)
- Add missing mappings for various bash/zsh files, see PR #3262 (@AdamGaskins)
- Send all bat errors to stderr by default, see #3336 (@JerryImMouse)
- Make --map-syntax target case insensitive to match --language, see #3206 (@keith-hall)
- Correctly determine the end of the line in UTF16LE/BE input #3369 (@keith-hall)
## Other
- Update base16 README links to community driven base16 work #2871 (@JamyGolden)
- 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: CICD: replace windows-2019 runners with windows-2025 #3339 (@cyqsimon)
- Build script: replace string-based codegen with quote-based codegen #3340 (@cyqsimon)
- Improve code coverage of `--list-languages` parameter #2942 (@sblondon)
- Only start offload worker thread when there's more than 1 core #2956 (@cyqsimon)
- Update terminal-colorsaurus (the library used for dark/light detection) to 1.0, see #3347 (@bash)
- Update console dependency to 0.16, see #3351 (@musicinmybrain)
- Fixed some typos #3244 (@ssbarnea)
## Syntaxes
- Add syntax mapping for `paru` configuration files #3182 (@cyqsimon)
- Add support for [Idris 2 programming language](https://www.idris-lang.org/) #3150 (@buzden)
- Add syntax mapping for `nix`'s '`flake.lock` lockfiles #3196 (@odilf)
- Improvements to CSV/TSV highlighting, with autodetection of delimiter and support for TSV files, see #3186 (@keith-
- Improve (Sys)log error highlighting, see #3205 (@keith-hall)
- Map `ndjson` extension to JSON syntax, see #3209 (@keith-hall)
- Map files with `csproj`, `vbproj`, `props` and `targets` extensions to XML syntax, see #3213 (@keith-hall)
- Add debsources syntax to highlight `/etc/apt/sources.list` files, see #3215 (@keith-hall)
- Add syntax definition and test file for GDScript highlighting, see #3236 (@chetanjangir0)
- Add syntax test file for Odin highlighting, see #3241 (@chetanjangir0)
- Update quadlet syntax mapping rules to cover quadlets in subdirectories #3299 (@cyqsimon)
- Add syntax Typst #3300 (@cskeeters)
- Map `.mill` files to Scala syntax for Mill build tool configuration files #3311 (@krikera)
- Add syntax highlighting for VHDL, see #3337 (@JerryImMouse)
- Add syntax mapping for certbot certificate configuration #3338 (@cyqsimon)
- Update Lean syntax from Lean 3 to Lean 4 #3322 (@YDX-2147483647)
- Map `.flatpakref` and `.flatpakrepo` files to INI syntax #3353 (@Ferenc-)
- Update hosts syntax #3368 (@keith-hall)
## Themes
- Add Catppuccin, see #3317 (@SchweGELBin)
- Updated Catppuccin, see #3333 (@SchweGELBin)
- Updated gruvbox, see #3372 (@Nicholas42)
- Updated GitHub theme, see #3382 (@CosmicHorrorDev)
## `bat` as a library
# v0.25.0
## Features

1133
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ version = "0.25.0"
exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build/main.rs"
edition = '2021'
# You are free to bump MSRV as soon as a reason for bumping emerges.
rust-version = "1.74"
[features]
@@ -44,14 +45,14 @@ regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine
nu-ansi-term = "0.50.0"
ansi_colours = "^1.2"
bincode = "1.0"
console = "0.15.10"
flate2 = "1.0"
console = "0.16.0"
flate2 = "1.1"
once_cell = "1.20"
thiserror = "1.0"
thiserror = "2.0"
wild = { version = "2.2", optional = true }
content_inspector = "0.2.4"
shell-words = { version = "1.1.0", optional = true }
unicode-width = "0.1.13"
unicode-width = "0.2.1"
globset = "0.4"
serde = "1.0"
serde_derive = "1.0"
@@ -60,17 +61,19 @@ semver = "1.0"
path_abs = { version = "0.5", default-features = false }
clircle = { version = "0.6.1", default-features = false }
bugreport = { version = "0.5.0", optional = true }
etcetera = { version = "0.8.0", optional = true }
etcetera = { version = "0.10.0", optional = true }
grep-cli = { version = "0.1.11", optional = true }
regex = { version = "1.10.6", optional = true }
walkdir = { version = "2.5", optional = true }
bytesize = { version = "1.3.0" }
encoding_rs = "0.8.35"
execute = { version = "0.2.13", optional = true }
terminal-colorsaurus = "0.4"
terminal-colorsaurus = "1.0"
unicode-segmentation = "1.12.0"
itertools = "0.13.0"
[dependencies.git2]
version = "0.19"
version = "0.20"
optional = true
default-features = false
@@ -94,22 +97,26 @@ expect-test = "1.5.0"
serial_test = { version = "2.0.0", default-features = false }
predicates = "3.1.3"
wait-timeout = "0.2.0"
tempfile = "3.8.1"
tempfile = "3.16.0"
serde = { version = "1.0", features = ["derive"] }
[target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.29", default-features = false, features = ["term"] }
nix = { version = "0.30", default-features = false, features = ["term"] }
[build-dependencies]
anyhow = "1.0.86"
indexmap = { version = "2.3.0", features = ["serde"] }
itertools = "0.13.0"
anyhow = "1.0.97"
indexmap = { version = "2.8.0", features = ["serde"] }
itertools = "0.14.0"
once_cell = "1.20"
prettyplease = "0.2.35"
proc-macro2 = "1.0.95"
quote = "1.0.40"
regex = "1.10.6"
serde = "1.0"
serde_derive = "1.0"
serde_with = { version = "3.12.0", default-features = false, features = ["macros"] }
toml = { version = "0.8.19", features = ["preserve_order"] }
syn = { version = "2.0.104", features = ["full"] }
toml = { version = "0.9.1", features = ["preserve_order"] }
walkdir = "2.5"
[build-dependencies.clap]

182
README.md
View File

@@ -22,25 +22,22 @@
### Sponsors
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">
<img src="doc/sponsors/workos-logo-white-bg.svg" width="200" alt="WorkOS">
<br>
<strong>Your app, enterprise-ready.</strong>
<br>
<sub>Start selling to enterprise customers with just a few lines of code.</sub>
<br>
<sup>Add Single Sign-On (and more) in minutes instead of months.</sup>
</a>
<a href="https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=bat_20231001">
<p>
<a href="https://www.warp.dev/bat">
<img src="doc/sponsors/warp-logo.png" width="200" alt="Warp">
<br>
<strong>Warp, the intelligent terminal</strong>
<br>
<sub>Run commands like a power user with AI and your dev teams</sub>
<br>
<sup>knowledge in one fast, intuitive terminal. For MacOS or Linux.</sup>
<sub>Available on MacOS, Linux, Windows</sub>
</a>
</p><p>
<a href="https://graphite.dev/?utm_source=github&utm_medium=repo&utm_campaign=bat">
<img src="doc/sponsors/graphite-logo.jpeg" width="200" alt="Graphite">
<br>
<strong>Graphite is the AI developer productivity platform helping<br>teams on GitHub ship higher quality software, faster</strong>
</a>
</p>
### Syntax highlighting
@@ -124,7 +121,7 @@ bat f - g # output 'f', then stdin, then 'g'.
#### `fzf`
You can use `bat` as a previewer for [`fzf`](https://github.com/junegunn/fzf). To do this,
use `bat`s `--color=always` option to force colorized output. You can also use `--line-range`
use `bat`'s `--color=always` option to force colorized output. You can also use `--line-range`
option to restrict the load times for long files:
```bash
@@ -181,7 +178,7 @@ You can combine `bat` with `git diff` to view lines around code changes with pro
highlighting:
```bash
batdiff() {
git diff --name-only --relative --diff-filter=d | xargs bat --diff
git diff --name-only --relative --diff-filter=d -z | xargs -0 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).
@@ -204,7 +201,7 @@ bat main.cpp | xclip
`MANPAGER` environment variable:
```bash
export MANPAGER="sh -c 'sed -u -e \"s/\\x1B\[[0-9;]*m//g; s/.\\x08//g\" | bat -p -lman'"
export MANPAGER="sh -c 'awk '\''{ gsub(/\x1B\[[0-9;]*m/, \"\", \$0); gsub(/.\x08/, \"\", \$0); print }'\'' | bat -p -lman'"
man 2 select
```
(replace `bat` with `batcat` if you are on Debian or Ubuntu)
@@ -222,6 +219,12 @@ Note that the [Manpage syntax](assets/syntaxes/02_Extra/Manpage.sublime-syntax)
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`.
#### `Warp`
<a href="https://app.warp.dev/drive/folder/-Bat-Warp-Pack-lxhe7HrEwgwpG17mvrFSz1">
<img src="doc/sponsors/warp-pack-header.png" alt="Warp">
</a>
#### Highlighting `--help` messages
You can use `bat` to colorize help text: `$ cp --help | bat -plhelp`
@@ -245,15 +248,32 @@ alias -g -- -h='-h 2>&1 | bat --language=help --style=plain'
alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'
```
For `fish`, you can use abbreviations:
```fish
abbr -a --position anywhere -- --help '--help | bat -plhelp'
abbr -a --position anywhere -- -h '-h | bat -plhelp'
```
This way, you can keep on using `cp --help`, but get colorized help pages.
Be aware that in some cases, `-h` may not be a shorthand of `--help` (for example with `ls`).
Be aware that in some cases, `-h` may not be a shorthand of `--help` (for example with `ls`). In cases where you need to use `-h`
as a command argument you can prepend `\` to the arguement (eg. `ls \-h`) to escape the aliasing defined above.
Please report any issues with the help syntax in [this repository](https://github.com/victor-gp/cmd-help-sublime-syntax).
## Installation
<!--
Installation instructions need to:
* be for widely used systems
* be non-obvious
* be from somewhat official sources
-->
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/bat-cat/versions)
### On Ubuntu (using `apt`)
@@ -274,6 +294,11 @@ mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
```
an example alias for `batcat` as `bat`:
```bash
alias bat="batcat"
```
### On Ubuntu (using most recent `.deb` packages)
*... and other Debian-based Linux distributions.*
@@ -311,14 +336,6 @@ You can install [the `bat` package](https://koji.fedoraproject.org/koji/packagei
dnf install bat
```
### On Funtoo Linux
You can install [the `bat` package](https://github.com/funtoo/dev-kit/tree/1.4-release/sys-apps/bat) from dev-kit.
```bash
emerge sys-apps/bat
```
### On Gentoo Linux
You can install [the `bat` package](https://packages.gentoo.org/packages/sys-apps/bat)
@@ -328,20 +345,6 @@ from the official sources:
emerge sys-apps/bat
```
### On Void Linux
You can install `bat` via xbps-install:
```bash
xbps-install -S bat
```
### On Termux
You can install `bat` via pkg:
```bash
pkg install bat
```
### On FreeBSD
You can install a precompiled [`bat` package](https://www.freshports.org/textproc/bat) with pkg:
@@ -373,14 +376,6 @@ You can install `bat` using the [nix package manager](https://nixos.org/nix):
nix-env -i bat
```
### Via flox
You can install `bat` using [Flox](https://flox.dev)
```bash
flox install bat
```
### On openSUSE
You can install `bat` with zypper:
@@ -417,7 +412,7 @@ take a look at the ["Using `bat` on Windows"](#using-bat-on-windows) section.
#### Prerequisites
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
You will need to install the [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
#### With WinGet
@@ -458,14 +453,25 @@ binaries are also available: look for archives with `musl` in the file name.
If you want to build `bat` from source, you need Rust 1.74.0 or
higher. You can then use `cargo` to build everything:
#### From local source
```bash
cargo install --path . --locked
```
> [!NOTE]
> The `--path .` above specifies the directory of the source code and NOT where `bat` will be installed.
> For more information see the docs for [`cargo install`](https://doc.rust-lang.org/cargo/commands/cargo-install.html).
#### From `crates.io`
```bash
cargo install --locked bat
```
Note that additional files like the man page or shell completion
files can not be installed in this way. They will be generated by `cargo` and should be available in the cargo target folder (under `build`).
files can not be installed automatically in both these ways.
If installing from a local source, they will be generated by `cargo`
and should be available in the cargo target folder under `build`.
Shell completions are also available by running:
Furthermore, shell completions are also available by running:
```bash
bat --completion <shell>
# see --help for supported shells
@@ -476,11 +482,12 @@ bat --completion <shell>
### Highlighting theme
Use `bat --list-themes` to get a list of all available themes for syntax
highlighting. To select the `TwoDark` theme, call `bat` with the
`--theme=TwoDark` option or set the `BAT_THEME` environment variable to
highlighting. By default, `bat` uses `Monokai Extended` or `Monokai Extended Light`
for dark and light themes respectively. To select the `TwoDark` theme, call `bat`
with the `--theme=TwoDark` option or set the `BAT_THEME` environment variable to
`TwoDark`. Use `export BAT_THEME="TwoDark"` in your shell's startup file to
make the change permanent. Alternatively, use `bat`s
[configuration file](https://github.com/sharkdp/bat#configuration-file).
make the change permanent. Alternatively, use `bat`'s
[configuration file](#configuration-file).
If you want to preview the different themes on a custom file, you can use
the following command (you need [`fzf`](https://github.com/junegunn/fzf) for this):
@@ -489,11 +496,11 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
```
`bat` automatically picks a fitting theme depending on your terminal's background color.
You can use the `--theme-light` / `--theme-light` options or the `BAT_THEME_DARK` / `BAT_THEME_LIGHT` environment variables
You can use the `--theme-dark` / `--theme-light` options or the `BAT_THEME_DARK` / `BAT_THEME_LIGHT` environment variables
to customize the themes used. This is especially useful if you frequently switch between dark and light mode.
You can also use a custom theme by following the
['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes).
['Adding new themes' section below](#adding-new-themes).
### 8-bit themes
@@ -502,12 +509,12 @@ even when truecolor support is available:
- `ansi` looks decent on any terminal. It uses 3-bit colors: black, red, green,
yellow, blue, magenta, cyan, and white.
- `base16` is designed for [base16](https://github.com/chriskempson/base16) terminal themes. It uses
- `base16` is designed for [base16](https://github.com/tinted-theming/home) terminal themes. It uses
4-bit colors (3-bit colors plus bright variants) in accordance with the
[base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md).
- `base16-256` is designed for [base16-shell](https://github.com/chriskempson/base16-shell).
[base16 styling guidelines](https://github.com/tinted-theming/home/blob/main/styling.md).
- `base16-256` is designed for [tinted-shell](https://github.com/tinted-theming/tinted-shell).
It replaces certain bright colors with 8-bit colors from 16 to 21. **Do not** use this simply
because you have a 256-color terminal but are not using base16-shell.
because you have a 256-color terminal but are not using tinted-shell.
Although these themes are more restricted, they have three advantages over truecolor themes. They:
@@ -517,11 +524,11 @@ Although these themes are more restricted, they have three advantages over truec
### Output style
You can use the `--style` option to control the appearance of `bat`s output.
You can use the `--style` option to control the appearance of `bat`'s output.
You can use `--style=numbers,changes`, for example, to show only Git changes
and line numbers but no grid and no file header. Set the `BAT_STYLE` environment
variable to make these changes permanent or use `bat`s
[configuration file](https://github.com/sharkdp/bat#configuration-file).
variable to make these changes permanent or use `bat`'s
[configuration file](#configuration-file).
>[!tip]
> If you specify a default style in `bat`'s config file, you can change which components
@@ -578,6 +585,8 @@ syntax:
### Adding new themes
This works very similar to how we add new syntax definitions.
> [!NOTE]
> Themes are stored in [`.tmTheme` files](https://www.sublimetext.com/docs/color_schemes_tmtheme.html).
First, create a folder with the new syntax highlighting themes:
```bash
@@ -592,6 +601,8 @@ bat cache --build
```
Finally, use `bat --list-themes` to check if the new themes are available.
> [!NOTE]
> `bat` uses the name of the `.tmTheme` file for the theme's name.
### Adding or changing file type associations
@@ -635,17 +646,17 @@ If you want to pass command-line arguments to the pager, you can also set them v
`PAGER`/`BAT_PAGER` variables:
```bash
export BAT_PAGER="less -RF"
export BAT_PAGER="less -RFK"
```
Instead of using environment variables, you can also use `bat`s [configuration file](https://github.com/sharkdp/bat#configuration-file) to configure the pager (`--pager` option).
Instead of using environment variables, you can also use `bat`'s [configuration file](#configuration-file) to configure the pager (`--pager` option).
### Using `less` as a pager
When using `less` as a pager, `bat` will automatically pass extra options along to `less`
to improve the experience. Specifically, `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen`,
and under certain conditions, `-X`/`--no-init` and/or `-S`/`--chop-long-lines`.
`-K`/`--quit-on-intr` and under certain conditions, `-X`/`--no-init` and/or `-S`/`--chop-long-lines`.
>[!IMPORTANT]
> These options will not be added if:
@@ -663,6 +674,9 @@ The `-F` option instructs `less` to exit immediately if the output size is small
the vertical size of the terminal. This is convenient for small files because you do not
have to press `q` to quit the pager.
The `-K` 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.
The `-X` option is needed to fix a bug with the `--quit-if-one-screen` feature in versions
of `less` older than version 530. 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
@@ -684,12 +698,40 @@ sidebar. Calling `bat` with `--tabs=0` will override it and let tabs be consumed
### Dark mode
If you make use of the dark mode feature in macOS, you might want to configure `bat` to use a different
If you make use of the dark mode feature in **macOS**, you might want to configure `bat` to use a different
theme based on the OS theme. The following snippet uses the `default` theme when in the _dark mode_
and the `GitHub` theme when in the _light mode_.
```bash
alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)"
alias cat="bat --theme auto:system --theme-dark default --theme-light GitHub"
```
The same dark mode feature is now available in **GNOME** and affects the `org.gnome.desktop.interface color-scheme` setting. The following code converts the above to use said setting.
```bash
# .bashrc
sys_color_scheme_is_dark() {
condition=$(gsettings get org.gnome.desktop.interface color-scheme)
condition=$(echo "$condition" | tr -d "[:space:]'")
if [ $condition == "prefer-dark" ]; then
return 0
else
return 1
fi
}
bat_alias_wrapper() {
#get color scheme
sys_color_scheme_is_dark
if [[ $? -eq 0 ]]; then
# bat command with dark color scheme
bat --theme=default "$@"
else
# bat command with light color scheme
bat --theme=GitHub "$@"
fi
}
alias cat='bat_alias_wrapper'
```
@@ -845,7 +887,7 @@ bash assets/create.sh
cargo install --path . --locked --force
```
If you want to build an application that uses `bat`s pretty-printing
If you want to build an application that uses `bat`'s pretty-printing
features as a library, check out the [the API documentation](https://docs.rs/bat/).
Note that you have to use either `regex-onig` or `regex-fancy` as a feature
when you depend on `bat` as a library.
@@ -863,7 +905,7 @@ Take a look at the [`CONTRIBUTING.md`](CONTRIBUTING.md) guide.
## Security vulnerabilities
Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`.
See [`SECURITY.md`](SECURITY.md).
## Project goals and alternatives

3
SECURITY.md Normal file
View File

@@ -0,0 +1,3 @@
# Security Vulnerabilities
To report a security vulnerability, please contact [David Peter](https://david-peter.de/) via email.

Binary file not shown.

View File

@@ -5,6 +5,24 @@ using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$ArrayStyle = @('default', 'auto', 'full', 'plain', 'changes', 'header', 'header-filename', 'header-filesize', 'grid', 'rule', 'numbers', 'snip')
$ArrayCompletion = @('bash', 'fish', 'zsh', 'ps1')
$ArrayWhen = @('auto', 'never', 'always')
$ArrayYesNo = @('never', 'always')
$ArrayWrap = @('always', 'never', 'character')
$ArrayBinary = @('no-printing', 'as-text')
$ArrayPrint = @('unicode', 'caret')
function Get-MyThemes(){
$themes = {{PROJECT_EXECUTABLE}} --list-themes | ForEach-Object {$_ -replace "^(.*)$", '''$1'''} | select-object
return $themes
}
function Get-MyLanguages(){
$themes = {{PROJECT_EXECUTABLE}} --list-languages | ForEach-Object{[pscustomobject]@{MyParameter=$_.Substring(0,$_.IndexOf(":")).Trim();MyDescription=$_.Substring($_.IndexOf(":")+1)}} | select-object
return $themes
}
$commandElements = $commandAst.CommandElements
$command = @(
'{{PROJECT_EXECUTABLE}}'
@@ -12,53 +30,148 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
$element = $commandElements[$i]
if ($element -isnot [StringConstantExpressionAst] -or
$element.StringConstantType -ne [StringConstantType]::BareWord -or
$element.Value.StartsWith('-')) {
#$element.Value.StartsWith('-') -or
$element.Value -eq $wordToComplete) {
break
}
$element.Value
}) -join ';'
$completions = @(switch ($command) {
'{{PROJECT_EXECUTABLE}}' {
[CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.')
$completions = @(switch -Wildcard ($command) {
'*;--help' {
break
}
'*;--version' {
break
}
'*;--acknowledgements' {
break
}
'*;--language' {
Get-MyLanguages |
ForEach-Object {[CompletionResult]::new(($_.MyParameter -replace "^(.*)$", '''$1'''), $_.MyParameter, [CompletionResultType]::ParameterName, $_.MyDescription ?? '_no value_')}
break
}
'*;--theme' {
Get-MyThemes |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterName, $_)}
break
}
'*;--binary' {
$ArrayBinary |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--style' {
$ArrayStyle |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--wrap' {
$ArrayWrap |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--color' {
$ArrayWhen |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--italic-text' {
$ArrayYesNo |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--paging' {
$ArrayWhen |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--decorations' {
$ArrayWhen |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--completion' {
$ArrayCompletion |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--strip-ansi' {
$ArrayWhen |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--nonprintable-notation' {
$ArrayPrint |
ForEach-Object {[System.Management.Automation.CompletionResult]::new($_, $_, [CompletionResultType]::ParameterValue, $_)}
break
}
'*;--generate-config-file' {
break
}
'{{PROJECT_EXECUTABLE}};cache' {
[CompletionResult]::new('--source' , 'source' , [CompletionResultType]::ParameterName, 'Use a different directory to load syntaxes and themes from.')
[CompletionResult]::new('--target' , 'target' , [CompletionResultType]::ParameterName, 'Use a different directory to store the cached syntax and theme set.')
# [CompletionResult]::new('-b' , 'b' , [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
[CompletionResult]::new('--build' , 'build' , [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
# [CompletionResult]::new('-c' , 'c' , [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
[CompletionResult]::new('--clear' , 'clear' , [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
[CompletionResult]::new('--blank' , 'blank' , [CompletionResultType]::ParameterName, 'Create completely new syntax and theme sets (instead of appending to the default sets).')
# [CompletionResult]::new('-h' , 'h' , [CompletionResultType]::ParameterName, 'Prints help information')
[CompletionResult]::new('--help' , 'help' , [CompletionResultType]::ParameterName, 'Prints help information')
# [CompletionResult]::new('-V' , 'V' , [CompletionResultType]::ParameterName, 'Prints version information')
# [CompletionResult]::new('--version' , 'version' , [CompletionResultType]::ParameterName, 'Prints version information')
break
}
default {
# [CompletionResult]::new('-l' , 'l' , [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.')
[CompletionResult]::new('--language' , 'language' , [CompletionResultType]::ParameterName, 'Set the language for syntax highlighting.')
[CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'Highlight lines N through M.')
# [CompletionResult]::new('-H' , 'H' , [CompletionResultType]::ParameterName, 'Highlight lines N through M.')
[CompletionResult]::new('--highlight-line' , 'highlight-line' , [CompletionResultType]::ParameterName, 'Highlight lines N through M.')
[CompletionResult]::new('--file-name' , 'file-name' , [CompletionResultType]::ParameterName, 'Specify the name to display for a file.')
[CompletionResult]::new('--diff-context' , 'diff-context' , [CompletionResultType]::ParameterName, 'diff-context')
[CompletionResult]::new('--tabs' , 'tabs' , [CompletionResultType]::ParameterName, 'Set the tab width to T spaces.')
[CompletionResult]::new('--wrap', 'wrap', [CompletionResultType]::ParameterName, 'Specify the text-wrapping mode (*auto*, never, character).')
[CompletionResult]::new('--wrap' , 'wrap' , [CompletionResultType]::ParameterName, 'Specify the text-wrapping mode (*auto*, character).')
[CompletionResult]::new('--terminal-width' , 'terminal-width' , [CompletionResultType]::ParameterName, 'Explicitly set the width of the terminal instead of determining it automatically. If prefixed with ''+'' or ''-'', the value will be treated as an offset to the actual terminal width. See also: ''--wrap''.')
[CompletionResult]::new('--color' , 'color' , [CompletionResultType]::ParameterName, 'When to use colors (*auto*, never, always).')
[CompletionResult]::new('--italic-text' , 'italic-text' , [CompletionResultType]::ParameterName, 'Use italics in output (always, *never*)')
[CompletionResult]::new('--decorations' , 'decorations' , [CompletionResultType]::ParameterName, 'When to show the decorations (*auto*, never, always).')
[CompletionResult]::new('--paging', 'paging', [CompletionResultType]::ParameterName, 'Specify when to use the pager, or use `-P` to disable (*auto*, never, always).')
[CompletionResult]::new('--paging' , 'paging' , [CompletionResultType]::ParameterName, 'Specify when to use the pager, or use ''-P'' to disable (*auto*, never, always).')
[CompletionResult]::new('--pager' , 'pager' , [CompletionResultType]::ParameterName, 'Determine which pager to use.')
[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('--theme' , 'theme' , [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting.')
[CompletionResult]::new('--theme-dark', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting for dark backgrounds.')
[CompletionResult]::new('--theme-light', 'theme', [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting for light backgrounds.')
[CompletionResult]::new('--theme-dark' , 'themedark' , [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting for dark backgrounds.')
[CompletionResult]::new('--theme-light' , 'themelight' , [CompletionResultType]::ParameterName, 'Set the color theme for syntax highlighting for light backgrounds.')
[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('-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('-A', 'A', [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')
# [CompletionResult]::new('-A' , 'A' , [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')
[CompletionResult]::new('--show-all' , 'show-all' , [CompletionResultType]::ParameterName, 'Show non-printable characters (space, tab, newline, ..).')
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').')
[CompletionResult]::new('--nonprintable-notation' , 'nonprintable-notation' , [CompletionResultType]::ParameterName, 'Set notation for non-printable characters. (unicode, caret)')
[CompletionResult]::new('--chop-long-lines' , 'chop-long-lines' , [CompletionResultType]::ParameterName, 'Truncate all lines longer than screen width. Alias for ''--wrap=never''.')
[CompletionResult]::new('--binary' , 'binary' , [CompletionResultType]::ParameterName, 'How to treat binary content. (*no-printing*, as-text)')
[CompletionResult]::new('--ignored-suffix' , 'ignored-suffix' , [CompletionResultType]::ParameterName, 'Ignore extension. For example: ''bat --ignored-suffix ".dev" my_file.json.dev'' will use JSON syntax, and ignore ''.dev''')
[CompletionResult]::new('--squeeze-blank' , 'squeeze-blank' , [CompletionResultType]::ParameterName, 'Squeeze consecutive empty lines into a single empty line.')
[CompletionResult]::new('--squeeze-limit' , 'squeeze-limit' , [CompletionResultType]::ParameterName, 'Set the maximum number of consecutive empty lines to be printed.')
[CompletionResult]::new('--strip-ansi' , 'strip-ansi' , [CompletionResultType]::ParameterName, 'Specify when to strip ANSI escape sequences from the input. The automatic mode will remove escape sequences unless the syntax highlighting language is plain text. (auto, always, *never*).')
# [CompletionResult]::new('-p' , 'p' , [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').')
[CompletionResult]::new('--plain' , 'plain' , [CompletionResultType]::ParameterName, 'Show plain style (alias for ''--style=plain'').')
[CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.')
# [CompletionResult]::new('-d' , 'd' , [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.')
[CompletionResult]::new('--diff' , 'diff' , [CompletionResultType]::ParameterName, 'Only show lines that have been added/removed/modified.')
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').')
# [CompletionResult]::new('-n' , 'n' , [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').')
[CompletionResult]::new('--number' , 'number' , [CompletionResultType]::ParameterName, 'Show line numbers (alias for ''--style=numbers'').')
[CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'f')
# [CompletionResult]::new('-f' , 'f' , [CompletionResultType]::ParameterName, 'f')
[CompletionResult]::new('--force-colorization' , 'force-colorization' , [CompletionResultType]::ParameterName, 'force-colorization')
[CompletionResult]::new('-P', 'P', [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''')
# [CompletionResult]::new('-P' , 'P' , [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''')
[CompletionResult]::new('--no-paging' , 'no-paging' , [CompletionResultType]::ParameterName, 'Alias for ''--paging=never''')
[CompletionResult]::new('--list-themes' , 'list-themes' , [CompletionResultType]::ParameterName, 'Display all supported highlighting themes.')
[CompletionResult]::new('-L', 'L', [CompletionResultType]::ParameterName, 'Display all supported languages.')
# [CompletionResult]::new('-L' , 'L' , [CompletionResultType]::ParameterName, 'Display all supported languages.')
[CompletionResult]::new('--list-languages' , 'list-languages' , [CompletionResultType]::ParameterName, 'Display all supported languages.')
[CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'u')
# [CompletionResult]::new('-u' , 'u' , [CompletionResultType]::ParameterName, 'u')
[CompletionResult]::new('--unbuffered' , 'unbuffered' , [CompletionResultType]::ParameterName, 'unbuffered')
[CompletionResult]::new('--completion' , 'completion' , [CompletionResultType]::ParameterName, 'Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1]')
[CompletionResult]::new('--no-config' , 'no-config' , [CompletionResultType]::ParameterName, 'Do not use the configuration file')
[CompletionResult]::new('--no-custom-assets' , 'no-custom-assets' , [CompletionResultType]::ParameterName, 'Do not load custom assets')
[CompletionResult]::new('--lessopen' , 'lessopen' , [CompletionResultType]::ParameterName, 'Enable the $LESSOPEN preprocessor')
@@ -67,31 +180,17 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
[CompletionResult]::new('--generate-config-file' , 'generate-config-file' , [CompletionResultType]::ParameterName, 'Generates a default configuration file.')
[CompletionResult]::new('--config-dir' , 'config-dir' , [CompletionResultType]::ParameterName, 'Show bat''s configuration directory.')
[CompletionResult]::new('--cache-dir' , 'cache-dir' , [CompletionResultType]::ParameterName, 'Show bat''s cache directory.')
[CompletionResult]::new('--acknowledgements' , 'acknowledgements' , [CompletionResultType]::ParameterName, 'Show acknowledgements.')
[CompletionResult]::new('--set-terminal-title' , 'set-terminal-title' , [CompletionResultType]::ParameterName, 'Sets terminal title to filenames when using a pager.')
[CompletionResult]::new('--diagnostic' , 'diagnostic' , [CompletionResultType]::ParameterName, 'Show diagnostic information for bug reports.')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print this help message.')
# [CompletionResult]::new('-h' , 'h' , [CompletionResultType]::ParameterName, 'Print this help message.')
[CompletionResult]::new('--help' , 'help' , [CompletionResultType]::ParameterName, 'Print this help message.')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Show version information.')
# [CompletionResult]::new('-V' , 'V' , [CompletionResultType]::ParameterName, 'Show version information.')
[CompletionResult]::new('--version' , 'version' , [CompletionResultType]::ParameterName, 'Show version information.')
## Completion of the 'cache' command itself is removed for better UX
## See https://github.com/sharkdp/bat/issues/2085#issuecomment-1271646802
break
}
'{{PROJECT_EXECUTABLE}};cache' {
[CompletionResult]::new('--source', 'source', [CompletionResultType]::ParameterName, 'Use a different directory to load syntaxes and themes from.')
[CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'Use a different directory to store the cached syntax and theme set.')
[CompletionResult]::new('-b', 'b', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
[CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'Initialize (or update) the syntax/theme cache.')
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
[CompletionResult]::new('--clear', 'clear', [CompletionResultType]::ParameterName, 'Remove the cached syntax definitions and themes.')
[CompletionResult]::new('--blank', 'blank', [CompletionResultType]::ParameterName, 'Create completely new syntax and theme sets (instead of appending to the default sets).')
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information')
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information')
[CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information')
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information')
break
}
})
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
Sort-Object -Property ListItemText
Sort-Object -Property CompletionText
}

View File

@@ -37,6 +37,23 @@ Use character sequences like ^G, ^J, ^@, .. to identify non-printable characters
Use special Unicode code points to identify non-printable characters
.RE
.HP
\fB\-\-binary\fR <behavior>
.IP
How to treat binary content.
Possible values:
.RS
.IP "no\-printing"
Do not print any binary content (default)
.IP "as\-text"
Treat binary content as normal text
.RE
.HP
\fB\-\-completion\fR <SHELL>
.IP
Show shell completion for a certain shell.
Possible values: bash, fish, zsh, ps1
.HP
\fB\-p\fR, \fB\-\-plain\fR
.IP
Only show plain style, no decorations. This is an alias for
@@ -180,8 +197,8 @@ This option only has an effect when \fB\-\-theme\fP option is set to \fBauto\fR
.HP
\fB\-\-theme\-light\fR <theme>
.IP
Sets the theme name for syntax highlighting used when the terminal uses a dark background.
To set a default theme, add the \fB\-\-theme-dark="..."\fP option to the configuration file or
Sets the theme name for syntax highlighting used when the terminal uses a light background.
To set a default theme, add the \fB\-\-theme-light="..."\fP option to the configuration file or
export the \fBBAT_THEME_LIGHT\fP environment variable (e.g. \fBexport BAT_THEME_LIGHT="..."\fP).
This option only has an effect when \fB\-\-theme\fP option is set to \fBauto\fR or \fBlight\fR.
.HP
@@ -197,14 +214,30 @@ Squeeze consecutive empty lines into a single empty line.
.IP
Set the maximum number of consecutive empty lines to be printed.
.HP
\fB\-\-strip\-ansi\fR <when>
.IP
Specify when to strip ANSI escape sequences from the input. The automatic mode will remove
escape sequences unless the syntax highlighting language is plain text. Possible values:
auto, always, *never*.
.HP
\fB\-\-style\fR <style\-components>
.IP
Configure which elements (line numbers, file headers, grid borders, Git modifications,
\&..) to display in addition to the file contents. The argument is a comma\-separated list
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
export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
values: *default*, full, auto, plain, changes, header, header-filename, header-filesize, grid,
export the BAT_STYLE environment variable (e.g.: export BAT_STYLE="..").
.IP
When styles are specified in multiple places, the "nearest" set of styles take precedence.
The command\-line arguments are the highest priority, followed by the BAT_STYLE environment
variable, and then the configuration file. If any set of styles consists entirely of
components prefixed with "+" or "\-", it will modify the previous set of styles instead of
replacing them.
.IP
By default, the following components are enabled:
changes, grid, header\-filename, numbers, snip
.IP
Possible values: *default*, full, auto, plain, changes, header, header-filename, header-filesize, grid,
rule, numbers, snip.
.HP
\fB\-r\fR, \fB\-\-line\-range\fR <N:M>...

View File

@@ -21,11 +21,26 @@ index 9c2aa3e..180cbbf 100644
<string>Invalid</string>
<key>scope</key>
- <string>invalid</string>
+ <string>invalid, markup.error</string>
+ <string>invalid, meta.annotation.error-line</string>
<key>settings</key>
<dict>
<key>background</key>
@@ -1042,7 +1042,7 @@
@@ -1038,11 +1038,22 @@
<string>#f8f8f0</string>
</dict>
</dict>
+ <dict>
+ <key>name</key>
+ <string>Error</string>
+ <key>scope</key>
+ <string>markup.error</string>
+ <key>settings</key>
+ <dict>
+ <key>foreground</key>
+ <string>#dd2020</string>
+ </dict>
+ </dict>
<dict>
<key>name</key>
<string>Invalid deprecated</string>
<key>scope</key>

BIN
assets/syntaxes.bin vendored

Binary file not shown.

View File

@@ -1,5 +1,6 @@
%YAML 1.2
---
name: x86_64 Assembly
file_extensions: [yasm, nasm, asm, inc, mac]
scope: source.asm.x86_64
@@ -1364,4 +1365,3 @@ contexts:
scope: invalid.keyword.operator.word.mnemonic.sse5.packed-arithmetic
- match: '(?i)\b(pcmov|permp[ds]|pperm|prot[bdqw]|psh[al][bdqw])\b'
scope: invalid.keyword.operator.word.mnemonic.sse5.simd-integer
...

View File

@@ -2,20 +2,21 @@
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Comma Separated Values
file_extensions:
- csv
- tsv
scope: text.csv
scope: text.csv.comma
variables:
field_separator: (?:[,;|\t])
field_separator: (?:,)
record_separator: (?:$\n?)
contexts:
prototype:
- match: (?={{record_separator}})
pop: true
main:
- match: '^'
push: fields
fields:
- match: ""
- include: record_separator
- match: ''
push:
- field_or_record_separator
- field5
- field_or_record_separator
- field4
- field_or_record_separator
@@ -24,54 +25,55 @@ contexts:
- field2
- field_or_record_separator
- field1
main:
record_separator_pop:
- match: (?={{record_separator}})
pop: true
record_separator:
- meta_include_prototype: false
- match: "^"
set: fields
- match: '{{record_separator}}'
scope: punctuation.terminator.record.csv
pop: true
field_or_record_separator:
- meta_include_prototype: false
- match: "{{record_separator}}"
scope: punctuation.terminator.record.csv
pop: true
- match: "{{field_separator}}"
- include: record_separator_pop
- match: '{{field_separator}}'
scope: punctuation.separator.sequence.csv
pop: true
field_contents:
- match: '"'
scope: punctuation.definition.string.begin.csv
push: double_quoted_string
push: scope:text.csv#double_quoted_string
- match: (?={{field_separator}}|{{record_separator}})
pop: true
double_quoted_string:
- meta_include_prototype: false
- meta_scope: string.quoted.double.csv
- match: '""'
scope: constant.character.escape.csv
- match: '"'
scope: punctuation.definition.string.end.csv
- include: record_separator_pop
- match: (?={{field_separator}})
pop: true
field1:
- match: ""
- match: ''
set:
- meta_content_scope: meta.field-1.csv support.type
- meta_content_scope: meta.field-1.csv variable.parameter
- include: field_contents
field2:
- match: ""
- match: ''
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ""
- match: ''
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ""
- match: ''
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents
field5:
- match: ''
set:
- meta_content_scope: meta.field-5.csv string.unquoted
- include: field_contents

View File

@@ -0,0 +1,80 @@
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Pipe Separated Values
scope: text.csv.pipe
variables:
field_separator: (?:\|)
record_separator: (?:$\n?)
contexts:
main:
- match: '^'
push: fields
fields:
- include: record_separator
- match: ''
push:
- field_or_record_separator
- field5
- field_or_record_separator
- field4
- field_or_record_separator
- field3
- field_or_record_separator
- field2
- field_or_record_separator
- field1
record_separator_pop:
- match: (?={{record_separator}})
pop: true
record_separator:
- meta_include_prototype: false
- match: '{{record_separator}}'
scope: punctuation.terminator.record.csv
pop: true
field_or_record_separator:
- meta_include_prototype: false
- include: record_separator_pop
- match: '{{field_separator}}'
scope: punctuation.separator.sequence.csv
pop: true
field_contents:
- match: '"'
scope: punctuation.definition.string.begin.csv
push: scope:text.csv#double_quoted_string
- include: record_separator_pop
- match: (?={{field_separator}})
pop: true
field1:
- match: ''
set:
- meta_content_scope: meta.field-1.csv variable.parameter
- include: field_contents
field2:
- match: ''
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ''
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ''
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents
field5:
- match: ''
set:
- meta_content_scope: meta.field-5.csv string.unquoted
- include: field_contents

View File

@@ -0,0 +1,79 @@
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Semi-Colon Separated Values
scope: text.csv.semi-colon
variables:
field_separator: (?:;)
record_separator: (?:$\n?)
contexts:
main:
- match: '^'
push: fields
fields:
- include: record_separator
- match: ''
push:
- field_or_record_separator
- field5
- field_or_record_separator
- field4
- field_or_record_separator
- field3
- field_or_record_separator
- field2
- field_or_record_separator
- field1
record_separator_pop:
- match: (?={{record_separator}})
pop: true
record_separator:
- meta_include_prototype: false
- match: '{{record_separator}}'
scope: punctuation.terminator.record.csv
pop: true
field_or_record_separator:
- meta_include_prototype: false
- include: record_separator_pop
- match: '{{field_separator}}'
scope: punctuation.separator.sequence.csv
pop: true
field_contents:
- match: '"'
scope: punctuation.definition.string.begin.csv
push: scope:text.csv#double_quoted_string
- include: record_separator_pop
- match: (?={{field_separator}})
pop: true
field1:
- match: ''
set:
- meta_content_scope: meta.field-1.csv variable.parameter
- include: field_contents
field2:
- match: ''
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ''
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ''
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents
field5:
- match: ''
set:
- meta_content_scope: meta.field-5.csv string.unquoted
- include: field_contents

View File

@@ -0,0 +1,113 @@
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Separated Values
file_extensions:
- csv
scope: text.csv
variables:
field_separator_chars: ',;\t|'
field_separator: (?:[{{field_separator_chars}}])
record_separator: (?:$\n?)
contexts:
main:
- meta_include_prototype: false
- include: three_field_separators
- include: single_separator_type_on_line
- match: '^'
push: unknown-separated-main
three_field_separators:
- match: ^(?=(?:[^,]*,){3})
set: scope:text.csv.comma
- match: ^(?=(?:[^;]*;){3})
set: scope:text.csv.semi-colon
- match: ^(?=(?:[^\t]*\t){3})
set: scope:text.csv.tab
- match: ^(?=(?:[^|]*\|){3})
set: scope:text.csv.pipe
single_separator_type_on_line:
- match: ^(?=[^{{field_separator_chars}}]*,[^;\t|]*$)
set: scope:text.csv.comma
- match: ^(?=[^{{field_separator_chars}}]*;[^,\t|]*$)
set: scope:text.csv.semi-colon
- match: ^(?=[^{{field_separator_chars}}]*\t[^,;|]*$)
set: scope:text.csv.tab
- match: ^(?=[^{{field_separator_chars}}]*\|[^,;\t]*$)
set: scope:text.csv.pipe
unknown-separated-main:
- include: record_separator
- match: ''
push:
- field_or_record_separator
- field5
- field_or_record_separator
- field4
- field_or_record_separator
- field3
- field_or_record_separator
- field2
- field_or_record_separator
- field1
record_separator_pop:
- match: (?={{record_separator}})
pop: true
record_separator:
- meta_include_prototype: false
- match: '{{record_separator}}'
scope: punctuation.terminator.record.csv
field_or_record_separator:
- meta_include_prototype: false
- include: record_separator_pop
- match: '{{field_separator}}'
scope: punctuation.separator.sequence.csv
pop: true
field_contents:
- match: '"'
scope: punctuation.definition.string.begin.csv
push: double_quoted_string
- include: record_separator_pop
- match: (?={{field_separator}})
pop: true
double_quoted_string:
- meta_include_prototype: false
- meta_scope: string.quoted.double.csv
- match: '""'
scope: constant.character.escape.csv
- match: '"'
scope: punctuation.definition.string.end.csv
pop: true
field1:
- match: ''
set:
- meta_content_scope: meta.field-1.csv variable.parameter
- include: field_contents
field2:
- match: ''
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ''
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ''
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents
field5:
- match: ''
set:
- meta_content_scope: meta.field-5.csv string.unquoted
- include: field_contents

View File

@@ -0,0 +1,83 @@
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: Tab Separated Values
scope: text.csv.tab
file_extensions:
- tsv
variables:
field_separator: (?:\t)
record_separator: (?:$\n?)
contexts:
main:
- match: '^'
push: fields
fields:
- include: record_separator
- match: ''
push:
- field_or_record_separator
- field5
- field_or_record_separator
- field4
- field_or_record_separator
- field3
- field_or_record_separator
- field2
- field_or_record_separator
- field1
record_separator_pop:
- match: (?={{record_separator}})
pop: true
record_separator:
- meta_include_prototype: false
- match: '{{record_separator}}'
scope: punctuation.terminator.record.csv
pop: true
field_or_record_separator:
- meta_include_prototype: false
- include: record_separator_pop
- match: '{{field_separator}}'
scope: punctuation.separator.sequence.csv
pop: true
field_contents:
- match: '"'
scope: punctuation.definition.string.begin.csv
push: scope:text.csv#double_quoted_string
- include: record_separator_pop
- match: (?={{field_separator}})
pop: true
field1:
- match: ''
set:
- meta_content_scope: meta.field-1.csv variable.parameter
- include: field_contents
field2:
- match: ''
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ''
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ''
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents
field5:
- match: ''
set:
- meta_content_scope: meta.field-5.csv string.unquoted
- include: field_contents

View File

@@ -1,23 +0,0 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: hosts
file_extensions:
- hosts
scope: source.hosts
contexts:
main:
- scope: comment.line.number-sign
match: \#.*
comment: comment
- match: ^\s*([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|[0-9a-f:]+)
comment: ipaddress
scope: constant.numeric.ipaddress
- match: \s(localhost|ip6-loopback|ip6-localhost|ip6-localnet|ip6-mcastprefix|ip6-allnodes|ip6-allrouters|ip6-allhosts|broadcasthost)\b
scope: keyword.host.predefined}
comment: prefdfined

View File

@@ -1,125 +1,130 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Lean
# http://www.sublimetext.com/docs/syntax.html
name: Lean 4
file_extensions:
- lean
scope: source.lean
scope: source.lean4
contexts:
main:
- include: comments
- match: '\b(?<!\.)(inductive|coinductive|structure|theorem|axiom|axioms|abbreviation|lemma|definition|def|instance|class|constant)\b\s+(\{[^}]*\})?'
- match: \b(Prop|Type|Sort)\b
scope: storage.type.lean4
- match: '\battribute\b\s*\[[^\]]*\]'
scope: storage.modifier.lean4
- match: '@\[[^\]]*\]'
scope: storage.modifier.lean4
- match: \b(?<!\.)(global|local|scoped|partial|unsafe|private|protected|noncomputable)(?!\.)\b
scope: storage.modifier.lean4
- match: \b(sorry|admit|stop)\b
scope: invalid.illegal.lean4
- match: '#(print|eval|reduce|check|check_failure)\b'
scope: keyword.other.lean4
- match: \bderiving\s+instance\b
scope: keyword.other.command.lean4
- match: '\b(?<!\.)(inductive|coinductive|structure|theorem|axiom|abbrev|lemma|def|instance|class|constant)\b\s+(\{[^}]*\})?'
captures:
1: keyword.other.definitioncommand.lean
1: keyword.other.definitioncommand.lean4
push:
- meta_scope: meta.definitioncommand.lean
- match: '(?=\bwith\b|\bextends\b|[:\|\(\[\{⦃<>])'
- meta_scope: meta.definitioncommand.lean4
- match: '(?=\bwith\b|\bextends\b|\bwhere\b|[:\|\(\[\{⦃<>])'
pop: true
- include: comments
- include: definitionName
- match: ","
- match: \b(Prop|Type|Sort)\b
scope: storage.type.lean
- match: '\battribute\b\s*\[[^\]]*\]'
scope: storage.modifier.lean
- match: '@\[[^\]]*\]'
scope: storage.modifier.lean
- match: \b(?<!\.)(private|meta|mutual|protected|noncomputable)\b
scope: keyword.control.definition.modifier.lean
- match: \b(sorry)\b
scope: invalid.illegal.lean
- match: '#print\s+(def|definition|inductive|instance|structure|axiom|axioms|class)\b'
scope: keyword.other.command.lean
- match: '#(print|eval|reduce|check|help|exit|find|where)\b'
scope: keyword.other.command.lean
- match: \b(?<!\.)(import|export|prelude|theory|definition|def|abbreviation|instance|renaming|hiding|exposing|parameter|parameters|begin|constant|constants|lemma|variable|variables|theorem|example|open|axiom|inductive|coinductive|with|structure|universe|universes|alias|precedence|reserve|postfix|prefix|infix|infixl|infixr|notation|end|using|namespace|section|local|set_option|extends|include|omit|class|classes|instances|raw|run_cmd|restate_axiom)(?!\.)\b
scope: keyword.other.lean
- match: \b(?<!\.)(calc|have|this|match|do|suffices|show|by|in|at|let|forall|fun|exists|assume|from|obtain|haveI|λ)(?!\.)\b
scope: keyword.other.lean
- match: ','
- match: \b(?<!\.)(theorem|show|have|from|suffices|nomatch|def|class|structure|instance|set_option|initialize|builtin_initialize|example|inductive|coinductive|axiom|constant|universe|universes|variable|variables|import|open|export|theory|prelude|renaming|hiding|exposing|do|by|let|extends|mutual|mut|where|rec|syntax|macro_rules|macro|deriving|fun|section|namespace|end|infix|infixl|infixr|postfix|prefix|notation|abbrev|if|then|else|calc|match|with|for|in|unless|try|catch|finally|return|continue|break)(?!\.)\b
scope: keyword.other.lean4
- match: «
push:
- meta_content_scope: entity.name.lean
- meta_content_scope: entity.name.lean4
- match: »
pop: true
- match: \b(?<!\.)(if|then|else)\b
scope: keyword.control.lean
- match: '"'
- match: (s!)"
captures:
0: punctuation.definition.string.begin.lean
1: keyword.other.lean4
push:
- meta_scope: string.quoted.double.lean
- meta_scope: string.interpolated.lean4
- match: '"'
captures:
0: punctuation.definition.string.end.lean
pop: true
- match: '\\[\\"nt'']'
scope: constant.character.escape.lean
- match: '\\x[0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean
- match: '\\u[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean
- match: '''[^\\'']'''
scope: string.quoted.single.lean
- match: '''(\\(x..|u....|.))'''
scope: string.quoted.single.lean
- match: '(\{)'
captures:
1: constant.character.escape.lean
1: keyword.other.lean4
push:
- match: '(\})'
captures:
1: keyword.other.lean4
pop: true
- include: main
- match: '\\[\\"ntr'']'
scope: constant.character.escape.lean4
- match: '\\x[0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean4
- match: '\\u[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean4
- match: '"'
push:
- meta_scope: string.quoted.double.lean4
- match: '"'
pop: true
- match: '\\[\\"ntr'']'
scope: constant.character.escape.lean4
- match: '\\x[0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean4
- match: '\\u[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'
scope: constant.character.escape.lean4
- match: \b(true|false)\b
scope: constant.language.lean4
- match: '''[^\\'']'''
scope: string.quoted.single.lean4
- match: '''(\\(x[0-9A-Fa-f][0-9A-Fa-f]|u[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]|.))'''
scope: string.quoted.single.lean4
captures:
1: constant.character.escape.lean4
- match: '`+[^\[(]\S+'
scope: entity.name.lean
- match: '\b([0-9]+|0([xX][0-9a-fA-F]+))\b'
scope: constant.numeric.lean
scope: entity.name.lean4
- match: '\b([0-9]+|0([xX][0-9a-fA-F]+)|[-]?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?)\b'
scope: constant.numeric.lean4
blockComment:
- match: /-
push:
- meta_scope: comment.block.lean
- match: "-/"
- meta_scope: comment.block.lean4
- match: '-/'
pop: true
- include: scope:source.lean.markdown
- include: scope:source.lean4.markdown
- include: blockComment
comments:
- include: dashComment
- include: docComment
- include: stringBlock
- include: modDocComment
- include: blockComment
dashComment:
- match: (--)
captures:
0: punctuation.definition.comment.lean
- match: '--'
push:
- meta_scope: comment.line.double-dash.lean
- meta_scope: comment.line.double-dash.lean4
- match: $
pop: true
- include: scope:source.lean.markdown
- include: scope:source.lean4.markdown
definitionName:
- match: '\b[^:«»\(\)\{\}[:space:]=→λ∀?][^:«»\(\)\{\}[:space:]]*'
scope: entity.name.function.lean
scope: entity.name.function.lean4
- match: «
push:
- meta_content_scope: entity.name.function.lean
- meta_content_scope: entity.name.function.lean4
- match: »
pop: true
docComment:
- match: /--
push:
- meta_scope: comment.block.documentation.lean
- match: "-/"
- meta_scope: comment.block.documentation.lean4
- match: '-/'
pop: true
- include: scope:source.lean.markdown
- include: scope:source.lean4.markdown
- include: blockComment
modDocComment:
- match: /-!
push:
- meta_scope: comment.block.documentation.lean
- match: "-/"
- meta_scope: comment.block.documentation.lean4
- match: '-/'
pop: true
- include: scope:source.lean.markdown
- include: blockComment
stringBlock:
- match: /-"
push:
- meta_scope: comment.block.string.lean
- match: '"-/'
pop: true
- include: scope:source.lean.markdown
- include: scope:source.lean4.markdown
- include: blockComment

View File

@@ -0,0 +1,42 @@
%YAML 1.2
---
# See http://www.sublimetext.com/docs/syntax.html
name: debsources
file_extensions:
- sources.list
scope: text.apt-source-list
contexts:
main:
- include: comments
- match: ^[\w-]+
scope: constant.language.apt-source-list
- match: \w+://\S+
scope: markup.underline.link.apt-source-list
push: distribution
- match: \bmain\b
scope: support.class.apt-source-list
- match: \buniverse\b
scope: support.constant.apt-source-list
- match: \brestricted\b
scope: storage.modifier.apt-source-list
- match: \bmultiverse\b
scope: keyword.other.apt-source-list
- match: '[\w-]+'
scope: constant.other.apt-source-list
comments:
- match: '#'
scope: punctuation.definition.comment.apt-source-list
push: line_comment
line_comment:
- meta_scope: comment.line.apt-source-list
- match: $
pop: true
distribution:
- match: \S+
scope: support.type.apt-source-list
pop: 1
- match: $
pop: 1

View File

@@ -38,21 +38,21 @@ contexts:
scope: markup.underline.link.scheme.log
push: url-host
log_level_lines:
- match: ^(?=.*{{error}})
- match: (?=.*{{error}})
push:
- error_line
- error_line_meta
- main_pop_at_eol
- match: ^(?=.*{{warning}})
- match: (?=.*{{warning}})
push:
- warning_line
- warning_line_meta
- main_pop_at_eol
- match: ^(?=.*{{info}})
- match: (?=.*{{info}})
push:
- info_line
- info_line_meta
- main_pop_at_eol
- match: ^(?=.*{{debug}})
- match: (?=.*{{debug}})
push:
- debug_line
- debug_line_meta
- main_pop_at_eol
log_levels:
- match: '{{error}}'
@@ -63,16 +63,16 @@ contexts:
scope: markup.info.log
- match: '{{debug}}'
scope: markup.info.log
error_line:
error_line_meta:
- meta_scope: meta.annotation.error-line.log
- include: immediately_pop
warning_line:
warning_line_meta:
- meta_scope: meta.annotation.warning-line.log
- include: immediately_pop
info_line:
info_line_meta:
- meta_scope: meta.annotation.info-line.log
- include: immediately_pop
debug_line:
debug_line_meta:
- meta_scope: meta.annotation.debug-line.log
- include: immediately_pop
immediately_pop:

View File

@@ -8,10 +8,10 @@ scope: text.log.syslog
contexts:
main:
- match: ^(\w+\s+\d+)\s+(\d{2}:\d{2}:\d{2})
scope: meta.datetime.syslog constant.numeric.syslog
scope: meta.datetime.syslog
captures:
1: meta.date.syslog
2: meta.time.syslog
1: meta.date.syslog constant.numeric.syslog
2: meta.time.syslog constant.numeric.syslog
push: loghost
- match: ^
push: text
@@ -31,7 +31,10 @@ contexts:
structured-data:
- match: '\['
scope: punctuation.section.mapping.begin.syslog
push:
push: structured-data-contents
- match: (?=\S)
set: text
structured-data-contents:
- match: \]
scope: punctuation.section.mapping.end.syslog
pop: true
@@ -39,14 +42,13 @@ contexts:
scope: variable.parameter.syslog
- match: =
scope: keyword.operator.assignment.syslog
push:
push: structured-data-assignment
structured-data-assignment:
- match: '[^\s\]]+'
scope: constant.other.syslog
pop: true
- match: (?=\])
pop: true
- match: (?=\S)
set: text
text:
- match: $
pop: true

View File

@@ -1,5 +1,5 @@
// Output the square of a number.
fn print_square(num: f64) {
let result = f64::powf(num, 2.0);
println!("The square of {:.2} is {:.2}.", num, result);
println!("The square of {num:.2} is {result:.2}.");
}

BIN
assets/themes.bin vendored

Binary file not shown.

1
assets/themes/Catppuccin vendored Submodule

View File

@@ -9,6 +9,8 @@ use anyhow::{anyhow, bail};
use indexmap::IndexMap;
use itertools::Itertools;
use once_cell::sync::Lazy;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
use regex::Regex;
use serde_derive::Deserialize;
use serde_with::DeserializeFromStr;
@@ -34,13 +36,14 @@ impl FromStr for MappingTarget {
}
}
}
impl MappingTarget {
fn codegen(&self) -> String {
match self {
Self::MapTo(syntax) => format!(r###"MappingTarget::MapTo(r#"{syntax}"#)"###),
Self::MapToUnknown => "MappingTarget::MapToUnknown".into(),
Self::MapExtensionToUnknown => "MappingTarget::MapExtensionToUnknown".into(),
}
impl ToTokens for MappingTarget {
fn to_tokens(&self, tokens: &mut TokenStream) {
let t = match self {
Self::MapTo(syntax) => quote! { MappingTarget::MapTo(#syntax) },
Self::MapToUnknown => quote! { MappingTarget::MapToUnknown },
Self::MapExtensionToUnknown => quote! { MappingTarget::MapExtensionToUnknown },
};
tokens.append_all(t);
}
}
@@ -116,22 +119,17 @@ impl FromStr for Matcher {
Ok(Self(non_empty_segments))
}
}
impl Matcher {
fn codegen(&self) -> String {
match self.0.len() {
0 => unreachable!("0-length matcher should never be created"),
// if-let guard would be ideal here
// see: https://github.com/rust-lang/rust/issues/51114
1 if self.0[0].is_text() => {
let s = self.0[0].text().unwrap();
format!(r###"Lazy::new(|| Some(build_matcher_fixed(r#"{s}"#)))"###)
impl ToTokens for Matcher {
fn to_tokens(&self, tokens: &mut TokenStream) {
let t = match self.0.as_slice() {
[] => unreachable!("0-length matcher should never be created"),
[MatcherSegment::Text(text)] => {
quote! { Lazy::new(|| Some(build_matcher_fixed(#text))) }
}
// parser logic ensures that this case can only happen when there are dynamic segments
_ => {
let segs = self.0.iter().map(MatcherSegment::codegen).join(", ");
format!(r###"Lazy::new(|| build_matcher_dynamic(&[{segs}]))"###)
}
}
segs @ [_, ..] => quote! { Lazy::new(|| build_matcher_dynamic(&[ #(#segs),* ])) },
};
tokens.append_all(t);
}
}
@@ -143,6 +141,15 @@ enum MatcherSegment {
Text(String),
Env(String),
}
impl ToTokens for MatcherSegment {
fn to_tokens(&self, tokens: &mut TokenStream) {
let t = match self {
Self::Text(text) => quote! { MatcherSegment::Text(#text) },
Self::Env(env) => quote! { MatcherSegment::Env(#env) },
};
tokens.append_all(t);
}
}
#[allow(dead_code)]
impl MatcherSegment {
fn is_text(&self) -> bool {
@@ -163,12 +170,6 @@ impl MatcherSegment {
Self::Env(t) => Some(t),
}
}
fn codegen(&self) -> String {
match self {
Self::Text(s) => format!(r###"MatcherSegment::Text(r#"{s}"#)"###),
Self::Env(s) => format!(r###"MatcherSegment::Env(r#"{s}"#)"###),
}
}
}
/// A struct that models a single .toml file in /src/syntax_mapping/builtins/.
@@ -194,22 +195,19 @@ impl MappingDefModel {
#[derive(Clone, Debug)]
struct MappingList(Vec<(Matcher, MappingTarget)>);
impl MappingList {
fn codegen(&self) -> String {
let array_items: Vec<_> = self
impl ToTokens for MappingList {
fn to_tokens(&self, tokens: &mut TokenStream) {
let len = self.0.len();
let array_items = self
.0
.iter()
.map(|(matcher, target)| {
format!("({m}, {t})", m = matcher.codegen(), t = target.codegen())
})
.collect();
let len = array_items.len();
.map(|(matcher, target)| quote! { (#matcher, #target) });
format!(
"/// Generated by build script from /src/syntax_mapping/builtins/.\n\
pub(crate) static BUILTIN_MAPPINGS: [(Lazy<Option<GlobMatcher>>, MappingTarget); {len}] = [\n{items}\n];",
items = array_items.join(",\n")
)
let t = quote! {
/// Generated by build script from /src/syntax_mapping/builtins/.
pub(crate) static BUILTIN_MAPPINGS: [(Lazy<Option<GlobMatcher>>, MappingTarget); #len] = [#(#array_items),*];
};
tokens.append_all(t);
}
}
@@ -236,8 +234,14 @@ fn get_def_paths() -> anyhow::Result<Vec<PathBuf>> {
];
let mut toml_paths = vec![];
for subdir in source_subdirs {
let wd = WalkDir::new(Path::new("src/syntax_mapping/builtins").join(subdir));
for subdir_name in source_subdirs {
let subdir = Path::new("src/syntax_mapping/builtins").join(subdir_name);
if !subdir.try_exists()? {
// Directory might not exist due to this `cargo vendor` bug:
// https://github.com/rust-lang/cargo/issues/15080
continue;
}
let wd = WalkDir::new(subdir);
let paths = wd
.into_iter()
.filter_map_ok(|entry| {
@@ -285,10 +289,15 @@ pub fn build_static_mappings() -> anyhow::Result<()> {
let mappings = read_all_mappings()?;
// IMPRV: parse + unparse is a bit cringe, but there seems to be no better
// option given the limited APIs of `prettyplease`
let rs_src = syn::parse_file(&mappings.to_token_stream().to_string())?;
let rs_src_pretty = prettyplease::unparse(&rs_src);
let codegen_path = Path::new(&env::var_os("OUT_DIR").ok_or(anyhow!("OUT_DIR is unset"))?)
.join("codegen_static_syntax_mappings.rs");
fs::write(codegen_path, mappings.codegen())?;
fs::write(codegen_path, rs_src_pretty)?;
Ok(())
}

View File

@@ -163,7 +163,7 @@ git show v0.6.0:src/main.rs | bat -l rs
볼 수 있습니다:
```bash
batdiff() {
git diff --name-only --diff-filter=d | xargs bat --diff
git diff --name-only --relative --diff-filter=d -z | xargs -0 bat --diff
}
```
이것을 별도의 도구로 쓰고 싶다면
@@ -461,11 +461,11 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
- `ansi`는 어떤 터미널에서도 무난하게 보입니다. 이는 3비트 색상을 사용합니다:
검정, 빨강, 녹색, 노랑, 파랑, 마젠타, 시안, 하양.
- `base16`은 [base16](https://github.com/chriskempson/base16) 터미널 테마를 위해
- `base16`은 [base16](https://github.com/tinted-theming/home) 터미널 테마를 위해
디자인되었습니다.
이는 [base16 스타일 가이드라인](https://github.com/chriskempson/base16/blob/master/styling.md)에
이는 [base16 스타일 가이드라인](https://github.com/tinted-theming/home/blob/main/styling.md)에
따라 4비트 색상(3비트 색상에 밝은 변형 추가)을 사용합니다.
- `base16-256`는 [base16-shell](https://github.com/chriskempson/base16-shell)을
- `base16-256`는 [base16-shell](https://github.com/tinted-theming/base16-shell)을
위해 디자인되었습니다.
이는 16부터 21의 일부 밝은 색상을 8비트 색상으로 대치합니다.
단지 256-색상 터미널을 쓰지만 base16-shell을 쓰지 않는다고 해서 이것을

View File

@@ -3,11 +3,11 @@
<a href="https://github.com/sharkdp/bat/actions?query=workflow%3ACICD"><img src="https://github.com/sharkdp/bat/workflows/CICD/badge.svg" alt="Build Status"></a>
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
Клон утилиты <i>cat(1)</i> с поддержкой выделения синтаксиса и Git
Клон утилиты <i>cat(1)</i> с поддержкой подсветки синтаксиса и Git
</p>
<p align="center">
<a href="#выделение-синтаксиса">Ключевые возможности</a>
<a href="#подсветка-синтаксиса">Ключевые возможности</a>
<a href="#как-использовать">Использование</a>
<a href="#установка">Установка</a>
<a href="#кастомизация">Кастомизация</a>
@@ -19,11 +19,11 @@
[Русский]
</p>
### Выделение синтаксиса
### Подсветка синтаксиса
`bat` поддерживает выделение синтаксиса для огромного количества языков программирования и разметки:
`bat` поддерживает подсветку синтаксиса для огромного количества языков программирования и разметки:
![Пример выделения синтаксиса](https://i.imgur.com/3FGy5tW.png)
![Пример подсветки синтаксиса](https://i.imgur.com/3FGy5tW.png)
### Интеграция с Git
`bat` использует `git`, чтобы показать изменения в коде
@@ -31,15 +31,17 @@
![Пример интеграции с Git](https://i.imgur.com/azUAzdx.png)
### Показать непечатаемые символы
### Показ непечатных символов
Вы можете использовать `-A` / `--show-all` флаг, чтобы показать символы, которые невозможно напечатать:
Вы можете использовать флаг `-A` / `--show-all`, чтобы показать непечатные символы:
![Строка с неотображемыми символами](https://i.imgur.com/X0orYY9.png)
### Автоматическое разделение текста
### Автоматический пейджинг терминала
`bat` умеет перенаправлять вывод в `less`, если вывод не помещается на экране полностью.
`bat` умеет перенаправлять вывод в пейджер терминала (например, в `less`), если вывод не помещается на экране полностью.
Если вы хотите, чтобы `bat` работал как `cat` всё время, вы можете установить опцию `--paging=never` в командной строке или в конфигурационном файле.
Если вы намерены использовать `bat` в качестве алиаса для `cat`, вы можете установить `alias cat='bat --paging=never'`, чтобы сохранить изначальное поведение.
### Объединение файлов
@@ -86,11 +88,23 @@ bat header.md content.md footer.md > document.md
bat -n main.rs # показываем только количество строк
bat f - g # выводит 'f' в stdin, а потом 'g'.
bat f - g # выводит 'f', потом stdin, а потом 'g'.
```
### Интеграция с другими утилитами
#### `fzf`
Вы можете использовать `bat` как просмотрщик для [`fzf`](https://github.com/junegunn/fzf).
Чтобы это заработало, используйте опцию `--color=always`, чтобы вывод был всегда цветным.
Вы можете также использовать опцию `--line-range`, чтобы уменьшить время загрузки для больших файлов:
```bash
fzf --preview "bat --color=always --style=numbers --line-range=:500 {}"
```
Больше деталей смотрите в [`README` программы `fzf`](https://github.com/junegunn/fzf#preview-window).
#### `find` или `fd`
Вы можете использовать флаг `-exec` в `find`, чтобы посмотреть превью всех файлов в `bat`
@@ -121,12 +135,22 @@ tail -f /var/log/pacman.log | bat --paging=never -l log
#### `git`
Вы можете использовать `bat` с `git show`, чтобы просмотреть старую версию файла с выделением синтаксиса:
Вы можете использовать `bat` с `git show`, чтобы просмотреть старую версию файла с подсветкой синтаксиса:
```bash
git show v0.6.0:src/main.rs | bat -l rs
```
Обратите внимание, что выделение синтаксиса не работает в `git diff` на данный момент. Если вам это нужно, посмотрите [`delta`](https://github.com/dandavison/delta).
#### `git diff`
Вы можете использовать `bat` с `git diff` для просмотра строк кода вокруг изменений с подсветкой синтаксиса:
```bash
batdiff() {
git diff --name-only --relative --diff-filter=d -z | xargs -0 bat --diff
}
```
Если вы хотите использовать это как отдельную программу, посмотрите `batdiff` из [`bat-extras`](https://github.com/eth-p/bat-extras).
Если вам это нужна более полная поддержка для операций с git и diff, посмотрите [`delta`](https://github.com/dandavison/delta).
#### `xclip`
@@ -135,17 +159,18 @@ git show v0.6.0:src/main.rs | bat -l rs
```bash
bat main.cpp | xclip
```
`bat` обнаружит перенаправление вывода и выведет обычный текст без выделения синтаксиса.
`bat` обнаружит перенаправление вывода и выведет обычный текст без подсветки синтаксиса.
#### `man`
`bat` может быть использован в виде выделения цвета для `man`, для этого установите переменную окружения
`bat` может быть использован для раскрашивания вывода `man`, для этого установите переменную окружения
`MANPAGER`:
```bash
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
man 2 select
```
(замените `bat` на `batcat`, если у вас Debian или Ubuntu)
Возможно вам понадобится также установить `MANROFFOPT="-c"`, если у вас есть проблемы с форматированием.
@@ -153,10 +178,40 @@ man 2 select
Обратите внимание, что [синтаксис manpage](assets/syntaxes/02_Extra/Manpage.sublime-syntax) разрабатывается в этом репозитории и все еще находится в разработке.
Также заметьте, что это [не заработает](https://github.com/sharkdp/bat/issues/1145) с реализацией `man` через Mandocs.
#### `prettier` / `shfmt` / `rustfmt`
[`Prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) — скрипт, который форматирует код и выводит его с помощью `bat`.
#### Подсветка сообщений `--help`
Вы можете использовать `bat`, чтобы подсвечивать текст справки комманд: `$ cp --help | bat -plhelp`
Вы можете сделать такую вспомогательную команду для этого:
```bash
# in your .bashrc/.zshrc/*rc
alias bathelp='bat --plain --language=help'
help() {
"$@" --help 2>&1 | bathelp
}
```
В этом случае, вы можете просто писать `$ help cp` или `$ help git commit`.
Если вы используете `zsh`, вы можете объявить глобальные алиасы для `-h` и `--help`:
```bash
alias -g -- -h='-h 2>&1 | bat --language=help --style=plain'
alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'
```
В этом случае, вы можете продолжать использовать `cp --help`, но при этом получать подцвеченный вывод.
Обратите внимание, что не всегда опция `-h` является краткой формы опции `--help` (например, у `ls`).
Пожалуйста, сообщайте о проблемах с подсветкой справки в [этот репозиторий](https://github.com/victor-gp/cmd-help-sublime-syntax).
## Установка
@@ -165,8 +220,7 @@ man 2 select
### Ubuntu (с помощью `apt`)
*... и другие дистрибутивы основанные на Debian.*
`bat` есть в репозиториях [Ubuntu](https://packages.ubuntu.com/eoan/bat) и
[Debian](https://packages.debian.org/sid/bat) и доступен начиная с Ubuntu Eoan 19.10. На Debian `bat` пока что доступен только с нестабильной веткой "Sid".
`bat` доступен на [Ubuntu since 20.04 ("Focal")](https://packages.ubuntu.com/search?keywords=bat&exact=1) и [Debian since August 2021 (Debian 11 - "Bullseye")](https://packages.debian.org/bullseye/bat).
Если ваша версия Ubuntu/Debian достаточно новая, вы можете установить `bat` так:
@@ -245,6 +299,14 @@ cd /usr/ports/textproc/bat
make install
```
### On OpenBSD
Вы можете установить `bat` с помощью [`pkg_add(1)`](https://man.openbsd.org/pkg_add.1):
```bash
pkg_add bat
```
### С помощью nix
Вы можете установить `bat`, используя [nix package manager](https://nixos.org/nix):
@@ -253,6 +315,14 @@ make install
nix-env -i bat
```
### Через flox
Вы можете установить `bat` используя [Flox](https://flox.dev)
```bash
flox install bat
```
### openSUSE
Вы можете установить `bat` с помощью `zypper`:
@@ -261,7 +331,7 @@ nix-env -i bat
zypper install bat
```
### macOS
### На macOS (или Linux) через Homebrew
Вы можете установить `bat` с помощью [Homebrew](http://braumeister.org/formula/bat):
@@ -269,6 +339,8 @@ zypper install bat
brew install bat
```
### На macOS через MacPorts
Или же установить его с помощью [MacPorts](https://ports.macports.org/port/bat/summary):
```bash
@@ -277,7 +349,19 @@ port install bat
### Windows
Есть несколько способов установить `bat`. Как только вы установили его, посмотрите на секцию ["Использование `bat` в Windows"](#using-bat-on-windows).
Есть несколько способов установить `bat`. Как только вы установили его, посмотрите на секцию ["Использование `bat` в Windows"](#использование-bat-в-windows).
#### Пререквитизы
Вам нужно установить пакет [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
#### С помощью WinGet
Вы можете установить `bat` через [WinGet](https://learn.microsoft.com/en-us/windows/package-manager/winget):
```bash
winget install sharkdp.bat
```
#### С помощью Chocolatey
@@ -293,50 +377,10 @@ choco install bat
scoop install bat
```
Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
#### Из заранее скомпилированных файлов:
Их вы можете скачать на [странице релизов](https://github.com/sharkdp/bat/releases).
Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
### С помощью Docker
Вы можете использовать [Docker image](https://hub.docker.com/r/danlynn/bat/), чтобы запустить `bat` в контейнере:
```bash
docker pull danlynn/bat
alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat'
```
### С помощью Ansible
Вы можете установить `bat` с [Ansible](https://www.ansible.com/):
```bash
# Устанавливаем роль на устройстве
ansible-galaxy install aeimer.install_bat
```
```yaml
---
# Playbook для установки bat
- host: all
roles:
- aeimer.install_bat
```
- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat)
- [GitHub](https://github.com/aeimer/ansible-install-bat)
Этот способ должен сработать со следующими дистрибутивами:
- Debian/Ubuntu
- ARM (например Raspberry PI)
- Arch Linux
- Void Linux
- FreeBSD
- macOS
### Из скомпилированных файлов
Перейдите на [страницу релизов](https://github.com/sharkdp/bat/releases) для
@@ -344,15 +388,24 @@ ansible-galaxy install aeimer.install_bat
### Из исходников
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.74.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.74.0 или выше. После этого используйте `cargo`, чтобы всё скомпилировать:
```bash
cargo install --locked bat
```
Заметьте, что дополнительные файлы, такие как документация man и подсказки командной строки, не могут быть установлены таким способом.
Они будут сгенерированы командой `cargo` должны быть доступны в папке сборки (в `build`).
Подсказки командной строки также доступны при таком запуске:
```bash
bat --completion <shell>
# see --help for supported shells
```
## Кастомизация
### Темы для выделения текста
### Темы для подсветки синтаксиса
Используйте `bat --list-themes`, чтобы вывести список всех доступных тем. Для выбора темы `TwoDark` используйте `bat` с флагом
`--theme=TwoDark` или выставьте переменную окружения `BAT_THEME` в `TwoDark`. Используйте `export BAT_THEME="TwoDark"` в конфигурационном файле вашей оболочки, чтобы изменить ее навсегда. Или же используйте [конфигурационный файл](https://github.com/sharkdp/bat#configuration-file) `bat`.
@@ -372,7 +425,7 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /путь/к/ф
### Добавление новых синтаксисов
`bat` использует [`syntect`](https://github.com/trishume/syntect/) для выделения синтаксиса. `syntect` может читать
`bat` использует [`syntect`](https://github.com/trishume/syntect/) для подсветки синтаксиса. `syntect` может читать
[файл `.sublime-syntax`](https://www.sublimetext.com/docs/3/syntax.html)
и темы. Чтобы добавить новый синтаксис, сделайте следующее:
@@ -403,7 +456,7 @@ bat cache --clear
### Добавление новых тем
Это работает похожим образом, так же как и добавление новых тем выделения синтаксиса
Это работает похожим образом, так же как и добавление новых тем подсветки синтаксиса
Во-первых, создайте каталог с новыми темами для синтаксиса:
```bash
@@ -590,7 +643,7 @@ cargo install --locked --force
Есть очень много альтернатив `bat`. Смотрите [этот документ](doc/alternatives.md) для сравнения.
## Лицензия
Copyright (c) 2018-2021 [Разработчики bat](https://github.com/sharkdp/bat).
Copyright (c) 2018-2024 [Разработчики bat](https://github.com/sharkdp/bat).
`bat` распространяется под лицензиями MIT License и Apache License 2.0 (на выбор пользователя).

View File

@@ -150,7 +150,7 @@ git show v0.6.0:src/main.rs | bat -l rs
```bash
batdiff() {
git diff --name-only --diff-filter=d | xargs bat --diff
git diff --name-only --relative --diff-filter=d -z | xargs -0 bat --diff
}
```
@@ -170,20 +170,23 @@ bat main.cpp | xclip
#### `man`
`bat`也能给`man`的输出上色。这需要设置`MANPAGER`环境变量:
`bat` 可以通过设置 `MANPAGER` 环境变量,用作 `man` 的彩色分页器
```bash
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
export MANPAGER="sh -c 'awk '\''{ gsub(/\x1B\[[0-9;]*m/, \"\", \$0); gsub(/.\x08/, \"\", \$0); print }'\'' | bat -p -lman'"
man 2 select
```
(如果你使用的是 Debian 或 Ubuntu使用`batcat`替换`bat`
(如果你使用 Debian 或 Ubuntu请将 `batcat` 替换`bat`
如果你遇到格式化问题,设置`MANROFFOPT="-c"`也许会有帮助
如果你希望将其打包为一个新的命令,也可以使用 [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md)
`batman`能提供类似功能——作为一个独立的命令。
> [!WARNING]
> 在使用 Mandoc 的 `man` 实现时,这[无法](https://github.com/sharkdp/bat/issues/1145)直接工作。
>
> 请使用 `batman`,或将此 Shell 脚本包装为 [Shebang 可执行文件](https://en.wikipedia.org/wiki/Shebang_(Unix)),并将 `MANPAGER` 指向该文件。
注意[man page 语法](assets/syntaxes/02_Extra/Manpage.sublime-syntax) 还需要完善。在使用特定的`man`实现时该功能[无法正常工作](https://github.com/sharkdp/bat/issues/1145)
注意[Manpage 语法](assets/syntaxes/02_Extra/Manpage.sublime-syntax)是在此仓库中开发的,仍需一些改进
#### `prettier` / `shfmt` / `rustfmt`
@@ -401,8 +404,8 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
`bat` 自带三个 [8-bit 色彩](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 主题:
- `ansi` 适应于大部分终端。它使用 3-bit 色彩:黑红绿黄蓝洋红靛青白。
- `base16`专为 [base16](https://github.com/chriskempson/base16) 终端设计。它使用 4-bit 色彩(带有亮度的 3-bit 色彩)。根据 [base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md) 制作。
- `base16-25`专为 [base16-shell](https://github.com/chriskempson/base16-shell) 设计。它把部分亮色替换为 8-bit 色彩。请不要直接使用该主题除非你清楚你的256色终端是否使用 base16-shell。
- `base16`专为 [base16](https://github.com/tinted-theming/home) 终端设计。它使用 4-bit 色彩(带有亮度的 3-bit 色彩)。根据 [base16 styling guidelines](https://github.com/tinted-theming/home/blob/main/styling.md) 制作。
- `base16-25`专为 [base16-shell](https://github.com/tinted-theming/base16-shell) 设计。它把部分亮色替换为 8-bit 色彩。请不要直接使用该主题除非你清楚你的256色终端是否使用 base16-shell。
尽管这些主题具有诸多限制,但具有一些 truecolor 主题不具有的三个优点:

View File

@@ -26,7 +26,7 @@ in the `.sublime-syntax` format.
4. Re-compile `bat`. At compilation time, the `syntaxes.bin` file will be stored inside the
`bat` binary.
5. Use `bat --list-languages` to check if the new languages are available.
5. Use `bat --list-languages` to check if the new languages are available. You may want to do something like ``export PATH="`pwd`/target/debug:$PATH"`` to ensure the locally compiled version is the one being used.
6. Add a syntax test for the new language. See [below](#Syntax-tests) for details.
@@ -102,4 +102,4 @@ The following files have been manually modified after converting from a `.tmLang
https://github.com/seanjames777/SML-Language-Definition/blob/master/sml.tmLanguage
* `Cabal.sublime_syntax` has been added manually from
https://github.com/SublimeHaskell/SublimeHaskell/ - we don't want to include the whole submodule because it includes other syntaxes ("Haskell improved") as well.
* `Lean.sublime-syntax` has been added manually from https://github.com/leanprover/vscode-lean/blob/master/syntaxes/lean.json via conversion.
* `Lean.sublime-syntax` has been added manually from https://github.com/leanprover/vscode-lean4/blob/master/vscode-lean4/syntaxes/lean4.json via conversion.

View File

@@ -194,6 +194,8 @@ Options:
'--line-range 40:' prints lines 40 to the end of the file
'--line-range 40' only prints line 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 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context)
-L, --list-languages
Display a list of supported languages for syntax highlighting.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -1,11 +0,0 @@
<svg width="1354" height="420" viewBox="0 0 1354 420" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="1354" height="420" rx="20" fill="white"/>
<path d="M434.751 133.122H466.637L489.595 227.729C493.852 245.585 494.697 256.219 494.697 256.219H495.128C495.128 256.219 496.61 245.808 500.867 227.729L522.757 133.122H558.9L582.066 227.729C586.53 246.223 587.598 256.219 587.598 256.219H588.236C588.236 256.219 588.666 246.223 592.907 227.729L615.02 133.122H646.907L606.523 288.313H571.017L546.576 194.344C541.474 173.936 541.044 164.801 541.044 164.801H540.614C540.614 164.801 540.183 173.936 535.512 194.344L512.553 288.313H475.996L434.751 133.122Z" fill="black"/>
<path d="M641.583 231.934C641.583 196.428 664.541 173.47 699.202 173.47C733.639 173.47 756.597 196.428 756.597 231.934C756.597 267.647 733.639 290.828 699.202 290.828C664.557 290.812 641.583 267.647 641.583 231.934ZM726.832 231.934C726.832 208.976 715.783 195.998 699.202 195.998C681.346 195.998 671.349 210.458 671.349 231.934C671.349 255.323 682.398 268.284 699.202 268.284C717.058 268.284 726.832 253.824 726.832 231.934Z" fill="black"/>
<path d="M770.836 175.21H799.103V196.048H799.741C804.635 185.207 816.322 174.365 836.299 174.365C839.695 174.365 841.831 174.796 843.314 175.21V203.478H842.469C842.469 203.478 839.918 202.633 832.903 202.633C811.013 202.633 799.103 215.594 799.103 239.828V288.295H770.836V175.21Z" fill="black"/>
<path d="M856.5 133.122H884.767V182.865C884.767 212.2 884.336 217.509 884.336 217.509H884.767L926.857 175.212H962.139L912.843 224.11L970.031 288.313H936.646L895.401 241.536L884.767 251.946V288.297H856.5V133.122Z" fill="black"/>
<path d="M970.444 211.285C970.444 163.455 1000.21 131.569 1044.85 131.569C1089.49 131.569 1119.26 163.455 1119.26 211.285C1119.26 259.114 1089.49 291.001 1044.85 291.001C1000.21 291.001 970.444 259.114 970.444 211.285ZM1088.42 211.285C1088.42 178.761 1071 156.855 1044.84 156.855C1018.67 156.855 1001.26 178.761 1001.26 211.285C1001.26 243.809 1018.69 265.715 1044.84 265.715C1070.98 265.715 1088.42 243.809 1088.42 211.285Z" fill="black"/>
<path d="M1130.08 236.656H1162.4C1162.4 254.943 1174.95 265.146 1194.08 265.146C1210.23 265.146 1221.29 257.063 1221.29 245.584C1221.29 232.622 1212.79 229.21 1185.79 223.901C1161.12 219.007 1134.98 210.716 1134.98 178.399C1134.98 151.408 1157.93 131 1193.01 131C1229.57 131 1252.11 150.132 1252.11 179.037H1219.79C1219.79 165.007 1208.95 156.286 1193.01 156.286C1176.86 156.286 1166.86 164.146 1166.86 175.625C1166.86 187.742 1173.88 192.413 1195.56 196.878C1227.65 203.685 1254.02 207.288 1254.02 243.001C1254.02 271.3 1229.36 290.432 1193.01 290.432C1156.02 290.432 1130.08 268.957 1130.08 236.656Z" fill="black"/>
<path d="M100 210C100 214.824 101.269 219.647 103.723 223.793L148.231 300.878C152.8 308.747 159.739 315.178 168.369 318.055C185.377 323.724 202.977 316.447 211.354 301.893L222.1 283.278L179.708 210L224.47 132.408L235.216 113.792C238.431 108.208 242.747 103.638 247.824 100H243.17H178.777C166.677 100 155.508 106.431 149.5 116.923L103.723 196.208C101.269 200.354 100 205.177 100 210Z" fill="#6363F1"/>
<path d="M353.847 210C353.847 205.177 352.578 200.353 350.124 196.207L305.024 118.107C296.647 103.638 279.047 96.3608 262.039 101.945C253.409 104.822 246.47 111.253 241.901 119.122L231.747 136.638L274.139 210L229.378 287.592L218.632 306.208C215.416 311.708 211.101 316.362 206.024 320H210.678H275.07C287.17 320 298.34 313.569 304.347 303.077L350.124 223.792C352.578 219.646 353.847 214.823 353.847 210Z" fill="#6363F1"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,4 +1,6 @@
use bat::{assets::HighlightingAssets, config::Config, controller::Controller, Input};
use bat::{
assets::HighlightingAssets, config::Config, controller::Controller, output::OutputHandle, Input,
};
fn main() {
let mut buffer = String::new();
@@ -10,7 +12,10 @@ fn main() {
let controller = Controller::new(&config, &assets);
let input = Input::from_file(file!());
controller
.run(vec![input.into()], Some(&mut buffer))
.run(
vec![input.into()],
Some(OutputHandle::FmtWrite(&mut buffer)),
)
.unwrap();
println!("{buffer}");

View File

@@ -152,7 +152,7 @@ impl HighlightingAssets {
&self,
path: impl AsRef<Path>,
mapping: &SyntaxMapping,
) -> Result<SyntaxReferenceInSet> {
) -> Result<SyntaxReferenceInSet<'_>> {
let path = path.as_ref();
let syntax_match = mapping.get_syntax_for(path);
@@ -163,7 +163,7 @@ impl HighlightingAssets {
if let Some(MappingTarget::MapTo(syntax_name)) = syntax_match {
return self
.find_syntax_by_name(syntax_name)?
.find_syntax_by_token(syntax_name)?
.ok_or_else(|| Error::UnknownSyntax(syntax_name.to_owned()));
}
@@ -191,11 +191,11 @@ impl HighlightingAssets {
Some(theme) => theme,
None => {
if theme == "ansi-light" || theme == "ansi-dark" {
bat_warning!("Theme '{}' is deprecated, using 'ansi' instead.", theme);
bat_warning!("Theme '{theme}' is deprecated, using 'ansi' instead.");
return self.get_theme("ansi");
}
if !theme.is_empty() {
bat_warning!("Unknown theme '{}', using default.", theme)
bat_warning!("Unknown theme '{theme}', using default.")
}
self.get_theme_set()
.get(
@@ -212,7 +212,7 @@ impl HighlightingAssets {
language: Option<&str>,
input: &mut OpenedInput,
mapping: &SyntaxMapping,
) -> Result<SyntaxReferenceInSet> {
) -> Result<SyntaxReferenceInSet<'_>> {
if let Some(language) = language {
let syntax_set = self.get_syntax_set()?;
return syntax_set
@@ -244,14 +244,17 @@ impl HighlightingAssets {
pub(crate) fn find_syntax_by_name(
&self,
syntax_name: &str,
) -> Result<Option<SyntaxReferenceInSet>> {
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let syntax_set = self.get_syntax_set()?;
Ok(syntax_set
.find_syntax_by_name(syntax_name)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
fn find_syntax_by_extension(&self, e: Option<&OsStr>) -> Result<Option<SyntaxReferenceInSet>> {
fn find_syntax_by_extension(
&self,
e: Option<&OsStr>,
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let syntax_set = self.get_syntax_set()?;
let extension = e.and_then(|x| x.to_str()).unwrap_or_default();
Ok(syntax_set
@@ -259,11 +262,18 @@ impl HighlightingAssets {
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
fn find_syntax_by_token(&self, token: &str) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let syntax_set = self.get_syntax_set()?;
Ok(syntax_set
.find_syntax_by_token(token)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
fn get_syntax_for_file_name(
&self,
file_name: &OsStr,
ignored_suffixes: &IgnoredSuffixes,
) -> Result<Option<SyntaxReferenceInSet>> {
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let mut syntax = self.find_syntax_by_extension(Some(file_name))?;
if syntax.is_none() {
syntax =
@@ -279,7 +289,7 @@ impl HighlightingAssets {
&self,
file_name: &OsStr,
ignored_suffixes: &IgnoredSuffixes,
) -> Result<Option<SyntaxReferenceInSet>> {
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let mut syntax = self.find_syntax_by_extension(Path::new(file_name).extension())?;
if syntax.is_none() {
syntax =
@@ -294,11 +304,15 @@ impl HighlightingAssets {
fn get_first_line_syntax(
&self,
reader: &mut InputReader,
) -> Result<Option<SyntaxReferenceInSet>> {
) -> Result<Option<SyntaxReferenceInSet<'_>>> {
let syntax_set = self.get_syntax_set()?;
Ok(String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| syntax_set.find_syntax_by_first_line(&l))
.and_then(|l| {
// Strip UTF-8 BOM if present
let line = l.strip_prefix('\u{feff}').unwrap_or(&l);
syntax_set.find_syntax_by_first_line(line)
})
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
}
@@ -343,8 +357,7 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
) -> Result<T> {
let contents = fs::read(path).map_err(|_| {
format!(
"Could not load cached {} '{}'",
description,
"Could not load cached {description} '{}'",
path.to_string_lossy()
)
})?;
@@ -370,7 +383,7 @@ mod tests {
pub temp_dir: TempDir,
}
impl<'a> SyntaxDetectionTest<'a> {
impl SyntaxDetectionTest<'_> {
fn new() -> Self {
SyntaxDetectionTest {
assets: HighlightingAssets::from_binary(),
@@ -533,6 +546,41 @@ mod tests {
);
}
#[test]
fn syntax_detection_first_line_with_utf8_bom() {
let test = SyntaxDetectionTest::new();
// Test that XML files are detected correctly even with UTF-8 BOM
// The BOM should be stripped before first-line syntax detection
let xml_with_bom = "\u{feff}<?xml version=\"1.0\" encoding=\"utf-8\"?>";
assert_eq!(
test.syntax_for_file_with_content("unknown_file", xml_with_bom),
"XML"
);
// Test the specific .csproj case mentioned in the issue
// Even if .csproj has extension mapping, this tests first-line fallback
let csproj_content_with_bom = "\u{feff}<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">";
assert_eq!(
test.syntax_for_file_with_content("test.csproj", csproj_content_with_bom),
"XML"
);
// Test that shell scripts are detected correctly even with UTF-8 BOM
let script_with_bom = "\u{feff}#!/bin/bash";
assert_eq!(
test.syntax_for_file_with_content("unknown_script", script_with_bom),
"Bourne Again Shell (bash)"
);
// Test that PHP files are detected correctly even with UTF-8 BOM
let php_with_bom = "\u{feff}<?php";
assert_eq!(
test.syntax_for_file_with_content("unknown_php", php_with_bom),
"PHP"
);
}
#[test]
fn syntax_detection_with_custom_mapping() {
let mut test = SyntaxDetectionTest::new();

View File

@@ -40,15 +40,15 @@ impl AssetsMetadata {
/// Load metadata about the stored cache file from the given folder.
///
/// There are several possibilities:
/// - We find a metadata.yaml file and are able to parse it
/// => return the contained information
/// - We find a metadata.yaml file and but are not able to parse it
/// => return a SerdeYamlError
/// - We do not find a metadata.yaml file but a syntaxes.bin or themes.bin file
/// => assume that these were created by an old version of bat and return
/// AssetsMetadata::default() without version information
/// - We do not find a metadata.yaml file and no cached assets
/// => no user provided assets are available, return None
/// - We find a `metadata.yaml` file and are able to parse it
/// - return the contained information
/// - We find a `metadata.yaml` file, but are not able to parse it
/// - return a [`Error::SerdeYamlError`]
/// - We do not find a `metadata.yaml` file but a `syntaxes.bin` or `themes.bin` file
/// - assume that these were created by an old version of bat and return
/// [`AssetsMetadata::default()`] without version information
/// - We do not find a `metadata.yaml` file and no cached assets
/// - no user provided assets are available, return `None`
pub fn load_from_folder(path: &Path) -> Result<Option<Self>> {
match Self::try_load_from_folder(path) {
Ok(metadata) => Ok(Some(metadata)),

View File

@@ -47,9 +47,8 @@ fn build_theme_set(source_dir: &Path, include_integrated_assets: bool) -> Result
let res = theme_set.add_from_folder(&theme_dir);
if let Err(err) = res {
println!(
"Failed to load one or more themes from '{}' (reason: '{}')",
"Failed to load one or more themes from '{}' (reason: '{err}')",
theme_dir.to_string_lossy(),
err,
);
}
} else {
@@ -162,15 +161,10 @@ fn asset_to_cache<T: serde::Serialize>(
description: &str,
compressed: bool,
) -> Result<()> {
print!("Writing {} to {} ... ", description, path.to_string_lossy());
print!("Writing {description} to {} ... ", path.to_string_lossy());
let contents = asset_to_contents(asset, description, compressed)?;
std::fs::write(path, &contents[..]).map_err(|_| {
format!(
"Could not save {} to {}",
description,
path.to_string_lossy()
)
})?;
std::fs::write(path, &contents[..])
.map_err(|_| format!("Could not save {description} to {}", path.to_string_lossy()))?;
println!("okay");
Ok(())
}

View File

@@ -60,7 +60,7 @@ fn to_path_and_stem(source_dir: &Path, entry: DirEntry) -> Option<PathAndStem> {
fn handle_file(path_and_stem: &PathAndStem) -> Result<Option<String>> {
if path_and_stem.stem == "NOTICE" {
handle_notice(&path_and_stem.path)
} else if path_and_stem.stem.to_ascii_uppercase() == "LICENSE" {
} else if path_and_stem.stem.eq_ignore_ascii_case("LICENSE") {
handle_license(&path_and_stem.path)
} else {
Ok(None)
@@ -95,6 +95,9 @@ fn include_license_in_acknowledgments(license_text: &str) -> bool {
// Apache 2.0
"Apache License Version 2.0, January 2004 http://www.apache.org/licenses/",
"Licensed under the Apache License, Version 2.0 (the \"License\");",
// CC BY 4.0
"Creative Commons Attribution 4.0 International Public License",
];
license_contains_marker(license_text, &markers)

View File

@@ -3,6 +3,7 @@ use std::env;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::thread::available_parallelism;
use crate::{
clap_app,
@@ -95,7 +96,7 @@ impl App {
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<'_>> {
let style_components = self.style_components()?;
let extra_plain = self.matches.get_count("plain") > 1;
@@ -124,7 +125,10 @@ impl App {
// If we have -pp as an option when in auto mode, the pager should be disabled.
if extra_plain || self.matches.get_flag("no-paging") {
PagingMode::Never
} else if inputs.iter().any(Input::is_stdin) {
} else if inputs.iter().any(Input::is_stdin)
// ignore stdin when --list-themes is used because in that case no input will be read anyways
&& !self.matches.get_flag("list-themes")
{
// If we are reading from stdin, only enable paging if we write to an
// interactive terminal and if we do not *read* from an interactive
// terminal.
@@ -146,7 +150,9 @@ impl App {
// start building glob matchers for builtin mappings immediately
// this is an appropriate approach because it's statistically likely that
// all the custom mappings need to be checked
if available_parallelism()?.get() > 1 {
syntax_mapping.start_offload_build_all();
}
if let Some(values) = self.matches.get_many::<String>("ignored-suffix") {
for suffix in values {
@@ -332,7 +338,7 @@ impl App {
})
}
pub fn inputs(&self) -> Result<Vec<Input>> {
pub fn inputs(&self) -> Result<Vec<Input<'_>>> {
let filenames: Option<Vec<&Path>> = self
.matches
.get_many::<PathBuf>("file-name")
@@ -425,7 +431,7 @@ impl App {
None => StyleComponents(HashSet::from_iter(
StyleComponent::Default
.components(self.interactive_output)
.into_iter()
.iter()
.cloned(),
)),
};

View File

@@ -50,7 +50,7 @@ fn clear_asset(path: PathBuf, description: &str) {
println!("skipped (not present)");
}
Err(err) => {
println!("could not remove the cache file {:?}: {}", &path, err);
println!("could not remove the cache file {path:?}: {err}");
}
Ok(_) => println!("okay"),
}

View File

@@ -16,7 +16,7 @@ static VERSION: Lazy<String> = Lazy::new(|| {
if git_version.is_empty() {
crate_version!().to_string()
} else {
format!("{} ({})", crate_version!(), git_version)
format!("{} ({git_version})", crate_version!())
}
});
@@ -525,7 +525,9 @@ pub fn build_app(interactive_output: bool) -> Command {
'--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' only prints line 40\n \
'--line-range 30:+10' prints lines 30 to 40",
'--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 30:40:2' prints lines 28 to 42 (range 30-40 with 2 lines of context)",
),
)
.arg(

View File

@@ -88,9 +88,8 @@ pub fn generate_config_file() -> bat::error::Result<()> {
fs::write(&config_file, default_config).map_err(|e| {
format!(
"Failed to create config file at '{}': {}",
"Failed to create config file at '{}': {e}",
config_file.to_string_lossy(),
e
)
})?;

View File

@@ -5,7 +5,7 @@ pub fn new_file_input<'a>(file: &'a Path, name: Option<&'a Path>) -> Input<'a> {
named(Input::ordinary_file(file), name.or(Some(file)))
}
pub fn new_stdin_input(name: Option<&Path>) -> Input {
pub fn new_stdin_input(name: Option<&Path>) -> Input<'_> {
named(Input::stdin(), name)
}

View File

@@ -16,6 +16,7 @@ use std::io::{BufReader, Write};
use std::path::Path;
use std::process;
use bat::output::{OutputHandle, OutputType};
use bat::theme::DetectColorScheme;
use nu_ansi_term::Color::Green;
use nu_ansi_term::Style;
@@ -161,7 +162,7 @@ pub fn get_languages(config: &Config, cache_dir: &Path) -> Result<String> {
};
for lang in languages {
write!(result, "{:width$}{}", lang.name, separator, width = longest).ok();
write!(result, "{:width$}{separator}", lang.name, width = longest).ok();
// Number of characters on this line so far, wrap before `desired_width`
let mut num_chars = 0;
@@ -172,7 +173,7 @@ pub fn get_languages(config: &Config, cache_dir: &Path) -> Result<String> {
let new_chars = word.len() + comma_separator.len();
if num_chars + new_chars >= desired_width {
num_chars = 0;
write!(result, "\n{:width$}{}", "", separator, width = longest).ok();
write!(result, "\n{:width$}{separator}", "", width = longest).ok();
}
num_chars += new_chars;
@@ -205,12 +206,13 @@ pub fn list_themes(
config.language = Some("Rust");
config.style_components = StyleComponents(style);
let stdout = io::stdout();
let mut stdout = stdout.lock();
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());
for theme in assets.themes() {
let default_theme_info = if !config.loop_through && default_theme_name == theme {
let default_theme_info = if default_theme_name == theme {
" (default)"
} else if default_theme(ColorScheme::Dark) == theme {
" (default dark)"
@@ -221,24 +223,28 @@ pub fn list_themes(
};
if config.colored_output {
writeln!(
stdout,
"Theme: {}{}\n",
writer,
"Theme: {}{default_theme_info}\n",
Style::new().bold().paint(theme.to_string()),
default_theme_info
)?;
config.theme = theme.to_string();
Controller::new(&config, &assets)
.run(vec![theme_preview_file()], None)
.run(
vec![theme_preview_file()],
Some(OutputHandle::IoWrite(&mut writer)),
)
.ok();
writeln!(stdout)?;
writeln!(writer)?;
} else if config.loop_through {
writeln!(writer, "{theme}")?;
} else {
writeln!(stdout, "{theme}{default_theme_info}")?;
writeln!(writer, "{theme}{default_theme_info}")?;
}
}
if config.colored_output {
writeln!(
stdout,
writer,
"Further themes can be installed to '{}', \
and are added to the cache with `bat cache --build`. \
For more information, see:\n\n \
@@ -356,7 +362,7 @@ fn run() -> Result<bool> {
"fish" => println!("{}", completions::FISH_COMPLETION),
"ps1" => println!("{}", completions::PS1_COMPLETION),
"zsh" => println!("{}", completions::ZSH_COMPLETION),
_ => unreachable!("No completion for shell '{}' available.", shell),
_ => unreachable!("No completion for shell '{shell}' available."),
}
return Ok(true);
}

View File

@@ -119,17 +119,25 @@ pub fn get_pager_executable(config_pager: Option<&str>) -> Option<String> {
#[test]
fn default_config_should_include_all_lines() {
use crate::line_range::MaxBufferedLineNumber;
use crate::line_range::RangeCheckResult;
assert_eq!(LineRanges::default().check(17), RangeCheckResult::InRange);
assert_eq!(
LineRanges::default().check(17, MaxBufferedLineNumber::Tentative(17)),
RangeCheckResult::InRange
);
}
#[test]
fn default_config_should_highlight_no_lines() {
use crate::line_range::MaxBufferedLineNumber;
use crate::line_range::RangeCheckResult;
assert_ne!(
Config::default().highlighted_lines.0.check(17),
Config::default()
.highlighted_lines
.0
.check(17, MaxBufferedLineNumber::Tentative(17)),
RangeCheckResult::InRange
);
}

View File

@@ -1,5 +1,3 @@
use std::io::{self, BufRead, Write};
use crate::assets::HighlightingAssets;
use crate::config::{Config, VisibleLines};
#[cfg(feature = "git")]
@@ -10,11 +8,14 @@ use crate::input::{Input, InputReader, OpenedInput};
use crate::lessopen::LessOpenPreprocessor;
#[cfg(feature = "git")]
use crate::line_range::LineRange;
use crate::line_range::{LineRanges, RangeCheckResult};
use crate::output::OutputType;
use crate::line_range::{LineRanges, MaxBufferedLineNumber, RangeCheckResult};
use crate::output::{OutputHandle, OutputType};
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
use crate::printer::{InteractivePrinter, OutputHandle, Printer, SimplePrinter};
use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
use std::collections::VecDeque;
use std::io::{self, BufRead, Write};
use std::mem;
use clircle::{Clircle, Identifier};
@@ -25,7 +26,7 @@ pub struct Controller<'a> {
preprocessor: Option<LessOpenPreprocessor>,
}
impl<'b> Controller<'b> {
impl Controller<'_> {
pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {
Controller {
config,
@@ -35,18 +36,14 @@ impl<'b> Controller<'b> {
}
}
pub fn run(
&self,
inputs: Vec<Input>,
output_buffer: Option<&mut dyn std::fmt::Write>,
) -> Result<bool> {
self.run_with_error_handler(inputs, output_buffer, default_error_handler)
pub fn run(&self, inputs: Vec<Input>, output_handle: Option<OutputHandle<'_>>) -> Result<bool> {
self.run_with_error_handler(inputs, output_handle, default_error_handler)
}
pub fn run_with_error_handler(
&self,
inputs: Vec<Input>,
output_buffer: Option<&mut dyn std::fmt::Write>,
output_handle: Option<OutputHandle<'_>>,
mut handle_error: impl FnMut(&Error, &mut dyn Write),
) -> Result<bool> {
let mut output_type;
@@ -88,8 +85,9 @@ impl<'b> Controller<'b> {
clircle::Identifier::stdout()
};
let mut writer = match output_buffer {
Some(buf) => OutputHandle::FmtWrite(buf),
let mut writer = match output_handle {
Some(OutputHandle::FmtWrite(w)) => OutputHandle::FmtWrite(w),
Some(OutputHandle::IoWrite(w)) => OutputHandle::IoWrite(w),
None => OutputHandle::IoWrite(output_type.handle()?),
};
let mut no_errors: bool = true;
@@ -241,20 +239,63 @@ impl<'b> Controller<'b> {
reader: &mut InputReader,
line_ranges: &LineRanges,
) -> Result<()> {
let mut line_buffer = Vec::new();
let mut line_number: usize = 1;
let mut current_line_buffer: Vec<u8> = Vec::new();
let mut current_line_number: usize = 1;
// Buffer needs to be 1 greater than the offset to have a look-ahead line for EOF
let buffer_size: usize = line_ranges.largest_offset_from_end() + 1;
// Buffers multiple line data and line number
let mut buffered_lines: VecDeque<(Vec<u8>, usize)> = VecDeque::with_capacity(buffer_size);
let mut reached_eof: bool = false;
let mut first_range: bool = true;
let mut mid_range: bool = false;
let style_snip = self.config.style_components.snip();
while reader.read_line(&mut line_buffer)? {
match line_ranges.check(line_number) {
loop {
if reached_eof && buffered_lines.is_empty() {
// Done processing all lines
break;
}
if !reached_eof {
if reader.read_line(&mut current_line_buffer)? {
// Fill the buffer
buffered_lines
.push_back((mem::take(&mut current_line_buffer), current_line_number));
current_line_number += 1;
} else {
// No more data to read
reached_eof = true;
}
}
if buffered_lines.len() < buffer_size && !reached_eof {
// The buffer needs to be completely filled first
continue;
}
let Some((line, line_nr)) = buffered_lines.pop_front() else {
break;
};
// Determine if the last line number in the buffer is the last line of the file or
// just a line somewhere in the file
let max_buffered_line_number = buffered_lines
.back()
.map(|(_, max_line_number)| {
if reached_eof {
MaxBufferedLineNumber::Final(*max_line_number)
} else {
MaxBufferedLineNumber::Tentative(*max_line_number)
}
})
.unwrap_or(MaxBufferedLineNumber::Final(line_nr));
match line_ranges.check(line_nr, max_buffered_line_number) {
RangeCheckResult::BeforeOrBetweenRanges => {
// Call the printer in case we need to call the syntax highlighter
// for this line. However, set `out_of_range` to `true`.
printer.print_line(true, writer, line_number, &line_buffer)?;
printer.print_line(true, writer, line_nr, &line, max_buffered_line_number)?;
mid_range = false;
}
@@ -269,15 +310,12 @@ impl<'b> Controller<'b> {
}
}
printer.print_line(false, writer, line_number, &line_buffer)?;
printer.print_line(false, writer, line_nr, &line, max_buffered_line_number)?;
}
RangeCheckResult::AfterLastRange => {
break;
}
}
line_number += 1;
line_buffer.clear();
}
Ok(())
}

View File

@@ -60,14 +60,18 @@ pub fn default_error_handler(error: &Error, output: &mut dyn Write) {
Error::SerdeYamlError(_) => {
writeln!(
output,
"{}: Error while parsing metadata.yaml file: {}",
"{}: Error while parsing metadata.yaml file: {error}",
Red.paint("[bat error]"),
error
)
.ok();
}
_ => {
writeln!(output, "{}: {}", Red.paint("[bat error]"), error).ok();
writeln!(
&mut std::io::stderr().lock(),
"{}: {error}",
Red.paint("[bat error]"),
)
.ok();
}
};
}

View File

@@ -75,7 +75,7 @@ pub(crate) enum InputKind<'a> {
CustomReader(Box<dyn Read + 'a>),
}
impl<'a> InputKind<'a> {
impl InputKind<'_> {
pub fn description(&self) -> InputDescription {
match self {
InputKind::OrdinaryFile(ref path) => InputDescription::new(path.to_string_lossy()),
@@ -217,14 +217,14 @@ impl<'a> Input<'a> {
metadata: self.metadata,
reader: {
let mut file = File::open(&path)
.map_err(|e| format!("'{}': {}", path.to_string_lossy(), e))?;
.map_err(|e| format!("'{}': {e}", path.to_string_lossy()))?;
if file.metadata()?.is_dir() {
return Err(format!("'{}' is a directory.", path.to_string_lossy()).into());
}
if let Some(stdout) = stdout_identifier {
let input_identifier = Identifier::try_from(file).map_err(|e| {
format!("{}: Error identifying file: {}", path.to_string_lossy(), e)
format!("{}: Error identifying file: {e}", path.to_string_lossy())
})?;
if stdout.surely_conflicts_with(&input_identifier) {
return Err(format!(
@@ -267,7 +267,9 @@ impl<'a> InputReader<'a> {
};
if content_type == Some(ContentType::UTF_16LE) {
reader.read_until(0x00, &mut first_line).ok();
read_utf16_line(&mut reader, &mut first_line, 0x00, 0x0A).ok();
} else if content_type == Some(ContentType::UTF_16BE) {
read_utf16_line(&mut reader, &mut first_line, 0x0A, 0x00).ok();
}
InputReader {
@@ -283,16 +285,44 @@ impl<'a> InputReader<'a> {
return Ok(true);
}
let res = self.inner.read_until(b'\n', buf).map(|size| size > 0)?;
if self.content_type == Some(ContentType::UTF_16LE) {
let _ = self.inner.read_until(0x00, buf);
return read_utf16_line(&mut self.inner, buf, 0x00, 0x0A);
}
if self.content_type == Some(ContentType::UTF_16BE) {
return read_utf16_line(&mut self.inner, buf, 0x0A, 0x00);
}
let res = self.inner.read_until(b'\n', buf).map(|size| size > 0)?;
Ok(res)
}
}
fn read_utf16_line<R: BufRead>(
reader: &mut R,
buf: &mut Vec<u8>,
read_until_char: u8,
preceded_by_char: u8,
) -> io::Result<bool> {
loop {
let mut temp = Vec::new();
let n = reader.read_until(read_until_char, &mut temp)?;
if n == 0 {
// EOF reached
break;
}
buf.extend_from_slice(&temp);
if buf.len() >= 2
&& buf[buf.len() - 2] == preceded_by_char
&& buf[buf.len() - 1] == read_until_char
{
// end of line found
break;
}
// end of line not found, keep going
}
Ok(!buf.is_empty())
}
#[test]
fn basic() {
let content = b"#!/bin/bash\necho hello";
@@ -350,3 +380,53 @@ fn utf16le() {
assert!(!res.unwrap());
assert!(buffer.is_empty());
}
#[test]
fn utf16le_issue3367() {
let content = b"\xFF\xFE\x0A\x4E\x00\x4E\x0A\x4F\x00\x52\x0A\x00\
\x6F\x00\x20\x00\x62\x00\x61\x00\x72\x00\x0A\x00\
\x68\x00\x65\x00\x6C\x00\x6C\x00\x6F\x00\x20\x00\x77\x00\x6F\x00\x72\x00\x6C\x00\x64\x00";
let mut reader = InputReader::new(&content[..]);
assert_eq!(
b"\xFF\xFE\x0A\x4E\x00\x4E\x0A\x4F\x00\x52\x0A\x00",
&reader.first_line[..]
);
let mut buffer = vec![];
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert!(res.unwrap());
assert_eq!(
b"\xFF\xFE\x0A\x4E\x00\x4E\x0A\x4F\x00\x52\x0A\x00",
&buffer[..]
);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert!(res.unwrap());
assert_eq!(
b"\x6F\x00\x20\x00\x62\x00\x61\x00\x72\x00\x0A\x00",
&buffer[..]
);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert!(res.unwrap());
assert_eq!(
b"\x68\x00\x65\x00\x6C\x00\x6C\x00\x6F\x00\x20\x00\x77\x00\x6F\x00\x72\x00\x6C\x00\x64\x00",
&buffer[..]
);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert!(!res.unwrap());
assert!(buffer.is_empty());
}

View File

@@ -1,5 +1,3 @@
#![cfg(feature = "lessopen")]
use std::convert::TryFrom;
use std::env;
use std::fs::File;
@@ -41,7 +39,7 @@ impl LessOpenPreprocessor {
// Note that $LESSCLOSE has no such requirement
if lessopen.match_indices("%s").count() != 1 {
let error_msg = "LESSOPEN ignored: must contain exactly one %s";
bat_warning!("{}", error_msg);
bat_warning!("{error_msg}");
return Err(error_msg.into());
}
@@ -112,7 +110,7 @@ impl LessOpenPreprocessor {
if self.preprocess_stdin {
if let Some(stdout) = stdout_identifier {
let input_identifier = Identifier::try_from(clircle::Stdio::Stdin)
.map_err(|e| format!("Stdin: Error identifying file: {}", e))?;
.map_err(|e| format!("Stdin: Error identifying file: {e}"))?;
if stdout.surely_conflicts_with(&input_identifier) {
return Err("IO circle detected. The input from stdin is also an output. Aborting to avoid infinite loop.".into());
}
@@ -200,7 +198,7 @@ impl LessOpenPreprocessor {
})
}
fn fall_back_to_original_file(&self, lessopen_stdout: &Vec<u8>, exit_code: ExitStatus) -> bool {
fn fall_back_to_original_file(&self, lessopen_stdout: &[u8], exit_code: ExitStatus) -> bool {
lessopen_stdout.is_empty()
&& (!exit_code.success() || matches!(self.kind, LessOpenKind::PipedIgnoreExitCode))
}

View File

@@ -38,7 +38,7 @@ mod less;
mod lessopen;
pub mod line_range;
pub(crate) mod nonprintable_notation;
mod output;
pub mod output;
#[cfg(feature = "paging")]
mod pager;
#[cfg(feature = "paging")]

View File

@@ -1,16 +1,26 @@
use crate::error::*;
use itertools::{Itertools, MinMaxResult};
#[derive(Debug, Clone)]
#[derive(Debug, Copy, Clone)]
pub struct LineRange {
lower: usize,
upper: usize,
lower: RangeBound,
upper: RangeBound,
}
/// Defines a boundary for a range
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub(crate) enum RangeBound {
// An absolute line number marking the boundary of a range
Absolute(usize),
// A relative (implicitly negative) offset from the end of the file as a boundary
OffsetFromEnd(usize),
}
impl Default for LineRange {
fn default() -> LineRange {
LineRange {
lower: usize::min_value(),
upper: usize::max_value(),
lower: RangeBound::Absolute(usize::MIN),
upper: RangeBound::Absolute(usize::MAX),
}
}
}
@@ -18,8 +28,8 @@ impl Default for LineRange {
impl LineRange {
pub fn new(from: usize, to: usize) -> Self {
LineRange {
lower: from,
upper: to,
lower: RangeBound::Absolute(from),
upper: RangeBound::Absolute(to),
}
}
@@ -29,31 +39,47 @@ impl LineRange {
fn parse_range(range_raw: &str) -> Result<LineRange> {
let mut new_range = LineRange::default();
let mut raw_range_iter = range_raw.bytes();
let first_byte = raw_range_iter.next().ok_or("Empty line range")?;
if range_raw.bytes().next().ok_or("Empty line range")? == b':' {
new_range.upper = range_raw[1..].parse()?;
if first_byte == b':' {
if raw_range_iter.next() == Some(b'-') {
// E.g. ':-3'
let value = range_raw[2..].parse()?;
new_range.upper = RangeBound::OffsetFromEnd(value);
} else {
let value = range_raw[1..].parse()?;
new_range.upper = RangeBound::Absolute(value);
}
return Ok(new_range);
} else if range_raw.bytes().last().ok_or("Empty line range")? == b':' {
new_range.lower = range_raw[..range_raw.len() - 1].parse()?;
if first_byte == b'-' {
// E.g. '-3:'
let value = range_raw[1..range_raw.len() - 1].parse()?;
new_range.lower = RangeBound::OffsetFromEnd(value);
} else {
let value = range_raw[..range_raw.len() - 1].parse()?;
new_range.lower = RangeBound::Absolute(value);
}
return Ok(new_range);
}
let line_numbers: Vec<&str> = range_raw.split(':').collect();
match line_numbers.len() {
1 => {
new_range.lower = line_numbers[0].parse()?;
new_range.lower = RangeBound::Absolute(line_numbers[0].parse()?);
new_range.upper = new_range.lower;
Ok(new_range)
}
2 => {
new_range.lower = line_numbers[0].parse()?;
let mut lower_absolute_bound: usize = line_numbers[0].parse()?;
let first_byte = line_numbers[1].bytes().next();
new_range.upper = if first_byte == Some(b'+') {
let upper_absolute_bound = if first_byte == Some(b'+') {
let more_lines = &line_numbers[1][1..]
.parse()
.map_err(|_| "Invalid character after +")?;
new_range.lower.saturating_add(*more_lines)
lower_absolute_bound.saturating_add(*more_lines)
} else if first_byte == Some(b'-') {
// this will prevent values like "-+5" even though "+5" is valid integer
if line_numbers[1][1..].bytes().next() == Some(b'+') {
@@ -62,77 +88,178 @@ impl LineRange {
let prior_lines = &line_numbers[1][1..]
.parse()
.map_err(|_| "Invalid character after -")?;
let prev_lower = new_range.lower;
new_range.lower = new_range.lower.saturating_sub(*prior_lines);
let prev_lower = lower_absolute_bound;
lower_absolute_bound = lower_absolute_bound.saturating_sub(*prior_lines);
prev_lower
} else {
line_numbers[1].parse()?
};
new_range.lower = RangeBound::Absolute(lower_absolute_bound);
new_range.upper = RangeBound::Absolute(upper_absolute_bound);
Ok(new_range)
}
3 => {
// Handle context syntax: N::C or N:M:C
if line_numbers[1].is_empty() {
// Format: N::C - single line with context
let line_number: usize = line_numbers[0].parse()
.map_err(|_| "Invalid line number in N::C format")?;
let context: usize = line_numbers[2].parse()
.map_err(|_| "Invalid context number in N::C format")?;
new_range.lower = RangeBound::Absolute(line_number.saturating_sub(context));
new_range.upper = RangeBound::Absolute(line_number.saturating_add(context));
} else {
// Format: N:M:C - range with context
let start_line: usize = line_numbers[0].parse()
.map_err(|_| "Invalid start line number in N:M:C format")?;
let end_line: usize = line_numbers[1].parse()
.map_err(|_| "Invalid end line number in N:M:C format")?;
let context: usize = line_numbers[2].parse()
.map_err(|_| "Invalid context number in N:M:C format")?;
new_range.lower = RangeBound::Absolute(start_line.saturating_sub(context));
new_range.upper = RangeBound::Absolute(end_line.saturating_add(context));
}
Ok(new_range)
}
_ => Err(
"Line range contained more than one ':' character. Expected format: 'N' or 'N:M'"
"Line range contained too many ':' characters. Expected format: 'N', 'N:M', 'N::C', or 'N:M:C'"
.into(),
),
}
}
pub(crate) fn is_inside(&self, line: usize) -> bool {
line >= self.lower && line <= self.upper
/// Checks if a line number is inside the range.
/// For ranges with relative offsets range bounds `max_buffered_line_number` is necessary
/// to convert the offset to an absolute value.
pub(crate) fn is_inside(
&self,
line: usize,
max_buffered_line_number: MaxBufferedLineNumber,
) -> bool {
match (self.lower, self.upper, max_buffered_line_number) {
(RangeBound::Absolute(lower), RangeBound::Absolute(upper), _) => {
lower <= line && line <= upper
}
(
RangeBound::Absolute(lower),
RangeBound::OffsetFromEnd(offset),
MaxBufferedLineNumber::Final(last_line_number),
) => lower <= line && line <= last_line_number.saturating_sub(offset),
(
RangeBound::Absolute(lower),
RangeBound::OffsetFromEnd(_),
MaxBufferedLineNumber::Tentative(_),
) => {
// We don't know the final line number yet, so the assumption is that the line is
// still far enough away from the upper end of the range
lower <= line
}
(
RangeBound::OffsetFromEnd(offset),
RangeBound::Absolute(upper),
MaxBufferedLineNumber::Final(last_line_number),
) => last_line_number.saturating_sub(offset) <= line && line <= upper,
(
RangeBound::OffsetFromEnd(_),
RangeBound::Absolute(_),
MaxBufferedLineNumber::Tentative(_),
) => {
// We don't know the final line number yet, so the assumption is that the line is
// still too far away from the having reached the lower end of the range
false
}
(
RangeBound::OffsetFromEnd(lower),
RangeBound::OffsetFromEnd(upper),
MaxBufferedLineNumber::Final(last_line_number),
) => {
last_line_number.saturating_sub(lower) <= line
&& line <= last_line_number.saturating_sub(upper)
}
(
RangeBound::OffsetFromEnd(_),
RangeBound::OffsetFromEnd(_),
MaxBufferedLineNumber::Tentative(_),
) => {
// We don't know the final line number yet, so the assumption is that we're still
// too far away from the having reached the lower end of the range
false
}
}
}
}
#[test]
fn test_parse_full() {
let range = LineRange::from("40:50").expect("Shouldn't fail on test!");
assert_eq!(40, range.lower);
assert_eq!(50, range.upper);
assert_eq!(RangeBound::Absolute(40), range.lower);
assert_eq!(RangeBound::Absolute(50), range.upper);
}
#[test]
fn test_parse_partial_min() {
let range = LineRange::from(":50").expect("Shouldn't fail on test!");
assert_eq!(usize::min_value(), range.lower);
assert_eq!(50, range.upper);
assert_eq!(RangeBound::Absolute(usize::MIN), range.lower);
assert_eq!(RangeBound::Absolute(50), range.upper);
}
#[test]
fn test_parse_partial_relative_negative_from_back() {
let range = LineRange::from(":-5").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(usize::MIN), range.lower);
assert_eq!(RangeBound::OffsetFromEnd(5), range.upper);
}
#[test]
fn test_parse_relative_negative_from_back_partial() {
let range = LineRange::from("-5:").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::OffsetFromEnd(5), range.lower);
assert_eq!(RangeBound::Absolute(usize::MAX), range.upper);
}
#[test]
fn test_parse_partial_max() {
let range = LineRange::from("40:").expect("Shouldn't fail on test!");
assert_eq!(40, range.lower);
assert_eq!(usize::max_value(), range.upper);
assert_eq!(RangeBound::Absolute(40), range.lower);
assert_eq!(RangeBound::Absolute(usize::MAX), range.upper);
}
#[test]
fn test_parse_single() {
let range = LineRange::from("40").expect("Shouldn't fail on test!");
assert_eq!(40, range.lower);
assert_eq!(40, range.upper);
assert_eq!(RangeBound::Absolute(40), range.lower);
assert_eq!(RangeBound::Absolute(40), range.upper);
}
#[test]
fn test_parse_fail() {
let range = LineRange::from("40:50:80");
// Test 4+ colon parts should still fail
let range = LineRange::from("40:50:80:90");
assert!(range.is_err());
let range = LineRange::from("40::80");
// Test invalid formats that should still fail
let range = LineRange::from("-2:5");
assert!(range.is_err());
let range = LineRange::from(":40:");
assert!(range.is_err());
// Test completely malformed input
let range = LineRange::from("abc:def");
assert!(range.is_err());
}
#[test]
fn test_parse_plus() {
let range = LineRange::from("40:+10").expect("Shouldn't fail on test!");
assert_eq!(40, range.lower);
assert_eq!(50, range.upper);
assert_eq!(RangeBound::Absolute(40), range.lower);
assert_eq!(RangeBound::Absolute(50), range.upper);
}
#[test]
fn test_parse_plus_overflow() {
let range = LineRange::from(&format!("{}:+1", usize::MAX)).expect("Shouldn't fail on test!");
assert_eq!(usize::MAX, range.lower);
assert_eq!(usize::MAX, range.upper);
assert_eq!(RangeBound::Absolute(usize::MAX), range.lower);
assert_eq!(RangeBound::Absolute(usize::MAX), range.upper);
}
#[test]
@@ -148,21 +275,21 @@ fn test_parse_plus_fail() {
#[test]
fn test_parse_minus_success() {
let range = LineRange::from("40:-10").expect("Shouldn't fail on test!");
assert_eq!(30, range.lower);
assert_eq!(40, range.upper);
assert_eq!(RangeBound::Absolute(30), range.lower);
assert_eq!(RangeBound::Absolute(40), range.upper);
}
#[test]
fn test_parse_minus_edge_cases_success() {
let range = LineRange::from("5:-4").expect("Shouldn't fail on test!");
assert_eq!(1, range.lower);
assert_eq!(5, range.upper);
assert_eq!(RangeBound::Absolute(1), range.lower);
assert_eq!(RangeBound::Absolute(5), range.upper);
let range = LineRange::from("5:-5").expect("Shouldn't fail on test!");
assert_eq!(0, range.lower);
assert_eq!(5, range.upper);
assert_eq!(RangeBound::Absolute(0), range.lower);
assert_eq!(RangeBound::Absolute(5), range.upper);
let range = LineRange::from("5:-100").expect("Shouldn't fail on test!");
assert_eq!(0, range.lower);
assert_eq!(5, range.upper);
assert_eq!(RangeBound::Absolute(0), range.lower);
assert_eq!(RangeBound::Absolute(5), range.upper);
}
#[test]
@@ -175,6 +302,57 @@ fn test_parse_minus_fail() {
assert!(range.is_err());
}
#[test]
fn test_parse_context_single_line() {
let range = LineRange::from("35::5").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(30), range.lower);
assert_eq!(RangeBound::Absolute(40), range.upper);
}
#[test]
fn test_parse_context_range() {
let range = LineRange::from("30:40:2").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(28), range.lower);
assert_eq!(RangeBound::Absolute(42), range.upper);
// Test the case that used to fail but should now work
let range = LineRange::from("40:50:80").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(0), range.lower); // 40 - 80 = 0 (saturated)
assert_eq!(RangeBound::Absolute(130), range.upper); // 50 + 80 = 130
}
#[test]
fn test_parse_context_edge_cases() {
// Test with small line numbers that would underflow
let range = LineRange::from("5::10").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(0), range.lower);
assert_eq!(RangeBound::Absolute(15), range.upper);
// Test with zero context
let range = LineRange::from("50::0").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(50), range.lower);
assert_eq!(RangeBound::Absolute(50), range.upper);
// Test range with zero context
let range = LineRange::from("30:40:0").expect("Shouldn't fail on test!");
assert_eq!(RangeBound::Absolute(30), range.lower);
assert_eq!(RangeBound::Absolute(40), range.upper);
}
#[test]
fn test_parse_context_fail() {
let range = LineRange::from("40::z");
assert!(range.is_err());
let range = LineRange::from("::5");
assert!(range.is_err());
let range = LineRange::from("40::");
assert!(range.is_err());
let range = LineRange::from("30:40:z");
assert!(range.is_err());
let range = LineRange::from("30::40:5");
assert!(range.is_err());
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum RangeCheckResult {
// Within one of the given ranges
@@ -187,10 +365,24 @@ pub enum RangeCheckResult {
AfterLastRange,
}
/// Represents the maximum line number in the buffer when reading a file.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub(crate) enum MaxBufferedLineNumber {
// The currently known maximum line number, may not be the final line number
Tentative(usize),
// The final line number, when EOF has been reached
Final(usize),
}
#[derive(Debug, Clone)]
pub struct LineRanges {
ranges: Vec<LineRange>,
largest_upper_bound: usize,
// The largest absolute upper line number of all ranges
largest_absolute_upper_bound: usize,
// The smallest relative offset from the end of all ranges
smallest_offset_from_end: usize,
// The largest relative offset from the end of all ranges
largest_offset_from_end: usize,
}
impl LineRanges {
@@ -203,26 +395,62 @@ impl LineRanges {
}
pub fn from(ranges: Vec<LineRange>) -> LineRanges {
let largest_upper_bound = ranges
let largest_absolute_upper_bound = ranges
.iter()
.map(|r| r.upper)
.filter_map(|r| match r.upper {
RangeBound::Absolute(upper) => Some(upper),
_ => None,
})
.max()
.unwrap_or(usize::max_value());
.unwrap_or(usize::MAX);
let offsets_min_max = ranges
.iter()
.flat_map(|r| [r.lower, r.upper])
.filter_map(|r| match r {
RangeBound::OffsetFromEnd(offset) => Some(offset),
_ => None,
})
.minmax();
let (smallest_offset_from_end, largest_offset_from_end) = match offsets_min_max {
MinMaxResult::NoElements => (usize::MIN, usize::MIN),
MinMaxResult::OneElement(offset) => (offset, offset),
MinMaxResult::MinMax(min, max) => (min, max),
};
LineRanges {
ranges,
largest_upper_bound,
largest_absolute_upper_bound,
smallest_offset_from_end,
largest_offset_from_end,
}
}
pub(crate) fn check(&self, line: usize) -> RangeCheckResult {
if self.ranges.iter().any(|r| r.is_inside(line)) {
pub(crate) fn check(
&self,
line: usize,
max_buffered_line_number: MaxBufferedLineNumber,
) -> RangeCheckResult {
if self
.ranges
.iter()
.any(|r| r.is_inside(line, max_buffered_line_number))
{
RangeCheckResult::InRange
} else if line < self.largest_upper_bound {
} else if matches!(max_buffered_line_number, MaxBufferedLineNumber::Final(final_line_number) if line > final_line_number.saturating_sub(self.smallest_offset_from_end))
{
RangeCheckResult::AfterLastRange
} else if line < self.largest_absolute_upper_bound {
RangeCheckResult::BeforeOrBetweenRanges
} else {
RangeCheckResult::AfterLastRange
}
}
pub(crate) fn largest_offset_from_end(&self) -> usize {
self.largest_offset_from_end
}
}
impl Default for LineRanges {
@@ -249,54 +477,292 @@ fn ranges(rs: &[&str]) -> LineRanges {
fn test_ranges_simple() {
let ranges = ranges(&["3:8"]);
assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(2));
assert_eq!(RangeCheckResult::InRange, ranges.check(5));
assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(9));
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(2, MaxBufferedLineNumber::Tentative(2))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(5))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(9, MaxBufferedLineNumber::Tentative(9))
);
}
#[test]
fn test_ranges_advanced() {
let ranges = ranges(&["3:8", "11:20", "25:30"]);
assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(2));
assert_eq!(RangeCheckResult::InRange, ranges.check(5));
assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(9));
assert_eq!(RangeCheckResult::InRange, ranges.check(11));
assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(22));
assert_eq!(RangeCheckResult::InRange, ranges.check(28));
assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(31));
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(2, MaxBufferedLineNumber::Tentative(2))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(5))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(9, MaxBufferedLineNumber::Tentative(9))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(11, MaxBufferedLineNumber::Tentative(11))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(22, MaxBufferedLineNumber::Tentative(22))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(28, MaxBufferedLineNumber::Tentative(28))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(31, MaxBufferedLineNumber::Tentative(31))
);
}
#[test]
fn test_ranges_open_low() {
let ranges = ranges(&["3:8", ":5"]);
assert_eq!(RangeCheckResult::InRange, ranges.check(1));
assert_eq!(RangeCheckResult::InRange, ranges.check(3));
assert_eq!(RangeCheckResult::InRange, ranges.check(7));
assert_eq!(RangeCheckResult::AfterLastRange, ranges.check(9));
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Tentative(3))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(7, MaxBufferedLineNumber::Tentative(7))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(9, MaxBufferedLineNumber::Tentative(9))
);
}
#[test]
fn test_ranges_open_high() {
let ranges = ranges(&["3:", "2:5"]);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
assert_eq!(RangeCheckResult::BeforeOrBetweenRanges, ranges.check(1));
assert_eq!(RangeCheckResult::InRange, ranges.check(3));
assert_eq!(RangeCheckResult::InRange, ranges.check(5));
assert_eq!(RangeCheckResult::InRange, ranges.check(9));
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(1, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(2, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(9, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(10, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Tentative(3))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(5))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(9, MaxBufferedLineNumber::Tentative(9))
);
}
#[test]
fn test_ranges_open_up_to_3_from_end() {
let ranges = ranges(&[":-3"]);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Tentative(3))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(8))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Final(6))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(2, MaxBufferedLineNumber::Final(6))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Final(6))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(4, MaxBufferedLineNumber::Final(6))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(5, MaxBufferedLineNumber::Final(6))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(6, MaxBufferedLineNumber::Final(6))
);
}
#[test]
fn test_ranges_multiple_negative_from_back() {
let ranges = ranges(&[":-3", ":-9"]);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Tentative(3))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(14))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Final(16))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(7, MaxBufferedLineNumber::Final(16))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(13, MaxBufferedLineNumber::Final(16))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(14, MaxBufferedLineNumber::Final(16))
);
assert_eq!(
RangeCheckResult::AfterLastRange,
ranges.check(16, MaxBufferedLineNumber::Final(16))
);
}
#[test]
fn test_ranges_3_from_back_up_to_end() {
let ranges = ranges(&["-3:"]);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(3, MaxBufferedLineNumber::Tentative(3))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(5, MaxBufferedLineNumber::Tentative(8))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(1, MaxBufferedLineNumber::Final(5))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(2, MaxBufferedLineNumber::Final(5))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(3, MaxBufferedLineNumber::Final(5))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(4, MaxBufferedLineNumber::Final(5))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Final(5))
);
}
#[test]
fn test_ranges_multiple_negative_offsets_to_end() {
let ranges = ranges(&["-3:", "-12:"]);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(5, MaxBufferedLineNumber::Tentative(8))
);
assert_eq!(
RangeCheckResult::BeforeOrBetweenRanges,
ranges.check(5, MaxBufferedLineNumber::Tentative(17))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(8, MaxBufferedLineNumber::Final(20))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(9, MaxBufferedLineNumber::Final(20))
);
}
#[test]
fn test_ranges_absolute_bound_and_offset() {
let ranges = ranges(&["5:", ":-2"]);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(4, MaxBufferedLineNumber::Tentative(6))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(5, MaxBufferedLineNumber::Tentative(7))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(8, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(9, MaxBufferedLineNumber::Final(10))
);
assert_eq!(
RangeCheckResult::InRange,
ranges.check(10, MaxBufferedLineNumber::Final(10))
);
}
#[test]
fn test_ranges_all() {
let ranges = LineRanges::all();
assert_eq!(RangeCheckResult::InRange, ranges.check(1));
assert_eq!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
}
#[test]
fn test_ranges_none() {
let ranges = LineRanges::none();
assert_ne!(RangeCheckResult::InRange, ranges.check(1));
assert_ne!(
RangeCheckResult::InRange,
ranges.check(1, MaxBufferedLineNumber::Tentative(1))
);
}

View File

@@ -1,3 +1,4 @@
use std::fmt;
use std::io::{self, Write};
#[cfg(feature = "paging")]
use std::process::Child;
@@ -92,6 +93,9 @@ impl OutputType {
p.arg("-S"); // Short version of --chop-long-lines for compatibility
}
// Ensures that 'less' quits together with 'bat'
p.arg("-K"); // Short version of '--quit-on-intr'
// Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older
// versions of 'less'. Unfortunately, it also breaks mouse-wheel support.
//
@@ -162,3 +166,17 @@ impl Drop for OutputType {
}
}
}
pub enum OutputHandle<'a> {
IoWrite(&'a mut dyn io::Write),
FmtWrite(&'a mut dyn fmt::Write),
}
impl OutputHandle<'_> {
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<()> {
match self {
Self::IoWrite(handle) => handle.write_fmt(args).map_err(Into::into),
Self::FmtWrite(handle) => handle.write_fmt(args).map_err(Into::into),
}
}
}

View File

@@ -10,6 +10,7 @@ use crate::{
error::Result,
input,
line_range::{HighlightedLineRanges, LineRange, LineRanges},
output::OutputHandle,
style::StyleComponent,
StripAnsiMode, SyntaxMapping, WrappingMode,
};
@@ -325,7 +326,10 @@ impl<'a> PrettyPrinter<'a> {
// If writer is provided, pass it to the controller, otherwise pass None
if let Some(mut w) = writer {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), Some(&mut w))
controller.run(
inputs.into_iter().map(|i| i.into()).collect(),
Some(OutputHandle::FmtWrite(&mut w)),
)
} else {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), None)
}

View File

@@ -1,5 +1,3 @@
use std::fmt;
use std::io;
use std::vec::Vec;
use nu_ansi_term::Color::{Fixed, Green, Red, Yellow};
@@ -17,6 +15,7 @@ use content_inspector::ContentType;
use encoding_rs::{UTF_16BE, UTF_16LE};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthChar;
use crate::assets::{HighlightingAssets, SyntaxReferenceInSet};
@@ -28,7 +27,8 @@ use crate::decorations::{Decoration, GridBorderDecoration, LineNumberDecoration}
use crate::diff::LineChanges;
use crate::error::*;
use crate::input::OpenedInput;
use crate::line_range::RangeCheckResult;
use crate::line_range::{MaxBufferedLineNumber, RangeCheckResult};
use crate::output::OutputHandle;
use crate::preprocessor::strip_ansi;
use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::style::StyleComponent;
@@ -68,20 +68,6 @@ const EMPTY_SYNTECT_STYLE: syntect::highlighting::Style = syntect::highlighting:
font_style: FontStyle::empty(),
};
pub enum OutputHandle<'a> {
IoWrite(&'a mut dyn io::Write),
FmtWrite(&'a mut dyn fmt::Write),
}
impl<'a> OutputHandle<'a> {
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<()> {
match self {
Self::IoWrite(handle) => handle.write_fmt(args).map_err(Into::into),
Self::FmtWrite(handle) => handle.write_fmt(args).map_err(Into::into),
}
}
}
pub(crate) trait Printer {
fn print_header(
&mut self,
@@ -99,6 +85,7 @@ pub(crate) trait Printer {
handle: &mut OutputHandle,
line_number: usize,
line_buffer: &[u8],
max_buffered_line_number: MaxBufferedLineNumber,
) -> Result<()>;
}
@@ -116,7 +103,7 @@ impl<'a> SimplePrinter<'a> {
}
}
impl<'a> Printer for SimplePrinter<'a> {
impl Printer for SimplePrinter<'_> {
fn print_header(
&mut self,
_handle: &mut OutputHandle,
@@ -140,11 +127,12 @@ impl<'a> Printer for SimplePrinter<'a> {
handle: &mut OutputHandle,
_line_number: usize,
line_buffer: &[u8],
_max_buffered_line_number: MaxBufferedLineNumber,
) -> Result<()> {
// Skip squeezed lines.
if let Some(squeeze_limit) = self.config.squeeze_lines {
if String::from_utf8_lossy(line_buffer)
.trim_end_matches(|c| c == '\r' || c == '\n')
.trim_end_matches(['\r', '\n'])
.is_empty()
{
self.consecutive_empty_lines += 1;
@@ -267,7 +255,7 @@ impl<'a> InteractivePrinter<'a> {
let is_printing_binary = input
.reader
.content_type
.map_or(false, |c| c.is_binary() && !config.show_nonprintable);
.is_some_and(|c| c.is_binary() && !config.show_nonprintable);
let needs_to_match_syntax = (!is_printing_binary
|| matches!(config.binary, BinaryBehavior::AsText))
@@ -341,7 +329,7 @@ impl<'a> InteractivePrinter<'a> {
self.print_horizontal_line_term(handle, self.colors.grid)?;
} else {
let hline = "".repeat(self.config.term_width - (self.panel_width + 1));
let hline = format!("{}{}{}", "".repeat(self.panel_width), grid_char, hline);
let hline = format!("{}{grid_char}{hline}", "".repeat(self.panel_width));
writeln!(handle, "{}", self.colors.grid.paint(hline))?;
}
@@ -355,8 +343,7 @@ impl<'a> InteractivePrinter<'a> {
let text_truncated: String = text.chars().take(self.panel_width - 1).collect();
let text_filled: String = format!(
"{}{}",
text_truncated,
"{text_truncated}{}",
" ".repeat(self.panel_width - 1 - text_truncated.len())
);
if self.config.style_components.grid() {
@@ -403,14 +390,18 @@ impl<'a> InteractivePrinter<'a> {
handle: &mut OutputHandle,
content: &str,
) -> Result<()> {
let mut content = content;
let content_width = self.config.term_width - self.get_header_component_indent_length();
while content.len() > content_width {
let (content_line, remaining) = content.split_at(content_width);
self.print_header_component_with_indent(handle, content_line)?;
content = remaining;
if content.chars().count() <= content_width {
return self.print_header_component_with_indent(handle, content);
}
self.print_header_component_with_indent(handle, content)
let mut content_graphemes: Vec<&str> = content.graphemes(true).collect();
while content_graphemes.len() > content_width {
let (content_line, remaining) = content_graphemes.split_at(content_width);
self.print_header_component_with_indent(handle, content_line.join("").as_str())?;
content_graphemes = remaining.to_vec();
}
self.print_header_component_with_indent(handle, content_graphemes.join("").as_str())
}
fn highlight_regions_for_line<'b>(
@@ -432,7 +423,7 @@ impl<'a> InteractivePrinter<'a> {
.highlight_line(for_highlighting, highlighter_from_set.syntax_set)?;
if too_long {
highlighted_line[0].1 = &line;
highlighted_line[0].1 = line;
}
Ok(highlighted_line)
@@ -448,7 +439,7 @@ impl<'a> InteractivePrinter<'a> {
}
}
impl<'a> Printer for InteractivePrinter<'a> {
impl Printer for InteractivePrinter<'_> {
fn print_header(
&mut self,
handle: &mut OutputHandle,
@@ -521,13 +512,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
.try_for_each(|component| match component {
StyleComponent::HeaderFilename => {
let header_filename = format!(
"{}{}{}",
"{}{}{mode}",
description
.kind()
.map(|kind| format!("{kind}: "))
.unwrap_or_else(|| "".into()),
self.colors.header_value.paint(description.title()),
mode
);
self.print_header_multiline_component(handle, &header_filename)
}
@@ -544,7 +534,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
})?;
if self.config.style_components.grid() {
if self.content_type.map_or(false, |c| c.is_text())
if self.content_type.is_some_and(|c| c.is_text())
|| self.config.show_nonprintable
|| matches!(self.config.binary, BinaryBehavior::AsText)
{
@@ -559,7 +549,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
if self.config.style_components.grid()
&& (self.content_type.map_or(false, |c| c.is_text())
&& (self.content_type.is_some_and(|c| c.is_text())
|| self.config.show_nonprintable
|| matches!(self.config.binary, BinaryBehavior::AsText))
{
@@ -599,6 +589,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
handle: &mut OutputHandle,
line_number: usize,
line_buffer: &[u8],
max_buffered_line_number: MaxBufferedLineNumber,
) -> Result<()> {
let line = if self.config.show_nonprintable {
replace_nonprintable(
@@ -644,7 +635,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
// Skip squeezed lines.
if let Some(squeeze_limit) = self.config.squeeze_lines {
if line.trim_end_matches(|c| c == '\r' || c == '\n').is_empty() {
if line.trim_end_matches(['\r', '\n']).is_empty() {
self.consecutive_empty_lines += 1;
if self.consecutive_empty_lines > squeeze_limit {
return Ok(());
@@ -660,8 +651,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
let mut panel_wrap: Option<String> = None;
// Line highlighting
let highlight_this_line =
self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange;
let highlight_this_line = self
.config
.highlighted_lines
.0
.check(line_number, max_buffered_line_number)
== RangeCheckResult::InRange;
if highlight_this_line && self.config.theme == "ansi" {
self.ansi_style.update(ANSI_UNDERLINE_ENABLE);
@@ -697,14 +692,14 @@ impl<'a> Printer for InteractivePrinter<'a> {
// Regular text.
EscapeSequence::Text(text) => {
let text = self.preprocess(text, &mut cursor_total);
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
let text_trimmed = text.trim_end_matches(['\r', '\n']);
write!(
handle,
"{}{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, text_trimmed),
&format!("{}{text_trimmed}", self.ansi_style),
true_color,
colored_output,
italics,
@@ -751,10 +746,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
match chunk {
// Regular text.
EscapeSequence::Text(text) => {
let text = self.preprocess(
text.trim_end_matches(|c| c == '\r' || c == '\n'),
&mut cursor_total,
);
let text = self
.preprocess(text.trim_end_matches(['\r', '\n']), &mut cursor_total);
let mut max_width = cursor_max - cursor;
@@ -796,7 +789,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
"{}{}\n{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, line_buf),
&format!("{}{line_buf}", self.ansi_style),
self.config.true_color,
self.config.colored_output,
self.config.use_italic_text,
@@ -823,7 +816,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
"{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, line_buf),
&format!("{}{line_buf}", self.ansi_style),
self.config.true_color,
self.config.colored_output,
self.config.use_italic_text,

View File

@@ -225,7 +225,7 @@ impl FromStr for StyleComponentList {
fn from_str(s: &str) -> Result<Self> {
Ok(StyleComponentList(
s.split(",")
.map(|s| ComponentAction::extract_from_str(s)) // If the component starts with "-", it's meant to be removed
.map(ComponentAction::extract_from_str) // If the component starts with "-", it's meant to be removed
.map(|(a, s)| Ok((a, StyleComponent::from_str(s)?)))
.collect::<Result<Vec<(ComponentAction, StyleComponent)>>>()?,
))

View File

@@ -61,7 +61,7 @@ pub struct SyntaxMapping<'a> {
halt_glob_build: Arc<AtomicBool>,
}
impl<'a> Drop for SyntaxMapping<'a> {
impl Drop for SyntaxMapping<'_> {
fn drop(&mut self) {
// signal the offload thread to halt early
self.halt_glob_build.store(true, Ordering::Relaxed);
@@ -153,7 +153,7 @@ impl<'a> SyntaxMapping<'a> {
if glob.is_match_candidate(&candidate)
|| candidate_filename
.as_ref()
.map_or(false, |filename| glob.is_match_candidate(filename))
.is_some_and(|filename| glob.is_match_candidate(filename))
{
return Some(*syntax);
}

View File

@@ -0,0 +1,2 @@
[mappings]
"XML" = ["*.csproj", "*.vbproj", "*.props", "*.targets"]

View File

@@ -1,3 +1,3 @@
# JSON Lines is a simple variation of JSON #2535
[mappings]
"JSON" = ["*.jsonl", "*.jsonc", "*.jsonld", "*.geojson"]
"JSON" = ["*.jsonl", "*.jsonc", "*.jsonld", "*.geojson", "*.ndjson"]

View File

@@ -0,0 +1,2 @@
[mappings]
"Scala" = ["*.mill"]

View File

@@ -0,0 +1,2 @@
[mappings]
"JSON" = ["flake.lock"]

View File

@@ -0,0 +1,5 @@
[mappings]
"INI" = [
"*.flatpakref",
"*.flatpakrepo"
]

View File

@@ -0,0 +1,6 @@
# See https://github.com/Morganamilo/paru/blob/master/man/paru.conf.5
[mappings]
"INI" = [
"${PARU_CONF}",
"paru.conf",
]

View File

@@ -1,7 +1,5 @@
# see `man quadlet`
[mappings]
"INI" = [
"**/containers/systemd/*.{container,volume,network,kube,image}",
"**/containers/systemd/users/*.{container,volume,network,kube,image}",
"**/containers/systemd/users/*/*.{container,volume,network,kube,image}",
"**/containers/systemd/**/*.{container,volume,network,kube,image}",
]

View File

@@ -0,0 +1,3 @@
# See https://eff-certbot.readthedocs.io/en/stable/using.html#configuration-file
[mappings]
"INI" = ["/etc/letsencrypt/renewal/*.conf"]

View File

@@ -2,4 +2,24 @@
"Bourne Again Shell (bash)" = [
# used by lots of shells
"/etc/profile",
"bashrc",
"*.bashrc",
"bash_profile",
"*.bash_profile",
"bash_login",
"*.bash_login",
"bash_logout",
"*.bash_logout",
"zshrc",
"*.zshrc",
"zprofile",
"*.zprofile",
"zlogin",
"*.zlogin",
"zlogout",
"*.zlogout",
"zshenv",
"*.zshenv"
]

View File

@@ -10,9 +10,9 @@ pub mod env {
/// See [`crate::theme::ThemeOptions::theme`].
pub const BAT_THEME: &str = "BAT_THEME";
/// See [`crate::theme::ThemeOptions::theme_dark`].
pub const BAT_THEME_DARK: &str = "BAT_THEME";
pub const BAT_THEME_DARK: &str = "BAT_THEME_DARK";
/// See [`crate::theme::ThemeOptions::theme_light`].
pub const BAT_THEME_LIGHT: &str = "BAT_THEME";
pub const BAT_THEME_LIGHT: &str = "BAT_THEME_LIGHT";
}
/// Chooses an appropriate theme or falls back to a default theme
@@ -266,10 +266,10 @@ impl ColorSchemeDetector for TerminalColorSchemeDetector {
}
fn detect(&self) -> Option<ColorScheme> {
use terminal_colorsaurus::{color_scheme, ColorScheme as ColorsaurusScheme, QueryOptions};
match color_scheme(QueryOptions::default()).ok()? {
ColorsaurusScheme::Dark => Some(ColorScheme::Dark),
ColorsaurusScheme::Light => Some(ColorScheme::Light),
use terminal_colorsaurus::{theme_mode, QueryOptions, ThemeMode};
match theme_mode(QueryOptions::default()).ok()? {
ThemeMode::Dark => Some(ColorScheme::Dark),
ThemeMode::Light => Some(ColorScheme::Light),
}
}
}
@@ -383,7 +383,6 @@ mod tests {
theme: ThemePreference::Fixed(ThemeName::Named("Theme".to_string())),
theme_dark: Some(ThemeName::Named("Dark Theme".to_string())),
theme_light: Some(ThemeName::Named("Light Theme".to_string())),
..Default::default()
},
] {
let detector = ConstantDetector(color_scheme);
@@ -509,7 +508,7 @@ mod tests {
ThemePreference::Light,
];
for pref in prefs {
assert_eq!(pref, ThemePreference::new(&pref.to_string()));
assert_eq!(pref, ThemePreference::new(pref.to_string()));
}
}
}

View File

@@ -212,15 +212,15 @@ impl Attributes {
}
fn update_with_charset(&mut self, kind: char, set: impl Iterator<Item = char>) -> bool {
self.charset = format!("\x1B{}{}", kind, set.take(1).collect::<String>());
self.charset = format!("\x1B{kind}{}", set.take(1).collect::<String>());
true
}
fn parse_color(color: u16, parameters: &mut dyn Iterator<Item = u16>) -> String {
match color % 10 {
8 => match parameters.next() {
Some(5) /* 256-color */ => format!("\x1B[{};5;{}m", color, join(";", 1, parameters)),
Some(2) /* 24-bit color */ => format!("\x1B[{};2;{}m", color, join(";", 3, parameters)),
Some(5) /* 256-color */ => format!("\x1B[{color};5;{}m", join(";", 1, parameters)),
Some(2) /* 24-bit color */ => format!("\x1B[{color};2;{}m", join(";", 3, parameters)),
Some(c) => format!("\x1B[{color};{c}m"),
_ => "".to_owned(),
},
@@ -360,10 +360,10 @@ pub struct EscapeSequenceOffsetsIterator<'a> {
impl<'a> EscapeSequenceOffsetsIterator<'a> {
pub fn new(text: &'a str) -> EscapeSequenceOffsetsIterator<'a> {
return EscapeSequenceOffsetsIterator {
EscapeSequenceOffsetsIterator {
text,
chars: text.char_indices().peekable(),
};
}
}
/// Takes values from the iterator while the predicate returns true.
@@ -539,7 +539,7 @@ impl<'a> EscapeSequenceOffsetsIterator<'a> {
}
}
impl<'a> Iterator for EscapeSequenceOffsetsIterator<'a> {
impl Iterator for EscapeSequenceOffsetsIterator<'_> {
type Item = EscapeSequenceOffsets;
fn next(&mut self) -> Option<Self::Item> {
match self.chars.peek() {
@@ -564,10 +564,10 @@ pub struct EscapeSequenceIterator<'a> {
impl<'a> EscapeSequenceIterator<'a> {
pub fn new(text: &'a str) -> EscapeSequenceIterator<'a> {
return EscapeSequenceIterator {
EscapeSequenceIterator {
text,
offset_iter: EscapeSequenceOffsetsIterator::new(text),
};
}
}
}

View File

@@ -14,6 +14,10 @@ fn all_themes_are_present() {
themes,
vec![
"1337",
"Catppuccin Frappe",
"Catppuccin Latte",
"Catppuccin Macchiato",
"Catppuccin Mocha",
"Coldark-Cold",
"Coldark-Dark",
"DarkNeon",

View File

@@ -2021,7 +2021,7 @@
tests/syntax-tests/highlighted/Manpage/bat-0.16.man:243: BAT(1)
tests/syntax-tests/highlighted/Svelte/App.svelte:30: // This block is a regression test for a bat panic when a LiveScript syntax definition is missing
tests/syntax-tests/highlighted/VimL/source.vim:77:" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064)
tests/syntax-tests/highlighted/Java/test.java:3:/* This Java program was submiited to help bat
tests/syntax-tests/highlighted/Java/test.java:3:/* This Java program was submitted to help bat
tests/syntax-tests/highlighted/Sass/example.sass:46: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg")
tests/syntax-tests/highlighted/HTML/test.html:5: <title>Bat Syntax Test</title>
tests/syntax-tests/highlighted/Cpp/test.cpp:6:/* This C program was submitted to help bat
@@ -2119,7 +2119,7 @@
tests/syntax-tests/source/Svelte/App.svelte:30: // This block is a regression test for a bat panic when a LiveScript syntax definition is missing
tests/syntax-tests/source/VimL/source.vim:77:" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064)
tests/syntax-tests/source/Git Config/LICENSE.md:1:The `test.gitconfig` file has been added from https://github.com/sharkdp/bat/pull/1336#issuecomment-715905807. Its "free to use".
tests/syntax-tests/source/Java/test.java:3:/* This Java program was submiited to help bat
tests/syntax-tests/source/Java/test.java:3:/* This Java program was submitted to help bat
tests/syntax-tests/source/Sass/example.sass:46: background-image: url("https://github.com/sharkdp/bat/raw/master/doc/logo-header.svg")
tests/syntax-tests/source/HTML/test.html:5: <title>Bat Syntax Test</title>
tests/syntax-tests/source/Cpp/test.cpp:6:/* This C program was submitted to help bat

View File

@@ -2,3 +2,9 @@ line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10

0
tests/examples/test.A—B가 vendored Normal file
View File

Binary file not shown.

BIN
tests/examples/test_UTF-16BE.txt vendored Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More