1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-09-01 19:02:22 +01:00

Compare commits

..

408 Commits

Author SHA1 Message Date
Keith Hall
25f4f96ea3 Release bat v0.25.0
Merge pull request #3166 from sharkdp/release_0_25
2025-01-07 21:05:49 +02:00
Keith Hall
5cfd22ee8b Bump version to 0.25.0 2025-01-07 20:44:21 +02:00
Keith Hall
ae07586fef Merge pull request #2805 from Anomalocaridid/refactor-lessopen
Rework `lessopen` implementation to use `execute` crate instead of `run_script`
2025-01-06 06:21:46 +02:00
Anomalocaridid
96e4882b5c tests: remove serial attribute on and un-ignore applicable lessopen tests 2025-01-05 21:36:33 +00:00
Anomalocaridid
a0a090c307 tests: disable lessopen for help tests 2025-01-05 21:36:33 +00:00
Anomalocaridid
bc61d84408 update CHANGELOG.md 2025-01-05 21:36:33 +00:00
Anomalocaridid
de8bb79a6f refactor lessopen implementation 2025-01-05 21:36:33 +00:00
Anomalocaridid
7bf459f0ff replace run_script with execute 2025-01-05 21:36:33 +00:00
Keith Hall
18ed69aff4 Merge pull request #3113 from niklasmohrin/bump-clircle
Bump clircle to 0.6.1
2025-01-05 22:10:45 +02:00
Niklas Mohrin
c9431933e5 Deactivate clircle default features and require 0.6.1
This release removes the dependency on `winapi`.
2025-01-05 16:50:45 +01:00
Keith Hall
2d3581e8c4 Merge pull request #2858 from eth-p/update-docs-for-manpager
Update README steps for using bat as MANPAGER
2025-01-03 09:07:57 +02:00
Ethan P.
8453bc93cc Update README steps for using bat as MANPAGER 2025-01-03 08:53:16 +02:00
Keith Hall
d1418a9ab0 Merge pull request #2994 from sharkdp/two_dark_manpage
Patch themes for better manpage syntax highlighting
2025-01-03 08:44:14 +02:00
Keith Hall
09bdcde6c5 Update changelog to mention theme improvements for Manpage 2025-01-03 08:31:05 +02:00
Keith Hall
0d2afe79af Improve base16 themes for better Man page syntax highlighting 2025-01-03 08:31:05 +02:00
Keith Hall
5a12f187fa Patch 1337 theme for better Man page syntax highlighting 2025-01-03 08:31:05 +02:00
Keith Hall
753bfaff49 Improve Ansi theme for better Man page syntax highlighting 2025-01-03 08:31:05 +02:00
Keith Hall
9744971b19 Patch OneHalfDark theme for better Man page syntax highlighting 2025-01-03 08:31:05 +02:00
Keith Hall
c8f7787281 Patch TwoDark theme for better Man page syntax highlighting 2025-01-03 08:31:05 +02:00
Keith Hall
26f19703d3 Merge pull request #3157 from sharkdp/man_gs
Manpage: Fix for OPTIONS consisting of a plain dash
2025-01-03 08:30:44 +02:00
Keith Hall
b7b05a3553 Fix for OPTIONS consisting of a plain dash 2025-01-03 08:20:40 +02:00
dependabot[bot]
caba54efc9 Bump clircle from 0.6.0 to 0.6.1 (#3161)
Bumps [clircle](https://github.com/niklasmohrin/clircle) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/niklasmohrin/clircle/releases)
- [Commits](https://github.com/niklasmohrin/clircle/compare/v0.6.0...v0.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-01 04:43:24 +00:00
dependabot[bot]
e2528dff6d Bump serde_with from 3.8.1 to 3.12.0 (#3162)
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.8.1 to 3.12.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.8.1...v3.12.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>
2025-01-01 04:30:15 +00:00
dependabot[bot]
ad11fb815f Bump predicates from 3.1.0 to 3.1.3 (#3158)
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 3.1.0 to 3.1.3.
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v3.1.0...v3.1.3)

---
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>
2025-01-01 04:15:10 +00:00
dependabot[bot]
305e8a4d84 Bump serde from 1.0.209 to 1.0.217 (#3160)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.209 to 1.0.217.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.209...v1.0.217)

---
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>
2025-01-01 03:57:42 +00:00
dependabot[bot]
7e804b27a0 Bump console from 0.15.8 to 0.15.10 (#3159)
Bumps [console](https://github.com/console-rs/console) from 0.15.8 to 0.15.10.
- [Release notes](https://github.com/console-rs/console/releases)
- [Changelog](https://github.com/console-rs/console/blob/main/CHANGELOG.md)
- [Commits](https://github.com/console-rs/console/compare/0.15.8...0.15.10)

---
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>
2025-01-01 03:34:32 +00:00
Keith Hall
18d963f423 Merge pull request #3152 from liliwilson/markdown-puppet-syntax-highlighting
Added patch for puppet syntax highlighting in Markdown code snippets
2024-12-30 21:40:15 +02:00
Lili Wilson
9d91d22e29 changelog entry 2024-12-30 21:27:28 +02:00
Lili Wilson
3fa9044029 added patch for puppet syntax highlighting in markdown 2024-12-30 21:27:28 +02:00
Keith Hall
8a9821fa9a Merge pull request #3154 from sharkdp/fix_cargo_audit_ci
[CI] fix cargo audit failing to run successfully
2024-12-30 21:26:22 +02:00
Keith Hall
75fadb8d1c ignore warning for idna also 2024-12-30 21:12:48 +02:00
Keith Hall
63560c4733 add cargo audit config file
ignore yaml-rust advisory for now
2024-12-30 20:53:31 +02:00
Keith Hall
d660cca8a9 Bump MSRV to 1.74
released over a year ago
2024-12-26 21:30:16 +02:00
Keith Hall
be62a4cea4 Upgrade clap to fix cargo audit failure on anstream 0.6.4
which is provided by clap 4.4.12
2024-12-26 21:19:02 +02:00
Keith Hall
874448c112 [CI] fix cargo audit failing to run 2024-12-26 21:13:14 +02:00
Keith Hall
3e07483f7a Merge pull request #3133 from sharkdp/keith-hall-patch-1
Build with MacOS 13 instead of 12
2024-12-07 12:08:41 +02:00
Keith Hall
9859077306 Build with MacOS 13 instead of 12
MacOS 12 is deprecated in GitHub Actions and no longer usable
2024-12-07 11:04:53 +02:00
Keith Hall
0cde7167d6 Merge pull request #3126 from einfachIrgendwer0815/feature/included_completions
Add `--completion <SHELL>` to provide shell completions
2024-12-01 19:16:05 +02:00
einfachIrgendwer0815
7eff8b687c Update changelog 2024-12-01 09:39:17 +01:00
einfachIrgendwer0815
04c7d15084 Mention --completion in the README 2024-12-01 09:39:17 +01:00
einfachIrgendwer0815
dbe25ba5e6 Include shell completions in the executable 2024-12-01 09:39:17 +01:00
dependabot[bot]
f81d4dc321 Bump terminal-colorsaurus from 0.4.4 to 0.4.7 (#3140)
Bumps [terminal-colorsaurus](https://github.com/bash/terminal-colorsaurus) from 0.4.4 to 0.4.7.
- [Release notes](https://github.com/bash/terminal-colorsaurus/releases)
- [Changelog](https://github.com/bash/terminal-colorsaurus/blob/main/changelog.md)
- [Commits](https://github.com/bash/terminal-colorsaurus/compare/0.4.4...0.4.7)

---
updated-dependencies:
- dependency-name: terminal-colorsaurus
  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-12-01 05:00:43 +00:00
dependabot[bot]
f1c5c02713 Bump once_cell from 1.20.1 to 1.20.2 (#3139)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.20.1 to 1.20.2.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.20.1...v1.20.2)

---
updated-dependencies:
- dependency-name: once_cell
  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-12-01 04:47:55 +00:00
dependabot[bot]
6c25c693a8 Bump regex from 1.10.2 to 1.10.6 (#3137)
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.2 to 1.10.6.
- [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.10.2...1.10.6)

---
updated-dependencies:
- dependency-name: regex
  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-12-01 04:30:40 +00:00
dependabot[bot]
4be55ead4d Bump flate2 from 1.0.34 to 1.0.35 (#3136)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.34 to 1.0.35.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Changelog](https://github.com/rust-lang/flate2-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.34...1.0.35)

---
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>
2024-12-01 04:05:04 +00:00
Keith Hall
8df326aeed Merge pull request #3135 from leo9800/master
Update syntax mapping for Apache Conf
2024-12-01 05:40:59 +02:00
Leo
f87157d009 Update syntax mapping for apache conf 2024-12-01 11:15:17 +08:00
Keith Hall
0b4fe03ec3 Merge pull request #3132 from fepegar/3130-use-toml-for-uv-lock
Use TOML syntax highlighting for uv.lock
2024-11-25 20:49:37 +02:00
Fernando Pérez-García
1063264d88 Replace issue number with pull request number 2024-11-24 08:14:24 +00:00
Fernando Pérez-García
4bee858c78 Update CHANGELOG 2024-11-22 22:50:53 +00:00
Fernando Pérez-García
d832367d95 Use TOML syntax highlighting for uv.lock 2024-11-22 22:39:35 +00:00
Keith Hall
d89a20f8b4 Merge pull request #3016 from CosmicHorrorDev/update-sublime-snazzy-theme
Bump themes/sublime-snazzy from `7034320` `48f43a7`
2024-11-21 21:13:27 +02:00
Keith Hall
41ef01f25d Merge branch 'master' into update-sublime-snazzy-theme 2024-11-21 20:30:53 +02:00
Keith Hall
7b797fd830 Merge pull request #3131 from binchengqu/master
chore: remove redundant word in comment
2024-11-21 06:09:50 +02:00
binchengqu
d27064cea5 chore: remove redundant word in comment
Signed-off-by: binchengqu <bincheng@before.tech>
2024-11-21 11:55:43 +08:00
Keith Hall
c9aa8d59ef Merge pull request #3015 from CosmicHorrorDev/update-nord-theme
Bump themes/Nord-submlime from `0d655b2` `bf92a9e`
2024-11-21 05:29:12 +02:00
Cosmic Horror
57a8b10883 Bump themes/Nord-submlime from 0d655b2 bf92a9e 2024-11-21 05:19:56 +02:00
Keith Hall
e608b33142 Merge pull request #3070 from kojix2/print
Add print_with_writer to PrettyPrint
2024-11-16 21:52:51 +02:00
kojix2
6598442d41 Merge branch 'master' into print 2024-11-14 10:08:21 +09:00
Keith Hall
822eff6028 Merge pull request #3063 from volklord/master
bat.zsh.in: Remove duplicate word
2024-11-13 22:19:09 +02:00
Keith Hall
da4defad07 Merge branch 'master' into master 2024-11-13 21:59:48 +02:00
Keith Hall
9bed8adb16 Merge pull request #3095 from mhelsley/mhelsley-fix-lessopen
Fix lessopen feature
2024-11-13 21:58:02 +02:00
Keith Hall
2e836e9822 Merge branch 'master' into mhelsley-fix-lessopen 2024-11-13 21:42:36 +02:00
Keith Hall
07554b0c1d Merge pull request #3098 from adamperkowski/bat_config_dir_docs
📔 docs: mention `BAT_CONFIG_DIR` in the README
2024-11-13 21:37:40 +02:00
Keith Hall
022574314f Merge branch 'master' into bat_config_dir_docs 2024-11-13 21:25:59 +02:00
Keith Hall
8a4701f93f Merge pull request #2896 from bash/dark-light
Choose Theme Based on The Terminal's Color Scheme
2024-11-13 21:10:50 +02:00
Keith Hall
08047a6a2e Merge branch 'master' into dark-light 2024-11-13 20:54:57 +02:00
Adam Perkowski
2caeaef14b 📔 docs: mention BAT_CONFIG_DIR in the README 2024-11-13 20:53:45 +02:00
Keith Hall
d00e05643f Merge pull request #3103 from Ugzuzg/citation-mapping
Add syntax mapping for CITATION.cff
2024-11-13 20:41:44 +02:00
Keith Hall
60693db73f Merge branch 'master' into dark-light 2024-11-13 20:33:37 +02:00
volklord
15f2553a3d bat.zsh.in: Remove duplicate word
Remove the duplicate word `disable disable`
2024-11-13 20:30:04 +02:00
Keith Hall
dbe352d8b8 Merge branch 'master' into citation-mapping 2024-11-13 20:25:26 +02:00
Keith Hall
517ddd8e00 Merge pull request #3115 from pratik-m/add-pipe-delimter-to-csv-syntax
Adding pipe delimeter support for csv files
2024-11-13 20:24:20 +02:00
Pratik Munot
558b487c91 Merge branch 'master' into add-pipe-delimter-to-csv-syntax 2024-11-11 20:41:52 -08:00
David Peter
f8f12a7db5 Update sponsorship information 2024-11-10 20:02:58 +01:00
Pratik Munot
d725443116 Merge branch 'master' into add-pipe-delimter-to-csv-syntax 2024-11-02 22:41:52 -07:00
dependabot[bot]
dbaa0a6d9e Bump grep-cli from 0.1.10 to 0.1.11 (#3120)
Bumps [grep-cli](https://github.com/BurntSushi/ripgrep) from 0.1.10 to 0.1.11.
- [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.10...0.1.11)

---
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>
2024-11-01 05:02:22 +00:00
dependabot[bot]
6b2c5645d2 Bump toml from 0.8.9 to 0.8.19 (#3121)
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.9 to 0.8.19.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.9...toml-v0.8.19)

---
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-11-01 04:46:28 +00:00
dependabot[bot]
e7bef716c9 Bump encoding_rs from 0.8.34 to 0.8.35 (#3119)
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.34 to 0.8.35.
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.34...v0.8.35)

---
updated-dependencies:
- dependency-name: encoding_rs
  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-11-01 04:23:23 +00:00
dependabot[bot]
c627526f8c Bump clircle from 0.5.0 to 0.6.0 (#3117)
Bumps [clircle](https://github.com/niklasmohrin/clircle) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/niklasmohrin/clircle/releases)
- [Commits](https://github.com/niklasmohrin/clircle/compare/v0.5.0...v0.6.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-11-01 03:57:52 +00:00
Keith Hall
95cb705ac0 Merge pull request #2947 from jacg/debdiff
Make .debdiff imply .diff using syntax_mapping toml
2024-10-31 08:13:35 +02:00
kojix2
ca43c7a8f8 Merge branch 'master' into print 2024-10-31 15:04:14 +09:00
Jacek Generowicz
0a8bfc52a6 Move from unix-family to common 2024-10-31 08:03:45 +02:00
Jacek Generowicz
d0ae2e6826 Add CHANGELOG entry for .debdiff => diff 2024-10-31 08:03:45 +02:00
Jacek Generowicz
9090fb75e0 Make .debdiff imply .diff using syntax_mapping toml
Closes #2940
2024-10-31 08:03:45 +02:00
Keith Hall
50fa25db60 Merge pull request #2961 from cyqsimon/pacman-conf
Add syntax mapping for `/etc/pacman.conf`
2024-10-31 05:20:09 +02:00
Keith Hall
bd3c49d234 Merge remote-tracking branch 'origin/master' into pacman-conf 2024-10-31 05:08:46 +02:00
Keith Hall
ce7a3d9f7d Merge pull request #3108 from einfachIrgendwer0815/fix/2731_plain_override
Fix override of --plain and --paging
2024-10-31 05:07:23 +02:00
einfachIrgendwer0815
3b71837174 Merge branch 'master' into fix/2731_plain_override 2024-10-30 13:06:13 +01:00
Keith Hall
2be3a14a7e Merge pull request #2976 from einfachIrgendwer0815/feature/binary_as_text
Allow printing binary content by treating it the same as text
2024-10-30 13:55:21 +02:00
einfachIrgendwer0815
8d82402d74 Merge branch 'master' into feature/binary_as_text 2024-10-30 12:46:11 +01:00
Pratik Munot
1942d40863 changelog updates 2024-10-29 22:36:43 -07:00
Pratik Munot
5042844342 Adding pipe delimeter support for csv files 2024-10-29 21:34:47 -07:00
Fabio Valentini
649fb05c58 Bump nix from 0.26.4 to 0.29 2024-10-25 09:16:21 +02:00
kojix2
c533a4aa14 Update CHANGELOG.md 2024-10-23 21:42:02 +09:00
kojix2
b93a41a9a3 Add print_with_writer to PrettyPrint 2024-10-23 21:21:15 +09:00
Keith Hall
937c59fca9 Merge pull request #3049 from cyqsimon/kubernetes
Add syntax mapping for kubernetes config files
2024-10-21 23:10:22 +03:00
Keith Hall
a80d5ea9f7 Merge branch 'master' into pacman-conf 2024-10-21 23:02:56 +03:00
Keith Hall
c11a7d9e41 Merge branch 'master' into kubernetes 2024-10-21 23:01:30 +03:00
einfachIrgendwer0815
ac082ab64b Update changelog 2024-10-18 12:44:53 +02:00
einfachIrgendwer0815
c9fd0f3cf0 Add partial override of -pp and --paging 2024-10-18 12:13:41 +02:00
einfachIrgendwer0815
e667415def Add tests against issue #2731 2024-10-18 12:13:41 +02:00
einfachIrgendwer0815
fd6c7637e4 Partially revert "Make -pp override --paging and vice versa when passed as a later argument. (#2660)"
This partially reverts commit e2bf85e749.
2024-10-18 11:46:51 +02:00
Jarasłaŭ Viktorčyk
9a816c9c68 Add syntax mapping for CITATION.cff 2024-10-13 11:47:31 +02:00
Matt Helsley
431344ba67 Merge branch 'master' into mhelsley-fix-lessopen 2024-10-06 21:52:34 -07:00
Keith Hall
eca6b8a376 Merge pull request #3075 from einfachIrgendwer0815/fix/3073_list_themes
Don't output default theme info to piped stdout
2024-10-06 22:27:18 +03:00
Keith Hall
b01ed8d773 Merge branch 'master' into fix/3073_list_themes 2024-10-06 22:08:00 +03:00
Matt Helsley
3e5f4266ce Fix lessopen feature
RawOsString API changed in os_str_bytes 7.0.0 and bat no longer builds
with the lessopen feature because:

- ::from_string() is deprecated and says to use new().
  The documentation says that new(), like from_string() no longer
  needs to copy the string.

- ::assert_from_raw_vec() is no longer merely deprecated and now
  requires selecting the "conversions" feature of os_str_bytes.

Replaces PR#2938
2024-10-03 16:32:23 -07:00
dependabot[bot]
61c9f312c9 Bump flate2 from 1.0.30 to 1.0.34 (#3093)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.30 to 1.0.34.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Changelog](https://github.com/rust-lang/flate2-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.30...1.0.34)

---
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>
2024-10-01 03:36:57 +00:00
dependabot[bot]
c59dad0cae Bump git2 from 0.18.3 to 0.19.0 (#3092)
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.18.3 to 0.19.0.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.18.3...git2-0.19.0)

---
updated-dependencies:
- dependency-name: git2
  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-10-01 03:19:34 +00:00
dependabot[bot]
16a79d38c2 Bump once_cell from 1.19.0 to 1.20.1 (#3091)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.19.0 to 1.20.1.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.19.0...v1.20.1)

---
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-10-01 03:02:02 +00:00
dependabot[bot]
9d635627dc Bump globset from 0.4.14 to 0.4.15 (#3090)
Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.14 to 0.4.15.
- [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.14...ignore-0.4.15)

---
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>
2024-10-01 02:40:45 +00:00
einfachIrgendwer0815
bc69ffb0f0 Map *.mkd files to Markdown syntax (#3061) 2024-09-26 21:06:07 +02:00
flytam
a0226f5670 Update Chinese version translation of README.md 2024-09-20 06:28:20 +02:00
Mikael Vaaltola
ed7789d9b7 Associate GeoJSON .geojson files with json syntax (fixes #3083) 2024-09-20 06:14:26 +02:00
Tau Gärtli
b747184788 Accept impl Into<String> to avoid cloning strings 2024-09-08 17:11:11 +02:00
Tau Gärtli
02ae6ef348 Remove redundant guard 2024-09-07 22:59:27 +02:00
Tau Gärtli
0ebb9cbfe2 Add Display impl 2024-09-07 21:57:27 +02:00
Tau Gärtli
f6cbee9e27 Update docs 2024-09-07 21:36:03 +02:00
Tau Gärtli
10e823c4b7 Rename internal function 2024-09-07 21:36:03 +02:00
Tau Gärtli
60e4027332 Expose theme env vars 2024-09-07 21:36:02 +02:00
Tau Gärtli
e075fee5bf Add infallible constructor 2024-09-07 21:36:02 +02:00
Tau Gärtli
16d9b99f6c Flatten preference enum 2024-09-04 21:18:29 +02:00
dependabot[bot]
ffa74a7f49 Bump serde from 1.0.199 to 1.0.209 (#3077)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.199 to 1.0.209.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.199...v1.0.209)

---
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-09-01 03:05:26 +00:00
dependabot[bot]
c1772b7793 Bump plist from 1.6.0 to 1.7.0 (#3076)
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.6.0...v1.7.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-09-01 02:45:53 +00:00
einfachIrgendwer0815
5be9d19500 Reinforce tests for --list-themes 2024-08-25 11:10:25 +02:00
einfachIrgendwer0815
0603f0b844 Don't output default theme info to piped stdout 2024-08-25 10:54:46 +02:00
Tau Gärtli
50958472e5 Return theme alongside detected color scheme 2024-08-23 18:03:07 +02:00
Tau Gärtli
89ce060183 Update help, man page and completions 2024-08-18 20:32:59 +02:00
Tau Gärtli
bc42149a72 Merge color scheme options into theme / BAT_THEME 2024-08-18 14:59:14 +02:00
einfachIrgendwer0815
0c3b22e0f0 Run syntax highlighting when --binary=as-text 2024-08-18 10:06:12 +02:00
einfachIrgendwer0815
a769a3d813 Update CHANGELOG 2024-08-18 10:06:09 +02:00
einfachIrgendwer0815
7cc231b82b Test --binary=as-text 2024-08-18 10:05:43 +02:00
einfachIrgendwer0815
7f089ead62 Add option --binary
`--binary` allows to specify how to deal with binary content. Current
options are not printing anything or treating the binary data as text.
2024-08-18 10:05:37 +02:00
Tau Gärtli
b9b981f657 Generalize --detect-color-scheme to --color-scheme 2024-08-16 14:14:30 +02:00
Tau Gärtli
abf9dada04 Remove HighlightingAssets::default_theme() 2024-08-16 14:13:58 +02:00
Tau Gärtli
5c6974703e Respect --detect-color-scheme flag when listing themes 2024-08-16 14:13:58 +02:00
Tau Gärtli
1b0a6da4be Use new default_theme fn for --list-themes 2024-08-16 14:13:58 +02:00
Tau Gärtli
06b645435a Add changelog entry 2024-08-16 14:13:57 +02:00
Tau Gärtli
c3b190d45b Disable color detection in test 2024-08-16 14:13:18 +02:00
Tau Gärtli
594b1417f1 Update readme 2024-08-16 14:13:18 +02:00
Tau Gärtli
e8ca6ec7c3 Remove cargo feature 2024-08-16 14:13:18 +02:00
Tau Gärtli
6498615f5f Improve upon the documentation 2024-08-16 14:13:18 +02:00
Tau Gärtli
30b0143ccf Make default_theme pub 2024-08-16 14:13:17 +02:00
Tau Gärtli
ff81cfd584 Move actual detection into library 2024-08-16 14:13:16 +02:00
Tau Gärtli
14ce668a1d Add generated powershell completion to ignore list 2024-08-16 14:12:23 +02:00
Tau Gärtli
9a1bfe946d Update completions and man page 2024-08-16 14:12:23 +02:00
Tau Gärtli
cea45e05f3 Expose new theme selection in CLI 2024-08-16 14:12:22 +02:00
Tau Gärtli
cda363a3f7 Use default_theme() function from theme module 2024-08-16 14:09:38 +02:00
Tau Gärtli
de796392cf Deprecate old default_theme function 2024-08-16 14:09:38 +02:00
Tau Gärtli
1423dd9440 Choose theme based on the terminal's color scheme 2024-08-16 14:09:35 +02:00
dependabot[bot]
b662fec214 Bump ansi_colours from 1.2.2 to 1.2.3 (#3058)
Bumps [ansi_colours](https://github.com/mina86/ansi_colours) from 1.2.2 to 1.2.3.
- [Commits](https://github.com/mina86/ansi_colours/commits)

---
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>
2024-08-01 03:28:12 +00:00
dependabot[bot]
d8d0b77568 Bump indexmap from 2.2.6 to 2.3.0 (#3057)
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.2.6 to 2.3.0.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/master/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.2.6...2.3.0)

---
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-08-01 03:14:26 +00:00
dependabot[bot]
13317b0a3b Bump expect-test from 1.4.1 to 1.5.0 (#3055)
Bumps [expect-test](https://github.com/rust-analyzer/expect-test) from 1.4.1 to 1.5.0.
- [Changelog](https://github.com/rust-analyzer/expect-test/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-analyzer/expect-test/compare/v1.4.1...v1.5.0)

---
updated-dependencies:
- dependency-name: expect-test
  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-08-01 02:47:46 +00:00
Ethan P.
2616296183 Merge pull request #2929 from eth-p/add-remove-styles
Merge `--style`s from different places using `+`/`-`
2024-07-30 21:30:19 -07:00
Ethan P.
39684b85ad Update changelog 2024-07-30 21:22:05 -07:00
Ethan P.
aa3ec109b7 First StyleComponentList should remove from 'auto' style.
This happens when there are no `--style` arguments other than the one
passed in as a command line argument.

Prior to this change, removing a style component (e.g. `--style=-numbers`)
would remove the component from an empty style component set, resulting
in no styles at all. That behaviour was less intuitive than the new
behaviour, which starts out with the default components and
removes the line numbers.
2024-07-30 21:22:02 -07:00
Ethan P.
180a77ee99 Add integration tests for merging styles
A huge thanks to @einfachIrgendwer0815 for helping me make sure
these tests work under the MSRV CI job.
2024-07-30 21:22:00 -07:00
Ethan P.
93b25d75a0 Join env var options with "=" instead of " "
Joining them with a space was causing certain styles (e.g. `-grid`) to
be misinterpreted as a separate option.
2024-07-30 21:21:58 -07:00
Ethan P.
6e91ba83b7 Update clap/docs for merging --style arguments 2024-07-30 21:21:55 -07:00
Ethan P.
b74c125c43 Support merging --style arguments
The `overrides_with` clap builder option was removed
because it interfered with the matcher's ability to
retain all occurrences of `--style`.

The behavior it covered is expressed within the new
`forced_style_components` function.
2024-07-30 21:21:53 -07:00
Keith Hall
fd1e0d5876 Merge pull request #2995 from akinomyoga/update-man
Update the man page of bat (`assets/manual/bat.1.in`)
2024-07-29 07:14:31 +03:00
Koichi Murase
9a650e8279 Update CHANGELOG 2024-07-29 12:18:40 +09:00
Koichi Murase
d5aa9d8e05 Add options generated by completions to the man page 2024-07-29 12:18:40 +09:00
Koichi Murase
b1cdc06430 Add --no-* options to Bash/Zsh completions 2024-07-29 12:18:40 +09:00
Koichi Murase
83a15ac05f Add --cache-dir to Fish completion 2024-07-29 12:18:40 +09:00
Koichi Murase
43a77a42f8 Add options present in --help to Bash completion 2024-07-29 12:18:40 +09:00
Koichi Murase
44ca1e7df1 Add options present in --help to the man page 2024-07-29 12:18:40 +09:00
Michael Vorburger
23fd200482 Associate JSON-LD .jsonld files with json syntax (fixes #3036)
Use PR instead of Issue # number in CHANGELOG.

Clean up (unify) CHANGELOG.
2024-07-27 15:48:02 +02:00
Keith Hall
9f1c62b013 Merge pull request #3031 from brenton-at-pieces/add-cfml
add CFML syntax
2024-07-26 19:45:44 +03:00
cyqsimon
319b8868fc Write changelog 2024-07-26 23:39:27 +08:00
cyqsimon
7bd6cdbebc Add syntax mapping for kubernetes config files 2024-07-26 23:23:58 +08:00
Brenton Bostick
1488a4a006 Merge branch 'master' into add-cfml 2024-07-26 09:09:30 -04:00
Keith Hall
56d2823b0e Merge pull request #3045 from cyqsimon/time
Bump time to 0.3.36 (fixes #3043)
2024-07-26 12:12:57 +03:00
cyqsimon
1a11ba11e3 Write changelog 2024-07-26 16:18:16 +08:00
cyqsimon
c34bdb5e66 Bump time to 0.3.36 (fixes #3043) 2024-07-26 16:10:17 +08:00
Brenton Bostick
10456e1d51 Merge branch 'master' into add-cfml 2024-07-25 15:54:50 -04:00
Keith Hall
bbdadc7e38 Merge pull request #3038 from vorburger/bump-textproto
Update the Protobuf sobmodule in order to add `.textproto` support
2024-07-23 23:02:35 +03:00
Michael Vorburger
ff71e32c0f Update the Protobuf sobmodule (fixes #2542) 2024-07-21 23:14:12 +02:00
Brenton Bostick
50b01ea8da update CHANGELOG 2024-07-17 16:17:41 -04:00
Brenton Bostick
de697f7717 add CFML syntax 2024-07-17 15:46:38 -04:00
Cosmic Horror
575457c944 Bump themes/sublime-snazzy from 7034320 48f43a7 2024-06-30 23:43:32 -06:00
dependabot[bot]
6fc58821a5 Bump anyhow from 1.0.78 to 1.0.86 (#3021)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.78 to 1.0.86.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.78...1.0.86)

---
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-07-01 03:34:46 +00:00
dependabot[bot]
7873b473e8 Bump unicode-width from 0.1.11 to 0.1.13 (#3019)
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.11 to 0.1.13.
- [Commits](https://github.com/unicode-rs/unicode-width/compare/v0.1.11...v0.1.13)

---
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>
2024-07-01 03:16:35 +00:00
dependabot[bot]
609005a225 Bump encoding_rs from 0.8.33 to 0.8.34 (#3020)
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.33 to 0.8.34.
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.33...v0.8.34)

---
updated-dependencies:
- dependency-name: encoding_rs
  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-07-01 02:51:38 +00:00
dependabot[bot]
b9c74ab859 Bump walkdir from 2.4.0 to 2.5.0 (#3018)
Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.4.0 to 2.5.0.
- [Commits](https://github.com/BurntSushi/walkdir/compare/2.4.0...2.5.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>
2024-07-01 02:29:47 +00:00
Driss Boumlik
cee5584daf Fix cmder link 2024-06-29 14:57:40 +02:00
Bryan Honof
b265b20721 Add flox install 2024-06-23 13:52:52 +02:00
Ethan P
a7a9727c11 Merge pull request #2999 from eth-p/strip-ansi-from-input-option
Add option to remove ANSI escape sequences from bat's input.
2024-06-17 18:37:22 -07:00
Ethan P.
90dfa7f18d Update README.md to mention --strip-ansi 2024-06-17 18:27:39 -07:00
Ethan P.
3f8d62e7d6 Update CHANGELOG.md 2024-06-17 18:27:39 -07:00
Ethan P.
3f22311ec8 Add ANSI stripping to bat-as-a-library 2024-06-17 18:27:39 -07:00
Ethan P.
9e8176b1c6 Add --strip-ansi=auto option
When using `auto`, escape sequences will be stripped unless printing
plain text.
2024-06-17 18:27:33 -07:00
Ethan P.
70ff93d238 Add --strip-ansi option 2024-06-16 16:49:07 -07:00
Tong Zhaoqi
c264ecd26b ci: support aarch64 statically-linked binary (#2992) 2024-06-16 20:16:11 +02:00
Ethan P
10a1b24191 Merge pull request #2998 from eth-p/improve-preprocessor
Update bat's tab expansion preprocessor to use bat's ANSI escape sequence iterator.
2024-06-15 16:28:05 -07:00
Ethan P.
243819ecdc Update CHANGELOG.md 2024-06-15 16:18:29 -07:00
Ethan P.
9c76b72825 Update expand_tabs to use bat's ANSI iterator 2024-06-10 20:07:54 -07:00
Ethan P.
b4fe182960 Make EscapeSequenceOffsetsIterator pub, add fns to get indices 2024-06-10 20:04:17 -07:00
dependabot[bot]
b7e44c76dc Bump semver from 1.0.21 to 1.0.23 (#2981)
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.21 to 1.0.23.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.21...1.0.23)

---
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-06-01 03:31:50 +00:00
dependabot[bot]
f3cc69733f Bump thiserror from 1.0.53 to 1.0.61 (#2979)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.53 to 1.0.61.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.53...1.0.61)

---
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-06-01 03:18:21 +00:00
dependabot[bot]
3625f0ea1c Bump itertools from 0.12.1 to 0.13.0 (#2978)
Bumps [itertools](https://github.com/rust-itertools/itertools) from 0.12.1 to 0.13.0.
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.12.1...v0.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-01 03:04:56 +00:00
dependabot[bot]
e6e2d4c65d Bump flate2 from 1.0.28 to 1.0.30 (#2980)
Bumps [flate2](https://github.com/rust-lang/flate2-rs) from 1.0.28 to 1.0.30.
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.28...1.0.30)

---
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>
2024-06-01 02:48:23 +00:00
dependabot[bot]
340e873eff Bump git2 from 0.18.2 to 0.18.3 (#2977)
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.18.2 to 0.18.3.
- [Changelog](https://github.com/rust-lang/git2-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/git2-rs/compare/git2-0.18.2...git2-0.18.3)

---
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-06-01 02:24:10 +00:00
Keith Hall
3407bf4bf6 Merge pull request #2970 from ccqpein/master
Patch the lisp syntax
2024-05-31 23:30:08 +03:00
ccQpein
25cd4991d2 update lisp test 2024-05-31 12:39:19 -04:00
ccQpein
503b2c5126 fix the prefix 2024-05-27 16:22:07 -04:00
ccQpein
026bc05d70 changelog 2024-05-27 15:58:04 -04:00
ccQpein
61005f19fa patch the lisp syntax 2024-05-27 15:52:26 -04:00
someposer
8f8c953ab6 Add support for Apple Silicon (#2967) 2024-05-27 06:14:11 +02:00
cyqsimon
f82487daf8 Write changelog 2024-05-15 14:35:47 +08:00
cyqsimon
3a9d574770 Add syntax mapping for /etc/pacman.conf 2024-05-15 14:31:25 +08:00
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
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
Oliver Looney
d7503bfc09 Merge branch 'master' into 2783-setting-terminal-title 2023-12-27 16:14:04 +00: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 GlobMatchers 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
131 changed files with 7413 additions and 1127 deletions

2
.cargo/audit.toml Normal file
View File

@@ -0,0 +1,2 @@
[advisories]
ignore = ["RUSTSEC-2024-0320", "RUSTSEC-2024-0421"]

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

@@ -152,6 +152,7 @@ jobs:
name: cargo audit
runs-on: ubuntu-latest
steps:
- run: cargo install cargo-audit --locked
- uses: actions/checkout@v4
- run: cargo audit
@@ -163,13 +164,15 @@ jobs:
fail-fast: false
matrix:
job:
- { target: aarch64-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: arm64, use-cross: true }
- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: arm64, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, dpkg_arch: armhf, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, dpkg_arch: musl-linux-armhf, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2019, }
- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: i686, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-i686, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-12, }
- { target: x86_64-apple-darwin , os: macos-13, }
- { target: aarch64-apple-darwin , os: macos-14, }
- { target: x86_64-pc-windows-gnu , os: windows-2019, }
- { target: x86_64-pc-windows-msvc , os: windows-2019, }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: amd64, use-cross: true }
@@ -444,7 +447,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: |

View File

@@ -29,15 +29,5 @@ jobs:
ADDED=$(git diff -U0 "origin/${PR_BASE}" HEAD -- CHANGELOG.md | grep -P '^\+[^\+].+$')
echo "Added lines in CHANGELOG.md:"
echo "$ADDED"
escape_regex_meta_chars() {
# https://stackoverflow.com/a/16951928/4473405
sed 's/[][\.|$(){}?+*^]/\\&/g' <<< "$*"
}
double_escape_slash_for_bash() {
sed 's/\\/\\\\/g' <<< "$*"
}
echo "Grepping for PR info:"
grep "#${PR_NUMBER}\\b.*[(]@$(quote ${PR_SUBMITTER})[)]" <<< "$ADDED"
echo "Grepping for PR info (see CONTRIBUTING.md):"
grep "#${PR_NUMBER}\\b.*@${PR_SUBMITTER}\\b" <<< "$ADDED"

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
**/*.rs.bk
# Generated files
/assets/completions/_bat.ps1
/assets/completions/bat.bash
/assets/completions/bat.fish
/assets/completions/bat.zsh

3
.gitmodules vendored
View File

@@ -260,3 +260,6 @@
[submodule "assets/syntaxes/02_Extra/vscode-wgsl"]
path = assets/syntaxes/02_Extra/vscode-wgsl
url = https://github.com/PolyMeilex/vscode-wgsl.git
[submodule "assets/syntaxes/02_Extra/CFML"]
path = assets/syntaxes/02_Extra/CFML
url = https://github.com/jcberquist/sublimetext-cfml.git

View File

@@ -1,10 +1,29 @@
# unreleased
# v0.25.0
## 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)
- `bat --strip-ansi={never,always,auto}` to remove ANSI escape sequences from bat's input, see #2999 (@eth-p)
- Add or remove individual style components without replacing all styles #2929 (@eth-p)
- Automatically choose theme based on the terminal's color scheme, see #2896 (@bash)
- Add option `--binary=as-text` for printing binary content, see issue #2974 and PR #2976 (@einfachIrgendwer0815)
- Make shell completions available via `--completion <shell>`, see issue #2057 and PR #3126 (@einfachIrgendwer0815)
- Syntax highlighting for puppet code blocks within Markdown files, see #3152 (@liliwilson)
## 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)
- Fix compile issue of `time` dependency caused by standard library regression #3045 (@cyqsimon)
- Fix override behavior of --plain and --paging, see issue #2731 and PR #3108 (@einfachIrgendwer0815)
- Fix bugs in `$LESSOPEN` support, see #2805 (@Anomalocaridid)
## Other
@@ -15,19 +34,63 @@
- 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)
- Add aarch64-apple-darwin ("Apple Silicon") binary tarballs to releases, see #2967 (@someposer)
- Update the Lisp syntax, see #2970 (@ccqpein)
- Use bat's ANSI iterator during tab expansion, see #2998 (@eth-p)
- Support 'statically linked binary' for aarch64 in 'Release' page, see #2992 (@tzq0301)
- Update options in shell completions and the man page of `bat`, see #2995 (@akinomyoga)
- Update nix dev-dependency to v0.29.0, see #3112 (@decathorpe)
- Bump MSRV to [1.74](https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html), see #3154 (@keith-hall)
- Update clircle dependency to remove winapi transitive dependency, see #3113 (@niklasmohrin)
## 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)
- Associate JSON with Comments `.jsonc` with `json` syntax, see #2795 (@mxaddict)
- Associate JSON-LD `.jsonld` files with `json` syntax, see #3037 (@vorburger)
- Associate `.textproto` files with `ProtoBuf` syntax, see #3038 (@vorburger)
- Associate GeoJSON `.geojson` files with `json` syntax, see #3084 (@mvaaltola)
- Associate `.aws/{config,credentials}`, see #2795 (@mxaddict)
- Associate Wireguard config `/etc/wireguard/*.conf`, see #2874 (@cyqsimon)
- Add support for [CFML](https://www.adobe.com/products/coldfusion-family.html), see #3031 (@brenton-at-pieces)
- Map `*.mkd` files to `Markdown` syntax, see issue #3060 and PR #3061 (@einfachIrgendwer0815)
- Add syntax mapping for CITATION.cff, see #3103 (@Ugzuzg)
- Add syntax mapping for kubernetes config files #3049 (@cyqsimon)
- Adds support for pipe delimiter for CSV #3115 (@pratik-m)
- Add syntax mapping for `/etc/pacman.conf` #2961 (@cyqsimon)
- Associate `uv.lock` with `TOML` syntax, see #3132 (@fepegar)
## Themes
- Patched/improved themes for better Manpage syntax highlighting support, see #2994 (@keith-hall).
## `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)
- Add `theme::theme` for choosing an appropriate theme based on the
terminal's color scheme, see #2896 (@bash)
- [BREAKING] Remove `HighlightingAssets::default_theme`. Use `theme::default_theme` instead.
- Add `PrettyPrinter::print_with_writer` for custom output destinations, see #3070 (@kojix2)
# v0.24.0
@@ -66,6 +129,7 @@
- Update `Julia` syntax, see #2553 (@dependabot)
- add `NSIS` support, see #2577 (@idleberg)
- Update `ssh-config`, see #2697 (@mrmeszaros)
- Add syntax mapping `*.debdiff` => `diff`, see #2947 (@jacg)
## `bat` as a library

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

775
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,11 +6,11 @@ homepage = "https://github.com/sharkdp/bat"
license = "MIT OR Apache-2.0"
name = "bat"
repository = "https://github.com/sharkdp/bat"
version = "0.24.0"
version = "0.25.0"
exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build/main.rs"
edition = '2021'
rust-version = "1.70"
rust-version = "1.74"
[features]
default = ["application"]
@@ -33,7 +33,7 @@ minimal-application = [
]
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
lessopen = ["execute"] # 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,40 +41,41 @@ regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine
regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine
[dependencies]
nu-ansi-term = "0.49.0"
nu-ansi-term = "0.50.0"
ansi_colours = "^1.2"
bincode = "1.0"
console = "0.15.7"
console = "0.15.10"
flate2 = "1.0"
once_cell = "1.19"
once_cell = "1.20"
thiserror = "1.0"
wild = { version = "2.2", optional = true }
content_inspector = "0.2.4"
shell-words = { version = "1.1.0", optional = true }
unicode-width = "0.1.11"
unicode-width = "0.1.13"
globset = "0.4"
serde = { version = "1.0", features = ["derive"] }
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.4"
clircle = { version = "0.6.1", default-features = false }
bugreport = { version = "0.5.0", optional = true }
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 }
grep-cli = { version = "0.1.11", optional = true }
regex = { version = "1.10.6", optional = true }
walkdir = { version = "2.5", optional = true }
bytesize = { version = "1.3.0" }
encoding_rs = "0.8.33"
os_str_bytes = { version = "~6.6", optional = true }
run_script = { version = "^0.10.1", optional = true}
encoding_rs = "0.8.35"
execute = { version = "0.2.13", optional = true }
terminal-colorsaurus = "0.4"
[dependencies.git2]
version = "0.18"
version = "0.19"
optional = true
default-features = false
[dependencies.syntect]
version = "5.1.0"
version = "5.2.0"
default-features = false
features = ["parsing"]
@@ -85,21 +86,31 @@ features = ["wrap_help", "cargo"]
[target.'cfg(target_os = "macos")'.dependencies]
home = "0.5.9"
plist = "1.5.1"
plist = "1.7.0"
[dev-dependencies]
assert_cmd = "2.0.12"
expect-test = "1.4.1"
expect-test = "1.5.0"
serial_test = { version = "2.0.0", default-features = false }
predicates = "3.0.4"
predicates = "3.1.3"
wait-timeout = "0.2.0"
tempfile = "3.8.1"
serde = { version = "1.0", features = ["derive"] }
[target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.26.4", default-features = false, features = ["term"] }
nix = { version = "0.29", default-features = false, features = ["term"] }
[build-dependencies]
anyhow = "1.0.78"
anyhow = "1.0.86"
indexmap = { version = "2.3.0", features = ["serde"] }
itertools = "0.13.0"
once_cell = "1.20"
regex = "1.10.6"
serde = "1.0"
serde_derive = "1.0"
serde_with = { version = "3.12.0", default-features = false, features = ["macros"] }
toml = { version = "0.8.19", features = ["preserve_order"] }
walkdir = "2.5"
[build-dependencies.clap]
version = "4.4.12"

110
README.md
View File

@@ -35,11 +35,11 @@ A special *thank you* goes to our biggest <a href="doc/sponsors.md">sponsors</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>
<strong>Warp, the intelligent terminal</strong>
<br>
<sub>Feel more productive on the command line with parameterized commands,</sub>
<sub>Run commands like a power user with AI and your dev teams</sub>
<br>
<sup>autosuggestions, and an IDE-like text editor.</sup>
<sup>knowledge in one fast, intuitive terminal. For MacOS or Linux.</sup>
</a>
### Syntax highlighting
@@ -204,19 +204,19 @@ bat main.cpp | xclip
`MANPAGER` environment variable:
```bash
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
export MANPAGER="sh -c 'sed -u -e \"s/\\x1B\[[0-9;]*m//g; s/.\\x08//g\" | bat -p -lman'"
man 2 select
```
(replace `bat` with `batcat` if you are on Debian or Ubuntu)
It might also be necessary to set `MANROFFOPT="-c"` if you experience
formatting problems.
If you prefer to have this bundled in a new command, you can also use [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md).
Note that the [Manpage syntax](assets/syntaxes/02_Extra/Manpage.sublime-syntax) is developed in this repository and still needs some work.
> [!WARNING]
> This will [not work](https://github.com/sharkdp/bat/issues/1145) out of the box with Mandoc's `man` implementation.
>
> Please either use `batman`, or convert the shell script to a [shebang executable](https://en.wikipedia.org/wiki/Shebang_(Unix)) and point `MANPAGER` to that.
Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145) with Mandocs `man` implementation.
Note that the [Manpage syntax](assets/syntaxes/02_Extra/Manpage.sublime-syntax) is developed in this repository and still needs some work.
#### `prettier` / `shfmt` / `rustfmt`
@@ -373,6 +373,14 @@ You can install `bat` using the [nix package manager](https://nixos.org/nix):
nix-env -i bat
```
### Via flox
You can install `bat` using [Flox](https://flox.dev)
```bash
flox install bat
```
### On openSUSE
You can install `bat` with zypper:
@@ -447,7 +455,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.70.0 or
If you want to build `bat` from source, you need Rust 1.74.0 or
higher. You can then use `cargo` to build everything:
```bash
@@ -457,6 +465,12 @@ cargo install --locked bat
Note that additional files like the man page or shell completion
files can not be installed in this way. They will be generated by `cargo` and should be available in the cargo target folder (under `build`).
Shell completions are also available by running:
```bash
bat --completion <shell>
# see --help for supported shells
```
## Customization
### Highlighting theme
@@ -474,8 +488,10 @@ the following command (you need [`fzf`](https://github.com/junegunn/fzf) for thi
bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
```
`bat` looks good on a dark background by default. However, if your terminal uses a
light background, some themes like `GitHub` or `OneHalfLight` will work better for you.
`bat` automatically picks a fitting theme depending on your terminal's background color.
You can use the `--theme-light` / `--theme-light` options or the `BAT_THEME_DARK` / `BAT_THEME_LIGHT` environment variables
to customize the themes used. This is especially useful if you frequently switch between dark and light mode.
You can also use a custom theme by following the
['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes).
@@ -507,6 +523,16 @@ and line numbers but no grid and no file header. Set the `BAT_STYLE` environment
variable to make these changes permanent or use `bat`s
[configuration file](https://github.com/sharkdp/bat#configuration-file).
>[!tip]
> If you specify a default style in `bat`'s config file, you can change which components
> are displayed during a single run of `bat` using the `--style` command-line argument.
> By prefixing a component with `+` or `-`, it can be added or removed from the current style.
>
> For example, if your config contains `--style=full,-snip`, you can run bat with
> `--style=-grid,+snip` to remove the grid and add back the `snip` component.
> Or, if you want to override the styles completely, you use `--style=numbers` to
> only show the line numbers.
### Adding new syntaxes / language definitions
Should you find that a particular syntax is not available within `bat`, you can follow these
@@ -602,7 +628,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:
@@ -613,20 +640,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
@@ -657,10 +701,11 @@ on your operating system. To get the default path for your system, call
bat --config-file
```
Alternatively, you can use the `BAT_CONFIG_PATH` environment variable to point `bat` to a
non-default location of the configuration file:
Alternatively, you can use `BAT_CONFIG_PATH` or `BAT_CONFIG_DIR` environment variables to point `bat`
to a non-default location of the configuration file or the configuration directory respectively:
```bash
export BAT_CONFIG_PATH="/path/to/bat.conf"
export BAT_CONFIG_PATH="/path/to/bat/bat.conf"
export BAT_CONFIG_DIR="/path/to/bat"
```
A default configuration file can be created with the `--generate-config-file` option.
@@ -711,7 +756,7 @@ your `PATH` or [define an environment variable](#using-a-different-pager). The [
Windows 10 natively supports colors in both `conhost.exe` (Command Prompt) and PowerShell since
[v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update)), as
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/).
[Cmder](http://cmder.app/), which includes [ConEmu](https://conemu.github.io/).
**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.
@@ -741,9 +786,14 @@ bat() {
If an input file contains color codes or other ANSI escape sequences or control characters, `bat` will have problems
performing syntax highlighting and text wrapping, and thus the output can become garbled.
When displaying such files it is recommended to disable both syntax highlighting and wrapping by
If your version of `bat` supports the `--strip-ansi=auto` option, it can be used to remove such sequences
before syntax highlighting. Alternatively, you may disable both syntax highlighting and wrapping by
passing the `--color=never --wrap=never` options to `bat`.
> [!NOTE]
> The `auto` option of `--strip-ansi` avoids removing escape sequences when the syntax is plain text.
### Terminals & colors
`bat` handles terminals *with* and *without* truecolor support. However, the colors in most syntax

Binary file not shown.

View File

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

View File

@@ -76,6 +76,7 @@ _bat() {
-m | --map-syntax | \
--ignored-suffix | \
--list-themes | \
--squeeze-limit | \
--line-range | \
-L | --list-languages | \
--lessopen | \
@@ -112,6 +113,13 @@ _bat() {
return 0
;;
--theme)
local IFS=$'\n'
COMPREPLY=($(compgen -W "auto${IFS}auto:always${IFS}auto:system${IFS}dark${IFS}light${IFS}$("$1" --list-themes)" -- "$cur"))
__bat_escape_completions
return 0
;;
--theme-dark | \
--theme-light)
local IFS=$'\n'
COMPREPLY=($(compgen -W "$("$1" --list-themes)" -- "$cur"))
__bat_escape_completions
@@ -157,6 +165,7 @@ _bat() {
--diff-context
--tabs
--wrap
--chop-long-lines
--terminal-width
--number
--color
@@ -168,19 +177,27 @@ _bat() {
--map-syntax
--ignored-suffix
--theme
--theme-dark
--theme-light
--list-themes
--squeeze-blank
--squeeze-limit
--style
--line-range
--list-languages
--lessopen
--diagnostic
--acknowledgements
--set-terminal-title
--help
--version
--cache-dir
--config-dir
--config-file
--generate-config-file
--no-config
--no-custom-assets
--no-lessopen
" -- "$cur"))
return 0
fi

View File

@@ -129,10 +129,20 @@ set -l tabs_opts '
8\t
'
set -l special_themes '
auto\tdefault,\ Choose\ a\ theme\ based\ on\ dark\ or\ light\ mode
auto:always\tChoose\ a\ theme\ based\ on\ dark\ or\ light\ mode
auto:system\tChoose\ a\ theme\ based\ on\ dark\ or\ light\ mode
dark\tUse\ the\ theme\ specified\ by\ --theme-dark
light\tUse\ the\ theme\ specified\ by\ --theme-light
'
# Completions:
complete -c $bat -l acknowledgements -d "Print acknowledgements" -n __fish_is_first_arg
complete -c $bat -l cache-dir -f -d "Show bat's cache directory" -n __fish_is_first_arg
complete -c $bat -l color -x -a "$color_opts" -d "When to use colored output" -n __bat_no_excl_args
complete -c $bat -l config-dir -f -d "Display location of configuration directory" -n __fish_is_first_arg
@@ -201,7 +211,11 @@ complete -c $bat -l tabs -x -a "$tabs_opts" -d "Set tab width" -n __bat_no_excl_
complete -c $bat -l terminal-width -x -d "Set terminal <width>, +<offset>, or -<offset>" -n __bat_no_excl_args
complete -c $bat -l theme -x -a "(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme" -n __bat_no_excl_args
complete -c $bat -l theme -x -a "$special_themes(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme" -n __bat_no_excl_args
complete -c $bat -l theme-dark -x -a "(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme for dark backgrounds" -n __bat_no_excl_args
complete -c $bat -l theme-light -x -a "(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme for light backgrounds" -n __bat_no_excl_args
complete -c $bat -s V -l version -f -d "Show version information" -n __fish_is_first_arg

View File

@@ -26,7 +26,7 @@ _{{PROJECT_EXECUTABLE}}_main() {
args=(
'(-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`)]'
\*{-p,--plain}'[show plain style (alias for `--style=plain`), repeat twice to 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'
@@ -42,12 +42,15 @@ _{{PROJECT_EXECUTABLE}}_main() {
--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'
'(--theme)'--theme='[set the color theme for syntax highlighting]:theme:->theme_preferences'
'(--theme-dark)'--theme-dark='[set the color theme for syntax highlighting for dark backgrounds]:theme:->themes'
'(--theme-light)'--theme-light='[set the color theme for syntax highlighting for light backgrounds]: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]'
-P'[disable paging]'
"--no-config[don't use the configuration file]"
"--no-custom-assets[don't load custom assets]"
'(--no-lessopen)'--lessopen'[enable the $LESSOPEN preprocessor]'
@@ -81,7 +84,13 @@ _{{PROJECT_EXECUTABLE}}_main() {
themes)
local -a themes expl
themes=( ${(f)"$(_call_program themes {{PROJECT_EXECUTABLE}} --list-themes)"} )
themes=(${(f)"$(_call_program themes {{PROJECT_EXECUTABLE}} --list-themes)"} )
_wanted themes expl 'theme' compadd -a themes && ret=0
;;
theme_preferences)
local -a themes expl
themes=(auto dark light auto:always auto:system ${(f)"$(_call_program themes {{PROJECT_EXECUTABLE}} --list-themes)"} )
_wanted themes expl 'theme' compadd -a themes && ret=0
;;

104
assets/manual/bat.1.in vendored
View File

@@ -87,6 +87,10 @@ Set the tab width to T spaces. Use a width of 0 to pass tabs through directly
Specify the text\-wrapping mode (*auto*, never, character). The '\-\-terminal\-width' option
can be used in addition to control the output width.
.HP
\fB\-S\fR, \fB\-\-chop\-long\-lines\fR
.IP
Truncate all lines longer than screen width. Alias for '\-\-wrap=never'.
.HP
\fB\-\-terminal\-width\fR <width>
.IP
Explicitly set the width of the terminal instead of determining it automatically. If
@@ -141,16 +145,58 @@ use -m '*.build:Python'. To highlight files named '.myignore' with the Git Ignor
syntax, use -m '.myignore:Git Ignore'.
Note that the right-hand side is the *name* of the syntax, not a file extension.
.HP
\fB\-\-ignored\-suffix\fR <ignored-suffix>
.IP
Ignore extension. For example: 'bat \-\-ignored-suffix ".dev" my_file.json.dev'
will use JSON syntax, and ignore '.dev'
.HP
\fB\-\-theme\fR <theme>
.IP
Set the theme for syntax highlighting. Use '\-\-list\-themes' to see all available themes.
To set a default theme, add the '\-\-theme="..."' option to the configuration file or
export the BAT_THEME environment variable (e.g.: export BAT_THEME="...").
Set the theme for syntax highlighting. Use \fB\-\-list\-themes\fP to see all available themes.
To set a default theme, add the \fB\-\-theme="..."\fP option to the configuration file or
export the \fBBAT_THEME\fP environment variable (e.g.: \fBexport BAT_THEME="..."\fP).
Special values:
.RS
.IP "auto (\fIdefault\fR)"
Picks a dark or light theme depending on the terminal's colors.
Use \fB-\-theme\-light\fR and \fB-\-theme\-dark\fR to customize the selected theme.
.IP "auto:always"
Variation of \fBauto\fR where where the terminal's colors are detected even when the output is redirected.
.IP "auto:system (macOS only)"
Variation of \fBauto\fR where the color scheme is detected from the system-wide preference instead.
.IP "dark"
Use the dark theme specified by \fB-\-theme-dark\fR.
.IP "light"
Use the light theme specified by \fB-\-theme-light\fR.
.RE
.HP
\fB\-\-theme\-dark\fR <theme>
.IP
Sets the theme name for syntax highlighting used when the terminal uses a dark background.
To set a default theme, add the \fB\-\-theme-dark="..."\fP option to the configuration file or
export the \fBBAT_THEME_DARK\fP environment variable (e.g. \fBexport BAT_THEME_DARK="..."\fP).
This option only has an effect when \fB\-\-theme\fP option is set to \fBauto\fR or \fBdark\fR.
.HP
\fB\-\-theme\-light\fR <theme>
.IP
Sets the theme name for syntax highlighting used when the terminal uses a dark background.
To set a default theme, add the \fB\-\-theme-dark="..."\fP option to the configuration file or
export the \fBBAT_THEME_LIGHT\fP environment variable (e.g. \fBexport BAT_THEME_LIGHT="..."\fP).
This option only has an effect when \fB\-\-theme\fP option is set to \fBauto\fR or \fBlight\fR.
.HP
\fB\-\-list\-themes\fR
.IP
Display a list of supported themes for syntax highlighting.
.HP
\fB\-s\fR, \fB\-\-squeeze\-blank\fR
.IP
Squeeze consecutive empty lines into a single empty line.
.HP
\fB\-\-squeeze\-limit\fR <squeeze-limit>
.IP
Set the maximum number of consecutive empty lines to be printed.
.HP
\fB\-\-style\fR <style\-components>
.IP
Configure which elements (line numbers, file headers, grid borders, Git modifications,
@@ -184,6 +230,30 @@ Display a list of supported languages for syntax highlighting.
This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). The output is
always unbuffered \- this option is simply ignored.
.HP
\fB\-\-no\-custom\-assets\fR
.IP
Do not load custom assets.
.HP
\fB\-\-config\-dir\fR
.IP
Show bat's configuration directory.
.HP
\fB\-\-cache\-dir\fR
.IP
Show bat's cache directory.
.HP
\fB\-\-diagnostic\fR
.IP
Show diagnostic information for bug reports.
.HP
\fB\-\-acknowledgements\fR
.IP
Show acknowledgements.
.HP
\fB\-\-set\-terminal\-title\fR
.IP
Sets terminal title to filenames when using a pager.
.HP
\fB\-h\fR, \fB\-\-help\fR
.IP
Print this help message.
@@ -212,6 +282,20 @@ location of the configuration file.
To generate a default configuration file, call:
\fB{{PROJECT_EXECUTABLE}} --generate-config-file\fR
These are related options:
.HP
\fB\-\-config\-file\fR
.IP
Show path to the configuration file.
.HP
\fB\-\-generate-config\-file\fR
.IP
Generates a default configuration file.
.HP
\fB\-\-no\-config\fR
.IP
Do not use the configuration file.
.SH "ADDING CUSTOM LANGUAGES"
{{PROJECT_EXECUTABLE}} supports Sublime Text \fB.sublime-syntax\fR language files, and can be
customized to add additional languages to your local installation. To do this, add the \fB.sublime-syntax\fR language
@@ -252,13 +336,23 @@ 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.
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).
These are related options:
.HP
\fB\-\-lessopen\fR
.IP
Enable the $LESSOPEN preprocessor.
.HP
\fB\-\-no\-lessopen\fR
.IP
Disable the $LESSOPEN preprocessor if enabled (overrides --lessopen)
.PP
For more information, see the "INPUT PREPROCESSOR" section of less(1).
.SH "MORE INFORMATION"

22
assets/patches/1337.tmTheme.patch vendored Normal file
View File

@@ -0,0 +1,22 @@
diff --git themes/1337-Scheme/1337.tmTheme themes/1337-Scheme/1337.tmTheme
index fdff5bf..8cfc888 100644
--- themes/1337-Scheme/1337.tmTheme
+++ themes/1337-Scheme/1337.tmTheme
@@ -280,7 +280,7 @@ SOFTWARE.
<key>name</key>
<string>PHP Namespaces</string>
<key>scope</key>
- <string>support.other.namespace, entity.name.type.namespace</string>
+ <string>support.other.namespace, entity.name.type.namespace, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -561,7 +561,7 @@ SOFTWARE.
<key>name</key>
<string>diff.header</string>
<key>scope</key>
- <string>meta.diff, meta.diff.header</string>
+ <string>meta.diff, meta.diff.header, markup.heading</string>
<key>settings</key>
<dict>
<key>foreground</key>

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_]'

2365
assets/patches/Lisp.sublime-syntax.patch vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
diff --git syntaxes/01_Packages/Markdown/Markdown.sublime-syntax syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
index 19dc685d..44440c7f 100644
index 19dc685d..3a45ea05 100644
--- syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
+++ syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
@@ -24,7 +24,6 @@ variables:
@@ -166,7 +166,29 @@ index 19dc685d..44440c7f 100644
- match: ^\s*$\n?
scope: invalid.illegal.non-terminated.bold-italic.markdown
pop: true
@@ -1152,7 +1110,7 @@ contexts:
@@ -1073,6 +1031,21 @@ contexts:
escape: '{{code_fence_escape}}'
escape_captures:
0: meta.code-fence.definition.end.python.markdown-gfm
+ 1: punctuation.definition.raw.code-fence.end.markdown
+ - match: |-
+ (?x)
+ {{fenced_code_block_start}}
+ ((?i:puppet))
+ {{fenced_code_block_trailing_infostring_characters}}
+ captures:
+ 0: meta.code-fence.definition.begin.puppet.markdown-gfm
+ 2: punctuation.definition.raw.code-fence.begin.markdown
+ 5: constant.other.language-name.markdown
+ embed: scope:source.puppet
+ embed_scope: markup.raw.code-fence.puppet.markdown-gfm
+ escape: '{{code_fence_escape}}'
+ escape_captures:
+ 0: meta.code-fence.definition.end.puppet.markdown-gfm
1: punctuation.definition.raw.code-fence.end.markdown
- match: |-
(?x)
@@ -1152,7 +1125,7 @@ contexts:
- match: |-
(?x)
{{fenced_code_block_start}}

View File

@@ -0,0 +1,47 @@
diff --git themes/onehalf/sublimetext/OneHalfDark.tmTheme themes/onehalf/sublimetext/OneHalfDark.tmTheme
index b16050c..b021071 100644
--- themes/onehalf/sublimetext/OneHalfDark.tmTheme
+++ themes/onehalf/sublimetext/OneHalfDark.tmTheme
@@ -28,7 +28,7 @@
<plist version="1.0">
<dict>
<key>name</key>
- <string>OneHalfLight</string>
+ <string>OneHalfDark</string>
<key>semanticClass</key>
<string>theme.dark.one_half_dark</string>
<key>uuid</key>
@@ -155,7 +155,7 @@
<key>name</key>
<string>Classes</string>
<key>scope</key>
- <string>support.class, entity.name.class, entity.name.type.class</string>
+ <string>support.class, entity.name.class, entity.name.type.class, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -188,7 +188,7 @@
<key>name</key>
<string>Storage</string>
<key>scope</key>
- <string>storage</string>
+ <string>storage, meta.mapping.key string</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -309,7 +309,7 @@
<key>name</key>
<string>Markdown: Headings</string>
<key>scope</key>
- <string>markup.heading punctuation.definition.heading, entity.name.section</string>
+ <string>markup.heading punctuation.definition.heading, entity.name.section, markup.heading - text.html.markdown</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
@@ -660,4 +660,4 @@
</dict>
</array>
</dict>
-</plist>
\ No newline at end of file
+</plist>

View File

@@ -2,6 +2,24 @@ diff --git themes/TwoDark/TwoDark.tmTheme themes/TwoDark/TwoDark.tmTheme
index 87fd358..56376d3 100644
--- themes/TwoDark/TwoDark.tmTheme
+++ themes/TwoDark/TwoDark.tmTheme
@@ -125,7 +125,7 @@
<key>name</key>
<string>Classes</string>
<key>scope</key>
- <string>support.class, entity.name.class, entity.name.type.class</string>
+ <string>support.class, entity.name.class, entity.name.type.class, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -290,7 +290,7 @@
<key>name</key>
<string>Headings</string>
<key>scope</key>
- <string>markup.heading punctuation.definition.heading, entity.name.section</string>
+ <string>markup.heading punctuation.definition.heading, entity.name.section, markup.heading - text.html.markdown</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
@@ -533,7 +533,7 @@
<key>name</key>
<string>Json key</string>

BIN
assets/syntaxes.bin vendored

Binary file not shown.

View File

@@ -7,14 +7,14 @@ file_extensions:
- tsv
scope: text.csv
variables:
field_separator: (?:[,;\t])
field_separator: (?:[,;|\t])
record_separator: (?:$\n?)
contexts:
prototype:
- match: (?={{record_separator}})
pop: true
fields:
- match: ''
- match: ""
push:
- field_or_record_separator
- field4
@@ -26,15 +26,15 @@ contexts:
- field1
main:
- meta_include_prototype: false
- match: '^'
- match: "^"
set: fields
field_or_record_separator:
- meta_include_prototype: false
- match: '{{record_separator}}'
- match: "{{record_separator}}"
scope: punctuation.terminator.record.csv
pop: true
- match: '{{field_separator}}'
- match: "{{field_separator}}"
scope: punctuation.separator.sequence.csv
pop: true
@@ -56,23 +56,22 @@ contexts:
pop: true
field1:
- match: ''
- match: ""
set:
- meta_content_scope: meta.field-1.csv support.type
- include: field_contents
field2:
- match: ''
- match: ""
set:
- meta_content_scope: meta.field-2.csv support.function
- include: field_contents
field3:
- match: ''
- match: ""
set:
- meta_content_scope: meta.field-3.csv constant.numeric
- include: field_contents
field4:
- match: ''
- match: ""
set:
- meta_content_scope: meta.field-4.csv keyword.operator
- include: field_contents

View File

@@ -85,6 +85,9 @@ contexts:
options:
# command-line options like --option=value, --some-flag, or -x
- match: '^[ ]{7}(-)(?=\s)'
captures:
1: entity.name.command-line-option.man
- match: '^[ ]{7}(?=-|\+)'
push: expect-command-line-option
- match: '(?:[^a-zA-Z0-9_-]|^|\s){{command_line_option}}'

View File

@@ -131,6 +131,12 @@ OPTIONS
# ^^ - variable
output NUM (default 3) lines of copied context
- This is not really a switch, but indicates that standard input
# ^ entity.name.command-line-option.man
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - entity - variable
is coming from a file or a pipe and not interactively from the
command line.
EXAMPLE
#include <stdio.h>
# ^^^^^^^^ source.c meta.preprocessor.include keyword.control.import.include

BIN
assets/themes.bin vendored

Binary file not shown.

View File

@@ -69,7 +69,7 @@
<key>name</key>
<string>Labels</string>
<key>scope</key>
<string>entity.name.label</string>
<string>entity.name.label, variable.parameter</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -80,7 +80,7 @@
<key>name</key>
<string>Classes</string>
<key>scope</key>
<string>support.class, entity.name.class, entity.name.type.class</string>
<string>support.class, entity.name.class, entity.name.type.class, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -234,7 +234,7 @@
<key>name</key>
<string>Headings</string>
<key>scope</key>
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
<string>markup.heading punctuation.definition.heading, entity.name.section, markup.heading - text.html.markdown</string>
<key>settings</key>
<dict>
<key>fontStyle</key>

View File

@@ -257,7 +257,7 @@
<key>name</key>
<string>Tags</string>
<key>scope</key>
<string>entity.name.tag</string>
<string>entity.name.tag, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -312,7 +312,7 @@
<key>name</key>
<string>Headings</string>
<key>scope</key>
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
<string>markup.heading punctuation.definition.heading, entity.name.section, markup.heading - text.html.markdown</string>
<key>settings</key>
<dict>
<key>fontStyle</key>

View File

@@ -256,7 +256,7 @@
<key>name</key>
<string>Tags</string>
<key>scope</key>
<string>entity.name.tag</string>
<string>entity.name.tag, entity.name</string>
<key>settings</key>
<dict>
<key>foreground</key>
@@ -311,7 +311,7 @@
<key>name</key>
<string>Headings</string>
<key>scope</key>
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
<string>markup.heading punctuation.definition.heading, entity.name.section, markup.heading - text.html.markdown</string>
<key>settings</key>
<dict>
<key>fontStyle</key>

View File

@@ -63,5 +63,22 @@ pub fn gen_man_and_comp() -> anyhow::Result<()> {
out_dir.join("assets/completions/bat.zsh"),
)?;
println!(
"cargo:rustc-env=BAT_GENERATED_COMPLETION_BASH={}",
out_dir.join("assets/completions/bat.bash").display()
);
println!(
"cargo:rustc-env=BAT_GENERATED_COMPLETION_FISH={}",
out_dir.join("assets/completions/bat.fish").display()
);
println!(
"cargo:rustc-env=BAT_GENERATED_COMPLETION_PS1={}",
out_dir.join("assets/completions/_bat.ps1").display()
);
println!(
"cargo:rustc-env=BAT_GENERATED_COMPLETION_ZSH={}",
out_dir.join("assets/completions/bat.zsh").display()
);
Ok(())
}

View File

@@ -1,5 +1,6 @@
#[cfg(feature = "application")]
mod application;
mod syntax_mapping;
mod util;
fn main() -> anyhow::Result<()> {
@@ -7,6 +8,8 @@ fn main() -> anyhow::Result<()> {
// 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()?;

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(())
}

View File

@@ -366,7 +366,7 @@ ansible-galaxy install aeimer.install_bat
### From source
`bat` をソースからビルドしたいならば、Rust 1.70.0 以上の環境が必要です。
`bat` をソースからビルドしたいならば、Rust 1.74.0 以上の環境が必要です。
`cargo` を使用してビルドすることができます:
```bash

View File

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

View File

@@ -344,7 +344,7 @@ ansible-galaxy install aeimer.install_bat
### Из исходников
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.70.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.74.0 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
```bash
cargo install --locked bat

View File

@@ -372,7 +372,7 @@ scoop install bat
### 从源码编译
如果你想要自己构建`bat`那么你需要安装有高于1.70.0版本的 Rust。
如果你想要自己构建`bat`那么你需要安装有高于1.74.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`环境变量具有相同功能。
### 添加新的语言和语法
@@ -616,63 +616,59 @@ iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat
注意: 当`bat`无法识别语言时你可能会需要`-l`/`--language`参数。
## Development
## 开发
```bash
# Recursive clone to retrieve all submodules
# 递归 clone 以获取所有子模块
git clone --recursive https://github.com/sharkdp/bat
# Build (debug version)
# 构建(调试版本)
cd bat
cargo build --bins
# Run unit tests and integration tests
# 运行单元测试和集成测试
cargo test
# Install (release version)
# 安装(发布版本)
cargo install --path . --locked
# Build a bat binary with modified syntaxes and themes
# 使用修改后的语法和主题构建一个 bat 二进制文件
bash assets/create.sh
cargo install --path . --locked --force
```
If you want to build an application that uses `bat`s pretty-printing
features as a library, check out the [the API documentation](https://docs.rs/bat/).
Note that you have to use either `regex-onig` or `regex-fancy` as a feature
when you depend on `bat` as a library.
如果你想构建一个使用 `bat` 美化打印功能的应用程序,请查看 [API 文档](https://docs.rs/bat/)。请注意,当你依赖 `bat` 作为库时,必须使用 `regex-onig` 或 `regex-fancy` 作为特性。
## Contributing
## 贡献指南
Take a look at the [`CONTRIBUTING.md`](CONTRIBUTING.md) guide.
请查看 [`CONTRIBUTING.md`](CONTRIBUTING.md) 指南。
## Maintainers
## 维护者
- [sharkdp](https://github.com/sharkdp)
- [eth-p](https://github.com/eth-p)
- [keith-hall](https://github.com/keith-hall)
- [Enselic](https://github.com/Enselic)
## Security vulnerabilities
## 安全漏洞
Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`.
如果你想报告 `bat` 中的漏洞,请通过邮件联系 [David Peter](https://david-peter.de/)
## Project goals and alternatives
## 项目目标和替代方案
`bat` tries to achieve the following goals:
`bat` 试图实现以下目标:
- Provide beautiful, advanced syntax highlighting
- Integrate with Git to show file modifications
- Be a drop-in replacement for (POSIX) `cat`
- Offer a user-friendly command-line interface
- 提供美观的高级语法高亮
- 与 Git 集成以显示文件修改
- 成为 (POSIX) `cat` 的替代品
- 提供用户友好的命令行界面
There are a lot of alternatives, if you are looking for similar programs. See
[this document](doc/alternatives.md) for a comparison.
如果你在寻找类似的程序,有很多替代方案。请参阅[本文档](doc/alternatives.md)进行比较。
## License
## 许可证
Copyright (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat).
版权所有 (c) 2018-2021 [bat-developers](https://github.com/sharkdp/bat)
`bat` is made available under the terms of either the MIT License or the Apache License 2.0, at your option.
`bat` 可根据 MIT 许可证或 Apache 许可证 2.0 的条款使用,任选其一。
See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details.
有关许可证的详细信息,请参阅 [LICENSE-APACHE](LICENSE-APACHE) [LICENSE-MIT](LICENSE-MIT) 文件。

View File

@@ -20,6 +20,13 @@ Options:
* unicode (␇, ␊, ␀, ..)
* caret (^G, ^J, ^@, ..)
--binary <behavior>
How to treat binary content. (default: no-printing)
Possible values:
* no-printing: do not print any binary content
* as-text: treat binary content as normal text
-p, --plain...
Only show plain style, no decorations. This is an alias for '--style=plain'. When '-p' is
used twice ('-pp'), it also disables automatic paging (alias for '--style=plain
@@ -112,10 +119,42 @@ Options:
Set the theme for syntax highlighting. Use '--list-themes' to see all available themes. To
set a default theme, add the '--theme="..."' option to the configuration file or export
the BAT_THEME environment variable (e.g.: export BAT_THEME="...").
Special values:
* auto: Picks a dark or light theme depending on the terminal's colors (default).
Use '--theme-light' and '--theme-dark' to customize the selected theme.
* auto:always: Detect the terminal's colors even when the output is redirected.
* auto:system: Detect the color scheme from the system-wide preference (macOS only).
* dark: Use the dark theme specified by '--theme-dark'.
* light: Use the light theme specified by '--theme-light'.
--theme-light <theme>
Sets the theme name for syntax highlighting used when the terminal uses a light
background. Use '--list-themes' to see all available themes. To set a default theme, add
the '--theme-light="..." option to the configuration file or export the BAT_THEME_LIGHT
environment variable (e.g. export BAT_THEME_LIGHT="...").
--theme-dark <theme>
Sets the theme name for syntax highlighting used when the terminal uses a dark background.
Use '--list-themes' to see all available themes. To set a default theme, add the
'--theme-dark="..." option to the configuration file or export the BAT_THEME_DARK
environment variable (e.g. export BAT_THEME_DARK="...").
--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.
--strip-ansi <when>
Specify when to strip ANSI escape sequences from the input. The automatic mode will remove
escape sequences unless the syntax highlighting language is plain text. Possible values:
auto, always, *never*.
--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 +162,15 @@ 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="..").
When styles are specified in multiple places, the "nearest" set of styles take precedence.
The command-line arguments are the highest priority, followed by the BAT_STYLE environment
variable, and then the configuration file. If any set of styles consists entirely of
components prefixed with "+" or "-", it will modify the previous set of styles instead of
replacing them.
By default, the following components are enabled:
changes, grid, header-filename, numbers, snip
Possible values:
* default: enables recommended style components (default).
@@ -154,12 +202,18 @@ Options:
This option exists for POSIX-compliance reasons ('u' is for 'unbuffered'). The output is
always unbuffered - this option is simply ignored.
--completion <SHELL>
Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1]
--diagnostic
Show diagnostic information for bug reports.
--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

@@ -11,6 +11,8 @@ Options:
Show non-printable characters (space, tab, newline, ..).
--nonprintable-notation <notation>
Set notation for non-printable characters.
--binary <behavior>
How to treat binary content. (default: no-printing)
-p, --plain...
Show plain style (alias for '--style=plain').
-l, --language <language>
@@ -41,8 +43,14 @@ Options:
Use the specified syntax for files matching the glob pattern ('*.cpp:C++').
--theme <theme>
Set the color theme for syntax highlighting.
--theme-light <theme>
Sets the color theme for syntax highlighting used for light backgrounds.
--theme-dark <theme>
Sets the color theme for syntax highlighting used for dark backgrounds.
--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).
@@ -50,6 +58,8 @@ Options:
Only print the lines from N to M.
-L, --list-languages
Display all supported languages.
--completion <SHELL>
Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1]
-h, --help
Print help (see more with '--help')
-V, --version

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

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

View File

@@ -13,6 +13,7 @@ use crate::error::*;
use crate::input::{InputReader, OpenedInput};
use crate::syntax_mapping::ignored_suffixes::IgnoredSuffixes;
use crate::syntax_mapping::MappingTarget;
use crate::theme::{default_theme, ColorScheme};
use crate::{bat_warning, SyntaxMapping};
use lazy_theme_set::LazyThemeSet;
@@ -69,57 +70,6 @@ impl HighlightingAssets {
}
}
/// The default theme.
///
/// ### Windows and Linux
///
/// Windows and most Linux distributions has a dark terminal theme by
/// default. On these platforms, this function always returns a theme that
/// looks good on a dark background.
///
/// ### macOS
///
/// On macOS the default terminal background is light, but it is common that
/// Dark Mode is active, which makes the terminal background dark. On this
/// platform, the default theme depends on
/// ```bash
/// defaults read -globalDomain AppleInterfaceStyle
/// ```
/// To avoid the overhead of the check on macOS, simply specify a theme
/// explicitly via `--theme`, `BAT_THEME`, or `~/.config/bat`.
///
/// See <https://github.com/sharkdp/bat/issues/1746> and
/// <https://github.com/sharkdp/bat/issues/1928> for more context.
pub fn default_theme() -> &'static str {
#[cfg(not(target_os = "macos"))]
{
Self::default_dark_theme()
}
#[cfg(target_os = "macos")]
{
if macos_dark_mode_active() {
Self::default_dark_theme()
} else {
Self::default_light_theme()
}
}
}
/**
* The default theme that looks good on a dark background.
*/
fn default_dark_theme() -> &'static str {
"Monokai Extended"
}
/**
* The default theme that looks good on a light background.
*/
#[cfg(target_os = "macos")]
fn default_light_theme() -> &'static str {
"Monokai Extended Light"
}
pub fn from_cache(cache_path: &Path) -> Result<Self> {
Ok(HighlightingAssets::new(
SerializedSyntaxSet::FromFile(cache_path.join("syntaxes.bin")),
@@ -248,7 +198,10 @@ impl HighlightingAssets {
bat_warning!("Unknown theme '{}', using default.", theme)
}
self.get_theme_set()
.get(self.fallback_theme.unwrap_or_else(Self::default_theme))
.get(
self.fallback_theme
.unwrap_or_else(|| default_theme(ColorScheme::Dark)),
)
.expect("something is very wrong if the default theme is missing")
}
}
@@ -380,7 +333,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,27 +349,7 @@ fn asset_from_cache<T: serde::de::DeserializeOwned>(
)
})?;
asset_from_contents(&contents[..], description, compressed)
.map_err(|_| format!("Could not parse cached {}", description).into())
}
#[cfg(target_os = "macos")]
fn macos_dark_mode_active() -> bool {
const PREFERENCES_FILE: &str = "Library/Preferences/.GlobalPreferences.plist";
const STYLE_KEY: &str = "AppleInterfaceStyle";
let preferences_file = home::home_dir()
.map(|home| home.join(PREFERENCES_FILE))
.expect("Could not get home directory");
match plist::Value::from_file(preferences_file).map(|file| file.into_dictionary()) {
Ok(Some(preferences)) => match preferences.get(STYLE_KEY).and_then(|val| val.as_string()) {
Some(value) => value == "Dark",
// If the key does not exist, then light theme is currently in use.
None => false,
},
// Unreachable, in theory. All macOS users have a home directory and preferences file setup.
Ok(None) | Err(_) => true,
}
.map_err(|_| format!("Could not parse cached {description}").into())
}
#[cfg(test)]
@@ -441,7 +374,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 +399,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 +447,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

@@ -2,18 +2,22 @@ use std::collections::HashSet;
use std::env;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use crate::{
clap_app,
config::{get_args_from_config_file, get_args_from_env_opts_var, get_args_from_env_vars},
};
use bat::style::StyleComponentList;
use bat::theme::{theme, ThemeName, ThemeOptions, ThemePreference};
use bat::BinaryBehavior;
use bat::StripAnsiMode;
use clap::ArgMatches;
use console::Term;
use crate::input::{new_file_input, new_stdin_input};
use bat::{
assets::HighlightingAssets,
bat_warning,
config::{Config, VisibleLines},
error::*,
@@ -85,7 +89,6 @@ impl App {
// .. and the rest at the end
cli_args.for_each(|a| args.push(a));
args
};
@@ -95,12 +98,30 @@ impl App {
pub fn config(&self, inputs: &[Input]) -> Result<Config> {
let style_components = self.style_components()?;
let extra_plain = self.matches.get_count("plain") > 1;
let plain_last_index = self
.matches
.indices_of("plain")
.and_then(Iterator::max)
.unwrap_or_default();
let paging_last_index = self
.matches
.indices_of("paging")
.and_then(Iterator::max)
.unwrap_or_default();
let paging_mode = match self.matches.get_one::<String>("paging").map(|s| s.as_str()) {
Some("always") => PagingMode::Always,
Some("always") => {
// Disable paging if the second -p (or -pp) is specified after --paging=always
if extra_plain && plain_last_index > paging_last_index {
PagingMode::Never
} else {
PagingMode::Always
}
}
Some("never") => PagingMode::Never,
Some("auto") | None => {
// If we have -pp as an option when in auto mode, the pager should be disabled.
let extra_plain = self.matches.get_count("plain") > 1;
if extra_plain || self.matches.get_flag("no-paging") {
PagingMode::Never
} else if inputs.iter().any(Input::is_stdin) {
@@ -121,7 +142,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 {
@@ -130,7 +155,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 {
@@ -185,6 +212,11 @@ impl App {
Some("caret") => NonprintableNotation::Caret,
_ => unreachable!("other values for --nonprintable-notation are not allowed"),
},
binary: match self.matches.get_one::<String>("binary").map(|s| s.as_str()) {
Some("as-text") => BinaryBehavior::AsText,
Some("no-printing") => BinaryBehavior::NoPrinting,
_ => unreachable!("other values for --binary are not allowed"),
},
wrapping_mode: if self.interactive_output || maybe_term_width.is_some() {
if !self.matches.get_flag("chop-long-lines") {
match self.matches.get_one::<String>("wrap").map(|s| s.as_str()) {
@@ -236,18 +268,17 @@ impl App {
4
},
),
theme: self
strip_ansi: match self
.matches
.get_one::<String>("theme")
.map(String::from)
.map(|s| {
if s == "default" {
String::from(HighlightingAssets::default_theme())
} else {
s
}
})
.unwrap_or_else(|| String::from(HighlightingAssets::default_theme())),
.get_one::<String>("strip-ansi")
.map(|s| s.as_str())
{
Some("never") => StripAnsiMode::Never,
Some("always") => StripAnsiMode::Always,
Some("auto") => StripAnsiMode::Auto,
_ => unreachable!("other values for --strip-ansi are not allowed"),
},
theme: theme(self.theme_options()).to_string(),
visible_lines: match self.matches.try_contains_id("diff").unwrap_or_default()
&& self.matches.get_flag("diff")
{
@@ -287,6 +318,17 @@ impl App {
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
},
})
}
@@ -336,34 +378,57 @@ impl App {
Ok(file_input)
}
fn forced_style_components(&self) -> Option<StyleComponents> {
// No components if `--decorations=never``.
if self
.matches
.get_one::<String>("decorations")
.map(|s| s.as_str())
== Some("never")
{
return Some(StyleComponents(HashSet::new()));
}
// Only line numbers if `--number`.
if self.matches.get_flag("number") {
return Some(StyleComponents(HashSet::from([
StyleComponent::LineNumbers,
])));
}
// Plain if `--plain` is specified at least once.
if self.matches.get_count("plain") > 0 {
return Some(StyleComponents(HashSet::from([StyleComponent::Plain])));
}
// Default behavior.
None
}
fn style_components(&self) -> Result<StyleComponents> {
let matches = &self.matches;
let mut styled_components = StyleComponents(
if matches.get_one::<String>("decorations").map(|s| s.as_str()) == Some("never") {
HashSet::new()
} else if matches.get_flag("number") {
[StyleComponent::LineNumbers].iter().cloned().collect()
} else if 0 < matches.get_count("plain") {
[StyleComponent::Plain].iter().cloned().collect()
} else {
matches
.get_one::<String>("style")
.map(|styles| {
styles
.split(',')
.map(|style| style.parse::<StyleComponent>())
.filter_map(|style| style.ok())
.collect::<Vec<_>>()
})
.unwrap_or_else(|| vec![StyleComponent::Default])
let mut styled_components = match self.forced_style_components() {
Some(forced_components) => forced_components,
// Parse the `--style` arguments and merge them.
None if matches.contains_id("style") => {
let lists = matches
.get_many::<String>("style")
.expect("styles present")
.map(|v| StyleComponentList::from_str(v))
.collect::<Result<Vec<StyleComponentList>>>()?;
StyleComponentList::to_components(lists, self.interactive_output, true)
}
// Use the default.
None => StyleComponents(HashSet::from_iter(
StyleComponent::Default
.components(self.interactive_output)
.into_iter()
.map(|style| style.components(self.interactive_output))
.fold(HashSet::new(), |mut acc, components| {
acc.extend(components.iter().cloned());
acc
})
},
);
.cloned(),
)),
};
// If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning.
if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) {
@@ -372,4 +437,25 @@ impl App {
Ok(styled_components)
}
fn theme_options(&self) -> ThemeOptions {
let theme = self
.matches
.get_one::<String>("theme")
.map(|t| ThemePreference::from_str(t).unwrap())
.unwrap_or_default();
let theme_dark = self
.matches
.get_one::<String>("theme-dark")
.map(|t| ThemeName::from_str(t).unwrap());
let theme_light = self
.matches
.get_one::<String>("theme-light")
.map(|t| ThemeName::from_str(t).unwrap());
ThemeOptions {
theme,
theme_dark,
theme_light,
}
}
}

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

@@ -1,9 +1,11 @@
use bat::style::StyleComponentList;
use clap::{
crate_name, crate_version, value_parser, Arg, ArgAction, ArgGroup, ColorChoice, Command,
};
use once_cell::sync::Lazy;
use std::env;
use std::path::{Path, PathBuf};
use std::str::FromStr;
static VERSION: Lazy<String> = Lazy::new(|| {
#[cfg(feature = "bugreport")]
@@ -75,11 +77,26 @@ pub fn build_app(interactive_output: bool) -> Command {
* caret (^G, ^J, ^@, ..)",
),
)
.arg(
Arg::new("binary")
.long("binary")
.action(ArgAction::Set)
.default_value("no-printing")
.value_parser(["no-printing", "as-text"])
.value_name("behavior")
.hide_default_value(true)
.help("How to treat binary content. (default: no-printing)")
.long_help(
"How to treat binary content. (default: no-printing)\n\n\
Possible values:\n \
* no-printing: do not print any binary content\n \
* as-text: treat binary content as normal text",
),
)
.arg(
Arg::new("plain")
.overrides_with("plain")
.overrides_with("number")
.overrides_with("paging")
.short('p')
.long("plain")
.action(ArgAction::Count)
@@ -304,7 +321,6 @@ pub fn build_app(interactive_output: bool) -> Command {
.long("paging")
.overrides_with("paging")
.overrides_with("no-paging")
.overrides_with("plain")
.value_name("when")
.value_parser(["auto", "never", "always"])
.default_value("auto")
@@ -377,9 +393,40 @@ pub fn build_app(interactive_output: bool) -> Command {
see all available themes. To set a default theme, add the \
'--theme=\"...\"' option to the configuration file or export the \
BAT_THEME environment variable (e.g.: export \
BAT_THEME=\"...\").",
BAT_THEME=\"...\").\n\n\
Special values:\n\n \
* auto: Picks a dark or light theme depending on the terminal's colors (default).\n \
Use '--theme-light' and '--theme-dark' to customize the selected theme.\n \
* auto:always: Detect the terminal's colors even when the output is redirected.\n \
* auto:system: Detect the color scheme from the system-wide preference (macOS only).\n \
* dark: Use the dark theme specified by '--theme-dark'.\n \
* light: Use the light theme specified by '--theme-light'.",
),
)
.arg(
Arg::new("theme-light")
.long("theme-light")
.overrides_with("theme-light")
.value_name("theme")
.help("Sets the color theme for syntax highlighting used for light backgrounds.")
.long_help(
"Sets the theme name for syntax highlighting used when the terminal uses a light background. \
Use '--list-themes' to see all available themes. To set a default theme, add the \
'--theme-light=\"...\" option to the configuration file or export the BAT_THEME_LIGHT \
environment variable (e.g. export BAT_THEME_LIGHT=\"...\")."),
)
.arg(
Arg::new("theme-dark")
.long("theme-dark")
.overrides_with("theme-dark")
.value_name("theme")
.help("Sets the color theme for syntax highlighting used for dark backgrounds.")
.long_help(
"Sets the theme name for syntax highlighting used when the terminal uses a dark background. \
Use '--list-themes' to see all available themes. To set a default theme, add the \
'--theme-dark=\"...\" option to the configuration file or export the BAT_THEME_DARK \
environment variable (e.g. export BAT_THEME_DARK=\"...\")."),
)
.arg(
Arg::new("list-themes")
.long("list-themes")
@@ -387,37 +434,45 @@ 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("strip-ansi")
.long("strip-ansi")
.overrides_with("strip-ansi")
.value_name("when")
.value_parser(["auto", "always", "never"])
.default_value("never")
.hide_default_value(true)
.help("Strip colors from the input (auto, always, *never*)")
.long_help("Specify when to strip ANSI escape sequences from the input. \
The automatic mode will remove escape sequences unless the syntax highlighting \
language is plain text. Possible values: auto, always, *never*.")
.hide_short_help(true)
)
.arg(
Arg::new("style")
.long("style")
.action(ArgAction::Append)
.value_name("components")
.overrides_with("style")
.overrides_with("plain")
.overrides_with("number")
// Cannot use claps built in validation because we have to turn off clap's delimiters
.value_parser(|val: &str| {
let mut invalid_vals = val.split(',').filter(|style| {
!&[
"auto",
"full",
"default",
"plain",
"header",
"header-filename",
"header-filesize",
"grid",
"rule",
"numbers",
"snip",
#[cfg(feature = "git")]
"changes",
].contains(style)
});
if let Some(invalid) = invalid_vals.next() {
Err(format!("Unknown style, '{}'", invalid))
} else {
Ok(val.to_owned())
match StyleComponentList::from_str(val) {
Err(err) => Err(err),
Ok(_) => Ok(val.to_owned()),
}
})
.help(
@@ -432,6 +487,14 @@ 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\
When styles are specified in multiple places, the \"nearest\" set \
of styles take precedence. The command-line arguments are the highest \
priority, followed by the BAT_STYLE environment variable, and then \
the configuration file. If any set of styles consists entirely of \
components prefixed with \"+\" or \"-\", it will modify the \
previous set of styles instead of replacing them.\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 \
@@ -501,6 +564,17 @@ pub fn build_app(interactive_output: bool) -> Command {
.help("Do not load custom assets"),
);
#[cfg(feature = "application")]
{
app = app.arg(
Arg::new("completion")
.long("completion")
.value_name("SHELL")
.value_parser(["bash", "fish", "ps1", "zsh"])
.help("Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1]"),
);
}
#[cfg(feature = "lessopen")]
{
app = app
@@ -567,6 +641,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

@@ -0,0 +1,6 @@
use std::env;
pub const BASH_COMPLETION: &str = include_str!(env!("BAT_GENERATED_COMPLETION_BASH"));
pub const FISH_COMPLETION: &str = include_str!(env!("BAT_GENERATED_COMPLETION_FISH"));
pub const PS1_COMPLETION: &str = include_str!(env!("BAT_GENERATED_COMPLETION_PS1"));
pub const ZSH_COMPLETION: &str = include_str!(env!("BAT_GENERATED_COMPLETION_ZSH"));

View File

@@ -140,14 +140,19 @@ fn get_args_from_str(content: &str) -> Result<Vec<OsString>, shell_words::ParseE
pub fn get_args_from_env_vars() -> Vec<OsString> {
[
("--tabs", "BAT_TABS"),
("--theme", "BAT_THEME"),
("--theme", bat::theme::env::BAT_THEME),
("--theme-dark", bat::theme::env::BAT_THEME_DARK),
("--theme-light", bat::theme::env::BAT_THEME_LIGHT),
("--pager", "BAT_PAGER"),
("--paging", "BAT_PAGING"),
("--style", "BAT_STYLE"),
]
.iter()
.filter_map(|(flag, key)| env::var(key).ok().map(|var| [flag.to_string(), var]))
.flatten()
.filter_map(|(flag, key)| {
env::var(key)
.ok()
.map(|var| [flag.to_string(), var].join("="))
})
.map(|a| a.into())
.collect()
}

View File

@@ -3,6 +3,8 @@
mod app;
mod assets;
mod clap_app;
#[cfg(feature = "application")]
mod completions;
mod config;
mod directories;
mod input;
@@ -14,6 +16,7 @@ use std::io::{BufReader, Write};
use std::path::Path;
use std::process;
use bat::theme::DetectColorScheme;
use nu_ansi_term::Color::Green;
use nu_ansi_term::Style;
@@ -35,6 +38,7 @@ use bat::{
error::*,
input::Input,
style::{StyleComponent, StyleComponents},
theme::{color_scheme, default_theme, ColorScheme},
MappingTarget, PagingMode,
};
@@ -78,9 +82,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 +129,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()) {
@@ -186,7 +192,12 @@ fn theme_preview_file<'a>() -> Input<'a> {
Input::from_reader(Box::new(BufReader::new(THEME_PREVIEW_DATA)))
}
pub fn list_themes(cfg: &Config, config_dir: &Path, cache_dir: &Path) -> Result<()> {
pub fn list_themes(
cfg: &Config,
config_dir: &Path,
cache_dir: &Path,
detect_color_scheme: DetectColorScheme,
) -> Result<()> {
let assets = assets_from_cache_or_binary(cfg.use_custom_assets, cache_dir)?;
let mut config = cfg.clone();
let mut style = HashSet::new();
@@ -197,19 +208,35 @@ 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_name = default_theme(color_scheme(detect_color_scheme).unwrap_or_default());
for theme in assets.themes() {
let default_theme_info = if !config.loop_through && default_theme_name == theme {
" (default)"
} else if default_theme(ColorScheme::Dark) == theme {
" (default dark)"
} else if default_theme(ColorScheme::Light) == theme {
" (default light)"
} 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()], None)
.ok();
writeln!(stdout)?;
} else {
writeln!(stdout, "{theme}{default_theme_info}")?;
}
}
if config.colored_output {
writeln!(
stdout,
"Further themes can be installed to '{}', \
@@ -218,18 +245,35 @@ 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);
if config.paging_mode != PagingMode::Never && config.set_terminal_title {
set_terminal_title_to(get_new_terminal_title(&inputs));
}
controller.run(inputs, None)
}
@@ -249,24 +293,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_PAGING",
"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()))
@@ -304,6 +349,18 @@ fn run() -> Result<bool> {
return Ok(true);
}
#[cfg(feature = "application")]
if let Some(shell) = app.matches.get_one::<String>("completion") {
match shell.as_str() {
"bash" => println!("{}", completions::BASH_COMPLETION),
"fish" => println!("{}", completions::FISH_COMPLETION),
"ps1" => println!("{}", completions::PS1_COMPLETION),
"zsh" => println!("{}", completions::ZSH_COMPLETION),
_ => unreachable!("No completion for shell '{}' available.", shell),
}
return Ok(true);
}
match app.matches.subcommand() {
Some(("cache", cache_matches)) => {
// If there is a file named 'cache' in the current working directory,
@@ -338,7 +395,7 @@ fn run() -> Result<bool> {
};
run_controller(inputs, &plain_config, cache_dir)
} else if app.matches.get_flag("list-themes") {
list_themes(&config, config_dir, cache_dir)?;
list_themes(&config, config_dir, cache_dir, DetectColorScheme::default())?;
Ok(true)
} else if app.matches.get_flag("config-file") {
println!("{}", config_file().to_string_lossy());

View File

@@ -1,10 +1,11 @@
use crate::line_range::{HighlightedLineRanges, LineRanges};
use crate::nonprintable_notation::NonprintableNotation;
use crate::nonprintable_notation::{BinaryBehavior, NonprintableNotation};
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
use crate::style::StyleComponents;
use crate::syntax_mapping::SyntaxMapping;
use crate::wrapping::WrappingMode;
use crate::StripAnsiMode;
#[derive(Debug, Clone)]
pub enum VisibleLines {
@@ -43,6 +44,9 @@ pub struct Config<'a> {
/// The configured notation for non-printable characters
pub nonprintable_notation: NonprintableNotation,
/// How to treat binary content
pub binary: BinaryBehavior,
/// The character width of the terminal
pub term_width: usize,
@@ -94,6 +98,15 @@ pub struct Config<'a> {
// 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>,
// Weather or not to set terminal title when using a pager
pub strip_ansi: StripAnsiMode,
}
#[cfg(all(feature = "minimal-application", feature = "paging"))]

View File

@@ -47,7 +47,7 @@ impl<'b> Controller<'b> {
&self,
inputs: Vec<Input>,
output_buffer: Option<&mut dyn std::fmt::Write>,
handle_error: impl Fn(&Error, &mut dyn Write),
mut handle_error: impl FnMut(&Error, &mut dyn Write),
) -> Result<bool> {
let mut output_type;

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

@@ -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());
}

View File

@@ -3,13 +3,12 @@
use std::convert::TryFrom;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, Cursor, Read, Write};
use std::io::{BufRead, BufReader, Cursor, Read};
use std::path::PathBuf;
use std::str;
use std::process::{ExitStatus, Stdio};
use clircle::{Clircle, Identifier};
use os_str_bytes::RawOsString;
use run_script::{IoOptions, ScriptOptions};
use execute::{shell, Execute};
use crate::error::Result;
use crate::{
@@ -21,7 +20,6 @@ use crate::{
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,
@@ -52,7 +50,7 @@ impl LessOpenPreprocessor {
// 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
// "|" means pipe as above, but ignore exit code and always use preprocessor output even if empty
} else if lessopen.starts_with('|') {
(
LessOpenKind::PipedIgnoreExitCode,
@@ -70,16 +68,9 @@ impl LessOpenPreprocessor {
(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,
lessopen,
lessclose: env::var("LESSCLOSE").ok(),
kind,
preprocess_stdin: stdin,
})
@@ -98,21 +89,21 @@ impl LessOpenPreprocessor {
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,
) {
let mut lessopen_command = shell(self.lessopen.replacen("%s", path_str, 1));
lessopen_command.stdout(Stdio::piped());
let lessopen_output = match lessopen_command.execute_output() {
Ok(output) => output,
Err(_) => return input.open(stdin, stdout_identifier),
};
if self.fall_back_to_original_file(&lessopen_stdout, exit_code) {
if self.fall_back_to_original_file(&lessopen_output.stdout, lessopen_output.status)
{
return input.open(stdin, stdout_identifier);
}
(
RawOsString::from_string(lessopen_stdout),
lessopen_output.stdout,
path_str.to_string(),
OpenedInputKind::OrdinaryFile(path.to_path_buf()),
)
@@ -127,47 +118,31 @@ impl LessOpenPreprocessor {
}
}
// stdin isn't Clone, so copy it to a cloneable buffer
// stdin isn't Clone or AsRef<[u8]>, so move it into a cloneable buffer
// so the data can be used multiple times if necessary
// NOTE: stdin will be empty from this point onwards
let mut stdin_buffer = Vec::new();
stdin.read_to_end(&mut stdin_buffer).unwrap();
stdin.read_to_end(&mut stdin_buffer)?;
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);
}
};
let mut lessopen_command = shell(self.lessopen.replacen("%s", "-", 1));
lessopen_command.stdout(Stdio::piped());
if lessopen_handle
.stdin
.as_mut()
.unwrap()
.write_all(&stdin_buffer.clone())
.is_err()
let lessopen_output = match lessopen_command.execute_input_output(&stdin_buffer)
{
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))
if self
.fall_back_to_original_file(&lessopen_output.stdout, lessopen_output.status)
{
return input.open(Cursor::new(stdin_buffer), stdout_identifier);
}
(
RawOsString::assert_from_raw_vec(lessopen_output.stdout),
lessopen_output.stdout,
"-".to_string(),
OpenedInputKind::StdIn,
)
@@ -184,13 +159,17 @@ impl LessOpenPreprocessor {
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 lessopen_string = match String::from_utf8(lessopen_stdout) {
Ok(string) => string,
Err(_) => {
return input.open(stdin, stdout_identifier);
}
};
// Remove newline at end of temporary file path returned by $LESSOPEN
let stdout = match lessopen_string.strip_suffix("\n") {
Some(stripped) => stripped.to_owned(),
None => lessopen_string,
};
let stdout = stdout.into_os_string();
let file = match File::open(PathBuf::from(&stdout)) {
Ok(file) => file,
@@ -201,16 +180,18 @@ impl LessOpenPreprocessor {
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(),
lessclose: self
.lessclose
.as_ref()
.map(|s| s.replacen("%s", &path_str, 1).replacen("%s", &stdout, 1)),
}
} 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(),
kind: PreprocessedKind::Piped(Cursor::new(lessopen_stdout)),
lessclose: self
.lessclose
.as_ref()
.map(|s| s.replacen("%s", &path_str, 1).replacen("%s", "-", 1)),
}
},
)),
@@ -219,9 +200,9 @@ impl LessOpenPreprocessor {
})
}
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))
fn fall_back_to_original_file(&self, lessopen_stdout: &Vec<u8>, exit_code: ExitStatus) -> bool {
lessopen_stdout.is_empty()
&& (!exit_code.success() || matches!(self.kind, LessOpenKind::PipedIgnoreExitCode))
}
#[cfg(test)]
@@ -261,8 +242,6 @@ impl Read for PreprocessedKind {
pub struct Preprocessed {
kind: PreprocessedKind,
lessclose: Option<String>,
command_args: Vec<String>,
command_options: ScriptOptions,
}
impl Read for Preprocessed {
@@ -273,11 +252,20 @@ impl Read for Preprocessed {
impl Drop for Preprocessed {
fn drop(&mut self) {
if let Some(ref command) = self.lessclose {
self.command_options.output_redirection = IoOptions::Inherit;
if let Some(lessclose) = self.lessclose.clone() {
let mut lessclose_command = shell(lessclose);
run_script::run(command, &self.command_args, &self.command_options)
.expect("failed to run $LESSCLOSE to clean up file");
let lessclose_output = match lessclose_command.execute_output() {
Ok(output) => output,
Err(_) => {
bat_warning!("failed to run $LESSCLOSE to clean up temporary file");
return;
}
};
if lessclose_output.status.success() {
bat_warning!("$LESSCLOSE exited with nonzero exit code",)
};
}
}
}
@@ -301,7 +289,7 @@ mod tests {
fn test_just_lessopen() -> Result<()> {
let preprocessor = LessOpenPreprocessor::mock_new(Some("|batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert_eq!(preprocessor.lessopen, "batpipe %s");
assert!(preprocessor.lessclose.is_none());
reset_env_vars();
@@ -327,8 +315,8 @@ mod tests {
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");
assert_eq!(preprocessor.lessopen, "lessopen.sh %s");
assert_eq!(preprocessor.lessclose.unwrap(), "lessclose.sh %s %s");
reset_env_vars();
@@ -340,13 +328,13 @@ mod tests {
fn test_lessopen_prefixes() -> Result<()> {
let preprocessor = LessOpenPreprocessor::mock_new(Some("batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert_eq!(preprocessor.lessopen, "batpipe %s");
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_eq!(preprocessor.lessopen, "batpipe %s");
assert!(matches!(
preprocessor.kind,
LessOpenKind::PipedIgnoreExitCode
@@ -355,19 +343,19 @@ mod tests {
let preprocessor = LessOpenPreprocessor::mock_new(Some("||batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert_eq!(preprocessor.lessopen, "batpipe %s");
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_eq!(preprocessor.lessopen, "batpipe %s");
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_eq!(preprocessor.lessopen, "batpipe %s");
assert!(matches!(
preprocessor.kind,
LessOpenKind::PipedIgnoreExitCode
@@ -376,7 +364,7 @@ mod tests {
let preprocessor = LessOpenPreprocessor::mock_new(Some("||-batpipe %s"), None)?;
assert_eq!(preprocessor.lessopen, "batpipe $1");
assert_eq!(preprocessor.lessopen, "batpipe %s");
assert!(matches!(preprocessor.kind, LessOpenKind::Piped));
assert!(preprocessor.preprocess_stdin);
@@ -391,8 +379,8 @@ mod tests {
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");
assert_eq!(preprocessor.lessopen, "echo File:%s");
assert_eq!(preprocessor.lessclose.unwrap(), "echo File:%s Temp:%s");
reset_env_vars();

View File

@@ -49,10 +49,12 @@ pub(crate) mod printer;
pub mod style;
pub(crate) mod syntax_mapping;
mod terminal;
pub mod theme;
mod vscreen;
pub(crate) mod wrapping;
pub use nonprintable_notation::NonprintableNotation;
pub use nonprintable_notation::{BinaryBehavior, NonprintableNotation};
pub use preprocessor::StripAnsiMode;
pub use pretty_printer::{Input, PrettyPrinter, Syntax};
pub use syntax_mapping::{MappingTarget, SyntaxMapping};
pub use wrapping::WrappingMode;

View File

@@ -10,3 +10,15 @@ pub enum NonprintableNotation {
#[default]
Unicode,
}
/// How to treat binary content
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum BinaryBehavior {
/// Do not print any binary content
#[default]
NoPrinting,
/// Treat binary content as normal text
AsText,
}

View File

@@ -1,17 +1,18 @@
use std::fmt::Write;
use console::AnsiCodeIterator;
use crate::nonprintable_notation::NonprintableNotation;
use crate::{
nonprintable_notation::NonprintableNotation,
vscreen::{EscapeSequenceOffsets, EscapeSequenceOffsetsIterator},
};
/// Expand tabs like an ANSI-enabled expand(1).
pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
let mut buffer = String::with_capacity(line.len() * 2);
for chunk in AnsiCodeIterator::new(line) {
match chunk {
(text, true) => buffer.push_str(text),
(mut text, false) => {
for seq in EscapeSequenceOffsetsIterator::new(line) {
match seq {
EscapeSequenceOffsets::Text { .. } => {
let mut text = &line[seq.index_of_start()..seq.index_past_end()];
while let Some(index) = text.find('\t') {
// Add previous text.
if index > 0 {
@@ -31,6 +32,10 @@ pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
*cursor += text.len();
buffer.push_str(text);
}
_ => {
// Copy the ANSI escape sequence.
buffer.push_str(&line[seq.index_of_start()..seq.index_past_end()])
}
}
}
@@ -131,6 +136,27 @@ pub fn replace_nonprintable(
output
}
/// Strips ANSI escape sequences from the input.
pub fn strip_ansi(line: &str) -> String {
let mut buffer = String::with_capacity(line.len());
for seq in EscapeSequenceOffsetsIterator::new(line) {
if let EscapeSequenceOffsets::Text { .. } = seq {
buffer.push_str(&line[seq.index_of_start()..seq.index_past_end()]);
}
}
buffer
}
#[derive(Debug, PartialEq, Clone, Copy, Default)]
pub enum StripAnsiMode {
#[default]
Never,
Always,
Auto,
}
#[test]
fn test_try_parse_utf8_char() {
assert_eq!(try_parse_utf8_char(&[0x20]), Some((' ', 1)));
@@ -174,3 +200,14 @@ fn test_try_parse_utf8_char() {
assert_eq!(try_parse_utf8_char(&[0xef, 0x20]), None);
assert_eq!(try_parse_utf8_char(&[0xf0, 0xf0]), None);
}
#[test]
fn test_strip_ansi() {
// The sequence detection is covered by the tests in the vscreen module.
assert_eq!(strip_ansi("no ansi"), "no ansi");
assert_eq!(strip_ansi("\x1B[33mone"), "one");
assert_eq!(
strip_ansi("\x1B]1\x07multiple\x1B[J sequences"),
"multiple sequences"
);
}

View File

@@ -11,7 +11,7 @@ use crate::{
input,
line_range::{HighlightedLineRanges, LineRange, LineRanges},
style::StyleComponent,
SyntaxMapping, WrappingMode,
StripAnsiMode, SyntaxMapping, WrappingMode,
};
#[cfg(feature = "paging")]
@@ -182,6 +182,15 @@ impl<'a> PrettyPrinter<'a> {
self
}
/// Whether to remove ANSI escape sequences from the input (default: never)
///
/// If `Auto` is used, escape sequences will only be removed when the input
/// is not plain text.
pub fn strip_ansi(&mut self, mode: StripAnsiMode) -> &mut Self {
self.config.strip_ansi = mode;
self
}
/// Text wrapping mode (default: do not wrap)
pub fn wrapping_mode(&mut self, mode: WrappingMode) -> &mut Self {
self.config.wrapping_mode = mode;
@@ -230,7 +239,15 @@ impl<'a> PrettyPrinter<'a> {
self
}
/// Specify the highlighting theme
/// 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.
/// You can use [`crate::theme::theme`] to pick a theme based on user preferences
/// and the terminal's background color.
pub fn theme(&mut self, theme: impl AsRef<str>) -> &mut Self {
self.config.theme = theme.as_ref().to_owned();
self
@@ -264,6 +281,11 @@ impl<'a> PrettyPrinter<'a> {
/// If you want to call 'print' multiple times, you have to call the appropriate
/// input_* methods again.
pub fn print(&mut self) -> Result<bool> {
self.print_with_writer(None::<&mut dyn std::fmt::Write>)
}
/// Pretty-print all specified inputs to a specified writer.
pub fn print_with_writer<W: std::fmt::Write>(&mut self, writer: Option<W>) -> Result<bool> {
let highlight_lines = std::mem::take(&mut self.highlighted_lines);
self.config.highlighted_lines = HighlightedLineRanges(LineRanges::from(highlight_lines));
self.config.term_width = self
@@ -300,7 +322,13 @@ 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(), None)
// If writer is provided, pass it to the controller, otherwise pass None
if let Some(mut w) = writer {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), Some(&mut w))
} else {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), None)
}
}
}

View File

@@ -7,10 +7,9 @@ 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;
@@ -30,11 +29,44 @@ use crate::diff::LineChanges;
use crate::error::*;
use crate::input::OpenedInput;
use crate::line_range::RangeCheckResult;
use crate::preprocessor::strip_ansi;
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;
use crate::BinaryBehavior;
use crate::StripAnsiMode;
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),
@@ -72,11 +104,15 @@ 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,
}
}
}
@@ -105,6 +141,21 @@ impl<'a> Printer for SimplePrinter<'a> {
_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(
@@ -112,7 +163,7 @@ impl<'a> Printer for SimplePrinter<'a> {
self.config.tab_width,
self.config.nonprintable_notation,
);
write!(handle, "{}", line)?;
write!(handle, "{line}")?;
} else {
match handle {
OutputHandle::IoWrite(handle) => handle.write_all(line_buffer)?,
@@ -158,6 +209,8 @@ 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,
strip_ansi: bool,
}
impl<'a> InteractivePrinter<'a> {
@@ -210,24 +263,48 @@ 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)
{
None
} else {
// Determine the type of syntax for highlighting
let syntax_in_set =
match assets.get_syntax(config.language, input, &config.syntax_mapping) {
Ok(syntax_in_set) => syntax_in_set,
Err(Error::UndetectedSyntax(_)) => assets
.find_syntax_by_name("Plain Text")?
.expect("A plain text syntax is available"),
Err(e) => return Err(e),
};
.map_or(false, |c| c.is_binary() && !config.show_nonprintable);
Some(HighlighterFromSet::new(syntax_in_set, theme))
let needs_to_match_syntax = (!is_printing_binary
|| matches!(config.binary, BinaryBehavior::AsText))
&& (config.colored_output || config.strip_ansi == StripAnsiMode::Auto);
let (is_plain_text, highlighter_from_set) = if needs_to_match_syntax {
// Determine the type of syntax for highlighting
const PLAIN_TEXT_SYNTAX: &str = "Plain Text";
match assets.get_syntax(config.language, input, &config.syntax_mapping) {
Ok(syntax_in_set) => (
syntax_in_set.syntax.name == PLAIN_TEXT_SYNTAX,
Some(HighlighterFromSet::new(syntax_in_set, theme)),
),
Err(Error::UndetectedSyntax(_)) => (
true,
Some(
assets
.find_syntax_by_name(PLAIN_TEXT_SYNTAX)?
.map(|s| HighlighterFromSet::new(s, theme))
.expect("A plain text syntax is available"),
),
),
Err(e) => return Err(e),
}
} else {
(false, None)
};
// Determine when to strip ANSI sequences
let strip_ansi = match config.strip_ansi {
_ if config.show_nonprintable => false,
StripAnsiMode::Always => true,
StripAnsiMode::Auto if is_plain_text => false, // Plain text may already contain escape sequences.
StripAnsiMode::Auto => true,
_ => false,
};
Ok(InteractivePrinter {
@@ -241,6 +318,8 @@ impl<'a> InteractivePrinter<'a> {
line_changes,
highlighter_from_set,
background_color_highlight,
consecutive_empty_lines: 0,
strip_ansi,
})
}
@@ -281,12 +360,20 @@ 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 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!(
@@ -302,6 +389,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);
@@ -324,7 +460,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
if !self.config.style_components.header() {
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
if Some(ContentType::BINARY) == self.content_type
&& !self.config.show_nonprintable
&& !matches!(self.config.binary, BinaryBehavior::AsText)
{
writeln!(
handle,
"{}: Binary content from {} will not be printed to the terminal \
@@ -377,34 +516,38 @@ 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 {
if self.content_type.map_or(false, |c| c.is_text())
|| self.config.show_nonprintable
|| matches!(self.config.binary, BinaryBehavior::AsText)
{
self.print_horizontal_line(handle, '┼')?;
} else {
self.print_horizontal_line(handle, '┴')?;
@@ -416,7 +559,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
if self.config.style_components.grid()
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
&& (self.content_type.map_or(false, |c| c.is_text())
|| self.config.show_nonprintable
|| matches!(self.config.binary, BinaryBehavior::AsText))
{
self.print_horizontal_line(handle, '┴')
} else {
@@ -442,7 +587,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(())
@@ -463,8 +608,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
)
.into()
} else {
match self.content_type {
Some(ContentType::BINARY) | None => {
let mut line = match self.content_type {
Some(ContentType::BINARY) | None
if !matches!(self.config.binary, BinaryBehavior::AsText) =>
{
return Ok(());
}
Some(ContentType::UTF_16LE) => UTF_16LE.decode_with_bom_removal(line_buffer).0,
@@ -480,37 +627,33 @@ impl<'a> Printer for InteractivePrinter<'a> {
line
}
}
}
};
let regions = {
let highlighter_from_set = match self.highlighter_from_set {
Some(ref mut highlighter_from_set) => highlighter_from_set,
_ => {
return Ok(());
}
};
// 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;
// If ANSI escape sequences are supposed to be stripped, do it before syntax highlighting.
if self.strip_ansi {
line = strip_ansi(&line).into()
}
highlighted_line
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;
@@ -521,7 +664,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
@@ -548,23 +691,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),
@@ -572,9 +709,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 {
@@ -592,6 +731,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);
}
}
}
}
@@ -601,17 +746,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,
@@ -654,7 +793,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
// It wraps.
write!(
handle,
"{}\n{}",
"{}{}\n{}",
as_terminal_escaped(
style,
&format!("{}{}", self.ansi_style, line_buf),
@@ -663,6 +802,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
self.config.use_italic_text,
background_color
),
self.ansi_style.to_reset_sequence(),
panel_wrap.clone().unwrap()
)?;
@@ -691,6 +831,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
)
)?;
}
// ANSI escape passthrough.
_ => {
write!(handle, "{}", chunk.raw())?;
self.ansi_style.update(chunk);
}
}
}
}
@@ -711,8 +857,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()),
}
}
}
@@ -138,3 +138,227 @@ impl StyleComponents {
self.0.clear();
}
}
#[derive(Debug, PartialEq)]
enum ComponentAction {
Override,
Add,
Remove,
}
impl ComponentAction {
fn extract_from_str(string: &str) -> (ComponentAction, &str) {
match string.chars().next() {
Some('-') => (ComponentAction::Remove, string.strip_prefix('-').unwrap()),
Some('+') => (ComponentAction::Add, string.strip_prefix('+').unwrap()),
_ => (ComponentAction::Override, string),
}
}
}
/// A list of [StyleComponent] that can be parsed from a string.
pub struct StyleComponentList(Vec<(ComponentAction, StyleComponent)>);
impl StyleComponentList {
fn expand_into(&self, components: &mut HashSet<StyleComponent>, interactive_terminal: bool) {
for (action, component) in self.0.iter() {
let subcomponents = component.components(interactive_terminal);
use ComponentAction::*;
match action {
Override | Add => components.extend(subcomponents),
Remove => components.retain(|c| !subcomponents.contains(c)),
}
}
}
/// Returns `true` if any component in the list was not prefixed with `+` or `-`.
fn contains_override(&self) -> bool {
self.0.iter().any(|(a, _)| *a == ComponentAction::Override)
}
/// Combines multiple [StyleComponentList]s into a single [StyleComponents] set.
///
/// ## Precedence
/// The most recent list will take precedence and override all previous lists
/// unless it only contains components prefixed with `-` or `+`. When this
/// happens, the list's components will be merged into the previous list.
///
/// ## Example
/// ```text
/// [numbers,grid] + [header,changes] -> [header,changes]
/// [numbers,grid] + [+header,-grid] -> [numbers,header]
/// ```
///
/// ## Parameters
/// - `with_default`: If true, the styles lists will build upon the StyleComponent::Auto style.
pub fn to_components(
lists: impl IntoIterator<Item = StyleComponentList>,
interactive_terminal: bool,
with_default: bool,
) -> StyleComponents {
let mut components: HashSet<StyleComponent> = HashSet::new();
if with_default {
components.extend(StyleComponent::Auto.components(interactive_terminal))
}
StyleComponents(lists.into_iter().fold(components, |mut components, list| {
if list.contains_override() {
components.clear();
}
list.expand_into(&mut components, interactive_terminal);
components
}))
}
}
impl Default for StyleComponentList {
fn default() -> Self {
StyleComponentList(vec![(ComponentAction::Override, StyleComponent::Default)])
}
}
impl FromStr for StyleComponentList {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
Ok(StyleComponentList(
s.split(",")
.map(|s| ComponentAction::extract_from_str(s)) // If the component starts with "-", it's meant to be removed
.map(|(a, s)| Ok((a, StyleComponent::from_str(s)?)))
.collect::<Result<Vec<(ComponentAction, StyleComponent)>>>()?,
))
}
}
#[cfg(test)]
mod test {
use std::collections::HashSet;
use std::str::FromStr;
use super::ComponentAction::*;
use super::StyleComponent;
use super::StyleComponent::*;
use super::StyleComponentList;
#[test]
pub fn style_component_list_parse() {
assert_eq!(
StyleComponentList::from_str("grid,+numbers,snip,-snip,header")
.expect("no error")
.0,
vec![
(Override, Grid),
(Add, LineNumbers),
(Override, Snip),
(Remove, Snip),
(Override, Header),
]
);
assert!(StyleComponentList::from_str("not-a-component").is_err());
assert!(StyleComponentList::from_str("grid,not-a-component").is_err());
assert!(StyleComponentList::from_str("numbers,-not-a-component").is_err());
}
#[test]
pub fn style_component_list_to_components() {
assert_eq!(
StyleComponentList::to_components(
vec![StyleComponentList::from_str("grid,numbers").expect("no error")],
false,
false
)
.0,
HashSet::from([Grid, LineNumbers])
);
}
#[test]
pub fn style_component_list_to_components_removes_negated() {
assert_eq!(
StyleComponentList::to_components(
vec![StyleComponentList::from_str("grid,numbers,-grid").expect("no error")],
false,
false
)
.0,
HashSet::from([LineNumbers])
);
}
#[test]
pub fn style_component_list_to_components_expands_subcomponents() {
assert_eq!(
StyleComponentList::to_components(
vec![StyleComponentList::from_str("full").expect("no error")],
false,
false
)
.0,
HashSet::from_iter(Full.components(true).to_owned())
);
}
#[test]
pub fn style_component_list_expand_negates_subcomponents() {
assert!(!StyleComponentList::to_components(
vec![StyleComponentList::from_str("full,-numbers").expect("no error")],
true,
false
)
.numbers());
}
#[test]
pub fn style_component_list_to_components_precedence_overrides_previous_lists() {
assert_eq!(
StyleComponentList::to_components(
vec![
StyleComponentList::from_str("grid").expect("no error"),
StyleComponentList::from_str("numbers").expect("no error"),
],
false,
false
)
.0,
HashSet::from([LineNumbers])
);
}
#[test]
pub fn style_component_list_to_components_precedence_merges_previous_lists() {
assert_eq!(
StyleComponentList::to_components(
vec![
StyleComponentList::from_str("grid,header").expect("no error"),
StyleComponentList::from_str("-grid").expect("no error"),
StyleComponentList::from_str("+numbers").expect("no error"),
],
false,
false
)
.0,
HashSet::from([HeaderFilename, LineNumbers])
);
}
#[test]
pub fn style_component_list_default_builds_on_auto() {
assert_eq!(
StyleComponentList::to_components(
vec![StyleComponentList::from_str("-numbers").expect("no error"),],
true,
true
)
.0,
{
let mut expected: HashSet<StyleComponent> = HashSet::new();
expected.extend(Auto.components(true));
expected.remove(&LineNumbers);
expected
}
);
}
}

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,204 +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(
"os-release",
MappingTarget::MapTo("Bourne Again Shell (bash)"),
)
.unwrap();
mapping
.insert("*.pac", MappingTarget::MapTo("JavaScript (Babel)"))
.unwrap();
mapping
.insert("fish_history", MappingTarget::MapTo("YAML"))
.unwrap();
for glob in ["*.jsonl", "*.sarif"] {
mapping.insert(glob, MappingTarget::MapTo("JSON")).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();
mapping
.insert("Containerfile", MappingTarget::MapTo("Dockerfile"))
.unwrap();
mapping
.insert("*.ksh", MappingTarget::MapTo("Bourne Again Shell (bash)"))
.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();
mapping
.insert("*.ron", MappingTarget::MapTo("Rust"))
.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
match (
std::env::var_os("XDG_CONFIG_HOME").filter(|val| !val.is_empty()),
std::env::var_os("HOME")
.filter(|val| !val.is_empty())
.map(|home| Path::new(&home).join(".config")),
) {
(Some(xdg_config_home), Some(default_config_home))
if xdg_config_home == default_config_home => {
insert_git_config_global(&mut mapping, &xdg_config_home)
/// 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);
}
(Some(xdg_config_home), Some(default_config_home)) /* else guard */ => {
insert_git_config_global(&mut mapping, &xdg_config_home);
insert_git_config_global(&mut mapping, &default_config_home)
}
(Some(config_home), None) => insert_git_config_global(&mut mapping, &config_home),
(None, Some(config_home)) => insert_git_config_global(&mut mapping, &config_home),
(None, None) => (),
};
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
});
// 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(true)
.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()
@@ -252,9 +175,46 @@ impl<'a> SyntaxMapping<'a> {
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic() {
let mut map = SyntaxMapping::empty();
fn builtin_mappings_work() {
let map = SyntaxMapping::new();
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"))
@@ -273,52 +233,32 @@ mod tests {
}
#[test]
fn user_can_override_builtin_mappings() {
let mut map = SyntaxMapping::builtin();
fn custom_mappings_override_builtin() {
let mut map = SyntaxMapping::new();
assert_eq!(
map.get_syntax_for("/etc/profile"),
Some(MappingTarget::MapTo("Bourne Again Shell (bash)"))
map.get_syntax_for("/path/to/httpd.conf"),
Some(MappingTarget::MapTo("Apache Conf"))
);
map.insert("/etc/profile", MappingTarget::MapTo("My Syntax"))
map.insert("httpd.conf", MappingTarget::MapTo("My Syntax"))
.ok();
assert_eq!(
map.get_syntax_for("/etc/profile"),
map.get_syntax_for("/path/to/httpd.conf"),
Some(MappingTarget::MapTo("My Syntax"))
);
}
#[test]
fn builtin_mappings() {
let map = SyntaxMapping::builtin();
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/build"),
Some(MappingTarget::MapToUnknown)
map.get_syntax_for("/path/to/foo"),
Some(MappingTarget::MapTo("alpha"))
);
}
#[test]
/// verifies that SyntaxMapping::builtin() doesn't repeat `Glob`-based keys
fn no_duplicate_builtin_keys() {
let mappings = SyntaxMapping::builtin().mappings;
for i in 0..mappings.len() {
let tail = mappings[i + 1..].into_iter();
let (dupl, _): (Vec<_>, Vec<_>) =
tail.partition(|item| item.0.glob() == mappings[i].0.glob());
// emit repeats on failure
assert_eq!(
dupl.len(),
0,
"Glob pattern `{}` mapped to multiple: {:?}",
mappings[i].0.glob().glob(),
{
let (_, mut dupl_targets): (Vec<GlobMatcher>, Vec<MappingTarget>) =
dupl.into_iter().cloned().unzip();
dupl_targets.push(mappings[i].1)
},
)
}
}
}

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]
"YAML" = ["CITATION.cff"]

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,3 @@
# .debdiff is the extension used for diffs in Debian packaging
[mappings]
"Diff" = ["*.debdiff"]

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", "*.jsonld", "*.geojson"]

View File

@@ -0,0 +1,2 @@
[mappings]
"Markdown" = ["*.mkd"]

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",
]

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