Compare commits

...

384 Commits

Author SHA1 Message Date
dependabot[bot] b4e3a84e1a
Bump serde from 1.0.197 to 1.0.199 (#2953)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.197 to 1.0.199.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.197...v1.0.199)

---
updated-dependencies:
- dependency-name: serde
  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>
2024-05-01 03:23:25 +00:00
dependabot[bot] f7c39e8353
Bump os_str_bytes from 6.6.1 to 7.0.0 (#2952)
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.6.1 to 7.0.0.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.6.1...7.0.0)

---
updated-dependencies:
- dependency-name: os_str_bytes
  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>
2024-05-01 03:10:09 +00:00
dependabot[bot] 37d9f0533c
Bump indexmap from 2.2.2 to 2.2.6 (#2950)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.2.2 to 2.2.6.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.2.2...2.2.6)

---
updated-dependencies:
- dependency-name: indexmap
  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>
2024-05-01 02:47:11 +00:00
dependabot[bot] d560f2a515
Bump serde_with from 3.7.0 to 3.8.1 (#2949)
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.7.0 to 3.8.1.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.7.0...v3.8.1)

---
updated-dependencies:
- dependency-name: serde_with
  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>
2024-05-01 02:27:04 +00:00
Stéphane Blondon bb4d1cbd2e refactor: factorize constants by inverting loop and condition order 2024-04-19 11:44:47 +02:00
Stéphane Blondon 23ec433167 display which theme is the default one in basic output 2024-04-19 11:44:47 +02:00
Sharun 9eaed3e3f0
[JavaScript] Support bun in shebang for syntax highlighting (#2913)
* [JavaScript] Support bun in shebang for syntax highlighting

---------

Co-authored-by: Keith Hall <keith-hall@users.noreply.github.com>
2024-04-15 06:17:41 +00:00
sblondon d5bd4aa93f
display which theme is the default one in colored output (#2838) 2024-04-14 15:54:52 +02:00
Keith Hall 66b70dd8ed
Merge pull request #2933 from vorburger/patch-1
Fix minor typo in GitHub Syntax Request Issue Template
2024-04-09 21:35:45 +03:00
Michael Vorburger 01731478a6
Fix minor typo in GitHub Syntax Request Issue Template 2024-04-09 19:54:46 +02:00
Rivera Calzadillas f8c5429a6c Print $TERM with --diagnostic 2024-04-07 14:24:16 +02:00
Rivera Calzadillas f71226adbb Sort env vars printed by --diagnostic 2024-04-07 14:24:16 +02:00
一个不知名の睡觉高手 e8d777b73a fix: some typos 2024-04-04 06:01:37 +02:00
dependabot[bot] 3cff44b652
Bump console from 0.15.7 to 0.15.8 (#2925)
Bumps [console](https://github.com/console-rs/console) from 0.15.7 to 0.15.8.
- [Changelog](https://github.com/console-rs/console/blob/master/CHANGELOG.md)
- [Commits](https://github.com/console-rs/console/compare/0.15.7...0.15.8)

---
updated-dependencies:
- dependency-name: console
  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>
2024-04-01 04:11:21 +00:00
dependabot[bot] 26302a8b08
Bump serde from 1.0.193 to 1.0.197 (#2926)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.193 to 1.0.197.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.197)

---
updated-dependencies:
- dependency-name: serde
  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>
2024-04-01 03:58:57 +00:00
dependabot[bot] adc5bd0402
Bump serde_with from 3.6.1 to 3.7.0 (#2923)
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.6.1 to 3.7.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.6.1...v3.7.0)

---
updated-dependencies:
- dependency-name: serde_with
  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>
2024-04-01 03:44:58 +00:00
dependabot[bot] e3c3be950a
Bump predicates from 3.0.4 to 3.1.0 (#2924)
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 3.0.4 to 3.1.0.
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v3.0.4...v3.1.0)

---
updated-dependencies:
- dependency-name: predicates
  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>
2024-04-01 03:30:00 +00:00
dependabot[bot] 8d92dc2083
Bump wild from 2.2.0 to 2.2.1 (#2922)
Bumps [wild](https://gitlab.com/kornelski/wild) from 2.2.0 to 2.2.1.
- [Commits](https://gitlab.com/kornelski/wild/compare/v2.2.0...v2.2.1)

---
updated-dependencies:
- dependency-name: wild
  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>
2024-04-01 03:11:04 +00:00
dependabot[bot] a1f85b9e06
Bump assets/syntaxes/02_Extra/Julia from `98233f9` to `3366b10` (#2918)
Bumps [assets/syntaxes/02_Extra/Julia](https://github.com/JuliaEditorSupport/Julia-sublime) from `98233f9` to `3366b10`.
- [Release notes](https://github.com/JuliaEditorSupport/Julia-sublime/releases)
- [Commits](98233f96d4...3366b10be9)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 02:47:26 +00:00
dependabot[bot] 424c02dfa7
Bump softprops/action-gh-release from 1 to 2 (#2917)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  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>
2024-04-01 02:29:01 +00:00
David Peter 018a482621 Update Warp logo 2024-03-23 21:15:25 +01:00
guoguangwu 4790def1ef fix: typo
Signed-off-by: guoguangwu <guoguangwug@gmail.com>
2024-03-17 15:40:48 +01:00
Hamir Mahal 07c26adc35 style: simplify equality check 2024-03-11 18:57:51 +01:00
David Peter f29f9387b5
Merge pull request #2868 from cyqsimon/builtin-offload-v2
Faster startup by offloading glob matcher building to a worker thread
2024-03-10 20:08:43 +01:00
Hamir Mahal c290bfff1e refactor: remove reference that is unnecessary 2024-03-10 11:17:02 +01:00
dependabot[bot] 42153f2b99
Bump nu-ansi-term from 0.49.0 to 0.50.0 (#2879)
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.49.0 to 0.50.0.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.49.0...v0.50.0)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  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>
2024-03-01 04:45:43 +00:00
dependabot[bot] 6d7537d3ec
Bump itertools from 0.11.0 to 0.12.1 (#2880)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.11.0 to 0.12.1.
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.11.0...v0.12.1)

---
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>
2024-03-01 04:29:33 +00:00
dependabot[bot] b30ec9f975
Bump git2 from 0.18.1 to 0.18.2 (#2877)
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.18.1 to 0.18.2.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.18.1...git2-0.18.2)

---
updated-dependencies:
- dependency-name: git2
  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>
2024-03-01 04:10:37 +00:00
dependabot[bot] a7074f10d4
Bump plist from 1.5.1 to 1.6.0 (#2875)
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.5.1...v1.6.0)

---
updated-dependencies:
- dependency-name: plist
  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>
2024-03-01 03:44:56 +00:00
David Peter d185f0973b
Merge pull request #2874 from cyqsimon/wg
Add syntax mapping for Wireguard config
2024-02-29 11:09:31 +01:00
cyqsimon 071874ea8f
Write changelog 2024-02-29 14:34:00 +08:00
cyqsimon 46a2c004a2
Add syntax mapping for Wireguard config 2024-02-29 14:25:20 +08:00
cyqsimon 26ac179548
Add note on thread synchronization 2024-02-26 11:31:30 +08:00
Lena 4c85483486 Inline `format!` args wherever possible 2024-02-25 00:38:11 +01:00
einfachIrgendwer0815 487bed2d95
Change CONTRIBUTING.md according to new changelog requirements (#2839)
* Mention changelog requirements in CONTRIBUTING

* Refer to CONTRIBUTING in changelog workflow

* Clarify when changelog entries are necessary

---------

Co-authored-by: Martin Nordholts <martin.nordholts@codetale.se>
2024-02-24 23:58:20 +01:00
David Peter 6f69682552
Merge pull request #2665 from einfachIrgendwer0815/feature_squeeze
Add `-s`/`--squeeze` and `--squeeze-limit` (based on #1441).
2024-02-24 20:36:17 +01:00
David Peter bc5beaec5d
Update CHANGELOG.md 2024-02-24 20:36:08 +01:00
einfachIrgendwer0815 83b00bc653
Rename `--squeeze` to `--squeeze-blank` 2024-02-24 14:02:27 +01:00
einfachIrgendwer0815 f041ff8c5f
Hide `--squeeze-limit` from short help 2024-02-24 13:57:44 +01:00
einfachIrgendwer0815 1fbdbfc4b2
Update CHANGELOG 2024-02-24 13:52:40 +01:00
einfachIrgendwer0815 2323aa0def
Add tests for `--squeeze` 2024-02-24 13:51:44 +01:00
einfachIrgendwer0815 6c2ce63101
Add squeeze functionality to `SimplePrinter` 2024-02-24 13:51:44 +01:00
einfachIrgendwer0815 13204c46e2
Update short-help/long-help 2024-02-24 13:51:43 +01:00
Ethan P 9bb0271e7d
Update CHANGELOG.md (PR #1441) 2024-02-24 13:51:40 +01:00
Ethan P 0e4e10edb6
Add --squeeze-limit to specify max number of consecutive empty lines
Co-authored-by: einfachIrgendwer0815 <85333734+einfachIrgendwer0815@users.noreply.github.com>
2024-02-24 13:51:06 +01:00
Ethan P 0c7e5299bf
Add squeeze_empty_lines to PrettyPrinter 2024-02-24 13:51:05 +01:00
Ethan P c36ed32816
Add --squeeze/-s option
Co-authored-by: einfachIrgendwer0815 <85333734+einfachIrgendwer0815@users.noreply.github.com>
2024-02-24 13:51:00 +01:00
David Peter e1a3fc5529
Merge pull request #2857 from eth-p/skip-highlighting-when-no-color
Skip syntax parsing when color is not being output.
2024-02-23 21:59:45 +01:00
David Peter 1ae9e843ed
Merge branch 'master' into skip-highlighting-when-no-color 2024-02-23 21:59:32 +01:00
David Peter dbe4cfb763
Merge pull request #2866 from cyqsimon/quadlet
Add syntax mapping for podman quadlets
2024-02-23 21:54:44 +01:00
David Peter 4549f83689
Merge branch 'master' into quadlet 2024-02-23 21:54:36 +01:00
David Peter e6e8f847be
Merge pull request #2865 from cyqsimon/syntax-mapping-fix
Relax syntax mapping rule restrictions to allow brace expansion
2024-02-23 21:52:55 +01:00
David Peter b9e249f782
Merge branch 'master' into syntax-mapping-fix 2024-02-23 21:52:46 +01:00
David Peter 3ffa3648cf
Merge pull request #2853 from einfachIrgendwer0815/document_default_style_components
Document default style components
2024-02-23 21:51:55 +01:00
David Peter 5c2cc53882
Merge pull request #2867 from cyqsimon/containers-conf
Map containers `.conf` files to TOML syntax
2024-02-23 21:50:55 +01:00
David Peter a6f01af8de
Merge branch 'master' into containers-conf 2024-02-23 21:50:35 +01:00
David Peter 85a549e293
Merge pull request #2840 from anki-code/master
Added xonsh shell support
2024-02-23 21:48:58 +01:00
David Peter b718889ba2
Merge branch 'master' into master 2024-02-23 21:48:44 +01:00
David Peter 708c74f6af
Merge pull request #2795 from mxaddict/master
Added JSONC and aws credentials to the syntax mappings
2024-02-23 21:48:20 +01:00
David Peter 74d666f5c0
Merge branch 'master' into skip-highlighting-when-no-color 2024-02-23 21:45:38 +01:00
David Peter 7604fe5567
Merge pull request #2807 from Oliver-Looney/2783-setting-terminal-title
2783 setting terminal title
2024-02-23 21:37:28 +01:00
David Peter 0080b043c4
Merge branch 'master' into master 2024-02-23 21:35:21 +01:00
cyqsimon c7bce46622
Write changelog 2024-02-21 15:24:36 +08:00
cyqsimon 2b4339663c
Builtin glob matchers build offload, v2 2024-02-21 14:56:37 +08:00
cyqsimon 6a6b02117b
Apply clippy fixes (#2864)
* Apply clippy fixes

* Write changelog
2024-02-20 19:39:22 +01:00
cyqsimon 511cd30105
Write changelog 2024-02-21 00:26:23 +08:00
cyqsimon 92915e22e7
Map containers `.conf` files to TOML syntax 2024-02-21 00:25:06 +08:00
cyqsimon d499191b0a
Write changelog 2024-02-20 14:54:43 +08:00
cyqsimon 152d69fe98
Add syntax mapping for podman quadlets 2024-02-20 14:49:12 +08:00
cyqsimon 81aa24310c
Write changelog 2024-02-20 14:33:02 +08:00
cyqsimon 75cdabaf13
Relax syntax mapping rule restrictions to allow brace expansion 2024-02-20 14:24:51 +08:00
Oliver Looney 1f628203e5
Merge branch 'master' into 2783-setting-terminal-title 2024-02-12 09:34:01 +00:00
David Peter 1b9fc1d5af
Merge pull request #2856 from eth-p/fix-2185
Fix incorrect categorization of ANSI SGR sequences.
2024-02-12 08:32:47 +01:00
David Peter bc1ca1a346
Merge branch 'master' into fix-2185 2024-02-12 08:19:56 +01:00
David Peter f735120978
Merge pull request #2854 from eth-p/fix-line-number-wrap-off-by-one
Fix off-by-one error in line number continuation
2024-02-12 08:19:34 +01:00
Ethan P. 25b5a41189
Skip syntax parsing when color output disabled 2024-02-11 22:49:49 -08:00
Ethan P. c94cf4e14e
Split syntax highlighting from print_line into fn
This simplifies the `print_line` function a little bit while also
providing a way for syntax highlighting to be skipped when it's
not being used (i.e. `--color=never`).
2024-02-11 22:27:35 -08:00
Ethan P. 84d80eebd0
Test for correct categorization of SGR sequences
This adds a regression test for the fix in the previous commit.
2024-02-11 19:40:29 -08:00
Ethan P. 915dd9fbf8
Fix incorrect categorization of SGR sequences
Specifically, prevent other attributes from leaking into the
bold/dim/italic/underline attributes, and ensure that bright backgrounds
are put into the background attribute instead of the foreground
attribute.
2024-02-11 19:35:54 -08:00
Ethan P. 9d77c1373c
Fix off-by-one error in line number continuation 2024-02-11 16:49:06 -08:00
Oliver Looney c3f2ddf509
Merge branch 'master' into 2783-setting-terminal-title 2024-02-11 22:53:48 +00:00
Oliver looney 8a51172b11
simplified basic_set_terminal_title 2024-02-11 22:43:07 +00:00
einfachIrgendwer0815 875046e4cd
Mention which style components are the default 2024-02-11 10:06:01 +01:00
mxaddict a5bd9f51be Added JSONC and aws credentials to the syntax mappings 2024-02-11 04:57:42 +08:00
Ethan P 5a2a20af42
Merge pull request #2544 from eth-p/fix-2541
Treat OSC ANSI Sequences as Invisible Text & Add OSC 8 Support
2024-02-09 22:20:30 -08:00
Ethan P 61029c8bd2
Update changelog for fix of ANSI OSC sequences 2024-02-09 22:09:40 -08:00
Ethan P 1023399c5e
Remove hyperlink when wrapping lines 2024-02-09 22:09:39 -08:00
Ethan P 6549e26f5d
Re-emit hyperlinks when wrapping lines 2024-02-09 22:09:39 -08:00
Ethan P 165c495e75
Replace AnsiCodeIterator in printer.rs
This uses the new EscapeSequenceIterator, saving us a preprocessing step
for each line.
2024-02-09 22:09:39 -08:00
Ethan P 6b9b085be3
Add EscapeSequenceIterator
This is an iterator for escape sequences, using
EscapeSequenceOffsetsIterator for the underlying parsing of individual
escape sequences.
2024-02-09 22:09:39 -08:00
Ethan P 2d46d54ae3
Add tests for re-emitting SGR sequences on wrap 2024-02-09 22:09:39 -08:00
Ethan P 3d04699710
Add regression test for #2541
More specifically, the test ensures that OSC sequences don't end up
wrapping the line.
2024-02-09 22:09:39 -08:00
Ethan P 054421268f
Strip OSC sequences before printing
This commit strips OSC (Operating System Command) sequences before
printing lines. Eventually when time permits, I want to add back
support for printing OSC sequences (and improve it to treat hyperlinks
like an attribute).

Until then, this should help prevent garbled output :)
2024-02-09 22:09:39 -08:00
Ethan P 414403b062
Add EscapeSequenceOffsetsIterator
This can be used to extract a subset of ANSI escape sequences from a
string of text. I have big plans for this eventually, but for now, it'll
be used to strip OSC before printing.
2024-02-09 22:09:35 -08:00
Ethan P c29bf2ff28 Update git2 dependency 2024-02-09 22:05:30 -08:00
David Peter ab4e5ed52e
Merge pull request #2815 from dtolnay-contrib/derive
Eliminate dependency on serde's "derive" feature
2024-02-09 08:21:21 +01:00
David Tolnay 1a54c9bf6d
Eliminate dependency on serde's "derive" feature 2024-02-08 15:55:30 -08:00
Oliver looney 02077db53e
undid unnecessary api visibility changes 2024-02-08 21:41:20 +00:00
Oliver looney 7ce010d9ed
Using hypens instead of underscores for set-terminal-title command 2024-02-08 21:33:03 +00:00
dependabot[bot] 95993cf37e
Bump assets/syntaxes/02_Extra/cmd-help from `b150d84` to `209559b` (#2841)
Bumps [assets/syntaxes/02_Extra/cmd-help](https://github.com/victor-gp/cmd-help-sublime-syntax) from `b150d84` to `209559b`.
- [Commits](b150d84534...209559b72f)

---
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>
2024-02-08 07:54:17 +00:00
David Peter 3761df9112
Merge pull request #2849 from eth-p/readme-less-options-explained
Clarify when/how default args are added to less.
2024-02-08 08:29:20 +01:00
Ethan P. adfaef19da
Clarify when/how default args are added to less 2024-02-07 21:22:08 -08:00
dependabot[bot] f7bea6de5b
Bump clircle from 0.4.0 to 0.5.0 (#2845)
Bumps [clircle](https://github.com/niklasmohrin/clircle) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/niklasmohrin/clircle/releases)
- [Commits](https://github.com/niklasmohrin/clircle/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: clircle
  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>
2024-02-01 05:00:25 +00:00
dependabot[bot] 65aae5d0a1
Bump toml from 0.8.6 to 0.8.9 (#2844)
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.6 to 0.8.9.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.6...toml-v0.8.9)

---
updated-dependencies:
- dependency-name: toml
  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>
2024-02-01 04:43:10 +00:00
dependabot[bot] e3866b1f7e
Bump indexmap from 2.1.0 to 2.2.2 (#2847)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.1.0 to 2.2.2.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.1.0...2.2.2)

---
updated-dependencies:
- dependency-name: indexmap
  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>
2024-02-01 04:25:19 +00:00
dependabot[bot] 23de8e093b
Bump semver from 1.0.20 to 1.0.21 (#2843)
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.20...1.0.21)

---
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>
2024-02-01 04:05:59 +00:00
dependabot[bot] 196a4cb18f
Bump assets/themes/zenburn from `e627f1c` to `86d4ee7` (#2842)
Bumps [assets/themes/zenburn](https://github.com/colinta/zenburn) from `e627f1c` to `86d4ee7`.
- [Commits](e627f1cb22...86d4ee7a1f)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 03:15:26 +00:00
Andy Kipp 695cf1f387
Update CHANGELOG.md 2024-01-31 14:12:00 +01:00
Andy Kipp 0af1df5258
Create xonsh.toml 2024-01-31 14:07:56 +01:00
Oliver looney a8d07333e9
updated integration_tests.rs 2024-01-30 19:29:28 +00:00
Oliver looney 7f12989127
added set_terminal_title arg to clap_app.rs to fix ci errors 2024-01-29 09:47:41 +00:00
Oliver looney 60e32cf823
removed set_terminal_title arg from clap_app.rs since other boolean args aren't in clap_app.rs 2024-01-27 14:46:13 +00:00
Oliver looney e9a6aaa30f
cargo fmt 2024-01-27 14:44:54 +00:00
Oliver looney 9be2a36a01
fixed system wide config tests failing 2024-01-27 14:38:09 +00:00
Oliver looney 22254936a2
ran cargo fmt 2024-01-27 14:32:34 +00:00
Oliver looney f6d76e0104
added integration test for setting terminal title 2024-01-27 14:31:28 +00:00
Oliver looney c911829771
fixed failing tests 2024-01-27 14:23:24 +00:00
Oliver looney b33e33fe26
terminal title is only set if user opts in with --set_terminal_title flag 2024-01-27 14:17:25 +00:00
Oliver looney 9239b125b1
added a flag to config for setting terminal title 2024-01-27 14:14:40 +00:00
David Peter 2086cd2668
Merge pull request #2835 from FilipRazek/fix-long-file-names
fix: Wrap file name in header
2024-01-21 20:17:34 +01:00
Filip Razek 1b88267320 Ensure test succeeds by adding flag 2024-01-21 19:48:26 +01:00
Filip Razek e586751208 Attempt to fix integration test 2024-01-21 19:48:26 +01:00
Filip Razek e7256a624b Refer to PR instead of issue in CHANGELOG 2024-01-21 19:48:26 +01:00
Filip Razek 5c1f47359e Run cargo fmt 2024-01-21 19:48:26 +01:00
Filip Razek 45ee2dc4c7 fix: Wrap file name in header 2024-01-21 19:48:26 +01:00
David Peter db66e4459b
Merge pull request #2755 from cyqsimon/syntax-mapping-refactor
More extensible syntax mapping mechanism
2024-01-21 19:43:24 +01:00
cyqsimon 55e02e101d
Apply review suggestions to benchmark script 2024-01-22 00:25:23 +08:00
cyqsimon 230abfd2bc
Merge branch 'master' into syntax-mapping-refactor 2024-01-19 15:18:48 +08:00
cyqsimon c0f2d6f934
Add note on subdirectory's irrelevance to ordering 2024-01-18 23:26:00 +08:00
cyqsimon 9f36a7a284
Minor codestyle improvements 2024-01-18 23:07:11 +08:00
cyqsimon e4d637a3d8
Reverse precedence of syntax mappings specified on CLI 2024-01-18 22:41:57 +08:00
rhysd 98a2b6bc17 Update changelog 2024-01-17 22:00:29 +01:00
rhysd 8e66bc8722 Make the error handler `FnMut` 2024-01-17 22:00:29 +01:00
dependabot[bot] cd81c7fa6b
Bump assets/syntaxes/02_Extra/SublimeJQ from `6870582` to `b7e53e5` (#2820)
* Bump assets/syntaxes/02_Extra/SublimeJQ from `6870582` to `b7e53e5`

Bumps [assets/syntaxes/02_Extra/SublimeJQ](https://github.com/zogwarg/SublimeJQ) from `6870582` to `b7e53e5`.
- [Commits](687058289c...b7e53e5d86)

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

Signed-off-by: dependabot[bot] <support@github.com>

* update highlighted version of sample.jq

* update changelog

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Keith Hall <kingkeith+github@gmail.com>
2024-01-03 14:16:33 +00:00
Oliver Looney b4fdb5dc36
Merge branch 'master' into 2783-setting-terminal-title 2024-01-01 09:45:53 +00:00
dependabot[bot] c76ed99db2
Bump once_cell from 1.18.0 to 1.19.0 (#2826)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.18.0 to 1.19.0.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.0)

---
updated-dependencies:
- dependency-name: once_cell
  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>
2024-01-01 04:50:36 +00:00
dependabot[bot] 06aef22943
Bump home from 0.5.5 to 0.5.9 (#2823)
Bumps [home](https://github.com/rust-lang/cargo) from 0.5.5 to 0.5.9.
- [Changelog](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cargo/commits)

---
updated-dependencies:
- dependency-name: home
  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>
2024-01-01 04:37:23 +00:00
dependabot[bot] 128b0d6dd3
Bump thiserror from 1.0.50 to 1.0.53 (#2825)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.50 to 1.0.53.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.50...1.0.53)

---
updated-dependencies:
- dependency-name: thiserror
  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>
2024-01-01 04:24:27 +00:00
dependabot[bot] 15dc20109f
Bump clap from 4.4.10 to 4.4.12 (#2824)
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.10 to 4.4.12.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.10...v4.4.12)

---
updated-dependencies:
- dependency-name: clap
  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>
2024-01-01 04:10:40 +00:00
dependabot[bot] 5c4bcd6611
Bump anyhow from 1.0.75 to 1.0.78 (#2822)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.75 to 1.0.78.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.75...1.0.78)

---
updated-dependencies:
- dependency-name: anyhow
  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>
2024-01-01 03:52:33 +00:00
Keith Hall ecf4029dc7
Merge pull request #2819 from victor-gp/bump-cmd-help-syntax-b150d84
Bump cmd-help syntax to `b150d84`
2024-01-01 05:22:23 +02:00
Oliver looney c261b41578
trying to fix failing system_wide_config.rs tests 2023-12-31 22:44:17 +00:00
Oliver Looney 6f1cc80d68
Merge branch 'master' into 2783-setting-terminal-title 2023-12-31 22:25:25 +00:00
Oliver looney 3b0ade9cb8
slightly changed set terminal command to match docs & broke print line into multiple variables 2023-12-31 22:24:44 +00:00
Oliver looney 57016f4e04
small refactoring of set terminal title function 2023-12-31 22:15:00 +00:00
Víctor González Prieto 497342fabb Bump cmd-help syntax to latest
Manual update (as opposed to Dependabot's) because the highlighting for
the test help message has changed. It's all good because it's as
intended, an improvement.

See victor-gp/cmd-help-sublime-syntax#23
2023-12-29 18:15:55 +01:00
David Tolnay bf56cd90f0 Eliminate dependency on syn v1 by updating git-version 2023-12-29 08:37:11 +01:00
David Tolnay 0acb979e9e Pull in fix for unsafe-libyaml security advisory 2023-12-28 23:01:55 +01:00
Oliver Looney d7503bfc09
Merge branch 'master' into 2783-setting-terminal-title 2023-12-27 16:14:04 +00:00
Martin Nordholts b89dc15be1 Use proper Architecture for Debian packages built for musl
New values taken from

    dpkg-architecture -L
2023-12-27 17:03:40 +01:00
cyqsimon 15ab4478c9
Reduce unnecessary build deps 2023-12-22 19:55:49 +08:00
Oliver looney 5b4ce684a1
ran cargo fmt 2023-12-18 17:47:09 +00:00
Oliver looney 0027055a83
fixed system_wide_config.rs tests 2023-12-18 17:44:52 +00:00
Oliver looney 321b3ec81b
updated CHANGELOG.md 2023-12-18 17:38:11 +00:00
Oliver looney 1679460f42
updated CHANGELOG.md 2023-12-18 17:32:08 +00:00
Oliver looney 907af9e35f
updated tests since terminal title is set conditionally 2023-12-18 17:27:51 +00:00
Oliver looney 12b74dfb4e
terminal title is only set when pager is being used 2023-12-18 16:59:12 +00:00
Oliver looney fd84e4f49f
fixed all but two failing tests. Last two tests are erroring because of IO circle detected error 2023-12-11 19:09:48 +00:00
cyqsimon f0a6fe216d
Benchmark prototype 2023-12-11 10:38:59 +08:00
cyqsimon d792dc5804
Move `rusty-fork` to dev-dependencies 2023-12-11 10:21:07 +08:00
cyqsimon 8a08025091
Disable `builtin_mappings_are_lazily_evaluated` for ARM builds 2023-12-11 10:21:06 +08:00
cyqsimon 586c804b1e
Add test: `builtin_mappings_are_lazily_evaluated` 2023-12-11 10:21:06 +08:00
cyqsimon e30161ac3c
Add test: `builtin_mappings_matcher_only_compile_once` 2023-12-11 10:21:06 +08:00
cyqsimon 3865908439
Add test: `custom_mappings_precedence` 2023-12-11 10:21:06 +08:00
cyqsimon 9474b4cf8b
Rename & sort syntax mapping tests 2023-12-11 10:21:06 +08:00
cyqsimon b48bda21a3
Add test: `all_fixed_builtin_mappings_can_compile` 2023-12-11 10:21:06 +08:00
cyqsimon daf33709a0
Additional sanity check for matcher parser 2023-12-11 10:21:06 +08:00
cyqsimon 36073a3d95
Document another rule ignore condition 2023-12-11 10:21:06 +08:00
cyqsimon 12fa2cb1eb
`-` is not a legal character in variable name 2023-12-11 10:21:06 +08:00
cyqsimon 1f10d846a3
Fix tests
1. for override test, test for something in `common`
2. move git mappings to `common`
2023-12-11 10:21:05 +08:00
cyqsimon 22531eab90
Port all mappings to new system 2023-12-11 10:21:05 +08:00
cyqsimon 0c1b80faab
Impl per-target syntax mappings 2023-12-11 10:21:05 +08:00
cyqsimon 2c9bf229e1
Add doc comment for `BUILTIN_MAPPINGS` 2023-12-11 10:21:05 +08:00
cyqsimon 822e81bb24
Suppress clippy warning for `MappingTarget` in build script 2023-12-11 10:21:05 +08:00
cyqsimon ad628c0471
Fix iterator lifetime incompatibility 2023-12-11 10:21:05 +08:00
cyqsimon f483d2df42
Lazily compile `GlobMatcher`s 2023-12-11 10:21:05 +08:00
cyqsimon 4ad3002543
`s/Lazy<GlobMatcher>/Lazy<Option<GlobMatcher>>/` 2023-12-11 10:21:05 +08:00
cyqsimon cfd622d6e1
Migrate `SyntaxMapping` impl to new system
Most existing builtins are removed but not yet ported, so the test
`user_can_override_builtin_mappings` should fail. It should pass once the old
rules have been ported.
2023-12-11 10:21:05 +08:00
cyqsimon 1c7c9a6b6d
Split `syntax_mapping/builtin.rs` 2023-12-11 10:21:05 +08:00
cyqsimon 0c93ca80f4
Guard against duplicate matchers in build script 2023-12-11 10:21:04 +08:00
cyqsimon de6d418d42
Remove `BuiltinMatcher` enum
Explanation added as comments in code
Using plain `Lazy<Option<GlobMatcher>>` is just better
2023-12-11 10:21:04 +08:00
cyqsimon c016b462c0
`STATIC_RULES` => `BUILTIN_MAPPINGS` 2023-12-11 10:21:04 +08:00
cyqsimon 7e1fbcfe95
Fix visibility for `SyntaxMapping::get_syntax_for`
This change was made in 31fb708, but then was reverted (I assume incorrectly)
in 6246485.
2023-12-11 10:21:04 +08:00
cyqsimon 4815b6155e
Write changelog 2023-12-11 10:21:03 +08:00
cyqsimon 075b5b288a
Matcher parser errors when empty 2023-12-11 10:20:12 +08:00
cyqsimon 7cfd1e0d78
Rerun build script only when necessary 2023-12-11 10:20:12 +08:00
cyqsimon 9f7d70f642
Use regex for matcher parsing
- Somewhat better maintainability I think
2023-12-11 10:20:12 +08:00
cyqsimon 0fea82cff9
Minor improvement of variable naming accuracy 2023-12-11 10:20:11 +08:00
cyqsimon 64840fbbae
`join_segments` -> `build_glob_string`
- this is a more descriptive name
2023-12-11 10:20:11 +08:00
cyqsimon 827b3eca2f
Add unset `*.conf` example 2023-12-11 10:20:11 +08:00
cyqsimon 9478d2dfe8
Isolate variables at compile time 2023-12-11 10:20:11 +08:00
cyqsimon d24501ab5e
`include!` generated mappings in source 2023-12-11 10:20:11 +08:00
cyqsimon 9f4259721a
Fix codegen type declaration 2023-12-11 10:20:11 +08:00
cyqsimon 77e491161c
Ensure lexicographical ordering 2023-12-11 10:20:10 +08:00
cyqsimon 97780f987e
`MappingDefModel::into_mapping_list` returns `MappingList` 2023-12-11 10:20:10 +08:00
cyqsimon d1bc0ef0d4
Build script codegen initial impl 2023-12-11 10:20:10 +08:00
cyqsimon 52f94b4623
Clarify syntax selection algorithm behaviour 2023-12-11 10:20:10 +08:00
cyqsimon 37fd050100
Describe filename ordering more accurately 2023-12-11 10:20:10 +08:00
cyqsimon 83286975ff
Add ordering prefix to git-config example 2023-12-11 10:20:10 +08:00
cyqsimon f705fcb984
Add global git-config example 2023-12-11 10:20:10 +08:00
cyqsimon 9ca1f20f43
Add specification draft 2023-12-11 10:20:10 +08:00
Oliver looney 6ad800e43a
tidied commits 2023-12-10 17:24:49 +00:00
Oliver looney 069318b139
fixed formatting of terminal title 2023-12-10 17:20:42 +00:00
Oliver looney b9b554248d
successfully setting the terminal title to bat's input's names 2023-12-10 17:17:19 +00:00
Oliver looney 4863d428dd
title is being reset on quit, so no need to restore terminal title 2023-12-10 16:44:47 +00:00
Oliver looney 2e103ee6b3
able to set terminal title to hardcoded value 2023-12-10 16:39:34 +00:00
Lena 28990bc451
fix: display color when NO_COLOR is an empty string (#2767) 2023-12-02 11:43:55 +00:00
cyqsimon 748e2a681f Add `columns=3` to repology badge 2023-12-01 21:39:25 +01:00
Broono Lu bfa0b5241f
Update Arch Linux package URL in README files (#2779) 2023-12-01 21:26:35 +01:00
Oliver looney 4af4bfc0f1 fixed syntax typo in russian readme 2023-12-01 20:59:52 +01:00
cyqsimon 51203ff750
Use GitHub API to get correct PR submitter (#2791) 2023-12-01 11:18:10 +00:00
dependabot[bot] 96cef9a24e
Bump assets/themes/zenburn from `43dc527` to `e627f1c` (#2790)
Bumps [assets/themes/zenburn](https://github.com/colinta/zenburn) from `43dc527` to `e627f1c`.
- [Commits](43dc527731...e627f1cb22)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 10:38:36 +00:00
Oliver Kiddle b43d31b75a Improvements and fixes to zsh completion
* Use correct return status so that approximate completion isn't broken
* Follow zsh conventions on description forms
* Some options can be used multiple times, e.g. -H, -r, --file-name
* Set completion context correctly for the cache subcommand
* Better completion for --map-syntax argument
* Add --nonprintable-notation option
* Correct some of the mutual exclusion lists for options
2023-12-01 11:11:44 +01:00
dependabot[bot] ad3ff26960
Bump serde from 1.0.190 to 1.0.193 (#2788)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.193.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.193)

---
updated-dependencies:
- dependency-name: serde
  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>
2023-12-01 04:15:35 +00:00
dependabot[bot] 86b40993c3
Bump grep-cli from 0.1.9 to 0.1.10 (#2789)
Bumps [grep-cli](https://github.com/BurntSushi/ripgrep) from 0.1.9 to 0.1.10.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/grep-cli-0.1.9...0.1.10)

---
updated-dependencies:
- dependency-name: grep-cli
  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>
2023-12-01 04:01:10 +00:00
dependabot[bot] 31bed250ba
Bump clap from 4.4.6 to 4.4.10 (#2786)
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.6 to 4.4.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.6...v4.4.10)

---
updated-dependencies:
- dependency-name: clap
  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>
2023-12-01 03:44:01 +00:00
Cosmic Horror 7658334645 Consider adding `?exclude_unsupported=1` to repology badge 2023-11-10 09:00:28 +01:00
cyqsimon 491ae70aa9 Write changelog 2023-11-06 06:02:59 +01:00
cyqsimon d64c568196 Allow overriding `{WARMUP,RUN}_COUNT` using env 2023-11-06 06:02:59 +01:00
cyqsimon b5982a6174 Allow setting number of runs in `run-benchmarks.sh` 2023-11-06 06:02:59 +01:00
Maria José Solano 04e7d2a313 fix(completions): add missing fish completions 2023-11-04 08:51:13 +01:00
cyqsimon bcc2de86b4
CI: add changelog check (#2766)
* Added changelog item check

Fetch the base branch and diff correctly

- See: https://github.com/actions/checkout/issues/160

Improve organisation

Add some echo for easier debugging

Fix bad variable syntax

Clarify the double-print in the success case

* Write to changelog

* Don't block dependabot PRs
2023-11-03 08:53:29 +01:00
cyqsimon 1296aea836 Write changelog for #2756
- I always forget to write changelog.
2023-11-03 06:25:18 +01:00
cyqsimon 5498c24c33 Rerun build script only when necessary 2023-11-02 17:54:57 +01:00
cyqsimon 79a03b4299 Reorganise build script into modules 2023-11-02 17:54:57 +01:00
cyqsimon f3a5e9a73c Use implicit format string capture syntax 2023-11-02 17:54:57 +01:00
cyqsimon 2710a19ecb Immutably construct variables map 2023-11-02 17:54:57 +01:00
cyqsimon 6d0ef259f6 Read env in build script at runtime 2023-11-02 17:54:57 +01:00
cyqsimon b1577cc083 Reorganise functions in build script 2023-11-02 17:54:57 +01:00
cyqsimon 28d947fd8b Use anyhow in build script 2023-11-02 17:54:57 +01:00
cyqsimon b000db8f32 Remove old completion generation code 2023-11-02 17:54:57 +01:00
dependabot[bot] 116a6cc9a8
Bump thiserror from 1.0.49 to 1.0.50 (#2758)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.49 to 1.0.50.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.49...1.0.50)

---
updated-dependencies:
- dependency-name: thiserror
  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>
2023-11-01 04:58:49 +00:00
dependabot[bot] c8291a36b7
Bump serde from 1.0.189 to 1.0.190 (#2760)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190)

---
updated-dependencies:
- dependency-name: serde
  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>
2023-11-01 04:39:45 +00:00
dependabot[bot] 8180c76890
Bump plist from 1.5.0 to 1.5.1 (#2759)
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: plist
  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>
2023-11-01 04:20:25 +00:00
dependabot[bot] a0f33b1cdc
Bump globset from 0.4.10 to 0.4.13 (#2761)
Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.10 to 0.4.13.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/globset-0.4.10...globset-0.4.13)

---
updated-dependencies:
- dependency-name: globset
  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>
2023-11-01 03:53:53 +00:00
dependabot[bot] 8b60dae81c
Bump tempfile from 3.8.0 to 3.8.1 (#2757)
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.8.0 to 3.8.1.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

---
updated-dependencies:
- dependency-name: tempfile
  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>
2023-11-01 03:26:48 +00:00
cyqsimon 4b33093f9e
Bump edition to 2021 (#2748) 2023-10-31 04:54:06 +01:00
einfachIrgendwer0815 3d87b25b19
Add unicode/caret replacements for all control characters (#2712) 2023-10-20 19:41:48 +02:00
dependabot[bot] f2f6902279
Bump syntect from 5.0.0 to 5.1.0 (#2742)
Bumps [syntect](https://github.com/trishume/syntect) from 5.0.0 to 5.1.0.
- [Release notes](https://github.com/trishume/syntect/releases)
- [Changelog](https://github.com/trishume/syntect/blob/master/CHANGELOG.md)
- [Commits](https://github.com/trishume/syntect/compare/v5.0.0...v5.1.0)

---
updated-dependencies:
- dependency-name: syntect
  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>
2023-10-19 06:43:09 +00:00
dependabot[bot] c0b17e73e1
Bump assert_cmd from 2.0.10 to 2.0.12 (#2741)
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 2.0.10 to 2.0.12.
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v2.0.10...v2.0.12)

---
updated-dependencies:
- dependency-name: assert_cmd
  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>
2023-10-19 06:21:55 +00:00
dependabot[bot] 94544d963b
Bump console from 0.15.5 to 0.15.7 (#2743)
Bumps [console](https://github.com/console-rs/console) from 0.15.5 to 0.15.7.
- [Changelog](https://github.com/console-rs/console/blob/master/CHANGELOG.md)
- [Commits](https://github.com/console-rs/console/compare/0.15.5...0.15.7)

---
updated-dependencies:
- dependency-name: console
  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>
2023-10-19 05:54:24 +00:00
dependabot[bot] 72abbd22de
Bump regex from 1.9.4 to 1.10.2 (#2740)
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.4 to 1.10.2.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.9.4...1.10.2)

---
updated-dependencies:
- dependency-name: regex
  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>
2023-10-19 05:26:40 +00:00
dependabot[bot] 64e10ffb21
Bump semver from 1.0.17 to 1.0.20 (#2739)
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.17 to 1.0.20.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.17...1.0.20)

---
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>
2023-10-19 05:01:07 +00:00
Martin Nordholts 35d8146bba Revert "Temporarily change dependabot to daily"
This reverts commit 86ac48d68e.
2023-10-19 06:33:48 +02:00
Martin Nordholts a5a7ede698 release-checklist.md: Adapt to new auto-merge workflow 2023-10-18 21:33:44 +02:00
dependabot[bot] b551049706
Bump nix from 0.26.2 to 0.26.4 (#2736)
Bumps [nix](https://github.com/nix-rust/nix) from 0.26.2 to 0.26.4.
- [Changelog](https://github.com/nix-rust/nix/blob/v0.26.4/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.26.2...v0.26.4)

---
updated-dependencies:
- dependency-name: nix
  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>
2023-10-18 16:48:05 +00:00
dependabot[bot] 99cfc13eab
Bump serde from 1.0.163 to 1.0.189 (#2735)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.163 to 1.0.189.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.163...v1.0.189)

---
updated-dependencies:
- dependency-name: serde
  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>
2023-10-18 16:28:33 +00:00
dependabot[bot] 4b0b5afa13
Bump wild from 2.1.0 to 2.2.0 (#2734)
Bumps [wild](https://gitlab.com/kornelski/wild) from 2.1.0 to 2.2.0.
- [Commits](https://gitlab.com/kornelski/wild/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: wild
  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>
2023-10-18 16:06:35 +00:00
dependabot[bot] d343428441
Bump run_script from 0.10.0 to 0.10.1 (#2737)
Bumps [run_script](https://github.com/sagiegurari/run_script) from 0.10.0 to 0.10.1.
- [Release notes](https://github.com/sagiegurari/run_script/releases)
- [Changelog](https://github.com/sagiegurari/run_script/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sagiegurari/run_script/compare/0.10.0...0.10.1)

---
updated-dependencies:
- dependency-name: run_script
  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>
2023-10-18 15:43:17 +00:00
dependabot[bot] 16e409ec87
Bump walkdir from 2.3.3 to 2.4.0 (#2733)
Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.3.3 to 2.4.0.
- [Commits](https://github.com/BurntSushi/walkdir/compare/2.3.3...2.4.0)

---
updated-dependencies:
- dependency-name: walkdir
  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>
2023-10-18 15:11:17 +00:00
dependabot[bot] 94d059f258
Bump ansi_colours from 1.2.1 to 1.2.2 (#2729)
Bumps [ansi_colours](https://github.com/mina86/ansi_colours) from 1.2.1 to 1.2.2.
- [Commits](https://github.com/mina86/ansi_colours/compare/v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: ansi_colours
  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>
2023-10-17 16:07:49 +00:00
dependabot[bot] c8b9de889d
Bump thiserror from 1.0.40 to 1.0.49 (#2730)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.40 to 1.0.49.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.40...1.0.49)

---
updated-dependencies:
- dependency-name: thiserror
  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>
2023-10-17 15:42:03 +00:00
dependabot[bot] 75340d54f9
Bump flate2 from 1.0.27 to 1.0.28 (#2727)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.27 to 1.0.28.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.27...1.0.28)

---
updated-dependencies:
- dependency-name: flate2
  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>
2023-10-17 15:17:31 +00:00
dependabot[bot] b28383e0fa
Bump regex from 1.8.3 to 1.9.4 (#2726)
Bumps [regex](https://github.com/rust-lang/regex) from 1.8.3 to 1.9.4.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.8.3...1.9.4)

---
updated-dependencies:
- dependency-name: regex
  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>
2023-10-17 14:50:40 +00:00
dependabot[bot] 8e866db281
Bump actions/checkout from 3 to 4 (#2719)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  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>
2023-10-17 14:13:22 +00:00
dependabot[bot] 0eb157e090
Bump unicode-width from 0.1.10 to 0.1.11 (#2716)
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.10 to 0.1.11.
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.10...v0.1.11)

---
updated-dependencies:
- dependency-name: unicode-width
  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>
2023-10-17 06:48:32 +00:00
dependabot[bot] 85636c28bc
Bump predicates from 3.0.3 to 3.0.4 (#2717)
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 3.0.3 to 3.0.4.
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v3.0.3...v3.0.4)

---
updated-dependencies:
- dependency-name: predicates
  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>
2023-10-17 06:31:56 +00:00
dependabot[bot] a70e5c6c65
Bump os_str_bytes from 6.4.1 to 6.6.1 (#2720)
Bumps [os_str_bytes](https://github.com/dylni/os_str_bytes) from 6.4.1 to 6.6.1.
- [Release notes](https://github.com/dylni/os_str_bytes/releases)
- [Commits](https://github.com/dylni/os_str_bytes/compare/6.4.1...6.6.1)

---
updated-dependencies:
- dependency-name: os_str_bytes
  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>
2023-10-17 06:12:48 +00:00
dependabot[bot] 32e01f740b
Bump plist from 1.4.3 to 1.5.0 (#2718)
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.4.3 to 1.5.0.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.4.3...v1.5.0)

---
updated-dependencies:
- dependency-name: plist
  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>
2023-10-17 05:50:47 +00:00
dependabot[bot] 7b20f8fc7b
Bump git2 from 0.18.0 to 0.18.1 (#2715)
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.18.0 to 0.18.1.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.18.0...git2-0.18.1)

---
updated-dependencies:
- dependency-name: git2
  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>
2023-10-17 05:00:01 +00:00
Martin Nordholts 86ac48d68e Temporarily change dependabot to daily
So we can more easily test that auto-merge works as it should. Once we
have confirmed it does, we revert this commit.
2023-10-17 06:36:36 +02:00
Martin Nordholts c42fc810ea Setup auto-merge of dependabot PRs that pass CI 2023-10-17 06:18:51 +02:00
Martin Nordholts 6baebd79fa Add test for what jobs 'all-jobs' references 2023-10-13 05:24:25 +02:00
Martin Nordholts c6cae09f99 CHANGELOG.md: Add new unreleased section 2023-10-11 20:43:52 +02:00
Martin Nordholts fc9546854f Bump version to v0.24.0
We need to bump 0.x.0 because the library API changed in incompatible
ways:

    $ cargo public-api diff
    Resolved `diff` to `diff 0.23.0`
    Removed items from the public API
    =================================
    (none)

    Changed items in the public API
    ===============================
    -pub fn bat::controller::Controller<'b>::run(&self, inputs: alloc::vec::Vec<bat::input::Input<'_>>) -> bat::error::Result<bool>
    +pub fn bat::controller::Controller<'b>::run(&self, inputs: alloc::vec::Vec<bat::input::Input<'_>>, output_buffer: core::option::Option<&mut dyn core::fmt::Write>) -> bat::error::Result<bool>
    -pub fn bat::controller::Controller<'b>::run_with_error_handler(&self, inputs: alloc::vec::Vec<bat::input::Input<'_>>, handle_error: impl core::ops::function::Fn(&bat::error::Error, &mut dyn std::io::Write)) -> bat::error::Result<bool>
    +pub fn bat::controller::Controller<'b>::run_with_error_handler(&self, inputs: alloc::vec::Vec<bat::input::Input<'_>>, output_buffer: core::option::Option<&mut dyn core::fmt::Write>, handle_error: impl core::ops::function::Fn(&bat::error::Error, &mut dyn std::io::Write)) -> bat::error::Result<bool>

    Added items to the public API
    =============================
    [...]
2023-10-11 19:14:12 +02:00
Martin Nordholts 32da58e723 Update CHANGELOG.md for v0.24.0 2023-10-10 16:50:20 +02:00
Mészáros Máté Róbert 63aaa03013
Update the ssh-config submodule (#2697)
* Update the ssh-config submodule

Pull in the fix for the syntax.
Fixes #2359

* Extend the ssh_config syntax test
2023-10-10 06:16:41 +02:00
David Peter fbe9b6f15f
New warp text/subtext 2023-10-06 09:14:08 +02:00
David Peter c946ddb012 Replace warp logo 2023-10-06 09:11:06 +02:00
rhysd e5c81ed41e Replace our own macros to write buffers with standard macros 2023-10-05 09:21:26 +02:00
skoriop 0937d575fd fix: rewrite overflow test using `usize::MAX` 2023-10-05 09:20:09 +02:00
skoriop 4382be5e7c docs: update `CHANGELOG.md` 2023-10-05 09:20:09 +02:00
skoriop d89df18de2 test: add test for overflow in `LineRange::from` 2023-10-05 09:20:09 +02:00
skoriop 9fcc57e496 fix: integer overflow in `LineRange::parse_range` 2023-10-05 09:20:09 +02:00
Raghav-Bell 8e35a56712 Updated version of `serde_yaml` to 0.9 2023-10-04 12:42:01 +02:00
Linda_pp 9f795dd947
Associate `*.sarif` files with `json` syntax (#2695)
* Associate `*.sarif` files with `json` syntax

* Update changelog for #2695
2023-10-04 09:34:40 +02:00
dependabot[bot] 721f956c1c Bump once_cell from 1.17.0 to 1.18.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.17.0 to 1.18.0.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.17.0...v1.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 09:29:33 +02:00
dependabot[bot] db4cdc1cb8 Bump clap from 4.4.2 to 4.4.6
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.2 to 4.4.6.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.4.2...v4.4.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 09:29:26 +02:00
dependabot[bot] e455f93a1e Bump encoding_rs from 0.8.32 to 0.8.33
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.32 to 0.8.33.
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.32...v0.8.33)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 09:29:16 +02:00
rhysd d756d6f1ed Fix syntax tests failure on macOS during the daytime 2023-10-04 09:28:34 +02:00
rhysd 6568fb775d Explain how to convert `.tmLanguage.json` and `.tmLanguage.yml` files in doc/assets.md 2023-10-04 09:09:54 +02:00
rhysd d376a4b631 Add support for WGSL 2023-10-04 09:09:54 +02:00
dependabot[bot] 6e5fd36882 Bump flate2 from 1.0.26 to 1.0.27
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.26 to 1.0.27.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.26...1.0.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 09:04:23 +02:00
dependabot[bot] c7cc4b5c59 Bump bytesize from 1.2.0 to 1.3.0
Bumps [bytesize](https://github.com/hyunsik/bytesize) from 1.2.0 to 1.3.0.
- [Release notes](https://github.com/hyunsik/bytesize/releases)
- [Commits](https://github.com/hyunsik/bytesize/compare/v1.2.0...v1.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 09:04:09 +02:00
dependabot[bot] db76091a53 Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-04 08:59:52 +02:00
David Peter 506fe65474 Add Warp as a sponsor 2023-10-03 20:04:26 +02:00
Connor Sullivan 69c326fd41 Prefer shorter winget install 2023-09-30 00:14:59 +02:00
Connor Sullivan 466b275e87 [docs] Remove duplicate winget
Removes duplicate winget instructions for Windows install.
2023-09-30 00:14:59 +02:00
Dan Gohman 319c675f3e Fix a double-`close` in the `no_args_doesnt_break` test.
Fix the `no_args_doesnt_break` test to avoid calling `from_raw_fd` twice
on the same raw file descriptor, as that cause the file descriptor to be
closed twice, which means it could accidentally close some unrelated newly
created file descriptor.
2023-09-29 18:27:27 +02:00
Nicolas AMBRY 5a240f36b9
Case insensitive `--map-syntax` (#2650)
Co-authored-by: Nicolas AMBRY <nicolas.ambry@atos.net>
2023-09-14 16:04:43 +02:00
J-Kappes e2bf85e749
Make -pp override --paging and vice versa when passed as a later argument. (#2660) 2023-09-14 05:45:46 +02:00
Anomalocaridid fe73010a5e ignore failing test 2023-09-08 06:25:20 +02:00
Anomalocaridid 150c04acb6 update CHANGELOG.md 2023-09-08 06:25:20 +02:00
Anomalocaridid 433176ab54 require LESSOPEN to have exactly one %s 2023-09-08 06:25:20 +02:00
Anomalocaridid b56021ffa9 make LESSOPEN support opt-in 2023-09-08 06:25:20 +02:00
Anomalocaridid ac2953c070 pass --no-lessopen to less by default 2023-09-08 06:25:20 +02:00
Boy van Duuren d6e11b59e7
#2592: Fixes unit tests dependent on echo on windows (#2602)
Co-authored-by: Boy van Duuren <boy.van.duuren@rabobank.nl>
2023-09-08 06:18:25 +02:00
Martin Nordholts f49278cfaa Do not enable `lessopen` feature by default 2023-09-05 16:37:14 +02:00
pseudometa 9b73eda957 docs: add global `--help` alias limitations 2023-09-02 14:54:55 +02:00
pseudometa ed99a3a104 docs: Add better snippet for colorizing help pages 2023-09-02 14:54:55 +02:00
Anomalocaridid e32ad0b048
Add `$LESSOPEN` and `$LESSCLOSE` support (#2444) 2023-09-02 08:48:26 +02:00
David Peter 3abc0c0fc4
Merge pull request #2548 from utkarshgupta137/master
Replace `dirs` crate with `etcetera` crate
2023-09-01 21:41:24 +02:00
David Peter b06f13f0c5
Merge pull request #2618 from Piturnah/feat/write-to-buffer
feat: Optionally write to a buffer instead of stdout
2023-09-01 21:18:04 +02:00
Utkarsh Gupta a721cc31f3 Replace `dirs` crate with `etcetera` crate 2023-09-01 21:13:21 +02:00
David Peter 1e52785d35
Merge pull request #2626 from rhysd/encoding_rs
Replace unmaintained `encoding` dependency with `encoding_rs`
2023-09-01 21:12:07 +02:00
Orion Yeung 9ba3b6ed13
No duplicate keys test, fixes #2643 (#2647)
* moved unit tests to conditional compile

made module `tests` and conditionally compiled

* added test to check for duplicate keys in builtin

checks all pairs in GlobMatcher::mappings via `GlobMatcher::glob`s `Eq`
panics at first match

```rs
SyntaxMapping {
  mappings: Vec<(
    GlobMatcher {
      glob: Glob, ...,
    }, ...,
  }, ...,
}
```

* output more info with test failure

* dont duplicatively add git config path

* use guard in match for adding builtin git config syntax mapping

---------

Co-authored-by: Orion Yeung <11580988+orionyeung001@users.noreply.github.com>
2023-09-01 21:11:41 +02:00
Peter Hebden 72e1a40bab Remove leftover unwrap 2023-09-01 20:52:55 +02:00
Peter Hebden 33a89410d4 Add example to show new feature 2023-09-01 20:52:55 +02:00
Peter Hebden b2c28cdddb Clippy lints 2023-09-01 20:52:55 +02:00
Peter Hebden 906e774372 Handle todos 2023-09-01 20:52:55 +02:00
Peter Hebden d929becefc Fix signatures 2023-09-01 20:52:55 +02:00
Peter Hebden 103a2f0d9b Add `OutputHandle` enum to use instead of `&mut dyn io::Write` 2023-09-01 20:52:55 +02:00
rhysd d33b2e158e Replace unmaintained `encoding` with `encoding_rs` 2023-09-01 20:41:55 +02:00
David Peter d295b3a394
Merge pull request #2613 from sharkdp/dependabot/cargo/expect-test-1.4.1
Bump expect-test from 1.4.0 to 1.4.1
2023-09-01 20:09:30 +02:00
David Peter 81a217b1f3
Merge pull request #2519 from sitiom/winget-releaser
Add Winget Releaser workflow
2023-09-01 20:01:02 +02:00
dependabot[bot] bb17f74757 Bump assets/syntaxes/02_Extra/Docker from `9e9a518` to `0f6b7bc`
Bumps [assets/syntaxes/02_Extra/Docker](https://github.com/asbjornenge/Docker.tmbundle) from `9e9a518` to `0f6b7bc`.
- [Release notes](https://github.com/asbjornenge/Docker.tmbundle/releases)
- [Commits](9e9a518aed...0f6b7bc87a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 19:34:48 +02:00
dependabot[bot] 75928d20f8 Bump nu-ansi-term from 0.47.0 to 0.49.0
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.47.0 to 0.49.0.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.47.0...v0.49.0)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 19:32:30 +02:00
dependabot[bot] 2cc45eea1a Bump clap from 4.3.0 to 4.4.2
Bumps [clap](https://github.com/clap-rs/clap) from 4.3.0 to 4.4.2.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.3.0...v4.4.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 19:32:16 +02:00
dependabot[bot] 7dbc6e3da4 Bump tempfile from 3.5.0 to 3.8.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.5.0 to 3.8.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.5.0...v3.8.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 19:31:59 +02:00
dependabot[bot] f34b852aa8 Bump git2 from 0.16.1 to 0.18.0
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.16.1 to 0.18.0.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.16.1...git2-0.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 18:01:55 +02:00
einfachIrgendwer0815 4b04f901fe Add test for `BAT_PAGING` 2023-09-01 17:59:41 +02:00
einfachIrgendwer0815 26111950b3 Add environment variable `BAT_PAGING` 2023-09-01 17:59:41 +02:00
Orion Yeung f21d3502e1 Add `*.ron` syntax mapping
Add a mapping to use `Rust` for rusty object notation, identified by `.ron` extension. See [#2427](https://github.com/sharkdp/bat/issues/2427).
2023-09-01 17:57:46 +02:00
Maros Kukan 5687af8bc7 feat: describe WinGet method for Windows install 2023-09-01 17:53:26 +02:00
nazar 0f5f51f9ba Fixed RU readme typos 2023-09-01 17:51:30 +02:00
Jan T. Sott 32c0e1fb45 update highlighted test file 2023-09-01 17:50:30 +02:00
Jan T. Sott 34440f1b0c update highlighted test file 2023-09-01 17:50:30 +02:00
Jan T. Sott f1d6cc7a64 add test files for NSIS syntax 2023-09-01 17:50:30 +02:00
Jan T. Sott 628ba5d31f add NSIS support 2023-09-01 17:50:30 +02:00
dependabot[bot] e24150ca3f Bump assets/syntaxes/02_Extra/Julia from `4fde0fd` to `98233f9`
Bumps [assets/syntaxes/02_Extra/Julia](https://github.com/JuliaEditorSupport/Julia-sublime) from `4fde0fd` to `98233f9`.
- [Release notes](https://github.com/JuliaEditorSupport/Julia-sublime/releases)
- [Commits](4fde0fdedd...98233f96d4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 17:48:06 +02:00
WinterCore d580445aef fix: Add syntax mapping `jsonl` => `json` 2023-09-01 17:45:41 +02:00
Martin Nordholts 48dc2b0d90 CICD: Add `all-jobs` job
This opens up future possibilities:
* GitHub's auto-merge feature that merges a PR once CI passes
* Auto-merge of dependabot PRs that pass CI

But before we do any of that we need to have this new job active for a
while to see that it works.
2023-09-01 17:42:14 +02:00
mataha 82664e3c82 Bump MSRV to 1.70.0
The intention is to take advantage of `std::io::IsTerminal` that landed
in 1.70.0, both in `bat` and its dependencies (`clap`, `grep-cli`).

This will fix #2570 as well - `grep-cli` 0.1.9 has a patch for that.

Signed-off-by: mataha <mataha@users.noreply.github.com>
2023-09-01 05:42:45 +02:00
Ville Skyttä 1893405cbf Add .dpkg-new and .dpkg-tmp to ignored suffixes
Refs https://www.debian.org/doc/manuals/debian-handbook/sect.package-meta-information.en.html#sect.conffiles
2023-08-28 17:50:29 +02:00
Keith Hall 00b7e3b864
Merge pull request #2639 from johnmatthiggins/doc_fix
fix for issue #2095
2023-08-09 17:38:15 +03:00
John Higgins 7826e506f8
Merge branch 'master' into doc_fix 2023-08-02 09:00:29 -07:00
David Peter 6dd8b28b0d
Merge pull request #2638 from johnmatthiggins/master
fix for issue #2633
2023-08-02 15:24:02 +02:00
John Higgins b720af8a06
fix for issue #2095 2023-08-02 00:28:26 -07:00
John Higgins b1fbcc8a6e
fix for issue #2633 2023-08-02 00:04:55 -07:00
Martin Nordholts 9bf74d687f Cargo.lock: Bump proc-macro2 to fix build with Rust nightly
Without fix:

    $ cargo +nightly build
       Compiling proc-macro2 v1.0.54
    error[E0635]: unknown feature `proc_macro_span_shrink`
      --> /home/martin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.54/src/lib.rs:92:30
       |
    92 |     feature(proc_macro_span, proc_macro_span_shrink)
       |                              ^^^^^^^^^^^^^^^^^^^^^^

    For more information about this error, try `rustc --explain E0635`.
    error: could not compile `proc-macro2` (lib) due to previous error
2023-07-27 07:08:38 +02:00
Keith Hall 783d4877e1
Merge pull request #2615 from einfachIrgendwer0815/feature_containerfile_mapping
Add `Containerfile` syntax mapping
2023-07-14 19:56:49 +03:00
einfachIrgendwer0815 8b187e6997
Update CHANGELOG 2023-07-02 13:55:54 +02:00
einfachIrgendwer0815 c46c53320b
Add `Containerfile` syntax mapping 2023-07-02 13:50:37 +02:00
dependabot[bot] 7f884fa582
Bump expect-test from 1.4.0 to 1.4.1
Bumps [expect-test](https://github.com/rust-analyzer/expect-test) from 1.4.0 to 1.4.1.
- [Changelog](https://github.com/rust-analyzer/expect-test/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-analyzer/expect-test/compare/v1.4.0...v1.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 02:58:07 +00:00
David Peter 8676bbf97f Update clircle
See https://github.com/niklasmohrin/clircle/issues/10
2023-06-14 20:14:11 +02:00
sitiom 77069b368c
Update CICD.yml 2023-06-07 17:30:10 +08:00
David Peter 70e49bd32b
Merge pull request #2587 from cyqsimon/os-release
Add `os-release` syntax mapping
2023-06-03 23:29:09 +02:00
dependabot[bot] 5042f969e5 Bump clap from 4.2.6 to 4.3.0
Bumps [clap](https://github.com/clap-rs/clap) from 4.2.6 to 4.3.0.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.2.6...clap_complete-v4.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-03 09:30:39 +02:00
dependabot[bot] 876f5d4113 Bump serde from 1.0.160 to 1.0.163
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.160 to 1.0.163.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.160...v1.0.163)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-02 05:49:14 +02:00
dependabot[bot] 39d9d64e1e Bump regex from 1.8.1 to 1.8.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.8.1 to 1.8.3.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.8.1...1.8.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 20:43:59 +02:00
cyqsimon 8e866babfc
Write changelog 2023-06-01 13:25:02 +08:00
cyqsimon f8c700027e
Add `os-release` syntax mapping 2023-06-01 13:17:22 +08:00
Martin Nordholts 7639e8b406 CICD.yml: Run cargo audit
This CI check will fail if there are crates with known security vulnerabilities in Cargo.lock.

It will not fail because of warnings. We currently have two warnings.

Note that cargo-audit is installed by default on GitHub's Ubuntu
runners.
2023-05-24 05:43:36 +02:00
Nigecat 149dec6953 Fix paging not happening when stdout is interactive but stdin is not 2023-05-22 05:42:01 +02:00
lesleyrs b420c42aff update readme 2023-05-17 06:25:20 +02:00
lesleyrs 3da7adb763 update readme 2023-05-17 06:25:20 +02:00
dependabot[bot] 165e5da6b9 Bump semver from 1.0.16 to 1.0.17
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.16 to 1.0.17.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.16...1.0.17)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-13 07:29:48 +02:00
dependabot[bot] c5a9fdff93 Bump regex from 1.7.0 to 1.8.1
Bumps [regex](https://github.com/rust-lang/regex) from 1.7.0 to 1.8.1.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.7.0...1.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-12 19:19:19 +02:00
dependabot[bot] 8aac5acc0a Bump serde from 1.0.159 to 1.0.160
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.159 to 1.0.160.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.159...v1.0.160)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-12 07:02:58 +02:00
dependabot[bot] 7162e38d50 Bump predicates from 3.0.2 to 3.0.3
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v3.0.2...v3.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-12 06:31:39 +02:00
dependabot[bot] 63ac60a3a0 Bump flate2 from 1.0.25 to 1.0.26
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.25 to 1.0.26.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-12 06:30:57 +02:00
Constantin Nickel 9683bfdb3f Update `clap` to 4.2.6 2023-05-12 06:01:47 +02:00
Adrián Bíro e155f56484 Clean-up bash comletion
"cword" is unset and even is not used in completion for other shells, so it probably shouldn't be here either. If it for some reason should be there add the directive "# shellcheck disable=SC2034" to the line above it.
2023-05-12 05:59:36 +02:00
Constantin Nickel e828d7840a Use valid SPDX license expression 2023-04-14 06:38:03 +02:00
Constantin Nickel 52f7a5a06f Update `plist` to 1.4
The version replaced `xml-rs` with the `quick-xml` crate.
That makes -1 warning for an unmaintained crate from `cargo audit`.
2023-04-14 06:37:45 +02:00
Constantin Nickel baa1476d8d Update `predicates` to 3.0
This also updates `assert_cmd` to 2.0.10 to avoid duplicate dependencies
because it depends on the new major version since 2.0.9.
2023-04-14 06:37:32 +02:00
Constantin Nickel 6be56972b6 Update `serial_test` to 2.0 2023-04-14 06:37:32 +02:00
dependabot[bot] 08445eba91 Bump serde from 1.0.152 to 1.0.159
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.152 to 1.0.159.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.152...v1.0.159)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 19:06:07 +02:00
dependabot[bot] 2298422e85 Bump bytesize from 1.1.0 to 1.2.0
Bumps [bytesize](https://github.com/hyunsik/bytesize) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/hyunsik/bytesize/releases)
- [Commits](https://github.com/hyunsik/bytesize/compare/v1.1.0...v1.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 19:05:53 +02:00
David Peter c5731b9079
Merge pull request #2530 from nickelc/deps/use_is_terminal
Use the `is-terminal` crate instead of `atty`
2023-04-05 21:00:18 +02:00
dependabot[bot] 458e818ab4 Bump walkdir from 2.3.2 to 2.3.3
Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/BurntSushi/walkdir/releases)
- [Commits](https://github.com/BurntSushi/walkdir/compare/2.3.2...2.3.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-05 20:42:34 +02:00
dependabot[bot] 993b33b5b4 Bump thiserror from 1.0.38 to 1.0.40
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.38 to 1.0.40.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.38...1.0.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-05 20:41:49 +02:00
dependabot[bot] ba95955fe6 Bump tempfile from 3.3.0 to 3.5.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.3.0 to 3.5.0.
- [Release notes](https://github.com/Stebalien/tempfile/releases)
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS)
- [Commits](https://github.com/Stebalien/tempfile/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-05 20:41:30 +02:00
Constantin Nickel 57cc0d8435 Use the `is-terminal` crate instead of `atty`
The crate is already used by `clap` and a similar trait is about to be
stabilized in `std`.
2023-04-05 19:26:52 +02:00
sitiom 60a9ac041f
Add Winget installation method in the readme 2023-03-30 13:41:11 +08:00
Ryan Caezar Itang 33997106da
Add Winget Releaser workflow 2023-03-28 08:32:51 +08:00
David Peter 1b2c69aee8
Merge pull request #2516 from sharkdp/big-ci-sync
CI improvements
2023-03-25 21:49:50 +01:00
David Peter 87e87a349a Extract crate metadata with cargo 2023-03-25 14:47:31 +01:00
David Peter e49235e119 Minor CI improvements 2023-03-25 13:44:00 +01:00
David Peter 1712ec9e73
Merge pull request #2515 from tranzystorek-io/custom-asset-gen-dir
Allow customizing output directory for generated assets
2023-03-25 13:18:02 +01:00
Marcin Puc 3ca8c43a67 Update CHANGELOG.md 2023-03-25 11:56:40 +01:00
Marcin Puc 01f1b1efe8 Allow customizing output directory for generated assets 2023-03-25 11:47:20 +01:00
David Peter c7905a6029 Minor fix in man page 2023-03-25 10:36:14 +01:00
David Peter d27aaffead New empty CHANGELOG section 2023-03-25 10:33:49 +01:00
137 changed files with 5249 additions and 1370 deletions

View File

@ -26,4 +26,4 @@ guidelines for adding new syntaxes:
[Name or description of the syntax/language here]
**Guideline Criteria:**
[packagecontro.io link here]
[packagecontrol.io link here]

View File

@ -0,0 +1,23 @@
# 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

@ -2,6 +2,7 @@ name: CICD
env:
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
MSRV_FEATURES: --no-default-features --features minimal-application,bugreport,build-assets
on:
workflow_dispatch:
@ -13,6 +14,43 @@ on:
- '*'
jobs:
all-jobs:
if: always() # Otherwise this job is skipped if the matrix job fails
name: all-jobs
runs-on: ubuntu-latest
needs:
- crate_metadata
- ensure_cargo_fmt
- min_version
- license_checks
- test_with_new_syntaxes_and_themes
- test_with_system_config
- documentation
- cargo-audit
- build
steps:
- run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
crate_metadata:
name: Extract crate metadata
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Extract crate information
id: crate_metadata
run: |
cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT
outputs:
name: ${{ steps.crate_metadata.outputs.name }}
version: ${{ steps.crate_metadata.outputs.version }}
maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
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
@ -20,46 +58,42 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: cargo fmt -- --check
license_checks:
name: License checks
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
submodules: true # we especially want to perform license checks on submodules
- run: tests/scripts/license-checks.sh
min_version:
name: Minimum supported rust version
runs-on: ubuntu-20.04
env:
MSRV_FEATURES: --no-default-features --features minimal-application,bugreport,build-assets
needs: crate_metadata
steps:
- name: Checkout source code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Get the MSRV from the package metadata
id: msrv
run: cargo metadata --no-deps --format-version 1 | jq -r '"version=" + (.packages[] | select(.name == "bat")).rust_version' >> $GITHUB_OUTPUT
- name: Install rust toolchain (v${{ steps.msrv.outputs.version }})
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.msrv.outputs.version }}
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
steps:
- uses: actions/checkout@v4
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
steps:
- name: Git checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: true # we need all syntax and theme submodules
- name: Install Rust toolchain
@ -88,7 +122,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Git checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Prepare environment variables
run: |
echo "BAT_SYSTEM_CONFIG_PREFIX=$GITHUB_WORKSPACE/tests/examples/system_config" >> $GITHUB_ENV
@ -104,7 +138,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Git checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Check documentation
@ -114,29 +148,37 @@ jobs:
- name: Show man page
run: man $(find . -name bat.1)
cargo-audit:
name: cargo audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cargo audit
build:
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
runs-on: ${{ matrix.job.os }}
needs: crate_metadata
strategy:
fail-fast: false
matrix:
job:
- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2019 }
- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-10.15 }
- { 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, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, 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: x86_64-apple-darwin , os: macos-12, }
- { 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 }
env:
BUILD_CMD: cargo
steps:
- name: Checkout source code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install prerequisites
shell: bash
@ -146,14 +188,6 @@ jobs:
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Extract crate information
shell: bash
run: |
echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV
echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
@ -184,7 +218,7 @@ jobs:
shell: bash
run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }}
- name: Set bin name & path
- name: Set binary name & path
id: bin
shell: bash
run: |
@ -195,10 +229,10 @@ jobs:
esac;
# Setup paths
BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}"
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
# Let subsequent steps know where to find the bin
# Let subsequent steps know where to find the binary
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
@ -208,12 +242,18 @@ jobs:
run: |
# test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac;
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
- name: Run tests
shell: bash
run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
run: |
if [[ ${{ matrix.job.os }} = windows-* ]]
then
powershell.exe -command "$BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}"
else
$BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
fi
- name: Run bat
shell: bash
@ -248,7 +288,7 @@ jobs:
shell: bash
run: |
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
PKG_BASENAME=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }}
PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }}
PKG_NAME=${PKG_BASENAME}${PKG_suffix}
echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT
@ -260,17 +300,17 @@ jobs:
# Binary
cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
# Man page
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR"
# README, LICENSE and CHANGELOG files
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
# Man page
cp 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR"
# Autocompletion files
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.bash"
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish"
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/_bat.ps1 "$ARCHIVE_DIR/autocomplete/_${{ env.PROJECT_NAME }}.ps1"
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.zsh"
cp 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.bash "$ARCHIVE_DIR/autocomplete/${{ needs.crate_metadata.outputs.name }}.bash"
cp 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ needs.crate_metadata.outputs.name }}.fish"
cp 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/_bat.ps1 "$ARCHIVE_DIR/autocomplete/_${{ needs.crate_metadata.outputs.name }}.ps1"
cp 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.zsh "$ARCHIVE_DIR/autocomplete/${{ needs.crate_metadata.outputs.name }}.zsh"
# base compressed package
pushd "${PKG_STAGING}/" >/dev/null
@ -293,20 +333,11 @@ jobs:
DPKG_DIR="${DPKG_STAGING}/dpkg"
mkdir -p "${DPKG_DIR}"
DPKG_BASENAME=${PROJECT_NAME}
DPKG_CONFLICTS=${PROJECT_NAME}-musl
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
DPKG_VERSION=${PROJECT_VERSION}
unset DPKG_ARCH
case ${{ matrix.job.target }} in
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
i686-*-linux-*) DPKG_ARCH=i686 ;;
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
*) DPKG_ARCH=notset ;;
esac;
DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}
DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }}-musl
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-musl ; DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }} ;; esac;
DPKG_VERSION=${{ needs.crate_metadata.outputs.version }}
DPKG_ARCH="${{ matrix.job.dpkg_arch }}"
DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
echo "DPKG_NAME=${DPKG_NAME}" >> $GITHUB_OUTPUT
@ -314,13 +345,13 @@ jobs:
install -Dm755 "${{ steps.bin.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.bin.outputs.BIN_NAME }}"
# Man page
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1"
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1"
# Autocompletion files
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.bash "${DPKG_DIR}/usr/share/bash-completion/completions/${{ env.PROJECT_NAME }}"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.bash "${DPKG_DIR}/usr/share/bash-completion/completions/${{ needs.crate_metadata.outputs.name }}"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ needs.crate_metadata.outputs.name }}.fish"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ needs.crate_metadata.outputs.name }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ needs.crate_metadata.outputs.name }}"
# README and LICENSE
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
@ -331,12 +362,12 @@ jobs:
cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: ${{ env.PROJECT_NAME }}
Source: ${{ env.PROJECT_HOMEPAGE }}
Upstream-Name: ${{ needs.crate_metadata.outputs.name }}
Source: ${{ needs.crate_metadata.outputs.homepage }}
Files: *
Copyright: ${{ env.PROJECT_MAINTAINER }}
Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
Copyright: ${{ needs.crate_metadata.outputs.maintainer }}
Copyright: $COPYRIGHT_YEARS ${{ needs.crate_metadata.outputs.maintainer }}
License: Apache-2.0 or MIT
License: Apache-2.0
@ -377,10 +408,10 @@ jobs:
Version: ${DPKG_VERSION}
Section: utils
Priority: optional
Maintainer: ${{ env.PROJECT_MAINTAINER }}
Homepage: ${{ env.PROJECT_HOMEPAGE }}
Maintainer: ${{ needs.crate_metadata.outputs.maintainer }}
Homepage: ${{ needs.crate_metadata.outputs.homepage }}
Architecture: ${DPKG_ARCH}
Provides: ${{ env.PROJECT_NAME }}
Provides: ${{ needs.crate_metadata.outputs.name }}
Conflicts: ${DPKG_CONFLICTS}
Description: cat(1) clone with wings.
A cat(1) clone with syntax highlighting and Git integration.
@ -413,7 +444,7 @@ jobs:
echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT
- name: Publish archives and packages
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
if: steps.is-release.outputs.IS_RELEASE
with:
files: |
@ -421,3 +452,15 @@ jobs:
${{ steps.debian-package.outputs.DPKG_PATH }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
winget:
name: Publish to Winget
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: sharkdp.bat
installers-regex: '-pc-windows-msvc\.zip$'
token: ${{ secrets.WINGET_TOKEN }}

View File

@ -0,0 +1,33 @@
name: Changelog
on:
pull_request:
jobs:
check-changelog:
name: Check for changelog entry
runs-on: ubuntu-latest
# dependabot PRs are automerged if CI passes; we shouldn't block these
if: github.actor != 'dependabot[bot]'
env:
PR_NUMBER: ${{ github.event.number }}
PR_BASE: ${{ github.base_ref }}
steps:
- uses: actions/checkout@v4
- name: Fetch PR base
run: git fetch --no-tags --prune --depth=1 origin
# cannot use `github.actor`: the triggering commit may be authored by a maintainer
- name: Get PR submitter
id: get-submitter
run: curl -sSfL https://api.github.com/repos/sharkdp/bat/pulls/${PR_NUMBER} | jq -r '"submitter=" + .user.login' | tee -a $GITHUB_OUTPUT
- name: Search for added line in changelog
env:
PR_SUBMITTER: ${{ steps.get-submitter.outputs.submitter }}
run: |
ADDED=$(git diff -U0 "origin/${PR_BASE}" HEAD -- CHANGELOG.md | grep -P '^\+[^\+].+$')
echo "Added lines in CHANGELOG.md:"
echo "$ADDED"
echo "Grepping for PR info (see CONTRIBUTING.md):"
grep "#${PR_NUMBER}\\b.*@${PR_SUBMITTER}\\b" <<< "$ADDED"

6
.gitmodules vendored
View File

@ -254,3 +254,9 @@
[submodule "assets/syntaxes/02_Extra/Crontab"]
path = assets/syntaxes/02_Extra/Crontab
url = https://github.com/michaelblyons/SublimeSyntax-Crontab
[submodule "assets/syntaxes/02_Extra/NSIS"]
path = assets/syntaxes/02_Extra/NSIS
url = https://github.com/SublimeText/NSIS
[submodule "assets/syntaxes/02_Extra/vscode-wgsl"]
path = assets/syntaxes/02_Extra/vscode-wgsl
url = https://github.com/PolyMeilex/vscode-wgsl.git

View File

@ -1,3 +1,107 @@
# unreleased
## Features
- Set terminal title to file names when Paging is not Paging::Never #2807 (@Oliver-Looney)
- `bat --squeeze-blank`/`bat -s` will now squeeze consecutive empty lines, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)
- `bat --squeeze-limit` to set the maximum number of empty consecutive when using `--squeeze-blank`, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)
- `PrettyPrinter::squeeze_empty_lines` to support line squeezing for bat as a library, see #1441 (@eth-p) and #2665 (@einfachIrgendwer0815)
- Syntax highlighting for JavaScript files that start with `#!/usr/bin/env bun` #2913 (@sharunkumar)
## Bugfixes
- Fix long file name wrapping in header, see #2835 (@FilipRazek)
- Fix `NO_COLOR` support, see #2767 (@acuteenvy)
- Fix handling of inputs with OSC ANSI escape sequences, see #2541 and #2544 (@eth-p)
- Fix handling of inputs with combined ANSI color and attribute sequences, see #2185 and #2856 (@eth-p)
- Fix panel width when line 10000 wraps, see #2854 (@eth-p)
## Other
- Upgrade to Rust 2021 edition #2748 (@cyqsimon)
- Refactor and cleanup build script #2756 (@cyqsimon)
- Checks changelog has been written to for PRs in CI #2766 (@cyqsimon)
- Use GitHub API to get correct PR submitter #2791 (@cyqsimon)
- Minor benchmark script improvements #2768 (@cyqsimon)
- Update Arch Linux package URL in README files #2779 (@brunobell)
- Update and improve `zsh` completion, see #2772 (@okapia)
- More extensible syntax mapping mechanism #2755 (@cyqsimon)
- Use proper Architecture for Debian packages built for musl, see #2811 (@Enselic)
- Pull in fix for unsafe-libyaml security advisory, see #2812 (@dtolnay)
- Update git-version dependency to use Syn v2, see #2816 (@dtolnay)
- Update git2 dependency to v0.18.2, see #2852 (@eth-p)
- Improve performance when color output disabled, see #2397 and #2857 (@eth-p)
- Relax syntax mapping rule restrictions to allow brace expansion #2865 (@cyqsimon)
- Apply clippy fixes #2864 (@cyqsimon)
- Faster startup by offloading glob matcher building to a worker thread #2868 (@cyqsimon)
- Display which theme is the default one in basic output (no colors), see #2937 (@sblondon)
- Display which theme is the default one in colored output, see #2838 (@sblondon)
## Syntaxes
- `cmd-help`: scope subcommands followed by other terms, and other misc improvements, see #2819 (@victor-gp)
- Upgrade JQ syntax, see #2820 (@dependabot[bot])
- Add syntax mapping for quadman quadlets #2866 (@cyqsimon)
- Map containers .conf files to TOML syntax #2867 (@cyqsimon)
- Associate `xsh` files with `xonsh` syntax that is Python, see #2840 (@anki-code).
- Added auto detect syntax for `.jsonc` #2795 (@mxaddict)
- Added auto detect syntax for `.aws/{config,credentials}` #2795 (@mxaddict)
- Add syntax mapping for Wireguard config #2874 (@cyqsimon)
## Themes
## `bat` as a library
- Changes to `syntax_mapping::SyntaxMapping` #2755 (@cyqsimon)
- `SyntaxMapping::get_syntax_for` is now correctly public
- [BREAKING] `SyntaxMapping::{empty,builtin}` are removed; use `SyntaxMapping::new` instead
- [BREAKING] `SyntaxMapping::mappings` is replaced by `SyntaxMapping::{builtin,custom,all}_mappings`
- Make `Controller::run_with_error_handler`'s error handler `FnMut`, see #2831 (@rhysd)
- Improve compile time by 20%, see #2815 (@dtolnay)
# v0.24.0
## Features
- Add environment variable `BAT_PAGING`, see #2629 (@einfachIrgendwer0815)
- Add opt-in (`--features lessopen`) support for `LESSOPEN` and `LESSCLOSE`. See #1597, #1739, #2444, #2602, and #2662 (@Anomalocaridid)
## Bugfixes
- Fix `more` not being found on Windows when provided via `BAT_PAGER`, see #2570, #2580, and #2651 (@mataha)
- Switched default behavior of `--map-syntax` to be case insensitive #2520
- Updated version of `serde_yaml` to `0.9`. See #2627 (@Raghav-Bell)
- Fix arithmetic overflow in `LineRange::from` and `LineRange::parse_range`, see #2674, #2698 (@skoriop)
- Fix paging not happening when stdout is interactive but stdin is not, see #2574 (@Nigecat)
- Make `-pp` override `--paging` and vice versa when passed as a later argument, see #2660 (@J-Kappes)
## Other
- Output directory for generated assets (completion, manual) can be customized, see #2515 (@tranzystorek-io)
- Use the `is-terminal` crate instead of `atty`, see #2530 (@nickelc)
- Add Winget Releaser workflow, see #2519 (@sitiom)
- Bump MSRV to 1.70, see #2651 (@mataha)
## Syntaxes
- Associate `os-release` with `bash` syntax, see #2587 (@cyqsimon)
- Associate `Containerfile` with `Dockerfile` syntax, see #2606 (@einfachIrgendwer0815)
- Replaced quotes with double quotes so fzf integration example script works on windows and linux. see #2095 (@johnmatthiggins)
- Associate `ksh` files with `bash` syntax, see #2633 (@johnmatthiggins)
- Associate `sarif` files with `JSON` syntax, see #2695 (@rhysd)
- Associate `ron` files with `rust` syntax, see #2427 (@YeungOnion)
- Add support for [WebGPU Shader Language](https://www.w3.org/TR/WGSL/), see #2692 (@rhysd)
- Add `.dpkg-new` and `.dpkg-tmp` to ignored suffixe, see #2595 (@scop)
- fix: Add syntax mapping `*.jsonl` => `json`, see #2539 (@WinterCore)
- Update `Julia` syntax, see #2553 (@dependabot)
- add `NSIS` support, see #2577 (@idleberg)
- Update `ssh-config`, see #2697 (@mrmeszaros)
## `bat` as a library
- Add optional output_buffer arg to `Controller::run()` and `Controller::run_with_error_handler()`, see #2618 (@Piturnah)
# v0.23.0
## Features

View File

@ -6,21 +6,42 @@ Thank you for considering to contribute to `bat`!
## Add an entry to the changelog
If your contribution changes the behavior of `bat` (as opposed to a typo-fix
in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md) file
and describe your changes. This makes the release process much easier and
therefore helps to get your changes into a new `bat` release faster.
Keeping the [`CHANGELOG.md`](CHANGELOG.md) file up-to-date makes the release
process much easier and therefore helps to get your changes into a new `bat`
release faster. However, not every change to the repository requires a
changelog entry. Below are a few examples of that.
Please update the changelog if your contribution contains changes regarding
any of the following:
- the behavior of `bat`
- syntax mappings
- syntax definitions
- themes
- the build system, linting, or CI workflows
A changelog entry is not necessary when:
- updating documentation
- fixing typos
>[!NOTE]
> For PRs, a CI workflow verifies that a suitable changelog entry is
> added. If such an entry is missing, the workflow will fail. If your
> changes do not need an entry to the changelog (see above), that
> workflow failure can be disregarded.
### Changelog entry format
The top of the `CHANGELOG` contains a *"unreleased"* section with a few
subsections (Features, Bugfixes, …). Please add your entry to the subsection
that best describes your change.
Entries follow this format:
Entries must follow this format:
```
- Short description of what has been changed, see #123 (@user)
```
Here, `#123` is the number of the original issue and/or your pull request.
Please replace `@user` by your GitHub username.
Please replace `#123` with the number of your pull request (not issue) and
`@user` by your GitHub username.
## Development

1106
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,14 +3,14 @@ authors = ["David Peter <mail@david-peter.de>"]
categories = ["command-line-utilities"]
description = "A cat(1) clone with wings."
homepage = "https://github.com/sharkdp/bat"
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
name = "bat"
repository = "https://github.com/sharkdp/bat"
version = "0.23.0"
version = "0.24.0"
exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build.rs"
edition = '2018'
rust-version = "1.64"
build = "build/main.rs"
edition = '2021'
rust-version = "1.70"
[features]
default = ["application"]
@ -25,15 +25,15 @@ application = [
# Mainly for developers that want to iterate quickly
# Be aware that the included features might change in the future
minimal-application = [
"atty",
"clap",
"dirs",
"etcetera",
"paging",
"regex-onig",
"wild",
]
git = ["git2"] # Support indicating git modifications
paging = ["shell-words", "grep-cli"] # Support applying a pager on the output
lessopen = ["run_script", "os_str_bytes"] # Support $LESSOPEN preprocessor
build-assets = ["syntect/yaml-load", "syntect/plist-load", "regex", "walkdir"]
# You need to use one of these if you depend on bat as a library:
@ -41,64 +41,79 @@ regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine
regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine
[dependencies]
atty = { version = "0.2.14", optional = true }
nu-ansi-term = "0.47.0"
nu-ansi-term = "0.50.0"
ansi_colours = "^1.2"
bincode = "1.0"
console = "0.15.5"
console = "0.15.8"
flate2 = "1.0"
once_cell = "1.17"
once_cell = "1.19"
thiserror = "1.0"
wild = { version = "2.1", optional = true }
wild = { version = "2.2", optional = true }
content_inspector = "0.2.4"
encoding = "0.2"
shell-words = { version = "1.1.0", optional = true }
unicode-width = "0.1.10"
unicode-width = "0.1.11"
globset = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
serde = "1.0"
serde_derive = "1.0"
serde_yaml = "0.9.28"
semver = "1.0"
path_abs = { version = "0.5", default-features = false }
clircle = "0.3"
clircle = "0.5"
bugreport = { version = "0.5.0", optional = true }
dirs = { version = "5.0.0", optional = true }
grep-cli = { version = "0.1.7", optional = true }
regex = { version = "1.7.0", optional = true }
walkdir = { version = "2.0", optional = true }
bytesize = { version = "1.1.0" }
etcetera = { version = "0.8.0", optional = true }
grep-cli = { version = "0.1.10", optional = true }
regex = { version = "1.10.2", optional = true }
walkdir = { version = "2.4", optional = true }
bytesize = { version = "1.3.0" }
encoding_rs = "0.8.33"
os_str_bytes = { version = "~7.0", optional = true }
run_script = { version = "^0.10.1", optional = true}
[dependencies.git2]
version = "0.16"
version = "0.18"
optional = true
default-features = false
[dependencies.syntect]
version = "5.0.0"
version = "5.2.0"
default-features = false
features = ["parsing"]
[dependencies.clap]
version = "4.1.8"
version = "4.4.12"
optional = true
features = ["wrap_help", "cargo"]
[target.'cfg(target_os = "macos")'.dependencies]
dirs = "5.0.0"
plist = "1.3"
home = "0.5.9"
plist = "1.6.0"
[dev-dependencies]
assert_cmd = "2.0.8"
expect-test = "1.4.0"
serial_test = "0.6.0"
predicates = "2.1.5"
assert_cmd = "2.0.12"
expect-test = "1.4.1"
serial_test = { version = "2.0.0", default-features = false }
predicates = "3.1.0"
wait-timeout = "0.2.0"
tempfile = "3.3.0"
tempfile = "3.8.1"
serde = { version = "1.0", features = ["derive"] }
[target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.26.2", default-features = false, features = ["term"] }
nix = { version = "0.26.4", default-features = false, features = ["term"] }
[build-dependencies]
anyhow = "1.0.78"
indexmap = { version = "2.2.6", features = ["serde"] }
itertools = "0.12.1"
once_cell = "1.18"
regex = "1.10.2"
serde = "1.0"
serde_derive = "1.0"
serde_with = { version = "3.8.1", default-features = false, features = ["macros"] }
toml = { version = "0.8.9", features = ["preserve_order"] }
walkdir = "2.4"
[build-dependencies.clap]
version = "4.1.8"
version = "4.4.12"
optional = true
features = ["wrap_help", "cargo"]

View File

@ -32,6 +32,16 @@ A special *thank you* goes to our biggest <a href="doc/sponsors.md">sponsors</a>
<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">
<img src="doc/sponsors/warp-logo.png" width="200" alt="Warp">
<br>
<strong>Warp is a modern, Rust-based terminal with AI built in<br>so you and your team can build great software, faster.</strong>
<br>
<sub>Feel more productive on the command line with parameterized commands,</sub>
<br>
<sup>autosuggestions, and an IDE-like text editor.</sup>
</a>
### Syntax highlighting
`bat` supports syntax highlighting for a large number of programming and markup
@ -118,7 +128,7 @@ use `bat`s `--color=always` option to force colorized output. You can also use `
option to restrict the load times for long files:
```bash
fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}'
fzf --preview "bat --color=always --style=numbers --line-range=:500 {}"
```
For more information, see [`fzf`'s `README`](https://github.com/junegunn/fzf#preview-window).
@ -228,12 +238,23 @@ help() {
Then you can do `$ help cp` or `$ help git commit`.
When you are using `zsh`, you can also use global aliases to override `-h` and `--help` entirely:
```bash
alias -g -- -h='-h 2>&1 | bat --language=help --style=plain'
alias -g -- --help='--help 2>&1 | bat --language=help --style=plain'
```
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`).
Please report any issues with the help syntax in [this repository](https://github.com/victor-gp/cmd-help-sublime-syntax).
## Installation
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/bat-cat/versions)
### On Ubuntu (using `apt`)
*... and other Debian-based Linux distributions.*
@ -275,7 +296,7 @@ apk add bat
### On Arch Linux
You can install [the `bat` package](https://www.archlinux.org/packages/community/x86_64/bat/)
You can install [the `bat` package](https://www.archlinux.org/packages/extra/x86_64/bat/)
from the official sources:
```bash
@ -390,6 +411,14 @@ take a look at the ["Using `bat` on Windows"](#using-bat-on-windows) section.
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
#### With WinGet
You can install `bat` via [WinGet](https://learn.microsoft.com/en-us/windows/package-manager/winget):
```bash
winget install sharkdp.bat
```
#### With Chocolatey
You can install `bat` via [Chocolatey](https://chocolatey.org/packages/Bat):
@ -418,7 +447,7 @@ binaries are also available: look for archives with `musl` in the file name.
### From source
If you want to build `bat` from source, you need Rust 1.64.0 or
If you want to build `bat` from source, you need Rust 1.70.0 or
higher. You can then use `cargo` to build everything:
```bash
@ -573,7 +602,8 @@ set, `less` is used by default. If you want to use a different pager, you can ei
`PAGER` variable or set the `BAT_PAGER` environment variable to override what is specified in
`PAGER`.
**Note**: If `PAGER` is `more` or `most`, `bat` will silently use `less` instead to ensure support for colors.
>[!NOTE]
> If `PAGER` is `more` or `most`, `bat` will silently use `less` instead to ensure support for colors.
If you want to pass command-line arguments to the pager, you can also set them via the
`PAGER`/`BAT_PAGER` variables:
@ -584,20 +614,37 @@ export BAT_PAGER="less -RF"
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).
**Note**: By default, if the pager is set to `less` (and no command-line options are specified),
`bat` will pass the following command line options to the pager: `-R`/`--RAW-CONTROL-CHARS`,
`-F`/`--quit-if-one-screen` and `-X`/`--no-init`. The last option (`-X`) is only used for `less`
versions older than 530.
The `-R` option is needed to interpret ANSI colors correctly. The second option (`-F`) instructs
less to exit immediately if the output size is smaller than the vertical size of the terminal.
This is convenient for small files because you do not have to press `q` to quit the pager. The
third option (`-X`) is needed to fix a bug with the `--quit-if-one-screen` feature in old versions
of `less`. Unfortunately, it also breaks mouse-wheel support in `less`.
### Using `less` as a pager
If you want to enable mouse-wheel scrolling on older versions of `less`, you can pass just `-R` (as
in the example above, this will disable the quit-if-one-screen feature). For less 530 or newer,
it should work out of the box.
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`.
>[!IMPORTANT]
> These options will not be added if:
> - The pager is not named `less`.
> - The `--pager` argument contains any command-line arguments (e.g. `--pager="less -R"`).
> - The `BAT_PAGER` environment variable contains any command-line arguments (e.g. `export BAT_PAGER="less -R"`)
>
> The `--quit-if-one-screen` option will not be added when:
> - The `--paging=always` argument is used.
> - The `BAT_PAGING` environment is set to `always`.
The `-R` option is needed to interpret ANSI colors correctly.
The `-F` option instructs `less` to exit immediately if the output size is smaller than
the vertical size of the terminal. This is convenient for small files because you do not
have to press `q` to quit the pager.
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
the quit-if-one-screen feature, you can set the pager (via `--pager` or `BAT_PAGER`) to `less -R`.
For `less` 530 or newer, it should work out of the box.
The `-S` option is added when `bat`'s `-S`/`--chop-long-lines` option is used. This tells `less`
to truncate any lines larger than the terminal width.
### Indentation
@ -684,9 +731,7 @@ Windows 10 natively supports colors in both `conhost.exe` (Command Prompt) and P
well as in newer versions of bash. On earlier versions of Windows, you can use
[Cmder](http://cmder.net/), which includes [ConEmu](https://conemu.github.io/).
**Note:** The Git and MSYS versions of `less` do not correctly interpret colors on Windows. If you
dont have any other pagers installed, you can disable paging entirely by passing `--paging=never`
or by setting `BAT_PAGER` to an empty string.
**Note:** Old versions of `less` do not correctly interpret colors on Windows. To fix this, you can add the optional Unix tools to your PATH when installing Git. If you dont have any other pagers installed, you can disable paging entirely by passing `--paging=never` or by setting `BAT_PAGER` to an empty string.
### Cygwin

Binary file not shown.

View File

@ -59,6 +59,8 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
[CompletionResult]::new('--unbuffered', 'unbuffered', [CompletionResultType]::ParameterName, 'unbuffered')
[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')
[CompletionResult]::new('--no-lessopen', 'no-lessopen', [CompletionResultType]::ParameterName, 'Disable the $LESSOPEN preprocessor if enabled (overrides --lessopen)')
[CompletionResult]::new('--config-file', 'config-file', [CompletionResultType]::ParameterName, 'Show path to the configuration file.')
[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.')

View File

@ -32,7 +32,7 @@ __bat_escape_completions()
}
_bat() {
local cur prev words cword split=false
local cur prev words split=false
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -s || return 0
else
@ -78,6 +78,7 @@ _bat() {
--list-themes | \
--line-range | \
-L | --list-languages | \
--lessopen | \
--diagnostic | \
--acknowledgements | \
-h | --help | \
@ -171,6 +172,7 @@ _bat() {
--style
--line-range
--list-languages
--lessopen
--diagnostic
--acknowledgements
--help

View File

@ -147,6 +147,8 @@ complete -c $bat -s d -l diff -d "Only show lines with Git changes" -n __bat_no_
complete -c $bat -l diff-context -x -d "Show N context lines around Git changes" -n "__fish_seen_argument -s d -l diff"
complete -c $bat -l generate-config-file -f -d "Generates a default configuration file" -n __fish_is_first_arg
complete -c $bat -l file-name -x -d "Specify the display name" -n __bat_no_excl_args
complete -c $bat -s f -l force-colorization -d "Force color and decorations" -n __bat_no_excl_args
@ -163,6 +165,8 @@ complete -c $bat -l italic-text -x -a "$italic_text_opts" -d "When to use italic
complete -c $bat -s l -l language -x -k -a "(__bat_complete_list_languages)" -d "Set the syntax highlighting language" -n __bat_no_excl_args
complete -c $bat -l lessopen -d "Enable the $LESSOPEN preprocessor" -n __fish_is_first_arg
complete -c $bat -s r -l line-range -x -d "Only print lines [M]:[N] (either optional)" -n __bat_no_excl_args
complete -c $bat -l list-languages -f -d "List syntax highlighting languages" -n __fish_is_first_arg
@ -171,6 +175,12 @@ complete -c $bat -l list-themes -f -d "List syntax highlighting themes" -n __fis
complete -c $bat -s m -l map-syntax -x -a "(__bat_complete_map_syntax)" -d "Map <glob pattern>:<language syntax>" -n __bat_no_excl_args
complete -c $bat -l no-config -d "Do not use the configuration file"
complete -c $bat -l no-custom-assets -d "Do not load custom assets"
complete -c $bat -l no-lessopen -d "Disable the $LESSOPEN preprocessor if enabled (overrides --lessopen)"
complete -c $bat -s n -l number -d "Only show line numbers, no other decorations" -n __bat_no_excl_args
complete -c $bat -l pager -x -a "$pager_opts" -d "Which pager to use" -n __bat_no_excl_args

View File

@ -1,19 +1,20 @@
#compdef {{PROJECT_EXECUTABLE}}
local context state state_descr line
local curcontext="$curcontext" ret=1
local -a state state_descr line
typeset -A opt_args
(( $+functions[_{{PROJECT_EXECUTABLE}}_cache_subcommand] )) ||
_{{PROJECT_EXECUTABLE}}_cache_subcommand() {
local -a args
args=(
'(-b --build -c --clear)'{-b,--build}'[Initialize or update the syntax/theme cache]'
'(-b --build -c --clear)'{-c,--clear}'[Remove the cached syntax definitions and themes]'
'(--source)'--source='[Use a different directory to load syntaxes and themes from]:directory:_files -/'
'(--target)'--target='[Use a different directory to store the cached syntax and theme set]:directory:_files -/'
'(--blank)'--blank'[Create completely new syntax and theme sets]'
'(: -)'{-h,--help}'[Prints help information]'
'*: :'
'(-b --build -c --clear)'{-b,--build}'[initialize or update the syntax/theme cache]'
'(-b --build -c --clear)'{-c,--clear}'[remove the cached syntax definitions and themes]'
--source='[specify directory to load syntaxes and themes from]:directory:_files -/'
--target='[specify directory to store the cached syntax and theme set in]:directory:_files -/'
--blank'[create completely new syntax and theme sets]'
--acknowledgements'[build acknowledgements.bin]'
'(: -)'{-h,--help}'[show help information]'
)
_arguments -S -s $args
@ -23,67 +24,79 @@ _{{PROJECT_EXECUTABLE}}_cache_subcommand() {
_{{PROJECT_EXECUTABLE}}_main() {
local -a args
args=(
'(-A --show-all)'{-A,--show-all}'[Show non-printable characters (space, tab, newline, ..)]'
'*'{-p,--plain}'[Show plain style (alias for `--style=plain`), repeat twice to disable disable automatic paging (alias for `--paging=never`)]'
'(-l --language)'{-l+,--language=}'[Set the language for syntax highlighting]:<language>:->language'
'(-H --highlight-line)'{-H,--highlight-line}'[Highlight lines N through M]:<N\:M>...'
'(--file-name)'--file-name'[Specify the name to display for a file]:<name>...:_files'
'(-d --diff)'--diff'[Only show lines that have been added/removed/modified]'
'(--diff-context)'--diff-context'[Include N lines of context around added/removed/modified lines when using `--diff`]:<N> (lines):()'
'(--tabs)'--tabs'[Set the tab width to T spaces]:<T> (tab width):()'
'(--wrap)'--wrap='[Specify the text-wrapping mode]:<when>:(auto never character)'
'(--terminal-width)'--terminal-width'[Explicitly set the width of the terminal instead of determining it automatically]:<width>'
'(-n --number)'{-n,--number}'[Show line numbers]'
'(--color)'--color='[When to use colors]:<when>:(auto never always)'
'(--italic-text)'--italic-text='[Use italics in output]:<when>:(always never)'
'(--decorations)'--decorations='[When to show the decorations]:<when>:(auto never always)'
'(--paging)'--paging='[Specify when to use the pager]:<when>:(auto never always)'
'(-m --map-syntax)'{-m+,--map-syntax=}'[Use the specified syntax for files matching the glob pattern]:<glob\:syntax>...'
'(--theme)'--theme='[Set the color theme for syntax highlighting]:<theme>:->theme'
'(: --list-themes --list-languages -L)'--list-themes'[Display all supported highlighting themes]'
'(--style)'--style='[Comma-separated list of style elements to display]:<components>:->style'
'(-r --line-range)'{-r+,--line-range=}'[Only print the lines from N to M]:<N\:M>...'
'(: --list-themes --list-languages -L)'{-L,--list-languages}'[Display all supported languages]'
'(: --no-config)'--no-config'[Do not use the configuration file]'
'(: --no-custom-assets)'--no-custom-assets'[Do not load custom assets]'
'(: --config-dir)'--config-dir'[Show bat'"'"'s configuration directory]'
'(: --config-file)'--config-file'[Show path to the configuration file]'
'(: --generate-config-file)'--generate-config-file'[Generates a default configuration file]'
'(: --cache-dir)'--cache-dir'[Show bat'"'"'s cache directory]'
'(: -)'{-h,--help}'[Print this help message]'
'(: -)'{-V,--version}'[Show version information]'
'*: :_files'
'(-A --show-all)'{-A,--show-all}'[show non-printable characters (space, tab, newline, ..)]'
--nonprintable-notation='[specify how to display non-printable characters when using --show-all]:notation:(caret unicode)'
\*{-p,--plain}'[show plain style (alias for `--style=plain`), repeat twice to disable disable automatic paging (alias for `--paging=never`)]'
'(-l --language)'{-l+,--language=}'[set the language for syntax highlighting]:language:->languages'
\*{-H+,--highlight-line=}'[highlight specified block of lines]:start\:end'
\*--file-name='[specify the name to display for a file]:name:_files'
'(-d --diff)'--diff'[only show lines that have been added/removed/modified]'
--diff-context='[specify lines of context around added/removed/modified lines when using `--diff`]:lines'
--tabs='[set the tab width]:tab width [4]'
--wrap='[specify the text-wrapping mode]:mode [auto]:(auto never character)'
'!(--wrap)'{-S,--chop-long-lines}
--terminal-width='[explicitly set the width of the terminal instead of determining it automatically]:width'
'(-n --number --diff --diff-context)'{-n,--number}'[show line numbers]'
--color='[specify when to use colors]:when:(auto never always)'
--italic-text='[use italics in output]:when:(always never)'
--decorations='[specify when to show the decorations]:when:(auto never always)'
--paging='[specify when to use the pager]:when:(auto never always)'
'(-m --map-syntax)'{-m+,--map-syntax=}'[map a glob pattern to an existing syntax name]: :->syntax-maps'
'(--theme)'--theme='[set the color theme for syntax highlighting]:theme:->themes'
'(: --list-themes --list-languages -L)'--list-themes'[show all supported highlighting themes]'
--style='[comma-separated list of style elements to display]: : _values "style [default]"
default auto full plain changes header header-filename header-filesize grid rule numbers snip'
\*{-r+,--line-range=}'[only print the specified line range]:start\:end'
'(* -)'{-L,--list-languages}'[display all supported languages]'
"--no-config[don't use the configuration file]"
"--no-custom-assets[don't load custom assets]"
'(--no-lessopen)'--lessopen'[enable the $LESSOPEN preprocessor]'
'(--lessopen)'--no-lessopen'[disable the $LESSOPEN preprocessor if enabled (overrides --lessopen)]'
'(* -)'--config-dir"[show bat's configuration directory]"
'(* -)'--config-file'[show path to the configuration file]'
'(* -)'--generate-config-file'[generate a default configuration file]'
'(* -)'--cache-dir"[show bat's cache directory]"
'(* -)'{-h,--help}'[show help information]'
'(* -)'{-V,--version}'[show version information]'
'*: :{ _files || compadd cache }'
)
_arguments -S -s $args
_arguments -S -s $args && ret=0
case "$state" in
language)
syntax-maps)
if ! compset -P '*:'; then
_message -e patterns 'glob pattern:language'
return
fi
;& # fall-through
languages)
local IFS=$'\n'
local -a languages
languages=( $({{PROJECT_EXECUTABLE}} --list-languages | awk -F':|,' '{ for (i = 1; i <= NF; ++i) printf("%s:%s\n", $i, $1) }') )
_describe 'language' languages
_describe 'language' languages && ret=0
;;
theme)
local IFS=$'\n'
local -a themes
themes=( $({{PROJECT_EXECUTABLE}} --list-themes | sort) )
themes)
local -a themes expl
themes=( ${(f)"$(_call_program themes {{PROJECT_EXECUTABLE}} --list-themes)"} )
_values 'theme' $themes
;;
style)
_values -s , 'style' default auto full plain changes header header-filename header-filesize grid rule numbers snip
_wanted themes expl 'theme' compadd -a themes && ret=0
;;
esac
return ret
}
case $words[2] in
cache)
## Completion of the 'cache' command itself is removed for better UX
## See https://github.com/sharkdp/bat/issues/2085#issuecomment-1271646802
shift words
(( CURRENT-- ))
curcontext="${curcontext%:*}-${words[1]}:"
_{{PROJECT_EXECUTABLE}}_cache_subcommand
;;

View File

@ -25,7 +25,7 @@ either '--language value', '--language=value', '-l value' or '-lvalue'.
Show non\-printable characters like space, tab or newline. Use '\-\-tabs' to
control the width of the tab\-placeholders.
.HP
\fB\-\-nonprintable\-notation\fR
\fB\-\-nonprintable\-notation\fR <notation>
.IP
Specify how to display non-printable characters when using \-\-show\-all.
@ -243,6 +243,23 @@ If you ever want to remove the custom languages, you can clear the cache with `\
Similarly to custom languages, {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.tmTheme\fR themes.
These can be installed to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/themes\fR`, and are added to the cache with
`\fB{{PROJECT_EXECUTABLE}} cache --build`.
.SH "INPUT PREPROCESSOR"
Much like less(1) does, {{PROJECT_EXECUTABLE}} supports input preprocessors via the LESSOPEN and LESSCLOSE environment variables.
In addition, {{PROJECT_EXECUTABLE}} attempts to be as compatible with less's preprocessor implementation as possible.
To use the preprocessor, call:
\fB{{PROJECT_EXECUTABLE}} --lessopen\fR
Alternatively, the preprocessor may be enabled by default by adding the '\-\-lessopen' option to the configuration file.
To temporarily disable the preprocessor if it is enabled by default, call:
\fB{{PROJECT_EXECUTABLE}} --no-lessopen\fR
For more information, see the "INPUT PREPROCESSOR" section of less(1).
.SH "MORE INFORMATION"
For more information and up-to-date documentation, visit the {{PROJECT_EXECUTABLE}} repo:

View File

@ -0,0 +1,14 @@
Submodule assets/syntaxes/01_Packages contains modified content
diff --git syntaxes/01_Packages/JavaScript/JavaScript.sublime-syntax syntaxes/01_Packages/JavaScript/JavaScript.sublime-syntax
index 05a4fed6..78a7bf55 100644
--- syntaxes/01_Packages/JavaScript/JavaScript.sublime-syntax
+++ syntaxes/01_Packages/JavaScript/JavaScript.sublime-syntax
@@ -5,7 +5,7 @@ name: JavaScript
file_extensions:
- js
- htc
-first_line_match: ^#!\s*/.*\b(node|js)\b
+first_line_match: ^#!\s*/.*\b(node|bun|js)\b
scope: source.js
variables:
bin_digit: '[01_]'

BIN
assets/syntaxes.bin vendored

Binary file not shown.

@ -1 +1 @@
Subproject commit 9e9a518aed93031042c54710f8f02c839301de26
Subproject commit 0f6b7bc87acf684f7b0790fd480731ffb4615b87

@ -1 +1 @@
Subproject commit 4fde0fdeddb3ca8486d3f490a2f051cba39a0a48
Subproject commit 3366b10be91aaab7a61ae0bc0a5af5cc375e58d1

1
assets/syntaxes/02_Extra/NSIS vendored Submodule

@ -0,0 +1 @@
Subproject commit 619a65a04efbf343bdfcde875700675b9b273368

@ -1 +1 @@
Subproject commit 687058289c1a888e0895378432d66b41609a84d8
Subproject commit b7e53e5d86814f04a48d2e441bcf5f9fdf07e9c1

@ -1 +1 @@
Subproject commit f41e5fc8381fe200a4e18c410bb41e911110a6e9
Subproject commit 209559b72f7e8848c988828088231b3a4d8b6838

@ -1 +1 @@
Subproject commit e1012e9f13c6073f559b14206df2ede35720e884
Subproject commit bf49e9181c6bf992a86beb133144d2651e826ddc

@ -0,0 +1 @@
Subproject commit acf26718d7a327377641e31d8f9a9dab376efa84

View File

@ -0,0 +1,198 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/syntax.html
name: WGSL
file_extensions:
- wgsl
scope: source.wgsl
contexts:
main:
- include: line_comments
- include: block_comments
- include: keywords
- include: attributes
- include: functions
- include: function_calls
- include: constants
- include: types
- include: variables
- include: punctuation
attributes:
- match: '(@)([A-Za-z_]+)'
comment: attribute declaration
scope: meta.attribute.wgsl
captures:
1: keyword.operator.attribute.at
2: entity.name.attribute.wgsl
block_comments:
- match: /\*\*/
comment: empty block comments
scope: comment.block.wgsl
- match: /\*\*
comment: block documentation comments
push:
- meta_scope: comment.block.documentation.wgsl
- match: \*/
pop: true
- include: block_comments
- match: /\*(?!\*)
comment: block comments
push:
- meta_scope: comment.block.wgsl
- match: \*/
pop: true
- include: block_comments
constants:
- match: '(-?\b[0-9][0-9]*\.[0-9][0-9]*)([eE][+-]?[0-9]+)?\b'
comment: decimal float literal
scope: constant.numeric.float.wgsl
- match: '-?\b0x[0-9a-fA-F]+\b|\b0\b|-?\b[1-9][0-9]*\b'
comment: int literal
scope: constant.numeric.decimal.wgsl
- match: '\b0x[0-9a-fA-F]+u\b|\b0u\b|\b[1-9][0-9]*u\b'
comment: uint literal
scope: constant.numeric.decimal.wgsl
- match: \b(true|false)\b
comment: boolean constant
scope: constant.language.boolean.wgsl
function_calls:
- match: '([A-Za-z0-9_]+)(\()'
comment: function/method calls
captures:
1: entity.name.function.wgsl
2: punctuation.brackets.round.wgsl
push:
- meta_scope: meta.function.call.wgsl
- match: \)
captures:
0: punctuation.brackets.round.wgsl
pop: true
- include: line_comments
- include: block_comments
- include: keywords
- include: attributes
- include: function_calls
- include: constants
- include: types
- include: variables
- include: punctuation
functions:
- match: '\b(fn)\s+([A-Za-z0-9_]+)((\()|(<))'
comment: function definition
captures:
1: keyword.other.fn.wgsl
2: entity.name.function.wgsl
4: punctuation.brackets.round.wgsl
push:
- meta_scope: meta.function.definition.wgsl
- match: '\{'
captures:
0: punctuation.brackets.curly.wgsl
pop: true
- include: line_comments
- include: block_comments
- include: keywords
- include: attributes
- include: function_calls
- include: constants
- include: types
- include: variables
- include: punctuation
keywords:
- match: \b(bitcast|block|break|case|continue|continuing|default|discard|else|elseif|enable|fallthrough|for|function|if|loop|private|read|read_write|return|storage|switch|uniform|while|workgroup|write)\b
comment: other keywords
scope: keyword.control.wgsl
- match: \b(asm|const|do|enum|handle|mat|premerge|regardless|typedef|unless|using|vec|void)\b
comment: reserved keywords
scope: keyword.control.wgsl
- match: \b(let|var)\b
comment: storage keywords
scope: keyword.other.wgsl storage.type.wgsl
- match: \b(type)\b
comment: type keyword
scope: keyword.declaration.type.wgsl storage.type.wgsl
- match: \b(enum)\b
comment: enum keyword
scope: keyword.declaration.enum.wgsl storage.type.wgsl
- match: \b(struct)\b
comment: struct keyword
scope: keyword.declaration.struct.wgsl storage.type.wgsl
- match: \bfn\b
comment: fn
scope: keyword.other.fn.wgsl
- match: (\^|\||\|\||&&|<<|>>|!)(?!=)
comment: logical operators
scope: keyword.operator.logical.wgsl
- match: '&(?![&=])'
comment: logical AND, borrow references
scope: keyword.operator.borrow.and.wgsl
- match: (\+=|-=|\*=|/=|%=|\^=|&=|\|=|<<=|>>=)
comment: assignment operators
scope: keyword.operator.assignment.wgsl
- match: '(?<![<>])=(?!=|>)'
comment: single equal
scope: keyword.operator.assignment.equal.wgsl
- match: (=(=)?(?!>)|!=|<=|(?<!=)>=)
comment: comparison operators
scope: keyword.operator.comparison.wgsl
- match: '(([+%]|(\*(?!\w)))(?!=))|(-(?!>))|(/(?!/))'
comment: math operators
scope: keyword.operator.math.wgsl
- match: \.(?!\.)
comment: dot access
scope: keyword.operator.access.dot.wgsl
- match: '->'
comment: dashrocket, skinny arrow
scope: keyword.operator.arrow.skinny.wgsl
line_comments:
- match: \s*//.*
comment: single line comment
scope: comment.line.double-slash.wgsl
punctuation:
- match: ','
comment: comma
scope: punctuation.comma.wgsl
- match: '[{}]'
comment: curly braces
scope: punctuation.brackets.curly.wgsl
- match: '[()]'
comment: parentheses, round brackets
scope: punctuation.brackets.round.wgsl
- match: ;
comment: semicolon
scope: punctuation.semi.wgsl
- match: '[\[\]]'
comment: square brackets
scope: punctuation.brackets.square.wgsl
- match: '(?<![=-])[<>]'
comment: angle brackets
scope: punctuation.brackets.angle.wgsl
types:
- match: \b(bool|i32|u32|f32)\b
comment: scalar Types
scope: storage.type.wgsl
- match: \b(i64|u64|f64)\b
comment: reserved scalar Types
scope: storage.type.wgsl
- match: \b(vec2i|vec3i|vec4i|vec2u|vec3u|vec4u|vec2f|vec3f|vec4f|vec2h|vec3h|vec4h)\b
comment: vector type aliasses
scope: storage.type.wgsl
- match: \b(mat2x2f|mat2x3f|mat2x4f|mat3x2f|mat3x3f|mat3x4f|mat4x2f|mat4x3f|mat4x4f|mat2x2h|mat2x3h|mat2x4h|mat3x2h|mat3x3h|mat3x4h|mat4x2h|mat4x3h|mat4x4h)\b
comment: matrix type aliasses
scope: storage.type.wgsl
- match: '\b(vec[2-4]|mat[2-4]x[2-4])\b'
comment: vector/matrix types
scope: storage.type.wgsl
- match: \b(atomic)\b
comment: atomic types
scope: storage.type.wgsl
- match: \b(array)\b
comment: array types
scope: storage.type.wgsl
- match: '\b([A-Z][A-Za-z0-9]*)\b'
comment: Custom type
scope: entity.name.type.wgsl
variables:
- match: '\b(?<!(?<!\.)\.)(?:r#(?!(crate|[Ss]elf|super)))?[a-z0-9_]+\b'
comment: variables
scope: variable.other.wgsl

@ -1 +1 @@
Subproject commit 43dc527731731666d6d2b1311e86951a8ce07fec
Subproject commit 86d4ee7a1f884851a1d21d66249687f527fced32

106
build.rs
View File

@ -1,106 +0,0 @@
// TODO: Re-enable generation of shell completion files (below) when clap 3 is out.
// For more details, see https://github.com/sharkdp/bat/issues/372
// For bat-as-a-library, no build script is required. The build script is for
// the manpage and completions, which are only relevant to the bat application.
#[cfg(not(feature = "application"))]
fn main() {}
#[cfg(feature = "application")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::path::Path;
// Read environment variables.
let project_name = option_env!("PROJECT_NAME").unwrap_or("bat");
let executable_name = option_env!("PROJECT_EXECUTABLE").unwrap_or(project_name);
let executable_name_uppercase = executable_name.to_uppercase();
static PROJECT_VERSION: &str = env!("CARGO_PKG_VERSION");
/// Generates a file from a template.
fn template(
variables: &HashMap<&str, &str>,
in_file: &str,
out_file: impl AsRef<Path>,
) -> Result<(), Box<dyn Error>> {
let mut content = fs::read_to_string(in_file)?;
for (variable_name, value) in variables {
// Replace {{variable_name}} by the value
let pattern = format!("{{{{{variable_name}}}}}", variable_name = variable_name);
content = content.replace(&pattern, value);
}
fs::write(out_file, content)?;
Ok(())
}
let mut variables = HashMap::new();
variables.insert("PROJECT_NAME", project_name);
variables.insert("PROJECT_EXECUTABLE", executable_name);
variables.insert("PROJECT_EXECUTABLE_UPPERCASE", &executable_name_uppercase);
variables.insert("PROJECT_VERSION", PROJECT_VERSION);
let out_dir_env = std::env::var_os("OUT_DIR").expect("OUT_DIR to be set in build.rs");
let out_dir = Path::new(&out_dir_env);
fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
fs::create_dir_all(out_dir.join("assets/completions")).unwrap();
template(
&variables,
"assets/manual/bat.1.in",
out_dir.join("assets/manual/bat.1"),
)?;
template(
&variables,
"assets/completions/bat.bash.in",
out_dir.join("assets/completions/bat.bash"),
)?;
template(
&variables,
"assets/completions/bat.fish.in",
out_dir.join("assets/completions/bat.fish"),
)?;
template(
&variables,
"assets/completions/_bat.ps1.in",
out_dir.join("assets/completions/_bat.ps1"),
)?;
template(
&variables,
"assets/completions/bat.zsh.in",
out_dir.join("assets/completions/bat.zsh"),
)?;
Ok(())
}
// #[macro_use]
// extern crate clap;
// use clap::Shell;
// use std::fs;
// include!("src/clap_app.rs");
// const BIN_NAME: &str = "bat";
// fn main() {
// let outdir = std::env::var_os("SHELL_COMPLETIONS_DIR").or(std::env::var_os("OUT_DIR"));
// let outdir = match outdir {
// None => return,
// Some(outdir) => outdir,
// };
// fs::create_dir_all(&outdir).unwrap();
// let mut app = build_app(true);
// app.gen_completions(BIN_NAME, Shell::Bash, &outdir);
// app.gen_completions(BIN_NAME, Shell::Fish, &outdir);
// app.gen_completions(BIN_NAME, Shell::Zsh, &outdir);
// app.gen_completions(BIN_NAME, Shell::PowerShell, &outdir);
// }

67
build/application.rs Normal file
View File

@ -0,0 +1,67 @@
use std::{env, fs, path::PathBuf};
use crate::util::render_template;
/// Generate manpage and shell completions for the bat application.
pub fn gen_man_and_comp() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=assets/manual/");
println!("cargo:rerun-if-changed=assets/completions/");
println!("cargo:rerun-if-env-changed=PROJECT_NAME");
println!("cargo:rerun-if-env-changed=PROJECT_EXECUTABLE");
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");
println!("cargo:rerun-if-env-changed=BAT_ASSETS_GEN_DIR");
// Read environment variables.
let project_name = env::var("PROJECT_NAME").unwrap_or("bat".into());
let executable_name = env::var("PROJECT_EXECUTABLE").unwrap_or(project_name.clone());
let executable_name_uppercase = executable_name.to_uppercase();
let project_version = env::var("CARGO_PKG_VERSION")?;
let variables = [
("PROJECT_NAME", project_name),
("PROJECT_EXECUTABLE", executable_name),
("PROJECT_EXECUTABLE_UPPERCASE", executable_name_uppercase),
("PROJECT_VERSION", project_version),
]
.into_iter()
.collect();
let Some(out_dir) = env::var_os("BAT_ASSETS_GEN_DIR")
.or_else(|| env::var_os("OUT_DIR"))
.map(PathBuf::from)
else {
anyhow::bail!("BAT_ASSETS_GEN_DIR or OUT_DIR should be set for build.rs");
};
fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
fs::create_dir_all(out_dir.join("assets/completions")).unwrap();
render_template(
&variables,
"assets/manual/bat.1.in",
out_dir.join("assets/manual/bat.1"),
)?;
render_template(
&variables,
"assets/completions/bat.bash.in",
out_dir.join("assets/completions/bat.bash"),
)?;
render_template(
&variables,
"assets/completions/bat.fish.in",
out_dir.join("assets/completions/bat.fish"),
)?;
render_template(
&variables,
"assets/completions/_bat.ps1.in",
out_dir.join("assets/completions/_bat.ps1"),
)?;
render_template(
&variables,
"assets/completions/bat.zsh.in",
out_dir.join("assets/completions/bat.zsh"),
)?;
Ok(())
}

17
build/main.rs Normal file
View File

@ -0,0 +1,17 @@
#[cfg(feature = "application")]
mod application;
mod syntax_mapping;
mod util;
fn main() -> anyhow::Result<()> {
// only watch manually-designated files
// see: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed
println!("cargo:rerun-if-changed=build/");
syntax_mapping::build_static_mappings()?;
#[cfg(feature = "application")]
application::gen_man_and_comp()?;
Ok(())
}

294
build/syntax_mapping.rs Normal file
View File

@ -0,0 +1,294 @@
use std::{
convert::Infallible,
env, fs,
path::{Path, PathBuf},
str::FromStr,
};
use anyhow::{anyhow, bail};
use indexmap::IndexMap;
use itertools::Itertools;
use once_cell::sync::Lazy;
use regex::Regex;
use serde_derive::Deserialize;
use serde_with::DeserializeFromStr;
use walkdir::WalkDir;
/// Known mapping targets.
///
/// Corresponds to `syntax_mapping::MappingTarget`.
#[allow(clippy::enum_variant_names)]
#[derive(Clone, Debug, Eq, PartialEq, Hash, DeserializeFromStr)]
pub enum MappingTarget {
MapTo(String),
MapToUnknown,
MapExtensionToUnknown,
}
impl FromStr for MappingTarget {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"MappingTarget::MapToUnknown" => Ok(Self::MapToUnknown),
"MappingTarget::MapExtensionToUnknown" => Ok(Self::MapExtensionToUnknown),
syntax => Ok(Self::MapTo(syntax.into())),
}
}
}
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(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, DeserializeFromStr)]
/// A single matcher.
///
/// Codegen converts this into a `Lazy<Option<GlobMatcher>>`.
struct Matcher(Vec<MatcherSegment>);
/// Parse a matcher.
///
/// Note that this implementation is rather strict: it will greedily interpret
/// every valid environment variable replacement as such, then immediately
/// hard-error if it finds a '$' anywhere in the remaining text segments.
///
/// The reason for this strictness is I currently cannot think of a valid reason
/// why you would ever need '$' as plaintext in a glob pattern. Therefore any
/// such occurrences are likely human errors.
///
/// If we later discover some edge cases, it's okay to make it more permissive.
///
/// Revision history:
/// - 2024-02-20: allow `{` and `}` (glob brace expansion)
impl FromStr for Matcher {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use MatcherSegment as Seg;
static VAR_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"\$\{([\w\d_]+)\}").unwrap());
let mut segments = vec![];
let mut text_start = 0;
for capture in VAR_REGEX.captures_iter(s) {
let match_0 = capture.get(0).unwrap();
// text before this var
let text_end = match_0.start();
segments.push(Seg::Text(s[text_start..text_end].into()));
text_start = match_0.end();
// this var
segments.push(Seg::Env(capture.get(1).unwrap().as_str().into()));
}
// possible trailing text
segments.push(Seg::Text(s[text_start..].into()));
// cleanup empty text segments
let non_empty_segments = segments
.into_iter()
.filter(|seg| seg.text().map(|t| !t.is_empty()).unwrap_or(true))
.collect_vec();
// sanity check
if non_empty_segments
.windows(2)
.any(|segs| segs[0].is_text() && segs[1].is_text())
{
unreachable!("Parsed into consecutive text segments: {non_empty_segments:?}");
}
// guard empty case
if non_empty_segments.is_empty() {
bail!(r#"Parsed an empty matcher: "{s}""#);
}
// guard variable syntax leftover fragments
if non_empty_segments
.iter()
.filter_map(Seg::text)
.any(|t| t.contains('$'))
{
bail!(r#"Invalid matcher: "{s}""#);
}
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}"#)))"###)
}
// 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}]))"###)
}
}
}
}
/// A segment in a matcher.
///
/// Corresponds to `syntax_mapping::MatcherSegment`.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum MatcherSegment {
Text(String),
Env(String),
}
#[allow(dead_code)]
impl MatcherSegment {
fn is_text(&self) -> bool {
matches!(self, Self::Text(_))
}
fn is_env(&self) -> bool {
matches!(self, Self::Env(_))
}
fn text(&self) -> Option<&str> {
match self {
Self::Text(t) => Some(t),
Self::Env(_) => None,
}
}
fn env(&self) -> Option<&str> {
match self {
Self::Text(_) => None,
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/.
#[derive(Clone, Debug, Deserialize)]
struct MappingDefModel {
mappings: IndexMap<MappingTarget, Vec<Matcher>>,
}
impl MappingDefModel {
fn into_mapping_list(self) -> MappingList {
let list = self
.mappings
.into_iter()
.flat_map(|(target, matchers)| {
matchers
.into_iter()
.map(|matcher| (matcher, target.clone()))
.collect::<Vec<_>>()
})
.collect();
MappingList(list)
}
}
#[derive(Clone, Debug)]
struct MappingList(Vec<(Matcher, MappingTarget)>);
impl MappingList {
fn codegen(&self) -> String {
let array_items: Vec<_> = self
.0
.iter()
.map(|(matcher, target)| {
format!("({m}, {t})", m = matcher.codegen(), t = target.codegen())
})
.collect();
let len = array_items.len();
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")
)
}
}
/// Get the list of paths to all mapping definition files that should be
/// included for the current target platform.
fn get_def_paths() -> anyhow::Result<Vec<PathBuf>> {
let source_subdirs = [
"common",
#[cfg(target_family = "unix")]
"unix-family",
#[cfg(any(
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "macos"
))]
"bsd-family",
#[cfg(target_os = "linux")]
"linux",
#[cfg(target_os = "macos")]
"macos",
#[cfg(target_os = "windows")]
"windows",
];
let mut toml_paths = vec![];
for subdir in source_subdirs {
let wd = WalkDir::new(Path::new("src/syntax_mapping/builtins").join(subdir));
let paths = wd
.into_iter()
.filter_map_ok(|entry| {
let path = entry.path();
(path.is_file() && path.extension().map(|ext| ext == "toml").unwrap_or(false))
.then(|| path.to_owned())
})
.collect::<Result<Vec<_>, _>>()?;
toml_paths.extend(paths);
}
toml_paths.sort_by_key(|path| {
path.file_name()
.expect("file name should not terminate in ..")
.to_owned()
});
Ok(toml_paths)
}
fn read_all_mappings() -> anyhow::Result<MappingList> {
let mut all_mappings = vec![];
for path in get_def_paths()? {
let toml_string = fs::read_to_string(path)?;
let mappings = toml::from_str::<MappingDefModel>(&toml_string)?.into_mapping_list();
all_mappings.extend(mappings.0);
}
let duplicates = all_mappings
.iter()
.duplicates_by(|(matcher, _)| matcher)
.collect_vec();
if !duplicates.is_empty() {
bail!("Rules with duplicate matchers found: {duplicates:?}");
}
Ok(MappingList(all_mappings))
}
/// Build the static syntax mappings defined in /src/syntax_mapping/builtins/
/// into a .rs source file, which is to be inserted with `include!`.
pub fn build_static_mappings() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=src/syntax_mapping/builtins/");
let mappings = read_all_mappings()?;
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())?;
Ok(())
}

21
build/util.rs Normal file
View File

@ -0,0 +1,21 @@
#![allow(dead_code)]
use std::{collections::HashMap, fs, path::Path};
/// Generates a file from a template.
pub fn render_template(
variables: &HashMap<&str, String>,
in_file: &str,
out_file: impl AsRef<Path>,
) -> anyhow::Result<()> {
let mut content = fs::read_to_string(in_file)?;
for (variable_name, value) in variables {
// Replace {{variable_name}} by the value
let pattern = format!("{{{{{variable_name}}}}}");
content = content.replace(&pattern, value);
}
fs::write(out_file, content)?;
Ok(())
}

View File

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

View File

@ -214,7 +214,7 @@ man 2 select
## 설치
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/bat-cat/versions)
### Ubuntu에서 (`apt` 사용)
*... 그리고 다른 Debian 기반의 Linux 배포판들에서.*
@ -264,7 +264,7 @@ apk add bat
### Arch Linux에서
공식 소스를 통해
[`bat` 패키지](https://www.archlinux.org/packages/community/x86_64/bat/)를
[`bat` 패키지](https://www.archlinux.org/packages/extra/x86_64/bat/)를
설치할 수 있습니다:
```bash
@ -416,7 +416,7 @@ scoop install bat
### 소스에서
`bat`의 소스를 빌드하기 위해서는, Rust 1.64.0 이상이 필요합니다.
`bat`의 소스를 빌드하기 위해서는, Rust 1.70.0 이상이 필요합니다.
`cargo`를 이용해 전부 빌드할 수 있습니다:
```bash

View File

@ -12,7 +12,7 @@
<a href="#установка">Установка</a>
<a href="#кастомизация">Кастомизация</a>
<a href="#цели-и-альтернативы">Цели и альтернативы </a><br>
[<a href="../README.md">English]
[<a href="../README.md">English</a>]
[<a href="README-zh.md">中文</a>]
[<a href="README-ja.md">日本語</a>]
[<a href="README-ko.md">한국어</a>]
@ -130,8 +130,8 @@ git show v0.6.0:src/main.rs | bat -l rs
#### `xclip`
Нумерация стро и отображение изменений затрудняет копирование содержимого файлов в буфер обмена.
Чтобы спроваиться с этим, используйте флаг `-p`/`--plain` или просто перенаправьте стандартный вывод в `xclip`:
Нумерация строк и отображение изменений затрудняет копирование содержимого файлов в буфер обмена.
Чтобы справиться с этим, используйте флаг `-p`/`--plain` или просто перенаправьте стандартный вывод в `xclip`:
```bash
bat main.cpp | xclip
```
@ -160,7 +160,7 @@ man 2 select
## Установка
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/bat-cat/versions)
### Ubuntu (с помощью `apt`)
*... и другие дистрибутивы основанные на Debian.*
@ -201,7 +201,7 @@ apk add bat
### Arch Linux
Вы можете установить [`bat`](https://www.archlinux.org/packages/community/x86_64/bat/) из официального источника:
Вы можете установить [`bat`](https://www.archlinux.org/packages/extra/x86_64/bat/) из официального источника:
```bash
pacman -S bat
@ -344,7 +344,7 @@ ansible-galaxy install aeimer.install_bat
### Из исходников
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.64.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.70.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
```bash
cargo install --locked bat
@ -487,7 +487,7 @@ bat --generate-config-file
# Использовать синтаксис C++ для всех Arduino .ino файлов
--map-syntax "*.ino:C++"
# Использовать синтаксик Git Ignore для всех файлов .ignore
# Использовать синтаксис Git Ignore для всех файлов .ignore
--map-syntax ".ignore:Git Ignore"
```
@ -535,7 +535,7 @@ bat() {
`bat` поддерживает терминалы *с* и *без* поддержки truecolor. Однако подсветка синтаксиса не оптимизирована для терминалов с 8-битными цветами, и рекомендуется использовать терминалы с поддержкой 24-битных цветов (`terminator`, `konsole`, `iTerm2`, ...).
Смотрите [эту статью](https://gist.github.com/XVilka/8346728) для полного списка терминалов.
Удостовертесь, что переменная `COLORTERM` равна `truecolor` или
Удостоверьтесь, что переменная `COLORTERM` равна `truecolor` или
`24bit`. Иначе `bat` не сможет определить поддержку 24-битных цветов (и будет использовать 8-битные).
### Текст и номера строк плохо видны
@ -550,7 +550,7 @@ bat() {
``` bash
iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat
```
Внимание: вам может понадобится флаг `-l`/`--language`, если `bat` не сможет автоматически определить синтаксис.
Внимание: вам может понадобиться флаг `-l`/`--language`, если `bat` не сможет автоматически определить синтаксис.
## Разработка
@ -568,7 +568,7 @@ cargo test
# Установка (релизная версия)
cargo install --locked
# Компилирование исполняего файла bat с другим синтаксисом и темами
# Компилирование исполняемого файла bat с другим синтаксисом и темами
bash assets/create.sh
cargo install --locked --force
```
@ -592,6 +592,6 @@ cargo install --locked --force
## Лицензия
Copyright (c) 2018-2021 [Разработчики bat](https://github.com/sharkdp/bat).
`bat` распостраняется под лицензями MIT License и Apache License 2.0 (на выбор пользователя).
`bat` распространяется под лицензиями MIT License и Apache License 2.0 (на выбор пользователя).
Смотрите [LICENSE-APACHE](LICENSE-APACHE) и [LICENSE-MIT](LICENSE-MIT) для более подробного ознакомления.

View File

@ -191,7 +191,7 @@ man 2 select
## 安装
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/bat-cat/versions)
### Ubuntu (使用 `apt`)
@ -232,7 +232,7 @@ apk add bat
### Arch Linux
你可以用下面下列命令从官方源中安装[`bat`包](https://www.archlinux.org/packages/community/x86_64/bat/)
你可以用下面下列命令从官方源中安装[`bat`包](https://www.archlinux.org/packages/extra/x86_64/bat/)
```bash
pacman -S bat
@ -372,7 +372,7 @@ scoop install bat
### 从源码编译
如果你想要自己构建`bat`那么你需要安装有高于1.64.0版本的 Rust。
如果你想要自己构建`bat`那么你需要安装有高于1.70.0版本的 Rust。
使用以下命令编译。
@ -412,7 +412,7 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
### 输出样式
你可以用`--style`参数来控制`bat`输出的样式。使用`--style=numbers,chanegs`可以只开启 Git 修改和行号显示而不添加其他内容。`BAT_STYLE`环境变量具有相同功能。
你可以用`--style`参数来控制`bat`输出的样式。使用`--style=numbers,changes`可以只开启 Git 修改和行号显示而不添加其他内容。`BAT_STYLE`环境变量具有相同功能。
### 添加新的语言和语法

View File

@ -16,6 +16,9 @@ in the `.sublime-syntax` format.
2. If the Sublime Text syntax is only available as a `.tmLanguage` file, open the file in
Sublime Text and convert it to a `.sublime-syntax` file via *Tools* -> *Developer* ->
*New Syntax from XXX.tmLanguage...*. Save the new file in the `assets/syntaxes` folder.
If only `.tmLanguage.json` or `.tmLanguage.yml` file is available, use
[PackageDev](https://packagecontrol.io/packages/PackageDev) to convert it to `.tmLanguage.plist`
format and then rename the converted file to `.tmLanguage` file.
3. Run the `assets/create.sh` script. It calls `bat cache --build` to parse all available
`.sublime-syntax` files and serialize them to a `syntaxes.bin` file.
@ -84,6 +87,7 @@ The following files have been manually modified after converting from a `.tmLang
* `Org mode.sublime-syntax` => removed `task` file type.
* `Robot.sublime_syntax` => changed name to "Robot Framework", added `.resource` extension.
* `SML.sublime_syntax` => removed `ml` file type.
* `wgsl.sublime-syntax` => added `wgsl` file extension.
### Non-submodule additions

View File

@ -89,8 +89,8 @@ Options:
--paging <when>
Specify when to use the pager. To disable the pager, use --paging=never' or its
alias,'-P'. To disable the pager permanently, set BAT_PAGER to an empty string. To control
which pager is used, see the '--pager' option. Possible values: *auto*, never, always.
alias,'-P'. To disable the pager permanently, set BAT_PAGING to 'never'. To control which
pager is used, see the '--pager' option. Possible values: *auto*, never, always.
--pager <command>
Determine which pager is used. This option will override the PAGER and BAT_PAGER
@ -116,6 +116,12 @@ Options:
--list-themes
Display a list of supported themes for syntax highlighting.
-s, --squeeze-blank
Squeeze consecutive empty lines into a single empty line.
--squeeze-limit <squeeze-limit>
Set the maximum number of consecutive empty lines to be printed.
--style <components>
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
@ -123,6 +129,9 @@ Options:
set a default style, add the '--style=".."' option to the configuration file or export the
BAT_STYLE environment variable (e.g.: export BAT_STYLE="..").
By default, the following components are enabled:
changes, grid, header-filename, numbers, snip
Possible values:
* default: enables recommended style components (default).
@ -160,6 +169,9 @@ Options:
--acknowledgements
Show acknowledgements.
--set-terminal-title
Sets terminal title to filenames when using a pager.
-h, --help
Print help (see a summary with '-h')

View File

@ -9,7 +9,16 @@
- [ ] Update the version and the min. supported Rust version in `README.md` and
`doc/README-*.md`. Check with
`git grep -i -e 'rust.*1\.' -e '1\..*rust' | grep README | grep -v tests/`.
- [ ] Update `CHANGELOG.md`. Introduce a section for the new release.
## CHANGELOG.md updates
- [ ] Go to https://github.com/sharkdp/bat/releases/new, click "Choose a tag",
type the name of the tag that will be created later, click "Generate release
notes". DO NOT ACTUALLY CREATE ANY RELEASE IN THIS STEP.
- [ ] Compare current `CHANGELOG.md` with auto-generated release notes and add
missing entries. Expect in particular dependabot PRs to not be in
`CHANGELOG.md` since they are [auto-merged] if CI passes.
- [ ] Introduce a section for the new release and perform final touch-ups.
## Update syntaxes and themes (build assets)
@ -71,3 +80,5 @@
```
[auto-merged]: https://github.com/sharkdp/bat/blob/master/.github/workflows/Auto-merge-dependabot-PRs.yml

View File

@ -43,6 +43,8 @@ Options:
Set the color theme for syntax highlighting.
--list-themes
Display all supported highlighting themes.
-s, --squeeze-blank
Squeeze consecutive empty lines.
--style <components>
Comma-separated list of style elements to display (*default*, auto, full, plain, changes,
header, header-filename, header-filesize, grid, rule, numbers, snip).

BIN
doc/sponsors/warp-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

17
examples/buffer.rs Normal file
View File

@ -0,0 +1,17 @@
use bat::{assets::HighlightingAssets, config::Config, controller::Controller, Input};
fn main() {
let mut buffer = String::new();
let config = Config {
colored_output: true,
..Default::default()
};
let assets = HighlightingAssets::from_binary();
let controller = Controller::new(&config, &assets);
let input = Input::from_file(file!());
controller
.run(vec![input.into()], Some(&mut buffer))
.unwrap();
println!("{buffer}");
}

View File

@ -13,6 +13,6 @@ fn main() {
println!("Themes:");
for theme in printer.themes() {
println!("- {}", theme);
println!("- {theme}");
}
}

View File

@ -23,7 +23,8 @@ fn main() {
}],
};
let bytes = serde_yaml::to_vec(&person).unwrap();
let mut bytes = Vec::with_capacity(128);
serde_yaml::to_writer(&mut bytes, &person).unwrap();
PrettyPrinter::new()
.language("yaml")
.line_numbers(true)

View File

@ -380,7 +380,7 @@ fn asset_from_contents<T: serde::de::DeserializeOwned>(
} else {
bincode::deserialize_from(contents)
}
.map_err(|_| format!("Could not parse {}", description).into())
.map_err(|_| format!("Could not parse {description}").into())
}
fn asset_from_cache<T: serde::de::DeserializeOwned>(
@ -396,7 +396,7 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
)
})?;
asset_from_contents(&contents[..], description, compressed)
.map_err(|_| format!("Could not parse cached {}", description).into())
.map_err(|_| format!("Could not parse cached {description}").into())
}
#[cfg(target_os = "macos")]
@ -404,7 +404,7 @@ fn macos_dark_mode_active() -> bool {
const PREFERENCES_FILE: &str = "Library/Preferences/.GlobalPreferences.plist";
const STYLE_KEY: &str = "AppleInterfaceStyle";
let preferences_file = dirs::home_dir()
let preferences_file = home::home_dir()
.map(|home| home.join(PREFERENCES_FILE))
.expect("Could not get home directory");
@ -441,7 +441,7 @@ mod tests {
fn new() -> Self {
SyntaxDetectionTest {
assets: HighlightingAssets::from_binary(),
syntax_mapping: SyntaxMapping::builtin(),
syntax_mapping: SyntaxMapping::new(),
temp_dir: TempDir::new().expect("creation of temporary directory"),
}
}
@ -466,7 +466,7 @@ mod tests {
let file_path = self.temp_dir.path().join(file_name);
{
let mut temp_file = File::create(&file_path).unwrap();
writeln!(temp_file, "{}", first_line).unwrap();
writeln!(temp_file, "{first_line}").unwrap();
}
let input = Input::ordinary_file(&file_path);
@ -514,8 +514,7 @@ mod tests {
if !consistent {
eprintln!(
"Inconsistent syntax detection:\nFor File: {}\nFor Reader: {}",
as_file, as_reader
"Inconsistent syntax detection:\nFor File: {as_file}\nFor Reader: {as_reader}"
)
}

View File

@ -3,7 +3,7 @@ use std::path::Path;
use std::time::SystemTime;
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_derive::{Deserialize, Serialize};
use crate::error::*;

View File

@ -93,7 +93,7 @@ fn print_unlinked_contexts(syntax_set: &SyntaxSet) {
if !missing_contexts.is_empty() {
println!("Some referenced contexts could not be found!");
for context in missing_contexts {
println!("- {}", context);
println!("- {context}");
}
}
}
@ -152,7 +152,7 @@ pub(crate) fn asset_to_contents<T: serde::Serialize>(
} else {
bincode::serialize_into(&mut contents, asset)
}
.map_err(|_| format!("Could not serialize {}", description))?;
.map_err(|_| format!("Could not serialize {description}"))?;
Ok(contents)
}

View File

@ -80,7 +80,7 @@ fn handle_license(path: &Path) -> Result<Option<String>> {
} else if license_not_needed_in_acknowledgements(&license_text) {
Ok(None)
} else {
Err(format!("ERROR: License is of unknown type: {:?}", path).into())
Err(format!("ERROR: License is of unknown type: {path:?}").into())
}
}
@ -125,7 +125,7 @@ fn append_to_acknowledgements(
relative_path: &str,
license_text: &str,
) {
write!(acknowledgements, "## {}\n\n{}", relative_path, license_text).ok();
write!(acknowledgements, "## {relative_path}\n\n{license_text}").ok();
// Make sure the last char is a newline to not mess up formatting later
if acknowledgements

View File

@ -3,8 +3,7 @@ use super::*;
use std::collections::BTreeMap;
use std::convert::TryFrom;
use serde::Deserialize;
use serde::Serialize;
use serde_derive::{Deserialize, Serialize};
use once_cell::unsync::OnceCell;
@ -89,7 +88,7 @@ impl TryFrom<ThemeSet> for LazyThemeSet {
let lazy_theme = LazyTheme {
serialized: crate::assets::build_assets::asset_to_contents(
&theme,
&format!("theme {}", name),
&format!("theme {name}"),
COMPRESS_LAZY_THEMES,
)?,
deserialized: OnceCell::new(),

View File

@ -1,9 +1,8 @@
use std::collections::HashSet;
use std::env;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
use atty::{self, Stream};
use crate::{
clap_app,
config::{get_args_from_config_file, get_args_from_env_opts_var, get_args_from_env_vars},
@ -30,6 +29,10 @@ fn is_truecolor_terminal() -> bool {
.unwrap_or(false)
}
pub fn env_no_color() -> bool {
env::var_os("NO_COLOR").is_some_and(|x| !x.is_empty())
}
pub struct App {
pub matches: ArgMatches,
interactive_output: bool,
@ -40,7 +43,7 @@ impl App {
#[cfg(windows)]
let _ = nu_ansi_term::enable_ansi_support();
let interactive_output = atty::is(Stream::Stdout);
let interactive_output = std::io::stdout().is_terminal();
Ok(App {
matches: Self::matches(interactive_output)?,
@ -104,7 +107,7 @@ impl App {
// 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.
if self.interactive_output && !atty::is(Stream::Stdin) {
if self.interactive_output && !std::io::stdin().is_terminal() {
PagingMode::QuitIfOneScreen
} else {
PagingMode::Never
@ -118,7 +121,11 @@ impl App {
_ => unreachable!("other values for --paging are not allowed"),
};
let mut syntax_mapping = SyntaxMapping::builtin();
let mut syntax_mapping = SyntaxMapping::new();
// 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
syntax_mapping.start_offload_build_all();
if let Some(values) = self.matches.get_many::<String>("ignored-suffix") {
for suffix in values {
@ -127,7 +134,9 @@ impl App {
}
if let Some(values) = self.matches.get_many::<String>("map-syntax") {
for from_to in values {
// later args take precedence over earlier ones, hence `.rev()`
// see: https://github.com/sharkdp/bat/pull/2755#discussion_r1456416875
for from_to in values.rev() {
let parts: Vec<_> = from_to.split(':').collect();
if parts.len() != 2 {
@ -208,7 +217,7 @@ impl App {
|| match self.matches.get_one::<String>("color").map(|s| s.as_str()) {
Some("always") => true,
Some("never") => false,
Some("auto") => env::var_os("NO_COLOR").is_none() && self.interactive_output,
Some("auto") => !env_no_color() && self.interactive_output,
_ => unreachable!("other values for --color are not allowed"),
},
paging_mode,
@ -282,6 +291,19 @@ impl App {
.map(HighlightedLineRanges)
.unwrap_or_default(),
use_custom_assets: !self.matches.get_flag("no-custom-assets"),
#[cfg(feature = "lessopen")]
use_lessopen: self.matches.get_flag("lessopen"),
set_terminal_title: self.matches.get_flag("set-terminal-title"),
squeeze_lines: if self.matches.get_flag("squeeze-blank") {
Some(
self.matches
.get_one::<usize>("squeeze-limit")
.map(|limit| limit.to_owned())
.unwrap_or(1),
)
} else {
None
},
})
}

View File

@ -44,7 +44,7 @@ pub fn assets_from_cache_or_binary(
}
fn clear_asset(path: PathBuf, description: &str) {
print!("Clearing {} ... ", description);
print!("Clearing {description} ... ");
match fs::remove_file(&path) {
Err(err) if err.kind() == io::ErrorKind::NotFound => {
println!("skipped (not present)");

View File

@ -19,7 +19,7 @@ static VERSION: Lazy<String> = Lazy::new(|| {
});
pub fn build_app(interactive_output: bool) -> Command {
let color_when = if interactive_output && env::var_os("NO_COLOR").is_none() {
let color_when = if interactive_output && !crate::app::env_no_color() {
ColorChoice::Auto
} else {
ColorChoice::Never
@ -79,6 +79,7 @@ pub fn build_app(interactive_output: bool) -> Command {
Arg::new("plain")
.overrides_with("plain")
.overrides_with("number")
.overrides_with("paging")
.short('p')
.long("plain")
.action(ArgAction::Count)
@ -303,6 +304,7 @@ pub fn build_app(interactive_output: bool) -> Command {
.long("paging")
.overrides_with("paging")
.overrides_with("no-paging")
.overrides_with("plain")
.value_name("when")
.value_parser(["auto", "never", "always"])
.default_value("auto")
@ -311,7 +313,7 @@ pub fn build_app(interactive_output: bool) -> Command {
.long_help(
"Specify when to use the pager. To disable the pager, use \
--paging=never' or its alias,'-P'. To disable the pager permanently, \
set BAT_PAGER to an empty string. To control which pager is used, see the \
set BAT_PAGING to 'never'. To control which pager is used, see the \
'--pager' option. Possible values: *auto*, never, always."
),
)
@ -385,6 +387,21 @@ pub fn build_app(interactive_output: bool) -> Command {
.help("Display all supported highlighting themes.")
.long_help("Display a list of supported themes for syntax highlighting."),
)
.arg(
Arg::new("squeeze-blank")
.long("squeeze-blank")
.short('s')
.action(ArgAction::SetTrue)
.help("Squeeze consecutive empty lines.")
.long_help("Squeeze consecutive empty lines into a single empty line.")
)
.arg(
Arg::new("squeeze-limit")
.long("squeeze-limit")
.value_parser(|s: &str| s.parse::<usize>().map_err(|_| "Requires a non-negative number".to_owned()))
.long_help("Set the maximum number of consecutive empty lines to be printed.")
.hide_short_help(true)
)
.arg(
Arg::new("style")
.long("style")
@ -413,7 +430,7 @@ pub fn build_app(interactive_output: bool) -> Command {
});
if let Some(invalid) = invalid_vals.next() {
Err(format!("Unknown style, '{}'", invalid))
Err(format!("Unknown style, '{invalid}'"))
} else {
Ok(val.to_owned())
}
@ -430,6 +447,8 @@ pub fn build_app(interactive_output: bool) -> Command {
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=\"..\").\n\n\
By default, the following components are enabled:\n \
changes, grid, header-filename, numbers, snip\n\n\
Possible values:\n\n \
* default: enables recommended style components (default).\n \
* full: enables all available components.\n \
@ -497,7 +516,28 @@ pub fn build_app(interactive_output: bool) -> Command {
.action(ArgAction::SetTrue)
.hide(true)
.help("Do not load custom assets"),
)
);
#[cfg(feature = "lessopen")]
{
app = app
.arg(
Arg::new("lessopen")
.long("lessopen")
.action(ArgAction::SetTrue)
.help("Enable the $LESSOPEN preprocessor"),
)
.arg(
Arg::new("no-lessopen")
.long("no-lessopen")
.action(ArgAction::SetTrue)
.overrides_with("lessopen")
.hide(true)
.help("Disable the $LESSOPEN preprocessor if enabled (overrides --lessopen)"),
)
}
app = app
.arg(
Arg::new("config-file")
.long("config-file")
@ -536,7 +576,7 @@ pub fn build_app(interactive_output: bool) -> Command {
.alias("diagnostics")
.action(ArgAction::SetTrue)
.hide_short_help(true)
.help("Show diagnostic information for bug reports.")
.help("Show diagnostic information for bug reports."),
)
.arg(
Arg::new("acknowledgements")
@ -544,6 +584,13 @@ pub fn build_app(interactive_output: bool) -> Command {
.action(ArgAction::SetTrue)
.hide_short_help(true)
.help("Show acknowledgements."),
)
.arg(
Arg::new("set-terminal-title")
.long("set-terminal-title")
.action(ArgAction::SetTrue)
.hide_short_help(true)
.help("Sets terminal title to filenames when using a pager."),
);
// Check if the current directory contains a file name cache. Otherwise,

View File

@ -142,6 +142,7 @@ pub fn get_args_from_env_vars() -> Vec<OsString> {
("--tabs", "BAT_TABS"),
("--theme", "BAT_THEME"),
("--pager", "BAT_PAGER"),
("--paging", "BAT_PAGING"),
("--style", "BAT_STYLE"),
]
.iter()

View File

@ -1,12 +1,11 @@
use std::env;
use std::path::{Path, PathBuf};
use etcetera::BaseStrategy;
use once_cell::sync::Lazy;
/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
/// The `XDG_CACHE_HOME` environment variable is checked first. `BAT_CONFIG_DIR`
/// is then checked before the `XDG_CONFIG_HOME` environment variable.
/// The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively.
/// Wrapper for 'etcetera' that checks BAT_CACHE_PATH and BAT_CONFIG_DIR and falls back to the
/// Windows known folder locations on Windows & the XDG Base Directory Specification everywhere else.
pub struct BatProjectDirs {
cache_dir: PathBuf,
config_dir: PathBuf,
@ -14,25 +13,24 @@ pub struct BatProjectDirs {
impl BatProjectDirs {
fn new() -> Option<BatProjectDirs> {
let cache_dir = BatProjectDirs::get_cache_dir()?;
let basedirs = etcetera::choose_base_strategy().ok()?;
// Checks whether or not $BAT_CONFIG_DIR exists. If it doesn't, set our config dir
// to our system's default configuration home.
let config_dir =
if let Some(config_dir_op) = env::var_os("BAT_CONFIG_DIR").map(PathBuf::from) {
config_dir_op
} else {
#[cfg(target_os = "macos")]
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs::home_dir().map(|d| d.join(".config")));
// Checks whether or not `$BAT_CACHE_PATH` exists. If it doesn't, set the cache dir to our
// system's default cache home.
let cache_dir = if let Some(cache_dir) = env::var_os("BAT_CACHE_PATH").map(PathBuf::from) {
cache_dir
} else {
basedirs.cache_dir().join("bat")
};
#[cfg(not(target_os = "macos"))]
let config_dir_op = dirs::config_dir();
config_dir_op.map(|d| d.join("bat"))?
};
// Checks whether or not `$BAT_CONFIG_DIR` exists. If it doesn't, set the config dir to our
// system's default configuration home.
let config_dir = if let Some(config_dir) = env::var_os("BAT_CONFIG_DIR").map(PathBuf::from)
{
config_dir
} else {
basedirs.config_dir().join("bat")
};
Some(BatProjectDirs {
cache_dir,
@ -40,25 +38,6 @@ impl BatProjectDirs {
})
}
fn get_cache_dir() -> Option<PathBuf> {
// on all OS prefer BAT_CACHE_PATH if set
let cache_dir_op = env::var_os("BAT_CACHE_PATH").map(PathBuf::from);
if cache_dir_op.is_some() {
return cache_dir_op;
}
#[cfg(target_os = "macos")]
let cache_dir_op = env::var_os("XDG_CACHE_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs::home_dir().map(|d| d.join(".cache")));
#[cfg(not(target_os = "macos"))]
let cache_dir_op = dirs::cache_dir();
cache_dir_op.map(|d| d.join("bat"))
}
pub fn cache_dir(&self) -> &Path {
&self.cache_dir
}

View File

@ -30,6 +30,7 @@ use directories::PROJECT_DIRS;
use globset::GlobMatcher;
use bat::{
assets::HighlightingAssets,
config::Config,
controller::Controller,
error::*,
@ -78,9 +79,11 @@ fn run_cache_subcommand(
Ok(())
}
fn get_syntax_mapping_to_paths<'a>(
mappings: &[(GlobMatcher, MappingTarget<'a>)],
) -> HashMap<&'a str, Vec<String>> {
fn get_syntax_mapping_to_paths<'r, 't, I>(mappings: I) -> HashMap<&'t str, Vec<String>>
where
I: IntoIterator<Item = (&'r GlobMatcher, &'r MappingTarget<'t>)>,
't: 'r, // target text outlives rule
{
let mut map = HashMap::new();
for mapping in mappings {
if let (matcher, MappingTarget::MapTo(s)) = mapping {
@ -123,7 +126,7 @@ pub fn get_languages(config: &Config, cache_dir: &Path) -> Result<String> {
languages.sort_by_key(|lang| lang.name.to_uppercase());
let configured_languages = get_syntax_mapping_to_paths(config.syntax_mapping.mappings());
let configured_languages = get_syntax_mapping_to_paths(config.syntax_mapping.all_mappings());
for lang in &mut languages {
if let Some(additional_paths) = configured_languages.get(lang.name.as_str()) {
@ -197,19 +200,31 @@ pub fn list_themes(cfg: &Config, config_dir: &Path, cache_dir: &Path) -> Result<
let stdout = io::stdout();
let mut stdout = stdout.lock();
if config.colored_output {
for theme in assets.themes() {
let default_theme = HighlightingAssets::default_theme();
for theme in assets.themes() {
let default_theme_info = if default_theme == theme {
" (default)"
} else {
""
};
if config.colored_output {
writeln!(
stdout,
"Theme: {}\n",
Style::new().bold().paint(theme.to_string())
"Theme: {}{}\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()])
.run(vec![theme_preview_file()], None)
.ok();
writeln!(stdout)?;
} else {
writeln!(stdout, "{theme}{default_theme_info}")?;
}
}
if config.colored_output {
writeln!(
stdout,
"Further themes can be installed to '{}', \
@ -218,19 +233,36 @@ pub fn list_themes(cfg: &Config, config_dir: &Path, cache_dir: &Path) -> Result<
https://github.com/sharkdp/bat#adding-new-themes",
config_dir.join("themes").to_string_lossy()
)?;
} else {
for theme in assets.themes() {
writeln!(stdout, "{}", theme)?;
}
}
Ok(())
}
fn set_terminal_title_to(new_terminal_title: String) {
let osc_command_for_setting_terminal_title = "\x1b]0;";
let osc_end_command = "\x07";
print!("{osc_command_for_setting_terminal_title}{new_terminal_title}{osc_end_command}");
io::stdout().flush().unwrap();
}
fn get_new_terminal_title(inputs: &Vec<Input>) -> String {
let mut new_terminal_title = "bat: ".to_string();
for (index, input) in inputs.iter().enumerate() {
new_terminal_title += input.description().title();
if index < inputs.len() - 1 {
new_terminal_title += ", ";
}
}
new_terminal_title
}
fn run_controller(inputs: Vec<Input>, config: &Config, cache_dir: &Path) -> Result<bool> {
let assets = assets_from_cache_or_binary(config.use_custom_assets, cache_dir)?;
let controller = Controller::new(config, &assets);
controller.run(inputs)
if config.paging_mode != PagingMode::Never && config.set_terminal_title {
set_terminal_title_to(get_new_terminal_title(&inputs));
}
controller.run(inputs, None)
}
#[cfg(feature = "bugreport")]
@ -249,23 +281,25 @@ fn invoke_bugreport(app: &App, cache_dir: &Path) {
.info(OperatingSystem::default())
.info(CommandLine::default())
.info(EnvironmentVariables::list(&[
"SHELL",
"PAGER",
"LESS",
"LANG",
"LC_ALL",
"BAT_PAGER",
"BAT_CACHE_PATH",
"BAT_CONFIG_PATH",
"BAT_OPTS",
"BAT_PAGER",
"BAT_PAGING",
"BAT_STYLE",
"BAT_TABS",
"BAT_THEME",
"XDG_CONFIG_HOME",
"XDG_CACHE_HOME",
"COLORTERM",
"NO_COLOR",
"LANG",
"LC_ALL",
"LESS",
"MANPAGER",
"NO_COLOR",
"PAGER",
"SHELL",
"TERM",
"XDG_CACHE_HOME",
"XDG_CONFIG_HOME",
]))
.info(FileContent::new("System Config file", system_config_file()))
.info(FileContent::new("Config file", config_file()))

View File

@ -90,6 +90,16 @@ pub struct Config<'a> {
/// Whether or not to allow custom assets. If this is false or if custom assets (a.k.a.
/// cached assets) are not available, assets from the binary will be used instead.
pub use_custom_assets: bool,
// Whether or not to use $LESSOPEN if set
#[cfg(feature = "lessopen")]
pub use_lessopen: bool,
// Weather or not to set terminal title when using a pager
pub set_terminal_title: bool,
/// The maximum number of consecutive empty lines to display
pub squeeze_lines: Option<usize>,
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]

View File

@ -6,34 +6,48 @@ use crate::config::{Config, VisibleLines};
use crate::diff::{get_git_diff, LineChanges};
use crate::error::*;
use crate::input::{Input, InputReader, OpenedInput};
#[cfg(feature = "lessopen")]
use crate::lessopen::LessOpenPreprocessor;
#[cfg(feature = "git")]
use crate::line_range::LineRange;
use crate::line_range::{LineRanges, RangeCheckResult};
use crate::output::OutputType;
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
use crate::printer::{InteractivePrinter, OutputHandle, Printer, SimplePrinter};
use clircle::{Clircle, Identifier};
pub struct Controller<'a> {
config: &'a Config<'a>,
assets: &'a HighlightingAssets,
#[cfg(feature = "lessopen")]
preprocessor: Option<LessOpenPreprocessor>,
}
impl<'b> Controller<'b> {
pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {
Controller { config, assets }
Controller {
config,
assets,
#[cfg(feature = "lessopen")]
preprocessor: LessOpenPreprocessor::new().ok(),
}
}
pub fn run(&self, inputs: Vec<Input>) -> Result<bool> {
self.run_with_error_handler(inputs, default_error_handler)
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_with_error_handler(
&self,
inputs: Vec<Input>,
handle_error: impl Fn(&Error, &mut dyn Write),
output_buffer: Option<&mut dyn std::fmt::Write>,
mut handle_error: impl FnMut(&Error, &mut dyn Write),
) -> Result<bool> {
let mut output_type;
@ -74,7 +88,10 @@ impl<'b> Controller<'b> {
clircle::Identifier::stdout()
};
let writer = output_type.handle()?;
let mut writer = match output_buffer {
Some(buf) => OutputHandle::FmtWrite(buf),
None => OutputHandle::IoWrite(output_type.handle()?),
};
let mut no_errors: bool = true;
let stderr = io::stderr();
@ -82,16 +99,23 @@ impl<'b> Controller<'b> {
let identifier = stdout_identifier.as_ref();
let is_first = index == 0;
let result = if input.is_stdin() {
self.print_input(input, writer, io::stdin().lock(), identifier, is_first)
self.print_input(input, &mut writer, io::stdin().lock(), identifier, is_first)
} else {
// Use dummy stdin since stdin is actually not used (#1902)
self.print_input(input, writer, io::empty(), identifier, is_first)
self.print_input(input, &mut writer, io::empty(), identifier, is_first)
};
if let Err(error) = result {
if attached_to_pager {
handle_error(&error, writer);
} else {
handle_error(&error, &mut stderr.lock());
match writer {
// It doesn't make much sense to send errors straight to stderr if the user
// provided their own buffer, so we just return it.
OutputHandle::FmtWrite(_) => return Err(error),
OutputHandle::IoWrite(ref mut writer) => {
if attached_to_pager {
handle_error(&error, writer);
} else {
handle_error(&error, &mut stderr.lock());
}
}
}
no_errors = false;
}
@ -103,12 +127,23 @@ impl<'b> Controller<'b> {
fn print_input<R: BufRead>(
&self,
input: Input,
writer: &mut dyn Write,
writer: &mut OutputHandle,
stdin: R,
stdout_identifier: Option<&Identifier>,
is_first: bool,
) -> Result<()> {
let mut opened_input = input.open(stdin, stdout_identifier)?;
let mut opened_input = {
#[cfg(feature = "lessopen")]
match self.preprocessor {
Some(ref preprocessor) if self.config.use_lessopen => {
preprocessor.open(input, stdin, stdout_identifier)?
}
_ => input.open(stdin, stdout_identifier)?,
}
#[cfg(not(feature = "lessopen"))]
input.open(stdin, stdout_identifier)?
};
#[cfg(feature = "git")]
let line_changes = if self.config.visible_lines.diff_mode()
|| (!self.config.loop_through && self.config.style_components.changes())
@ -164,7 +199,7 @@ impl<'b> Controller<'b> {
fn print_file(
&self,
printer: &mut dyn Printer,
writer: &mut dyn Write,
writer: &mut OutputHandle,
input: &mut OpenedInput,
add_header_padding: bool,
#[cfg(feature = "git")] line_changes: &Option<LineChanges>,
@ -202,7 +237,7 @@ impl<'b> Controller<'b> {
fn print_file_ranges(
&self,
printer: &mut dyn Printer,
writer: &mut dyn Write,
writer: &mut OutputHandle,
reader: &mut InputReader,
line_ranges: &LineRanges,
) -> Result<()> {

View File

@ -46,7 +46,7 @@ impl Decoration for LineNumberDecoration {
_printer: &InteractivePrinter,
) -> DecorationText {
if continuation {
if line_number > self.cached_wrap_invalid_at {
if line_number >= self.cached_wrap_invalid_at {
let new_width = self.cached_wrap.width + 1;
return DecorationText {
text: self.color.paint(" ".repeat(new_width)).to_string(),
@ -56,7 +56,7 @@ impl Decoration for LineNumberDecoration {
self.cached_wrap.clone()
} else {
let plain: String = format!("{:4}", line_number);
let plain: String = format!("{line_number:4}");
DecorationText {
width: plain.len(),
text: self.color.paint(plain).to_string(),

View File

@ -7,6 +7,8 @@ pub enum Error {
#[error(transparent)]
Io(#[from] ::std::io::Error),
#[error(transparent)]
Fmt(#[from] ::std::fmt::Error),
#[error(transparent)]
SyntectError(#[from] ::syntect::Error),
#[error(transparent)]
SyntectLoadingError(#[from] ::syntect::LoadingError),
@ -26,6 +28,12 @@ pub enum Error {
InvalidPagerValueBat,
#[error("{0}")]
Msg(String),
#[cfg(feature = "lessopen")]
#[error(transparent)]
VarError(#[from] ::std::env::VarError),
#[cfg(feature = "lessopen")]
#[error(transparent)]
CommandParseError(#[from] ::shell_words::ParseError),
}
impl From<&'static str> for Error {

View File

@ -197,7 +197,7 @@ impl<'a> Input<'a> {
InputKind::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());
}
@ -256,7 +256,7 @@ pub(crate) struct InputReader<'a> {
}
impl<'a> InputReader<'a> {
fn new<R: BufRead + 'a>(mut reader: R) -> InputReader<'a> {
pub(crate) fn new<R: BufRead + 'a>(mut reader: R) -> InputReader<'a> {
let mut first_line = vec![];
reader.read_until(b'\n', &mut first_line).ok();

401
src/lessopen.rs Normal file
View File

@ -0,0 +1,401 @@
#![cfg(feature = "lessopen")]
use std::convert::TryFrom;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Cursor, Read, Write};
use std::path::PathBuf;
use std::str;
use clircle::{Clircle, Identifier};
use os_str_bytes::RawOsString;
use run_script::{IoOptions, ScriptOptions};
use crate::error::Result;
use crate::{
bat_warning,
input::{Input, InputKind, InputReader, OpenedInput, OpenedInputKind},
};
/// Preprocess files and/or stdin using $LESSOPEN and $LESSCLOSE
pub(crate) struct LessOpenPreprocessor {
lessopen: String,
lessclose: Option<String>,
command_options: ScriptOptions,
kind: LessOpenKind,
/// Whether or not data piped via stdin is to be preprocessed
preprocess_stdin: bool,
}
enum LessOpenKind {
Piped,
PipedIgnoreExitCode,
TempFile,
}
impl LessOpenPreprocessor {
/// Create a new instance of LessOpenPreprocessor
/// Will return Ok if and only if $LESSOPEN is set and contains exactly one %s
pub(crate) fn new() -> Result<LessOpenPreprocessor> {
let lessopen = env::var("LESSOPEN")?;
// Ignore $LESSOPEN if it does not contains exactly one %s
// 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);
return Err(error_msg.into());
}
// "||" means pipe directly to bat without making a temporary file
// Also, if preprocessor output is empty and exit code is zero, use the empty output
// Otherwise, if output is empty and exit code is nonzero, use original file contents
let (kind, lessopen) = if lessopen.starts_with("||") {
(LessOpenKind::Piped, lessopen.chars().skip(2).collect())
// "|" means pipe, but ignore exit code, always using preprocessor output
} else if lessopen.starts_with('|') {
(
LessOpenKind::PipedIgnoreExitCode,
lessopen.chars().skip(1).collect(),
)
// If neither appear, write output to a temporary file and read from that
} else {
(LessOpenKind::TempFile, lessopen)
};
// "-" means that stdin is preprocessed along with files and may appear alongside "|" and "||"
let (stdin, lessopen) = if lessopen.starts_with('-') {
(true, lessopen.chars().skip(1).collect())
} else {
(false, lessopen)
};
let mut command_options = ScriptOptions::new();
command_options.runner = env::var("SHELL").ok();
command_options.input_redirection = IoOptions::Pipe;
Ok(Self {
lessopen: lessopen.replacen("%s", "$1", 1),
lessclose: env::var("LESSCLOSE")
.ok()
.map(|str| str.replacen("%s", "$1", 1).replacen("%s", "$2", 1)),
command_options,
kind,
preprocess_stdin: stdin,
})
}
pub(crate) fn open<'a, R: BufRead + 'a>(
&self,
input: Input<'a>,
mut stdin: R,
stdout_identifier: Option<&Identifier>,
) -> Result<OpenedInput<'a>> {
let (lessopen_stdout, path_str, kind) = match input.kind {
InputKind::OrdinaryFile(ref path) => {
let path_str = match path.to_str() {
Some(str) => str,
None => return input.open(stdin, stdout_identifier),
};
let (exit_code, lessopen_stdout, _) = match run_script::run(
&self.lessopen,
&vec![path_str.to_string()],
&self.command_options,
) {
Ok(output) => output,
Err(_) => return input.open(stdin, stdout_identifier),
};
if self.fall_back_to_original_file(&lessopen_stdout, exit_code) {
return input.open(stdin, stdout_identifier);
}
(
RawOsString::from_string(lessopen_stdout),
path_str.to_string(),
OpenedInputKind::OrdinaryFile(path.to_path_buf()),
)
}
InputKind::StdIn => {
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))?;
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());
}
}
// stdin isn't Clone, so copy it to a cloneable buffer
let mut stdin_buffer = Vec::new();
stdin.read_to_end(&mut stdin_buffer).unwrap();
let mut lessopen_handle = match run_script::spawn(
&self.lessopen,
&vec!["-".to_string()],
&self.command_options,
) {
Ok(handle) => handle,
Err(_) => {
return input.open(stdin, stdout_identifier);
}
};
if lessopen_handle
.stdin
.as_mut()
.unwrap()
.write_all(&stdin_buffer.clone())
.is_err()
{
return input.open(stdin, stdout_identifier);
}
let lessopen_output = match lessopen_handle.wait_with_output() {
Ok(output) => output,
Err(_) => {
return input.open(Cursor::new(stdin_buffer), stdout_identifier);
}
};
if lessopen_output.stdout.is_empty()
&& (!lessopen_output.status.success()
|| matches!(self.kind, LessOpenKind::PipedIgnoreExitCode))
{
return input.open(Cursor::new(stdin_buffer), stdout_identifier);
}
(
RawOsString::assert_from_raw_vec(lessopen_output.stdout),
"-".to_string(),
OpenedInputKind::StdIn,
)
} else {
return input.open(stdin, stdout_identifier);
}
}
InputKind::CustomReader(_) => {
return input.open(stdin, stdout_identifier);
}
};
Ok(OpenedInput {
kind,
reader: InputReader::new(BufReader::new(
if matches!(self.kind, LessOpenKind::TempFile) {
// Remove newline at end of temporary file path returned by $LESSOPEN
let stdout = match lessopen_stdout.strip_suffix("\n") {
Some(stripped) => stripped.to_owned(),
None => lessopen_stdout,
};
let stdout = stdout.into_os_string();
let file = match File::open(PathBuf::from(&stdout)) {
Ok(file) => file,
Err(_) => {
return input.open(stdin, stdout_identifier);
}
};
Preprocessed {
kind: PreprocessedKind::TempFile(file),
lessclose: self.lessclose.clone(),
command_args: vec![path_str, stdout.to_str().unwrap().to_string()],
command_options: self.command_options.clone(),
}
} else {
Preprocessed {
kind: PreprocessedKind::Piped(Cursor::new(lessopen_stdout.into_raw_vec())),
lessclose: self.lessclose.clone(),
command_args: vec![path_str, "-".to_string()],
command_options: self.command_options.clone(),
}
},
)),
metadata: input.metadata,
description: input.description,
})
}
fn fall_back_to_original_file(&self, lessopen_output: &str, exit_code: i32) -> bool {
lessopen_output.is_empty()
&& (exit_code != 0 || matches!(self.kind, LessOpenKind::PipedIgnoreExitCode))
}
#[cfg(test)]
/// For testing purposes only
/// Create an instance of LessOpenPreprocessor with specified valued for $LESSOPEN and $LESSCLOSE
fn mock_new(lessopen: Option<&str>, lessclose: Option<&str>) -> Result<LessOpenPreprocessor> {
if let Some(command) = lessopen {
env::set_var("LESSOPEN", command)
} else {
env::remove_var("LESSOPEN")
}
if let Some(command) = lessclose {
env::set_var("LESSCLOSE", command)
} else {
env::remove_var("LESSCLOSE")
}
Self::new()
}
}
enum PreprocessedKind {
Piped(Cursor<Vec<u8>>),
TempFile(File),
}
impl Read for PreprocessedKind {
fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
match self {
PreprocessedKind::Piped(data) => data.read(buf),
PreprocessedKind::TempFile(data) => data.read(buf),
}
}
}
pub struct Preprocessed {
kind: PreprocessedKind,
lessclose: Option<String>,
command_args: Vec<String>,
command_options: ScriptOptions,
}
impl Read for Preprocessed {
fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
self.kind.read(buf)
}
}
impl Drop for Preprocessed {
fn drop(&mut self) {
if let Some(ref command) = self.lessclose {
self.command_options.output_redirection = IoOptions::Inherit;
run_script::run(command, &self.command_args, &self.command_options)
.expect("failed to run $LESSCLOSE to clean up file");
}
}
}
#[cfg(test)]
mod tests {
// All tests here are serial because they all involve reading and writing environment variables
// Running them in parallel causes these tests and some others to randomly fail
use serial_test::serial;
use super::*;
/// Reset environment variables after each test as a precaution
fn reset_env_vars() {
env::remove_var("LESSOPEN");
env::remove_var("LESSCLOSE");
}
#[test]
#[serial]
fn test_just_lessopen() -> Result<()> {
let preprocessor = LessOpenPreprocessor::mock_new(Some("|batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(preprocessor.lessclose.is_none());
reset_env_vars();
Ok(())
}
#[test]
#[serial]
fn test_just_lessclose() -> Result<()> {
let preprocessor = LessOpenPreprocessor::mock_new(None, Some("lessclose.sh %s %s"));
assert!(preprocessor.is_err());
reset_env_vars();
Ok(())
}
#[test]
#[serial]
fn test_both_lessopen_and_lessclose() -> Result<()> {
let preprocessor =
LessOpenPreprocessor::mock_new(Some("lessopen.sh %s"), Some("lessclose.sh %s %s"))?;
assert_eq!(preprocessor.lessopen, "lessopen.sh $1");
assert_eq!(preprocessor.lessclose.unwrap(), "lessclose.sh $1 $2");
reset_env_vars();
Ok(())
}
#[test]
#[serial]
fn test_lessopen_prefixes() -> Result<()> {
let preprocessor = LessOpenPreprocessor::mock_new(Some("batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(preprocessor.kind, LessOpenKind::TempFile));
assert!(!preprocessor.preprocess_stdin);
let preprocessor = LessOpenPreprocessor::mock_new(Some("|batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(
preprocessor.kind,
LessOpenKind::PipedIgnoreExitCode
));
assert!(!preprocessor.preprocess_stdin);
let preprocessor = LessOpenPreprocessor::mock_new(Some("||batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(preprocessor.kind, LessOpenKind::Piped));
assert!(!preprocessor.preprocess_stdin);
let preprocessor = LessOpenPreprocessor::mock_new(Some("-batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(preprocessor.kind, LessOpenKind::TempFile));
assert!(preprocessor.preprocess_stdin);
let preprocessor = LessOpenPreprocessor::mock_new(Some("|-batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(
preprocessor.kind,
LessOpenKind::PipedIgnoreExitCode
));
assert!(preprocessor.preprocess_stdin);
let preprocessor = LessOpenPreprocessor::mock_new(Some("||-batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert!(matches!(preprocessor.kind, LessOpenKind::Piped));
assert!(preprocessor.preprocess_stdin);
reset_env_vars();
Ok(())
}
#[test]
#[serial]
fn replace_part_of_argument() -> Result<()> {
let preprocessor =
LessOpenPreprocessor::mock_new(Some("|echo File:%s"), Some("echo File:%s Temp:%s"))?;
assert_eq!(preprocessor.lessopen, "echo File:$1");
assert_eq!(preprocessor.lessclose.unwrap(), "echo File:$1 Temp:$2");
reset_env_vars();
Ok(())
}
}

View File

@ -34,6 +34,8 @@ mod diff;
pub mod error;
pub mod input;
mod less;
#[cfg(feature = "lessopen")]
mod lessopen;
pub mod line_range;
pub(crate) mod nonprintable_notation;
mod output;

View File

@ -53,7 +53,7 @@ impl LineRange {
let more_lines = &line_numbers[1][1..]
.parse()
.map_err(|_| "Invalid character after +")?;
new_range.lower + more_lines
new_range.lower.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'+') {
@ -128,6 +128,13 @@ fn test_parse_plus() {
assert_eq!(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);
}
#[test]
fn test_parse_plus_fail() {
let range = LineRange::from("40:+z");

View File

@ -114,6 +114,10 @@ impl OutputType {
p.args(args);
}
p.env("LESSCHARSET", "UTF-8");
#[cfg(feature = "lessopen")]
// Ensures that 'less' does not preprocess input again if '$LESSOPEN' is set.
p.arg("--no-lessopen");
} else {
p.args(args);
};

View File

@ -91,31 +91,27 @@ pub fn replace_nonprintable(
});
line_idx = 0;
}
// carriage return
'\x0D' => output.push_str(match nonprintable_notation {
NonprintableNotation::Caret => "^M",
NonprintableNotation::Unicode => "",
}),
// null
'\x00' => output.push_str(match nonprintable_notation {
NonprintableNotation::Caret => "^@",
NonprintableNotation::Unicode => "",
}),
// bell
'\x07' => output.push_str(match nonprintable_notation {
NonprintableNotation::Caret => "^G",
NonprintableNotation::Unicode => "",
}),
// backspace
'\x08' => output.push_str(match nonprintable_notation {
NonprintableNotation::Caret => "^H",
NonprintableNotation::Unicode => "",
}),
// escape
'\x1B' => output.push_str(match nonprintable_notation {
NonprintableNotation::Caret => "^[",
NonprintableNotation::Unicode => "",
}),
// ASCII control characters
'\x00'..='\x1F' => {
let c = u32::from(chr);
match nonprintable_notation {
NonprintableNotation::Caret => {
let caret_character = char::from_u32(0x40 + c).unwrap();
write!(output, "^{caret_character}").ok();
}
NonprintableNotation::Unicode => {
let replacement_symbol = char::from_u32(0x2400 + c).unwrap();
output.push(replacement_symbol)
}
}
}
// delete
'\x7F' => match nonprintable_notation {
NonprintableNotation::Caret => output.push_str("^?"),
NonprintableNotation::Unicode => output.push('\u{2421}'),
},
// printable ASCII
c if c.is_ascii_alphanumeric()
|| c.is_ascii_punctuation()

View File

@ -230,6 +230,12 @@ impl<'a> PrettyPrinter<'a> {
self
}
/// Specify the maximum number of consecutive empty lines to print.
pub fn squeeze_empty_lines(&mut self, maximum: Option<usize>) -> &mut Self {
self.config.squeeze_lines = maximum;
self
}
/// Specify the highlighting theme
pub fn theme(&mut self, theme: impl AsRef<str>) -> &mut Self {
self.config.theme = theme.as_ref().to_owned();
@ -300,7 +306,7 @@ impl<'a> PrettyPrinter<'a> {
// Run the controller
let controller = Controller::new(&self.config, &self.assets);
controller.run(inputs.into_iter().map(|i| i.into()).collect())
controller.run(inputs.into_iter().map(|i| i.into()).collect(), None)
}
}

View File

@ -1,4 +1,5 @@
use std::io::Write;
use std::fmt;
use std::io;
use std::vec::Vec;
use nu_ansi_term::Color::{Fixed, Green, Red, Yellow};
@ -6,17 +7,15 @@ use nu_ansi_term::Style;
use bytesize::ByteSize;
use console::AnsiCodeIterator;
use syntect::easy::HighlightLines;
use syntect::highlighting::Color;
use syntect::highlighting::FontStyle;
use syntect::highlighting::Theme;
use syntect::parsing::SyntaxSet;
use content_inspector::ContentType;
use encoding::all::{UTF_16BE, UTF_16LE};
use encoding::{DecoderTrap, Encoding};
use encoding_rs::{UTF_16BE, UTF_16LE};
use unicode_width::UnicodeWidthChar;
@ -33,24 +32,68 @@ use crate::line_range::RangeCheckResult;
use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::style::StyleComponent;
use crate::terminal::{as_terminal_escaped, to_ansi_color};
use crate::vscreen::AnsiStyle;
use crate::vscreen::{AnsiStyle, EscapeSequence, EscapeSequenceIterator};
use crate::wrapping::WrappingMode;
const ANSI_UNDERLINE_ENABLE: EscapeSequence = EscapeSequence::CSI {
raw_sequence: "\x1B[4m",
parameters: "4",
intermediates: "",
final_byte: "m",
};
const ANSI_UNDERLINE_DISABLE: EscapeSequence = EscapeSequence::CSI {
raw_sequence: "\x1B[24m",
parameters: "24",
intermediates: "",
final_byte: "m",
};
const EMPTY_SYNTECT_STYLE: syntect::highlighting::Style = syntect::highlighting::Style {
foreground: Color {
r: 127,
g: 127,
b: 127,
a: 255,
},
background: Color {
r: 127,
g: 127,
b: 127,
a: 255,
},
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,
handle: &mut dyn Write,
handle: &mut OutputHandle,
input: &OpenedInput,
add_header_padding: bool,
) -> Result<()>;
fn print_footer(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()>;
fn print_footer(&mut self, handle: &mut OutputHandle, input: &OpenedInput) -> Result<()>;
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
fn print_snip(&mut self, handle: &mut OutputHandle) -> Result<()>;
fn print_line(
&mut self,
out_of_range: bool,
handle: &mut dyn Write,
handle: &mut OutputHandle,
line_number: usize,
line_buffer: &[u8],
) -> Result<()>;
@ -58,39 +101,58 @@ pub(crate) trait Printer {
pub struct SimplePrinter<'a> {
config: &'a Config<'a>,
consecutive_empty_lines: usize,
}
impl<'a> SimplePrinter<'a> {
pub fn new(config: &'a Config) -> Self {
SimplePrinter { config }
SimplePrinter {
config,
consecutive_empty_lines: 0,
}
}
}
impl<'a> Printer for SimplePrinter<'a> {
fn print_header(
&mut self,
_handle: &mut dyn Write,
_handle: &mut OutputHandle,
_input: &OpenedInput,
_add_header_padding: bool,
) -> Result<()> {
Ok(())
}
fn print_footer(&mut self, _handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
fn print_footer(&mut self, _handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
Ok(())
}
fn print_snip(&mut self, _handle: &mut dyn Write) -> Result<()> {
fn print_snip(&mut self, _handle: &mut OutputHandle) -> Result<()> {
Ok(())
}
fn print_line(
&mut self,
out_of_range: bool,
handle: &mut dyn Write,
handle: &mut OutputHandle,
_line_number: usize,
line_buffer: &[u8],
) -> 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')
.is_empty()
{
self.consecutive_empty_lines += 1;
if self.consecutive_empty_lines > squeeze_limit {
return Ok(());
}
} else {
self.consecutive_empty_lines = 0;
}
}
if !out_of_range {
if self.config.show_nonprintable {
let line = replace_nonprintable(
@ -98,9 +160,21 @@ impl<'a> Printer for SimplePrinter<'a> {
self.config.tab_width,
self.config.nonprintable_notation,
);
write!(handle, "{}", line)?;
write!(handle, "{line}")?;
} else {
handle.write_all(line_buffer)?
match handle {
OutputHandle::IoWrite(handle) => handle.write_all(line_buffer)?,
OutputHandle::FmtWrite(handle) => {
write!(
handle,
"{}",
std::str::from_utf8(line_buffer).map_err(|_| Error::Msg(
"encountered invalid utf8 while printing to non-io buffer"
.to_string()
))?
)?;
}
}
};
}
Ok(())
@ -132,6 +206,7 @@ pub(crate) struct InteractivePrinter<'a> {
pub line_changes: &'a Option<LineChanges>,
highlighter_from_set: Option<HighlighterFromSet<'a>>,
background_color_highlight: Option<Color>,
consecutive_empty_lines: usize,
}
impl<'a> InteractivePrinter<'a> {
@ -184,11 +259,13 @@ impl<'a> InteractivePrinter<'a> {
panel_width = 0;
}
let highlighter_from_set = if input
// Get the highlighter for the output.
let is_printing_binary = input
.reader
.content_type
.map_or(false, |c| c.is_binary() && !config.show_nonprintable)
{
.map_or(false, |c| c.is_binary() && !config.show_nonprintable);
let highlighter_from_set = if is_printing_binary || !config.colored_output {
None
} else {
// Determine the type of syntax for highlighting
@ -215,10 +292,15 @@ impl<'a> InteractivePrinter<'a> {
line_changes,
highlighter_from_set,
background_color_highlight,
consecutive_empty_lines: 0,
})
}
fn print_horizontal_line_term(&mut self, handle: &mut dyn Write, style: Style) -> Result<()> {
fn print_horizontal_line_term(
&mut self,
handle: &mut OutputHandle,
style: Style,
) -> Result<()> {
writeln!(
handle,
"{}",
@ -227,7 +309,7 @@ impl<'a> InteractivePrinter<'a> {
Ok(())
}
fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> {
fn print_horizontal_line(&mut self, handle: &mut OutputHandle, grid_char: char) -> Result<()> {
if self.panel_width == 0 {
self.print_horizontal_line_term(handle, self.colors.grid)?;
} else {
@ -251,13 +333,21 @@ impl<'a> InteractivePrinter<'a> {
" ".repeat(self.panel_width - 1 - text_truncated.len())
);
if self.config.style_components.grid() {
format!("{}", text_filled)
format!("{text_filled}")
} else {
text_filled
}
}
fn print_header_component_indent(&mut self, handle: &mut dyn Write) -> std::io::Result<()> {
fn get_header_component_indent_length(&self) -> usize {
if self.config.style_components.grid() && self.panel_width > 0 {
self.panel_width + 2
} else {
self.panel_width
}
}
fn print_header_component_indent(&mut self, handle: &mut OutputHandle) -> Result<()> {
if self.config.style_components.grid() {
write!(
handle,
@ -272,6 +362,55 @@ impl<'a> InteractivePrinter<'a> {
}
}
fn print_header_component_with_indent(
&mut self,
handle: &mut OutputHandle,
content: &str,
) -> Result<()> {
self.print_header_component_indent(handle)?;
writeln!(handle, "{content}")
}
fn print_header_multiline_component(
&mut self,
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;
}
self.print_header_component_with_indent(handle, content)
}
fn highlight_regions_for_line<'b>(
&mut self,
line: &'b str,
) -> Result<Vec<(syntect::highlighting::Style, &'b str)>> {
let highlighter_from_set = match self.highlighter_from_set {
Some(ref mut highlighter_from_set) => highlighter_from_set,
_ => return Ok(vec![(EMPTY_SYNTECT_STYLE, line)]),
};
// skip syntax highlighting on long lines
let too_long = line.len() > 1024 * 16;
let for_highlighting: &str = if too_long { "\n" } else { line };
let mut highlighted_line = highlighter_from_set
.highlighter
.highlight_line(for_highlighting, highlighter_from_set.syntax_set)?;
if too_long {
highlighted_line[0].1 = &line;
}
Ok(highlighted_line)
}
fn preprocess(&self, text: &str, cursor: &mut usize) -> String {
if self.config.tab_width > 0 {
return expand_tabs(text, self.config.tab_width, cursor);
@ -285,7 +424,7 @@ impl<'a> InteractivePrinter<'a> {
impl<'a> Printer for InteractivePrinter<'a> {
fn print_header(
&mut self,
handle: &mut dyn Write,
handle: &mut OutputHandle,
input: &OpenedInput,
add_header_padding: bool,
) -> Result<()> {
@ -347,31 +486,32 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
}
header_components.iter().try_for_each(|component| {
self.print_header_component_indent(handle)?;
match component {
StyleComponent::HeaderFilename => writeln!(
handle,
"{}{}{}",
description
.kind()
.map(|kind| format!("{}: ", kind))
.unwrap_or_else(|| "".into()),
self.colors.header_value.paint(description.title()),
mode
),
header_components
.iter()
.try_for_each(|component| match component {
StyleComponent::HeaderFilename => {
let header_filename = format!(
"{}{}{}",
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)
}
StyleComponent::HeaderFilesize => {
let bsize = metadata
.size
.map(|s| format!("{}", ByteSize(s)))
.unwrap_or_else(|| "-".into());
writeln!(handle, "Size: {}", self.colors.header_value.paint(bsize))
let header_filesize =
format!("Size: {}", self.colors.header_value.paint(bsize));
self.print_header_multiline_component(handle, &header_filesize)
}
_ => Ok(()),
}
})?;
})?;
if self.config.style_components.grid() {
if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
@ -384,7 +524,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
Ok(())
}
fn print_footer(&mut self, handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
if self.config.style_components.grid()
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
{
@ -394,7 +534,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
}
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()> {
fn print_snip(&mut self, handle: &mut OutputHandle) -> Result<()> {
let panel = self.create_fake_panel(" ...");
let panel_count = panel.chars().count();
@ -412,7 +552,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
"{}",
self.colors
.grid
.paint(format!("{}{}{}{}", panel, snip_left, title, snip_right))
.paint(format!("{panel}{snip_left}{title}{snip_right}"))
)?;
Ok(())
@ -421,7 +561,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
fn print_line(
&mut self,
out_of_range: bool,
handle: &mut dyn Write,
handle: &mut OutputHandle,
line_number: usize,
line_buffer: &[u8],
) -> Result<()> {
@ -431,58 +571,45 @@ impl<'a> Printer for InteractivePrinter<'a> {
self.config.tab_width,
self.config.nonprintable_notation,
)
.into()
} else {
let line = match self.content_type {
match self.content_type {
Some(ContentType::BINARY) | None => {
return Ok(());
}
Some(ContentType::UTF_16LE) => UTF_16LE
.decode(line_buffer, DecoderTrap::Replace)
.map_err(|_| "Invalid UTF-16LE")?,
Some(ContentType::UTF_16BE) => UTF_16BE
.decode(line_buffer, DecoderTrap::Replace)
.map_err(|_| "Invalid UTF-16BE")?,
_ => String::from_utf8_lossy(line_buffer).to_string(),
};
// Remove byte order mark from the first line if it exists
if line_number == 1 {
match line.strip_prefix('\u{feff}') {
Some(stripped) => stripped.to_string(),
None => line,
}
} else {
line
}
};
let regions = {
let highlighter_from_set = match self.highlighter_from_set {
Some(ref mut highlighter_from_set) => highlighter_from_set,
Some(ContentType::UTF_16LE) => UTF_16LE.decode_with_bom_removal(line_buffer).0,
Some(ContentType::UTF_16BE) => UTF_16BE.decode_with_bom_removal(line_buffer).0,
_ => {
return Ok(());
let line = String::from_utf8_lossy(line_buffer);
if line_number == 1 {
match line.strip_prefix('\u{feff}') {
Some(stripped) => stripped.to_string().into(),
None => line,
}
} else {
line
}
}
};
// skip syntax highlighting on long lines
let too_long = line.len() > 1024 * 16;
let for_highlighting: &str = if too_long { "\n" } else { &line };
let mut highlighted_line = highlighter_from_set
.highlighter
.highlight_line(for_highlighting, highlighter_from_set.syntax_set)?;
if too_long {
highlighted_line[0].1 = &line;
}
highlighted_line
};
let regions = self.highlight_regions_for_line(&line)?;
if out_of_range {
return Ok(());
}
// Skip squeezed lines.
if let Some(squeeze_limit) = self.config.squeeze_lines {
if line.trim_end_matches(|c| c == '\r' || c == '\n').is_empty() {
self.consecutive_empty_lines += 1;
if self.consecutive_empty_lines > squeeze_limit {
return Ok(());
}
} else {
self.consecutive_empty_lines = 0;
}
}
let mut cursor: usize = 0;
let mut cursor_max: usize = self.config.term_width;
let mut cursor_total: usize = 0;
@ -493,7 +620,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
self.config.highlighted_lines.0.check(line_number) == RangeCheckResult::InRange;
if highlight_this_line && self.config.theme == "ansi" {
self.ansi_style.update("^[4m");
self.ansi_style.update(ANSI_UNDERLINE_ENABLE);
}
let background_color = self
@ -520,23 +647,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
let italics = self.config.use_italic_text;
for &(style, region) in &regions {
let ansi_iterator = AnsiCodeIterator::new(region);
let ansi_iterator = EscapeSequenceIterator::new(region);
for chunk in ansi_iterator {
match chunk {
// ANSI escape passthrough.
(ansi, true) => {
self.ansi_style.update(ansi);
write!(handle, "{}", ansi)?;
}
// Regular text.
(text, false) => {
let text = &*self.preprocess(text, &mut cursor_total);
EscapeSequence::Text(text) => {
let text = self.preprocess(text, &mut cursor_total);
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
write!(
handle,
"{}",
"{}{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, text_trimmed),
@ -544,9 +665,11 @@ impl<'a> Printer for InteractivePrinter<'a> {
colored_output,
italics,
background_color
)
),
self.ansi_style.to_reset_sequence(),
)?;
// Pad the rest of the line.
if text.len() != text_trimmed.len() {
if let Some(background_color) = background_color {
let ansi_style = Style {
@ -564,6 +687,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
write!(handle, "{}", &text[text_trimmed.len()..])?;
}
}
// ANSI escape passthrough.
_ => {
write!(handle, "{}", chunk.raw())?;
self.ansi_style.update(chunk);
}
}
}
}
@ -573,17 +702,11 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
} else {
for &(style, region) in &regions {
let ansi_iterator = AnsiCodeIterator::new(region);
let ansi_iterator = EscapeSequenceIterator::new(region);
for chunk in ansi_iterator {
match chunk {
// ANSI escape passthrough.
(ansi, true) => {
self.ansi_style.update(ansi);
write!(handle, "{}", ansi)?;
}
// Regular text.
(text, false) => {
EscapeSequence::Text(text) => {
let text = self.preprocess(
text.trim_end_matches(|c| c == '\r' || c == '\n'),
&mut cursor_total,
@ -626,7 +749,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
// It wraps.
write!(
handle,
"{}\n{}",
"{}{}\n{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, line_buf),
@ -635,6 +758,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
self.config.use_italic_text,
background_color
),
self.ansi_style.to_reset_sequence(),
panel_wrap.clone().unwrap()
)?;
@ -663,6 +787,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
)
)?;
}
// ANSI escape passthrough.
_ => {
write!(handle, "{}", chunk.raw())?;
self.ansi_style.update(chunk);
}
}
}
}
@ -683,8 +813,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
if highlight_this_line && self.config.theme == "ansi" {
self.ansi_style.update("^[24m");
write!(handle, "\x1B[24m")?;
write!(handle, "{}", ANSI_UNDERLINE_DISABLE.raw())?;
self.ansi_style.update(ANSI_UNDERLINE_DISABLE);
}
Ok(())

View File

@ -80,7 +80,7 @@ impl FromStr for StyleComponent {
"full" => Ok(StyleComponent::Full),
"default" => Ok(StyleComponent::Default),
"plain" => Ok(StyleComponent::Plain),
_ => Err(format!("Unknown style '{}'", s).into()),
_ => Err(format!("Unknown style '{s}'").into()),
}
}
}

View File

@ -1,12 +1,31 @@
use std::path::Path;
use crate::error::Result;
use ignored_suffixes::IgnoredSuffixes;
use std::{
path::Path,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
};
use globset::{Candidate, GlobBuilder, GlobMatcher};
use once_cell::sync::Lazy;
use crate::error::Result;
use builtin::BUILTIN_MAPPINGS;
use ignored_suffixes::IgnoredSuffixes;
mod builtin;
pub mod ignored_suffixes;
fn make_glob_matcher(from: &str) -> Result<GlobMatcher> {
let matcher = GlobBuilder::new(from)
.case_insensitive(true)
.literal_separator(true)
.build()?
.compile_matcher();
Ok(matcher)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum MappingTarget<'a> {
@ -29,175 +48,108 @@ pub enum MappingTarget<'a> {
#[derive(Debug, Clone, Default)]
pub struct SyntaxMapping<'a> {
mappings: Vec<(GlobMatcher, MappingTarget<'a>)>,
/// User-defined mappings at run time.
///
/// Rules in front have precedence.
custom_mappings: Vec<(GlobMatcher, MappingTarget<'a>)>,
pub(crate) ignored_suffixes: IgnoredSuffixes<'a>,
/// A flag to halt glob matcher building, which is offloaded to another thread.
///
/// We have this so that we can signal the thread to halt early when appropriate.
halt_glob_build: Arc<AtomicBool>,
}
impl<'a> Drop for SyntaxMapping<'a> {
fn drop(&mut self) {
// signal the offload thread to halt early
self.halt_glob_build.store(true, Ordering::Relaxed);
}
}
impl<'a> SyntaxMapping<'a> {
pub fn empty() -> SyntaxMapping<'a> {
pub fn new() -> SyntaxMapping<'a> {
Default::default()
}
pub fn builtin() -> SyntaxMapping<'a> {
let mut mapping = Self::empty();
mapping.insert("*.h", MappingTarget::MapTo("C++")).unwrap();
mapping
.insert(".clang-format", MappingTarget::MapTo("YAML"))
.unwrap();
mapping.insert("*.fs", MappingTarget::MapTo("F#")).unwrap();
mapping
.insert("build", MappingTarget::MapToUnknown)
.unwrap();
mapping
.insert("**/.ssh/config", MappingTarget::MapTo("SSH Config"))
.unwrap();
mapping
.insert(
"**/bat/config",
MappingTarget::MapTo("Bourne Again Shell (bash)"),
)
.unwrap();
mapping
.insert(
"/etc/profile",
MappingTarget::MapTo("Bourne Again Shell (bash)"),
)
.unwrap();
mapping
.insert("*.pac", MappingTarget::MapTo("JavaScript (Babel)"))
.unwrap();
mapping
.insert("fish_history", MappingTarget::MapTo("YAML"))
.unwrap();
// See #2151, https://nmap.org/book/nse-language.html
mapping
.insert("*.nse", MappingTarget::MapTo("Lua"))
.unwrap();
// See #1008
mapping
.insert("rails", MappingTarget::MapToUnknown)
.unwrap();
// Nginx and Apache syntax files both want to style all ".conf" files
// see #1131 and #1137
mapping
.insert("*.conf", MappingTarget::MapExtensionToUnknown)
.unwrap();
for glob in &[
"/etc/nginx/**/*.conf",
"/etc/nginx/sites-*/**/*",
"nginx.conf",
"mime.types",
] {
mapping.insert(glob, MappingTarget::MapTo("nginx")).unwrap();
}
for glob in &[
"/etc/apache2/**/*.conf",
"/etc/apache2/sites-*/**/*",
"httpd.conf",
] {
mapping
.insert(glob, MappingTarget::MapTo("Apache Conf"))
.unwrap();
}
for glob in &[
"**/systemd/**/*.conf",
"**/systemd/**/*.example",
"*.automount",
"*.device",
"*.dnssd",
"*.link",
"*.mount",
"*.netdev",
"*.network",
"*.nspawn",
"*.path",
"*.service",
"*.scope",
"*.slice",
"*.socket",
"*.swap",
"*.target",
"*.timer",
] {
mapping.insert(glob, MappingTarget::MapTo("INI")).unwrap();
}
// unix mail spool
for glob in &["/var/spool/mail/*", "/var/mail/*"] {
mapping.insert(glob, MappingTarget::MapTo("Email")).unwrap()
}
// pacman hooks
mapping
.insert("*.hook", MappingTarget::MapTo("INI"))
.unwrap();
// Global git config files rooted in `$XDG_CONFIG_HOME/git/` or `$HOME/.config/git/`
// See e.g. https://git-scm.com/docs/git-config#FILES
if let Some(xdg_config_home) =
std::env::var_os("XDG_CONFIG_HOME").filter(|val| !val.is_empty())
{
insert_git_config_global(&mut mapping, &xdg_config_home);
}
if let Some(default_config_home) = std::env::var_os("HOME")
.filter(|val| !val.is_empty())
.map(|home| Path::new(&home).join(".config"))
{
insert_git_config_global(&mut mapping, &default_config_home);
}
fn insert_git_config_global(mapping: &mut SyntaxMapping, config_home: impl AsRef<Path>) {
let git_config_path = config_home.as_ref().join("git");
mapping
.insert(
&git_config_path.join("config").to_string_lossy(),
MappingTarget::MapTo("Git Config"),
)
.ok();
mapping
.insert(
&git_config_path.join("ignore").to_string_lossy(),
MappingTarget::MapTo("Git Ignore"),
)
.ok();
mapping
.insert(
&git_config_path.join("attributes").to_string_lossy(),
MappingTarget::MapTo("Git Attributes"),
)
.ok();
}
mapping
/// Start a thread to build the glob matchers for all builtin mappings.
///
/// The use of this function while not necessary, is useful to speed up startup
/// times by starting this work early in parallel.
///
/// The thread halts if/when `halt_glob_build` is set to true.
pub fn start_offload_build_all(&self) {
let halt = Arc::clone(&self.halt_glob_build);
thread::spawn(move || {
for (matcher, _) in BUILTIN_MAPPINGS.iter() {
if halt.load(Ordering::Relaxed) {
break;
}
Lazy::force(matcher);
}
});
// Note that this thread is not joined upon completion because there's
// no shared resources that need synchronization to be safely dropped.
// If we later add code into this thread that requires interesting
// resources (e.g. IO), it would be a good idea to store the handle
// and join it on drop.
}
pub fn insert(&mut self, from: &str, to: MappingTarget<'a>) -> Result<()> {
let glob = GlobBuilder::new(from)
.case_insensitive(false)
.literal_separator(true)
.build()?;
self.mappings.push((glob.compile_matcher(), to));
let matcher = make_glob_matcher(from)?;
self.custom_mappings.push((matcher, to));
Ok(())
}
pub fn mappings(&self) -> &[(GlobMatcher, MappingTarget<'a>)] {
&self.mappings
/// Returns an iterator over all mappings. User-defined mappings are listed
/// before builtin mappings; mappings in front have higher precedence.
///
/// Builtin mappings' `GlobMatcher`s are lazily compiled.
///
/// Note that this function only returns mappings that are valid under the
/// current environment. For details see [`Self::builtin_mappings`].
pub fn all_mappings(&self) -> impl Iterator<Item = (&GlobMatcher, &MappingTarget<'a>)> {
self.custom_mappings()
.iter()
.map(|(matcher, target)| (matcher, target)) // as_ref
.chain(
// we need a map with a closure to "do" the lifetime variance
// see: https://discord.com/channels/273534239310479360/1120124565591425034/1170543402870382653
// also, clippy false positive:
// see: https://github.com/rust-lang/rust-clippy/issues/9280
#[allow(clippy::map_identity)]
self.builtin_mappings().map(|rule| rule),
)
}
pub(crate) fn get_syntax_for(&self, path: impl AsRef<Path>) -> Option<MappingTarget<'a>> {
/// Returns an iterator over all valid builtin mappings. Mappings in front
/// have higher precedence.
///
/// The `GlabMatcher`s are lazily compiled.
///
/// Mappings that are invalid under the current environment (i.e. rule
/// requires environment variable(s) that is unset, or the joined string
/// after variable(s) replacement is not a valid glob expression) are
/// ignored.
pub fn builtin_mappings(
&self,
) -> impl Iterator<Item = (&'static GlobMatcher, &'static MappingTarget<'static>)> {
BUILTIN_MAPPINGS
.iter()
.filter_map(|(matcher, target)| matcher.as_ref().map(|glob| (glob, target)))
}
/// Returns all user-defined mappings.
pub fn custom_mappings(&self) -> &[(GlobMatcher, MappingTarget<'a>)] {
&self.custom_mappings
}
pub fn get_syntax_for(&self, path: impl AsRef<Path>) -> Option<MappingTarget<'a>> {
// Try matching on the file name as-is.
let candidate = Candidate::new(&path);
let candidate_filename = path.as_ref().file_name().map(Candidate::new);
for (ref glob, ref syntax) in self.mappings.iter().rev() {
for (glob, syntax) in self.all_mappings() {
if glob.is_match_candidate(&candidate)
|| candidate_filename
.as_ref()
@ -220,48 +172,93 @@ impl<'a> SyntaxMapping<'a> {
}
}
#[test]
fn basic() {
let mut map = SyntaxMapping::empty();
map.insert("/path/to/Cargo.lock", MappingTarget::MapTo("TOML"))
.ok();
map.insert("/path/to/.ignore", MappingTarget::MapTo("Git Ignore"))
.ok();
#[cfg(test)]
mod tests {
use super::*;
assert_eq!(
map.get_syntax_for("/path/to/Cargo.lock"),
Some(MappingTarget::MapTo("TOML"))
);
assert_eq!(map.get_syntax_for("/path/to/other.lock"), None);
#[test]
fn builtin_mappings_work() {
let map = SyntaxMapping::new();
assert_eq!(
map.get_syntax_for("/path/to/.ignore"),
Some(MappingTarget::MapTo("Git Ignore"))
);
}
#[test]
fn user_can_override_builtin_mappings() {
let mut map = SyntaxMapping::builtin();
assert_eq!(
map.get_syntax_for("/etc/profile"),
Some(MappingTarget::MapTo("Bourne Again Shell (bash)"))
);
map.insert("/etc/profile", MappingTarget::MapTo("My Syntax"))
.ok();
assert_eq!(
map.get_syntax_for("/etc/profile"),
Some(MappingTarget::MapTo("My Syntax"))
);
}
#[test]
fn builtin_mappings() {
let map = SyntaxMapping::builtin();
assert_eq!(
map.get_syntax_for("/path/to/build"),
Some(MappingTarget::MapToUnknown)
);
assert_eq!(
map.get_syntax_for("/path/to/build"),
Some(MappingTarget::MapToUnknown)
);
}
#[test]
fn all_fixed_builtin_mappings_can_compile() {
let map = SyntaxMapping::new();
// collect call evaluates all lazy closures
// fixed builtin mappings will panic if they fail to compile
let _mappings = map.builtin_mappings().collect::<Vec<_>>();
}
#[test]
fn builtin_mappings_matcher_only_compile_once() {
let map = SyntaxMapping::new();
let two_iterations: Vec<_> = (0..2)
.map(|_| {
// addresses of every matcher
map.builtin_mappings()
.map(|(matcher, _)| matcher as *const _ as usize)
.collect::<Vec<_>>()
})
.collect();
// if the matchers are only compiled once, their address should remain the same
assert_eq!(two_iterations[0], two_iterations[1]);
}
#[test]
fn custom_mappings_work() {
let mut map = SyntaxMapping::new();
map.insert("/path/to/Cargo.lock", MappingTarget::MapTo("TOML"))
.ok();
map.insert("/path/to/.ignore", MappingTarget::MapTo("Git Ignore"))
.ok();
assert_eq!(
map.get_syntax_for("/path/to/Cargo.lock"),
Some(MappingTarget::MapTo("TOML"))
);
assert_eq!(map.get_syntax_for("/path/to/other.lock"), None);
assert_eq!(
map.get_syntax_for("/path/to/.ignore"),
Some(MappingTarget::MapTo("Git Ignore"))
);
}
#[test]
fn custom_mappings_override_builtin() {
let mut map = SyntaxMapping::new();
assert_eq!(
map.get_syntax_for("/path/to/httpd.conf"),
Some(MappingTarget::MapTo("Apache Conf"))
);
map.insert("httpd.conf", MappingTarget::MapTo("My Syntax"))
.ok();
assert_eq!(
map.get_syntax_for("/path/to/httpd.conf"),
Some(MappingTarget::MapTo("My Syntax"))
);
}
#[test]
fn custom_mappings_precedence() {
let mut map = SyntaxMapping::new();
map.insert("/path/to/foo", MappingTarget::MapTo("alpha"))
.ok();
map.insert("/path/to/foo", MappingTarget::MapTo("bravo"))
.ok();
assert_eq!(
map.get_syntax_for("/path/to/foo"),
Some(MappingTarget::MapTo("alpha"))
);
}
}

View File

@ -0,0 +1,91 @@
use std::env;
use globset::GlobMatcher;
use once_cell::sync::Lazy;
use crate::syntax_mapping::{make_glob_matcher, MappingTarget};
// Static syntax mappings generated from /src/syntax_mapping/builtins/ by the
// build script (/build/syntax_mapping.rs).
include!(concat!(
env!("OUT_DIR"),
"/codegen_static_syntax_mappings.rs"
));
// The defined matcher strings are analysed at compile time and converted into
// lazily-compiled `GlobMatcher`s. This is so that the string searches are moved
// from run time to compile time, thus improving startup performance.
//
// To any future maintainer (including possibly myself) wondering why there is
// not a `BuiltinMatcher` enum that looks like this:
//
// ```
// enum BuiltinMatcher {
// Fixed(&'static str),
// Dynamic(Lazy<Option<String>>),
// }
// ```
//
// Because there was. I tried it and threw it out.
//
// Naively looking at the problem from a distance, this may seem like a good
// design (strongly typed etc. etc.). It would also save on compiled size by
// extracting out common behaviour into functions. But while actually
// implementing the lazy matcher compilation logic, I realised that it's most
// convenient for `BUILTIN_MAPPINGS` to have the following type:
//
// `[(Lazy<Option<GlobMatcher>>, MappingTarget); N]`
//
// The benefit for this is that operations like listing all builtin mappings
// would be effectively memoised. The caller would not have to compile another
// `GlobMatcher` for rules that they have previously visited.
//
// Unfortunately, this means we are going to have to store a distinct closure
// for each rule anyway, which makes a `BuiltinMatcher` enum a pointless layer
// of indirection.
//
// In the current implementation, the closure within each generated rule simply
// calls either `build_matcher_fixed` or `build_matcher_dynamic`, depending on
// whether the defined matcher contains dynamic segments or not.
/// Compile a fixed glob string into a glob matcher.
///
/// A failure to compile is a fatal error.
///
/// Used internally by `Lazy<Option<GlobMatcher>>`'s lazy evaluation closure.
fn build_matcher_fixed(from: &str) -> GlobMatcher {
make_glob_matcher(from).expect("A builtin fixed glob matcher failed to compile")
}
/// Join a list of matcher segments to create a glob string, replacing all
/// environment variables, then compile to a glob matcher.
///
/// Returns `None` if any replacement fails, or if the joined glob string fails
/// to compile.
///
/// Used internally by `Lazy<Option<GlobMatcher>>`'s lazy evaluation closure.
fn build_matcher_dynamic(segs: &[MatcherSegment]) -> Option<GlobMatcher> {
// join segments
let mut buf = String::new();
for seg in segs {
match seg {
MatcherSegment::Text(s) => buf.push_str(s),
MatcherSegment::Env(var) => {
let replaced = env::var(var).ok()?;
buf.push_str(&replaced);
}
}
}
// compile glob matcher
let matcher = make_glob_matcher(&buf).ok()?;
Some(matcher)
}
/// A segment of a dynamic builtin matcher.
///
/// Used internally by `Lazy<Option<GlobMatcher>>`'s lazy evaluation closure.
#[derive(Clone, Debug)]
enum MatcherSegment {
Text(&'static str),
Env(&'static str),
}

View File

@ -0,0 +1,116 @@
# `/src/syntax_mapping/builtins`
The files in this directory define path/name-based syntax mappings, which amend
and take precedence over the extension/content-based syntax mappings provided by
[syntect](https://github.com/trishume/syntect).
## File organisation
Each TOML file should describe the syntax mappings of a single application, or
otherwise a set of logically-related rules.
What defines "a single application" here is deliberately vague, since the
file-splitting is purely for maintainability reasons. (Technically, we could
just as well use a single TOML file.) So just use common sense.
TOML files should reside in the corresponding subdirectory of the platform(s)
that they intend to target. At compile time, the build script will go through
each subdirectory that is applicable to the compilation target, collect the
syntax mappings defined by all TOML files, and embed them into the binary.
## File syntax
Each TOML file should contain a single section named `mappings`, with each of
its keys being a language identifier (first column of `bat -L`; also referred to
as "target").
The value of each key should be an array of strings, with each item being a glob
matcher. We will call each of these items a "rule".
For example, if `foo-application` uses both TOML and YAML configuration files,
we could write something like this:
```toml
# 30-foo-application.toml
[mappings]
"TOML" = [
# rules for TOML syntax go here
"/usr/share/foo-application/toml-config/*.conf",
"/etc/foo-application/toml-config/*.conf",
]
"YAML" = [
# rules for YAML syntax go here
# ...
]
```
### Dynamic environment variable replacement
In additional to the standard glob matcher syntax, rules also support dynamic
replacement of environment variables at runtime. This allows us to concisely
handle things like [XDG](https://specifications.freedesktop.org/basedir-spec/latest/).
All environment variables intended to be replaced at runtime must be enclosed in
`${}`, for example `"/foo/*/${YOUR_ENV}-suffix/*.log"`. Note that this is the
**only** admissible syntax; other variable substitution syntaxes are not
supported and will either cause a compile time error, or be treated as plain
text.
For example, if `foo-application` also supports per-user configuration files, we
could write something like this:
```toml
# 30-foo-application.toml
[mappings]
"TOML" = [
# rules for TOML syntax go here
"/usr/share/foo-application/toml-config/*.conf",
"/etc/foo-application/toml-config/*.conf",
"${XDG_CONFIG_HOME}/foo-application/toml-config/*.conf",
"${HOME}/.config/foo-application/toml-config/*.conf",
]
"YAML" = [
# rules for YAML syntax go here
# ...
]
```
If any environment variable replacement in a rule fails (for example when a
variable is unset), or if the glob string after replacements is invalid, the
entire rule will be ignored.
### Explicitly mapping to unknown
Sometimes it may be necessary to "unset" a particular syntect mapping - perhaps
a syntax's matching rules are "too greedy", and is claiming files that it should
not. In this case, there are two special identifiers:
`MappingTarget::MapToUnknown` and `MappingTarget::MapExtensionToUnknown`
(corresponding to the two variants of the `syntax_mapping::MappingTarget` enum).
An example of this would be `*.conf` files in general. So we may write something
like this:
```toml
# 99-unset-ambiguous-extensions.toml
[mappings]
"MappingTarget::MapExtensionToUnknown" = [
"*.conf",
]
```
## Ordering
At compile time, all TOML files applicable to the target are processed in
lexicographical filename order. So `00-foo.toml` takes precedence over
`10-bar.toml`, which takes precedence over `20-baz.toml`, and so on. Note that
**only** the filenames of the TOML files are taken into account; the
subdirectories they are placed in have no influence on ordering.
This behaviour can be occasionally useful for creating high/low priority rules,
such as in the aforementioned example of explicitly mapping `*.conf` files to
unknown. Generally this should not be much of a concern though, since rules
should be written as specifically as possible for each application.
Rules within each TOML file are processed (and therefore matched) in the order
in which they are defined. At runtime, the syntax selection algorithm will
short-circuit and return the target of the first matching rule.

View File

@ -0,0 +1,2 @@
[mappings]
"Bourne Again Shell (bash)" = ["/etc/os-release", "/var/run/os-release"]

View File

@ -0,0 +1,2 @@
[mappings]
"Apache Conf" = ["httpd.conf"]

View File

@ -0,0 +1,2 @@
[mappings]
"INI" = ["**/.aws/credentials", "**/.aws/config"]

View File

@ -0,0 +1,2 @@
[mappings]
"Bourne Again Shell (bash)" = ["**/bat/config"]

View File

@ -0,0 +1,2 @@
[mappings]
"Dockerfile" = ["Containerfile"]

View File

@ -0,0 +1,6 @@
[mappings]
"C++" = [
# probably better than the default Objective C mapping #877
"*.h",
]
"YAML" = [".clang-format"]

View File

@ -0,0 +1,2 @@
[mappings]
"F#" = ["*.fs"]

View File

@ -0,0 +1,10 @@
# Global git config files rooted in `$XDG_CONFIG_HOME/git/` or `$HOME/.config/git/`
# See e.g. https://git-scm.com/docs/git-config#FILES
[mappings]
"Git Config" = ["${XDG_CONFIG_HOME}/git/config", "${HOME}/.config/git/config"]
"Git Ignore" = ["${XDG_CONFIG_HOME}/git/ignore", "${HOME}/.config/git/ignore"]
"Git Attributes" = [
"${XDG_CONFIG_HOME}/git/attributes",
"${HOME}/.config/git/attributes",
]

View File

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

View File

@ -0,0 +1,2 @@
[mappings]
"nginx" = ["nginx.conf", "mime.types"]

View File

@ -0,0 +1,3 @@
[mappings]
# See #2151, https://nmap.org/book/nse-language.html
"Lua" = ["*.nse"]

View File

@ -0,0 +1,3 @@
# 1515
[mappings]
"JavaScript (Babel)" = ["*.pac"]

View File

@ -0,0 +1,3 @@
# Rusty Object Notation #2427
[mappings]
"Rust" = ["*.ron"]

View File

@ -0,0 +1,3 @@
# SARIF is a format for reporting static analysis results #2695
[mappings]
"JSON" = ["*.sarif"]

View File

@ -0,0 +1,2 @@
[mappings]
"SSH Config" = ["**/.ssh/config"]

View File

@ -0,0 +1,5 @@
[mappings]
"MappingTarget::MapExtensionToUnknown" = [
# common extension used for all kinds of formats
"*.conf",
]

View File

@ -0,0 +1,7 @@
[mappings]
"MappingTarget::MapToUnknown" = [
# "NAnt Build File" should only match *.build files, not files named "build"
"build",
# "bin/rails" scripts in a Ruby project misidentified as HTML (Rails) #1008
"rails",
]

View File

@ -0,0 +1,3 @@
# Xonsh shell (https://xon.sh/)
[mappings]
"Python" = ["*.xsh", "*.xonshrc"]

View File

@ -0,0 +1,8 @@
# see https://github.com/containers/image/tree/main/docs
[mappings]
"TOML" = [
"/usr/share/containers/**/*.conf",
"/etc/containers/**/*.conf",
"${HOME}/.config/containers/**/*.conf",
"${XDG_CONFIG_HOME}/containers/**/*.conf",
]

View File

@ -0,0 +1,7 @@
[mappings]
"Bourne Again Shell (bash)" = [
"/etc/os-release",
"/usr/lib/os-release",
"/etc/initrd-release",
"/usr/lib/extension-release.d/extension-release.*",
]

View File

@ -0,0 +1,3 @@
[mappings]
# pacman hooks
"INI" = ["/usr/share/libalpm/hooks/*.hook", "/etc/pacman.d/hooks/*.hook"]

View File

@ -0,0 +1,7 @@
# 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}",
]

View File

@ -0,0 +1,21 @@
[mappings]
"INI" = [
"**/systemd/**/*.conf",
"**/systemd/**/*.example",
"*.automount",
"*.device",
"*.dnssd",
"*.link",
"*.mount",
"*.netdev",
"*.network",
"*.nspawn",
"*.path",
"*.service",
"*.scope",
"*.slice",
"*.socket",
"*.swap",
"*.target",
"*.timer",
]

View File

@ -0,0 +1,2 @@
[mappings]
"Apache Conf" = ["/etc/apache2/**/*.conf", "/etc/apache2/sites-*/**/*"]

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