on master help sign in
Merge remote-tracking branch 'origin/master' into fix-1063
commitcc0f8ca813b2d820e85a9fa3e42b0aded244fef8 authorMartin Nordholts <enselic@gmail.com> dateMon 28 Dec 2020, 21:57 (6 years ago) parent986d0e99c16571
52 files changed+423−711
.github/workflows/CICD.yml+21−8 .gitmodules+4−3 CHANGELOG.md+14 CONTRIBUTING.md+2−2 Cargo.lock+2−2 Cargo.toml+1−2 README.md+20−5 assets/syntaxes.bin assets/syntaxes/02_Extra/AWK+1−1 assets/syntaxes/02_Extra/GraphQL+1−1 assets/syntaxes/02_Extra/Svelte+1−1 assets/syntaxes/02_Extra/VimL+1−1 assets/syntaxes/02_Extra/VimL.sublime-syntax+2−2 assets/syntaxes/02_Extra/ssh-config+1−1 assets/themes.bin assets/themes/Coldark+1−1 assets/themes/ansi-light.tmTheme−504 assets/themes/ansi-dark.tmTheme → assets/themes/ansi.tmTheme+13−87 assets/themes/gruvbox+1−1 diagnostics/info.sh+6−4 src/assets.rs+6−6 src/bin/bat/app.rs+5−9 src/bin/bat/main.rs+27−21 src/controller.rs+3−1 src/lib.rs+2 src/macros.rs+7 src/preprocessor.rs+1−1 src/printer.rs+18−15 src/terminal.rs+19−9 tests/assets.rs+2−4 tests/benchmarks/comparison.sh+2−2 tests/benchmarks/run-benchmarks.sh+2−2 tests/integration_tests.rs+38 tests/syntax-tests/highlighted/Plaintext/plaintext.txt+1−1 tests/syntax-tests/highlighted/VimL/source.vim+92 tests/syntax-tests/regression_test.sh+1−1 tests/syntax-tests/source/ActionScript/test.as+1−1 tests/syntax-tests/source/Batch/build.bat+1−1 tests/syntax-tests/source/Clojure/test.clj+1−1 tests/syntax-tests/source/Dockerfile/Dockerfile+1−1 tests/syntax-tests/source/Git Attributes/example.gitattributes+1−1 tests/syntax-tests/source/Git Config/text.gitconfig+1−1 tests/syntax-tests/source/Hosts/hosts+1−1 tests/syntax-tests/source/Makefile/Makefile+1−1 tests/syntax-tests/source/PHP/test.php+1−1 tests/syntax-tests/source/Plaintext/plaintext.txt tests/syntax-tests/source/PowerShell/test.ps1 tests/syntax-tests/source/RequirementsTXT/requirements.txt+1−1 tests/syntax-tests/source/VimL/source.vim+92 tests/syntax-tests/source/YAML/example.yaml+1−1 tests/syntax-tests/source/reStructuredText/reference.rst+1−1 tests/syntax-tests/update.sh+1−1
.github/workflows/CICD.yml+21−8
@@ -22,6 +22,12 @@ jobs:
2222 toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
2323 default: true
2424 profile: minimal # minimal component installation (ie, no documentation)
25+ components: clippy
26+ - name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
27+ uses: actions-rs/cargo@v1
28+ with:
29+ command: clippy
30+ args: --all-targets --all-features
2531 - name: Test
2632 uses: actions-rs/cargo@v1
2733 with:
@@ -152,6 +158,8 @@ jobs:
152158 echo ::set-output name=PKG_NAME::${PKG_NAME}
153159 # deployable tag? (ie, leading "vM" or "M"; M == version number)
154160 unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi
161+ # unset deploy on ubuntu-18.04 x64 - we will deploy the tarball/deb built on ubuntu-16.04 x64
162+ if [ "${{ matrix.job.os }}" = "ubuntu-18.04" ] && [ "${{ matrix.job.target }}" = "x86_64-unknown-linux-gnu" ]; then unset DEPLOY; fi
155163 echo set-output name=DEPLOY::${DEPLOY:-<empty>/false}
156164 echo ::set-output name=DEPLOY::${DEPLOY}
157165 # DPKG architecture?
@@ -274,6 +282,7 @@ jobs:
274282 shell: bash
275283 run: |
276284 ARCHIVE_DIR='${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
285+ COPYRIGHT_YEARS="2018 - "$(date "+%Y")
277286 # Binary
278287 cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' "$ARCHIVE_DIR"
279288
@@ -283,8 +292,8 @@ jobs:
283292 # Man page
284293 cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR"
285294
286− # README and LICENSE files
287− cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "$ARCHIVE_DIR"
295+ # README, LICENSE and CHANGELOG files
296+ cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
288297
289298 # Autocompletion files
290299 cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish"
@@ -308,24 +317,27 @@ jobs:
308317
309318 # Man page
310319 install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
311− gzip --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
320+ gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
312321
313322 # Autocompletion files
314323 install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish"
315324 install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}"
316325
317326 # README and LICENSE
318− install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/README.md"
319− install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/LICENSE-MIT"
320− install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/LICENSE-APACHE"
327+ install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/README.md"
328+ install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/LICENSE-MIT"
329+ install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/LICENSE-APACHE"
330+ install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/changelog"
331+ gzip -n --best "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/changelog"
321332
322− cat > "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/copyright" <<EOF
333+ cat > "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/copyright" <<EOF
323334 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
324335 Upstream-Name: ${{ env.PROJECT_NAME }}
325336 Source: ${{ env.PROJECT_HOMEPAGE }}
326337
327338 Files: *
328339 Copyright: ${{ env.PROJECT_MAINTAINER }}
340+ Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
329341 License: Apache-2.0 or MIT
330342
331343 License: Apache-2.0
@@ -357,6 +369,7 @@ jobs:
357369 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
358370 DEALINGS IN THE SOFTWARE.
359371 EOF
372+ chmod 644 "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/copyright"
360373
361374 # control file
362375 mkdir -p "${DPKG_DIR}/DEBIAN"
@@ -370,7 +383,7 @@ jobs:
370383 Architecture: ${{ steps.vars.outputs.DPKG_ARCH }}
371384 Provides: ${{ env.PROJECT_NAME }}
372385 Conflicts: ${{ steps.vars.outputs.DPKG_CONFLICTS }}
373− Description: A cat(1) clone with wings.
386+ Description: cat(1) clone with wings.
374387 A cat(1) clone with syntax highlighting and Git integration.
375388 EOF
376389
.gitmodules+4−3
@@ -185,9 +185,6 @@
185185[submodule "assets/syntaxes/02_Extra/AsciiDoc"]
186186 path = assets/syntaxes/02_Extra/AsciiDoc
187187 url = https://github.com/asciidoctor/sublimetext-asciidoc.git
188−[submodule "assets/themes/gruvbox"]
189− path = assets/themes/gruvbox
190− url = https://github.com/peaceant/gruvbox.git
191188[submodule "assets/syntaxes/02_Extra/GLSL"]
192189 path = assets/syntaxes/02_Extra/GLSL
193190 url = https://github.com/euler0/sublime-glsl
@@ -206,3 +203,7 @@
206203[submodule "assets/themes/Coldark"]
207204 path = assets/themes/Coldark
208205 url = https://github.com/ArmandPhilippot/coldark-bat.git
206+[submodule "assets/themes/gruvbox"]
207+ path = assets/themes/gruvbox
208+ url = https://github.com/subnut/gruvbox-tmTheme.git
209+ branch = bat-source
CHANGELOG.md+14
@@ -2,27 +2,41 @@
22
33
44## Features
5+- Use a pager when `bat --list-languages` is called, see #1394 (@stku1985)
56
67## Bugfixes
78
9+- If the last line doesn't end with a newline character, don't add it if `--style=plain`, see #1438 (@Enselic)
10+- Only print themes hint in interactive mode (`bat --list-themes`), see #1439 (@rsteube)
11+- Make ./tests/syntax-tests/regression_test.sh work on recent versions of macOS, see #1443 (@Enselic)
12+- VimL syntax highlighting fix, see #1450 (@esensar)
813- Ignore PAGER=most by default with a warning to stderr, but allow override with BAT_PAGER or --config, see #1063 (@Enselic)
914
1015## Other
1116
17+- Performance improvements, see #1421 (@LovecraftianHorror)
18+
1219## Syntaxes
1320
1421## New themes
1522
23+- `ansi` replaces `ansi-dark` and `ansi-light`, see #1104 and #1412 (@mk12)
24+- The Gruvbox theme has been updated, see #1291 (@j0hnmeow). **Breaking change:** users that were previously usuing `gruvbox` or `gruvbox-white` should update and use `gruvbox-dark`/`gruvbox-light` instead.
25+
1626## `bat` as a library
1727
1828## Packaging
1929
30+- `bat` is now available on snapstore with package name called `batcat`, see #1401 (@purveshpatel511)
31+
32+
2033# v0.17.1
2134
2235## Bugfixes
2336
2437- Running `bat` without arguments fails ("output file is also an input"), see #1396
2538
39+
2640# v0.17.0
2741
2842## Features
CONTRIBUTING.md+2−2
@@ -8,12 +8,12 @@ Thank you for considering to contribute to `bat`!
88
99If your contribution changes the behavior of `bat` (as opposed to a typo-fix
1010in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md) file
11−and describe your changes. This makes the release proess much easier and
11+and describe your changes. This makes the release process much easier and
1212therefore helps to get your changes into a new `bat` release faster.
1313
1414The top of the `CHANGELOG` contains a *"unreleased"* section with a few
1515subsections (Features, Bugfixes, …). Please add your entry to the subsection
16−that best describes your change
16+that best describes your change.
1717
1818Entries follow this format:
1919```
Cargo.lock+2−2
@@ -56,9 +56,9 @@ checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
5656
5757[[package]]
5858name = "assert_cmd"
59−version = "1.0.1"
59+version = "1.0.2"
6060source = "registry+https://github.com/rust-lang/crates.io-index"
61−checksum = "c88b9ca26f9c16ec830350d309397e74ee9abdfd8eb1f71cb6ecc71a3fc818da"
61+checksum = "3dc1679af9a1ab4bea16f228b05d18f8363f8327b1fa8db00d2760cfafc6b61e"
6262dependencies = [
6363 "doc-comment",
6464 "predicates",
Cargo.toml+1−2
@@ -5,7 +5,6 @@ description="A cat(1) clone with wings."
55homepage = "https://github.com/sharkdp/bat"
66license = "MIT/Apache-2.0"
77name = "bat"
8−readme = "README.md"
98repository = "https://github.com/sharkdp/bat"
109version = "0.17.1"
1110exclude = [
@@ -74,7 +73,7 @@ default-features = false
7473
7574[dev-dependencies]
7675tempdir = "0.3"
77−assert_cmd = "1.0.1"
76+assert_cmd = "1.0.2"
7877predicates = "1.0.5"
7978
8079[build-dependencies]
README.md+20−5
@@ -196,7 +196,7 @@ If your Ubuntu/Debian installation is new enough you can simply run:
196196apt install bat
197197```
198198
199−If you install `bat` this way, please note that the executable may be installed as `batcat` instead of `bat` (due to [a name
199+**Important**: If you install `bat` this way, please note that the executable may be installed as `batcat` instead of `bat` (due to [a name
200200clash with another package](https://github.com/sharkdp/bat/issues/982)). You can set up a `bat -> batcat` symlink or alias to prevent any issues that may come up because of this and to be consistent with other distributions:
201201``` bash
202202mkdir -p ~/.local/bin
@@ -256,6 +256,13 @@ You can install `bat` via xbps-install:
256256xbps-install -S bat
257257```
258258
259+### On Termux
260+
261+You can install `bat` via pkg:
262+```bash
263+pkg install bat
264+```
265+
259266### On FreeBSD
260267
261268You can install a precompiled [`bat` package](https://www.freshports.org/textproc/bat) with pkg:
@@ -287,6 +294,15 @@ You can install `bat` with zypper:
287294zypper install bat
288295```
289296
297+### Via snap package
298+
299+```
300+sudo snap install batcat
301+```
302+
303+[Get it from the Snap Store](https://snapcraft.io/batcat)
304+
305+
290306### On macOS (or Linux) via Homebrew
291307
292308You can install `bat` with [Homebrew on MacOS](https://formulae.brew.sh/formula/bat) or [Homebrew on Linux](https://formulae.brew.sh/formula-linux/bat):
@@ -374,12 +390,11 @@ You can also use a custom theme by following the
374390
375391### 8-bit themes
376392
377−`bat` has four themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors),
393+`bat` has three themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors),
378394even when truecolor support is available:
379395
380−- `ansi-dark` looks decent on any terminal with a dark background. It uses 3-bit colors: black, red,
381− green, yellow, blue, magenta, cyan, and white.
382−- `ansi-light` is like `ansi-dark`, but for terminals with a light background.
396+- `ansi` looks decent on any terminal. It uses 3-bit colors: black, red, green,
397+ yellow, blue, magenta, cyan, and white.
383398- `base16` is designed for [base16](https://github.com/chriskempson/base16) terminal themes. It uses
384399 4-bit colors (3-bit colors plus bright variants) in accordance with the
385400 [base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md).
assets/syntaxes.bin

Binary file not shown.

assets/syntaxes/02_Extra/AWK+1−1

Submodule changed.

assets/syntaxes/02_Extra/GraphQL+1−1

Submodule changed.

assets/syntaxes/02_Extra/Svelte+1−1

Submodule changed.

assets/syntaxes/02_Extra/VimL+1−1

Submodule changed.

assets/syntaxes/02_Extra/VimL.sublime-syntax+2−2
@@ -75,10 +75,10 @@ contexts:
7575 - match: '''(''''|\n[^\S\n]*\\|[^\n''])*'''
7676 scope: string.quoted.single.viml
7777 string_regex:
78− - match: '/(\\\\|\\/|\n[^\S\n]*\\|[^\n/])*/'
78+ - match: '[gvs]{1}/(\\\\|\\/|\n[^\S\n]*\\|[^\n/])*/'
7979 scope: string.regexp.viml
8080 support_function:
81− - match: \b(set(local|global)?|let|command|filetype|colorscheme|\w*map|\w*a(b|brev)?|syn|exe(c|cute)?|ec(ho|)?|au(tocmd|)?)\b
81+ - match: \b(set(local|global)?|let|command|filetype|syntax|colorscheme|\w*map|\w*a(b|brev)?|syn|exe(c|cute)?|ec(ho|)?|au(tocmd|)?)\b
8282 scope: support.function.viml
8383 support_type:
8484 - match: <.*?>
assets/syntaxes/02_Extra/ssh-config+1−1

Submodule changed.

assets/themes.bin

Binary file not shown.

assets/themes/Coldark+1−1

Submodule changed.

assets/themes/ansi-light.tmThemedeleted−504
@@ -1,504 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3−<plist version="1.0">
4− <dict>
5− <!--
6− The colors in this theme are encoded as #RRGGBBAA where RR is an ANSI
7− palette number from 00 to 0f, and AA is the special value 00 to indicate
8− that this encoding is being used.
9− -->
10− <key>author</key>
11− <string>Template: Chris Kempson, Scheme: Mitchell Kember</string>
12− <key>name</key>
13− <string>ANSI Light</string>
14− <key>colorSpaceName</key>
15− <string>sRGB</string>
16− <key>settings</key>
17− <array>
18− <dict>
19− <key>settings</key>
20− <dict>
21− <key>background</key>
22− <string>#07000000</string>
23− <key>caret</key>
24− <string>#00000000</string>
25− <key>foreground</key>
26− <string>#00000000</string>
27− <key>invisibles</key>
28− <string>#00000000</string>
29− <key>lineHighlight</key>
30− <string>#00000000</string>
31− <key>selection</key>
32− <string>#00000000</string>
33− <key>gutter</key>
34− <string>#07000000</string>
35− <key>gutterForeground</key>
36− <string>#00000000</string>
37− </dict>
38− </dict>
39− <dict>
40− <key>name</key>
41− <string>Text</string>
42− <key>scope</key>
43− <string>variable.parameter.function</string>
44− <key>settings</key>
45− <dict>
46− <key>foreground</key>
47− <string>#00000000</string>
48− </dict>
49− </dict>
50− <dict>
51− <key>name</key>
52− <string>Comments</string>
53− <key>scope</key>
54− <string>comment, punctuation.definition.comment</string>
55− <key>settings</key>
56− <dict>
57− <key>foreground</key>
58− <string>#02000000</string>
59− </dict>
60− </dict>
61− <dict>
62− <key>name</key>
63− <string>Punctuation</string>
64− <key>scope</key>
65− <string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
66− <key>settings</key>
67− <dict>
68− <key>foreground</key>
69− <string>#00000000</string>
70− </dict>
71− </dict>
72− <dict>
73− <key>name</key>
74− <string>Delimiters</string>
75− <key>scope</key>
76− <string>none</string>
77− <key>settings</key>
78− <dict>
79− <key>foreground</key>
80− <string>#00000000</string>
81− </dict>
82− </dict>
83− <dict>
84− <key>name</key>
85− <string>Operators</string>
86− <key>scope</key>
87− <string>keyword.operator</string>
88− <key>settings</key>
89− <dict>
90− <key>foreground</key>
91− <string>#00000000</string>
92− </dict>
93− </dict>
94− <dict>
95− <key>name</key>
96− <string>Keywords</string>
97− <key>scope</key>
98− <string>keyword</string>
99− <key>settings</key>
100− <dict>
101− <key>foreground</key>
102− <string>#05000000</string>
103− </dict>
104− </dict>
105− <dict>
106− <key>name</key>
107− <string>Variables</string>
108− <key>scope</key>
109− <string>variable</string>
110− <key>settings</key>
111− <dict>
112− <key>foreground</key>
113− <string>#00000000</string>
114− </dict>
115− </dict>
116− <dict>
117− <key>name</key>
118− <string>Functions</string>
119− <key>scope</key>
120− <string>entity.name.function, meta.require, support.function.any-method</string>
121− <key>settings</key>
122− <dict>
123− <key>foreground</key>
124− <string>#04000000</string>
125− </dict>
126− </dict>
127− <dict>
128− <key>name</key>
129− <string>Labels</string>
130− <key>scope</key>
131− <string>entity.name.label</string>
132− <key>settings</key>
133− <dict>
134− <key>foreground</key>
135− <string>#06000000</string>
136− </dict>
137− </dict>
138− <dict>
139− <key>name</key>
140− <string>Classes</string>
141− <key>scope</key>
142− <string>support.class, entity.name.class, entity.name.type.class</string>
143− <key>settings</key>
144− <dict>
145− <key>foreground</key>
146− <string>#03000000</string>
147− </dict>
148− </dict>
149− <dict>
150− <key>name</key>
151− <string>Classes</string>
152− <key>scope</key>
153− <string>meta.class</string>
154− <key>settings</key>
155− <dict>
156− <key>foreground</key>
157− <string>#00000000</string>
158− </dict>
159− </dict>
160− <dict>
161− <key>name</key>
162− <string>Methods</string>
163− <key>scope</key>
164− <string>keyword.other.special-method</string>
165− <key>settings</key>
166− <dict>
167− <key>foreground</key>
168− <string>#04000000</string>
169− </dict>
170− </dict>
171− <dict>
172− <key>name</key>
173− <string>Storage</string>
174− <key>scope</key>
175− <string>storage</string>
176− <key>settings</key>
177− <dict>
178− <key>foreground</key>
179− <string>#05000000</string>
180− </dict>
181− </dict>
182− <dict>
183− <key>name</key>
184− <string>Support</string>
185− <key>scope</key>
186− <string>support.function</string>
187− <key>settings</key>
188− <dict>
189− <key>foreground</key>
190− <string>#06000000</string>
191− </dict>
192− </dict>
193− <dict>
194− <key>name</key>
195− <string>Strings, Inherited Class</string>
196− <key>scope</key>
197− <string>string, constant.other.symbol, entity.other.inherited-class</string>
198− <key>settings</key>
199− <dict>
200− <key>foreground</key>
201− <string>#02000000</string>
202− </dict>
203− </dict>
204− <dict>
205− <key>name</key>
206− <string>Integers</string>
207− <key>scope</key>
208− <string>constant.numeric</string>
209− <key>settings</key>
210− <dict>
211− <key>foreground</key>
212− <string>#03000000</string>
213− </dict>
214− </dict>
215− <dict>
216− <key>name</key>
217− <string>Floats</string>
218− <key>scope</key>
219− <string>none</string>
220− <key>settings</key>
221− <dict>
222− <key>foreground</key>
223− <string>#03000000</string>
224− </dict>
225− </dict>
226− <dict>
227− <key>name</key>
228− <string>Boolean</string>
229− <key>scope</key>
230− <string>none</string>
231− <key>settings</key>
232− <dict>
233− <key>foreground</key>
234− <string>#03000000</string>
235− </dict>
236− </dict>
237− <dict>
238− <key>name</key>
239− <string>Constants</string>
240− <key>scope</key>
241− <string>constant</string>
242− <key>settings</key>
243− <dict>
244− <key>foreground</key>
245− <string>#03000000</string>
246− </dict>
247− </dict>
248− <dict>
249− <key>name</key>
250− <string>Tags</string>
251− <key>scope</key>
252− <string>entity.name.tag</string>
253− <key>settings</key>
254− <dict>
255− <key>foreground</key>
256− <string>#01000000</string>
257− </dict>
258− </dict>
259− <dict>
260− <key>name</key>
261− <string>Attributes</string>
262− <key>scope</key>
263− <string>entity.other.attribute-name</string>
264− <key>settings</key>
265− <dict>
266− <key>foreground</key>
267− <string>#03000000</string>
268− </dict>
269− </dict>
270− <dict>
271− <key>name</key>
272− <string>Attribute IDs</string>
273− <key>scope</key>
274− <string>entity.other.attribute-name.id, punctuation.definition.entity</string>
275− <key>settings</key>
276− <dict>
277− <key>foreground</key>
278− <string>#04000000</string>
279− </dict>
280− </dict>
281− <dict>
282− <key>name</key>
283− <string>Selector</string>
284− <key>scope</key>
285− <string>meta.selector</string>
286− <key>settings</key>
287− <dict>
288− <key>foreground</key>
289− <string>#05000000</string>
290− </dict>
291− </dict>
292− <dict>
293− <key>name</key>
294− <string>Values</string>
295− <key>scope</key>
296− <string>none</string>
297− <key>settings</key>
298− <dict>
299− <key>foreground</key>
300− <string>#03000000</string>
301− </dict>
302− </dict>
303− <dict>
304− <key>name</key>
305− <string>Headings</string>
306− <key>scope</key>
307− <string>markup.heading punctuation.definition.heading, entity.name.section</string>
308− <key>settings</key>
309− <dict>
310− <key>fontStyle</key>
311− <string></string>
312− <key>foreground</key>
313− <string>#04000000</string>
314− </dict>
315− </dict>
316− <dict>
317− <key>name</key>
318− <string>Units</string>
319− <key>scope</key>
320− <string>keyword.other.unit</string>
321− <key>settings</key>
322− <dict>
323− <key>foreground</key>
324− <string>#03000000</string>
325− </dict>
326− </dict>
327− <dict>
328− <key>name</key>
329− <string>Bold</string>
330− <key>scope</key>
331− <string>markup.bold, punctuation.definition.bold</string>
332− <key>settings</key>
333− <dict>
334− <key>fontStyle</key>
335− <string>bold</string>
336− <key>foreground</key>
337− <string>#03000000</string>
338− </dict>
339− </dict>
340− <dict>
341− <key>name</key>
342− <string>Italic</string>
343− <key>scope</key>
344− <string>markup.italic, punctuation.definition.italic</string>
345− <key>settings</key>
346− <dict>
347− <key>fontStyle</key>
348− <string>italic</string>
349− <key>foreground</key>
350− <string>#05000000</string>
351− </dict>
352− </dict>
353− <dict>
354− <key>name</key>
355− <string>Code</string>
356− <key>scope</key>
357− <string>markup.raw.inline</string>
358− <key>settings</key>
359− <dict>
360− <key>foreground</key>
361− <string>#02000000</string>
362− </dict>
363− </dict>
364− <dict>
365− <key>name</key>
366− <string>Link Text</string>
367− <key>scope</key>
368− <string>string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown</string>
369− <key>settings</key>
370− <dict>
371− <key>foreground</key>
372− <string>#01000000</string>
373− </dict>
374− </dict>
375− <dict>
376− <key>name</key>
377− <string>Link Url</string>
378− <key>scope</key>
379− <string>meta.link</string>
380− <key>settings</key>
381− <dict>
382− <key>foreground</key>
383− <string>#03000000</string>
384− </dict>
385− </dict>
386− <dict>
387− <key>name</key>
388− <string>Quotes</string>
389− <key>scope</key>
390− <string>markup.quote</string>
391− <key>settings</key>
392− <dict>
393− <key>foreground</key>
394− <string>#03000000</string>
395− </dict>
396− </dict>
397− <dict>
398− <key>name</key>
399− <string>Inserted</string>
400− <key>scope</key>
401− <string>markup.inserted</string>
402− <key>settings</key>
403− <dict>
404− <key>foreground</key>
405− <string>#02000000</string>
406− </dict>
407− </dict>
408− <dict>
409− <key>name</key>
410− <string>Deleted</string>
411− <key>scope</key>
412− <string>markup.deleted</string>
413− <key>settings</key>
414− <dict>
415− <key>foreground</key>
416− <string>#01000000</string>
417− </dict>
418− </dict>
419− <dict>
420− <key>name</key>
421− <string>Changed</string>
422− <key>scope</key>
423− <string>markup.changed</string>
424− <key>settings</key>
425− <dict>
426− <key>foreground</key>
427− <string>#05000000</string>
428− </dict>
429− </dict>
430− <dict>
431− <key>name</key>
432− <string>Colors</string>
433− <key>scope</key>
434− <string>constant.other.color</string>
435− <key>settings</key>
436− <dict>
437− <key>foreground</key>
438− <string>#06000000</string>
439− </dict>
440− </dict>
441− <dict>
442− <key>name</key>
443− <string>Regular Expressions</string>
444− <key>scope</key>
445− <string>string.regexp</string>
446− <key>settings</key>
447− <dict>
448− <key>foreground</key>
449− <string>#06000000</string>
450− </dict>
451− </dict>
452− <dict>
453− <key>name</key>
454− <string>Escape Characters</string>
455− <key>scope</key>
456− <string>constant.character.escape</string>
457− <key>settings</key>
458− <dict>
459− <key>foreground</key>
460− <string>#06000000</string>
461− </dict>
462− </dict>
463− <dict>
464− <key>name</key>
465− <string>Embedded</string>
466− <key>scope</key>
467− <string>punctuation.section.embedded, variable.interpolation</string>
468− <key>settings</key>
469− <dict>
470− <key>foreground</key>
471− <string>#05000000</string>
472− </dict>
473− </dict>
474− <dict>
475− <key>name</key>
476− <string>Illegal</string>
477− <key>scope</key>
478− <string>invalid.illegal</string>
479− <key>settings</key>
480− <dict>
481− <key>background</key>
482− <string>#01000000</string>
483− <key>foreground</key>
484− <string>#00000000</string>
485− </dict>
486− </dict>
487− <dict>
488− <key>name</key>
489− <string>Broken</string>
490− <key>scope</key>
491− <string>invalid.broken</string>
492− <key>settings</key>
493− <dict>
494− <key>background</key>
495− <string>#03000000</string>
496− <key>foreground</key>
497− <string>#07000000</string>
498− </dict>
499− </dict>
500− </array>
501− <key>uuid</key>
502− <string>uuid</string>
503− </dict>
504−</plist>
assets/themes/ansi-dark.tmTheme → assets/themes/ansi.tmThemerenamed+13−87
@@ -3,14 +3,14 @@
33<plist version="1.0">
44 <dict>
55 <!--
6− The colors in this theme are encoded as #RRGGBBAA where RR is an ANSI
7− palette number from 00 to 0f, and AA is the special value 00 to indicate
8− that this encoding is being used.
6+ The colors in this theme are encoded as #RRGGBBAA where:
7+ * If AA is 00, then RR is an ANSI palette number from 00 to 07.
8+ * If AA is 01, the terminal's default fg/bg color is used.
99 -->
1010 <key>author</key>
1111 <string>Template: Chris Kempson, Scheme: Mitchell Kember</string>
1212 <key>name</key>
13− <string>ANSI Dark</string>
13+ <string>ANSI</string>
1414 <key>colorSpaceName</key>
1515 <string>sRGB</string>
1616 <key>settings</key>
@@ -19,32 +19,17 @@
1919 <key>settings</key>
2020 <dict>
2121 <key>background</key>
22− <string>#00000000</string>
23− <key>caret</key>
24− <string>#07000000</string>
25− <key>foreground</key>
26− <string>#07000000</string>
27− <key>invisibles</key>
28− <string>#07000000</string>
29− <key>lineHighlight</key>
30− <string>#07000000</string>
31− <key>selection</key>
32− <string>#07000000</string>
22+ <string>#00000001</string>
23+ <key>foreground</key>
24+ <string>#00000001</string>
25+ <!--
26+ Explicitly set the gutter color since bat falls back to a
27+ hardcoded DEFAULT_GUTTER_COLOR otherwise.
28+ -->
3329 <key>gutter</key>
34− <string>#00000000</string>
30+ <string>#00000001</string>
3531 <key>gutterForeground</key>
36− <string>#07000000</string>
37− </dict>
38− </dict>
39− <dict>
40− <key>name</key>
41− <string>Text</string>
42− <key>scope</key>
43− <string>variable.parameter.function</string>
44− <key>settings</key>
45− <dict>
46− <key>foreground</key>
47− <string>#07000000</string>
32+ <string>#00000001</string>
4833 </dict>
4934 </dict>
5035 <dict>
@@ -58,39 +43,6 @@
5843 <string>#02000000</string>
5944 </dict>
6045 </dict>
61− <dict>
62− <key>name</key>
63− <string>Punctuation</string>
64− <key>scope</key>
65− <string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
66− <key>settings</key>
67− <dict>
68− <key>foreground</key>
69− <string>#07000000</string>
70− </dict>
71− </dict>
72− <dict>
73− <key>name</key>
74− <string>Delimiters</string>
75− <key>scope</key>
76− <string>none</string>
77− <key>settings</key>
78− <dict>
79− <key>foreground</key>
80− <string>#07000000</string>
81− </dict>
82− </dict>
83− <dict>
84− <key>name</key>
85− <string>Operators</string>
86− <key>scope</key>
87− <string>keyword.operator</string>
88− <key>settings</key>
89− <dict>
90− <key>foreground</key>
91− <string>#07000000</string>
92− </dict>
93− </dict>
9446 <dict>
9547 <key>name</key>
9648 <string>Keywords</string>
@@ -102,17 +54,6 @@
10254 <string>#05000000</string>
10355 </dict>
10456 </dict>
105− <dict>
106− <key>name</key>
107− <string>Variables</string>
108− <key>scope</key>
109− <string>variable</string>
110− <key>settings</key>
111− <dict>
112− <key>foreground</key>
113− <string>#07000000</string>
114− </dict>
115− </dict>
11657 <dict>
11758 <key>name</key>
11859 <string>Functions</string>
@@ -146,17 +87,6 @@
14687 <string>#03000000</string>
14788 </dict>
14889 </dict>
149− <dict>
150− <key>name</key>
151− <string>Classes</string>
152− <key>scope</key>
153− <string>meta.class</string>
154− <key>settings</key>
155− <dict>
156− <key>foreground</key>
157− <string>#07000000</string>
158− </dict>
159− </dict>
16090 <dict>
16191 <key>name</key>
16292 <string>Methods</string>
@@ -480,8 +410,6 @@
480410 <dict>
481411 <key>background</key>
482412 <string>#01000000</string>
483− <key>foreground</key>
484− <string>#07000000</string>
485413 </dict>
486414 </dict>
487415 <dict>
@@ -493,8 +421,6 @@
493421 <dict>
494422 <key>background</key>
495423 <string>#03000000</string>
496− <key>foreground</key>
497− <string>#00000000</string>
498424 </dict>
499425 </dict>
500426 </array>
assets/themes/gruvbox+1−1

Submodule changed.

diagnostics/info.sh+6−4
@@ -58,7 +58,8 @@ _bat_:run() {
5858 _out "$BAT" --version
5959 _out env | grep '^BAT_\|^PAGER='
6060
61− local cache_dir="$($BAT --cache-dir)"
61+ local cache_dir
62+ cache_dir="$($BAT --cache-dir)"
6263 if [[ -f "${cache_dir}/syntaxes.bin" ]]; then
6364 _print_command "$BAT" "--list-languages"
6465 echo "Found custom syntax set."
@@ -79,8 +80,8 @@ _bat_config_:run() {
7980_bat_wrapper_:run() {
8081 _bat_wrapper_:detect_wrapper() {
8182 local bat="$1"
82− if file "$(which "${bat}")" | grep "text executable" &> /dev/null; then
83− _out_fence cat "$(which "${bat}")"
83+ if file "$(command -v "${bat}")" | grep "text executable" &> /dev/null; then
84+ _out_fence cat "$(command -v "${bat}")"
8485 return
8586 fi
8687
@@ -104,7 +105,8 @@ _bat_wrapper_function_:run() {
104105 fi ;;
105106
106107 *bash* | *zsh*)
107− local type="$("$SHELL" --login -i -c "type ${command}" 2>&1)"
108+ local type
109+ type="$("$SHELL" --login -i -c "type ${command}" 2>&1)"
108110 if grep 'function' <<< "$type" &> /dev/null; then
109111 _out_fence "$SHELL" --login -i -c "declare -f ${command}"
110112 return
src/assets.rs+6−6
@@ -11,6 +11,7 @@ use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
1111use path_abs::PathAbs;
1212
1313use crate::assets_metadata::AssetsMetadata;
14+use crate::bat_warning;
1415use crate::error::*;
1516use crate::input::{InputReader, OpenedInput, OpenedInputKind};
1617use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
@@ -189,13 +190,12 @@ impl HighlightingAssets {
189190 match self.theme_set.themes.get(theme) {
190191 Some(theme) => theme,
191192 None => {
193+ if theme == "ansi-light" || theme == "ansi-dark" {
194+ bat_warning!("Theme '{}' is deprecated, using 'ansi' instead.", theme);
195+ return self.get_theme("ansi");
196+ }
192197 if theme != "" {
193− use ansi_term::Colour::Yellow;
194− eprintln!(
195− "{}: Unknown theme '{}', using default.",
196− Yellow.paint("[bat warning]"),
197− theme
198− );
198+ bat_warning!("Unknown theme '{}', using default.", theme)
199199 }
200200 &self.theme_set.themes[self.fallback_theme.unwrap_or_else(|| Self::default_theme())]
201201 }
src/bin/bat/app.rs+5−9
@@ -16,6 +16,7 @@ use console::Term;
1616use crate::input::{new_file_input, new_stdin_input};
1717use bat::{
1818 assets::HighlightingAssets,
19+ bat_warning,
1920 config::{Config, VisibleLines},
2021 error::*,
2122 input::Input,
@@ -82,10 +83,9 @@ impl App {
8283 Some("always") => PagingMode::Always,
8384 Some("never") => PagingMode::Never,
8485 Some("auto") | None => {
85− if self.matches.occurrences_of("plain") > 1 {
86− // If we have -pp as an option when in auto mode, the pager should be disabled.
87− PagingMode::Never
88− } else if self.matches.is_present("no-paging") {
86+ // If we have -pp as an option when in auto mode, the pager should be disabled.
87+ let extra_plain = self.matches.occurrences_of("plain") > 1;
88+ if extra_plain || self.matches.is_present("no-paging") {
8989 PagingMode::Never
9090 } else if inputs.iter().any(Input::is_stdin) {
9191 // If we are reading from stdin, only enable paging if we write to an
@@ -323,11 +323,7 @@ impl App {
323323
324324 // If `grid` is set, remove `rule` as it is a subset of `grid`, and print a warning.
325325 if styled_components.grid() && styled_components.0.remove(&StyleComponent::Rule) {
326− use ansi_term::Colour::Yellow;
327− eprintln!(
328− "{}: Style 'rule' is a subset of style 'grid', 'rule' will not be visible.",
329− Yellow.paint("[bat warning]"),
330− );
326+ bat_warning!("Style 'rule' is a subset of style 'grid', 'rule' will not be visible.");
331327 }
332328
333329 Ok(styled_components)
src/bin/bat/main.rs+27−21
@@ -36,6 +36,7 @@ use bat::{
3636 input::Input,
3737 style::{StyleComponent, StyleComponents},
3838 MappingTarget,
39+ PagingMode,
3940};
4041
4142const THEME_PREVIEW_DATA: &[u8] = include_bytes!("../../../assets/theme_preview.rs");
@@ -78,7 +79,9 @@ fn get_syntax_mapping_to_paths<'a>(
7879 map
7980}
8081
81−pub fn list_languages(config: &Config) -> Result<()> {
82+pub fn get_languages(config: &Config) -> Result<String> {
83+ let mut result: String = String::new();
84+
8285 let assets = assets_from_cache_or_binary()?;
8386 let mut languages = assets
8487 .syntaxes()
@@ -119,12 +122,9 @@ pub fn list_languages(config: &Config) -> Result<()> {
119122 }
120123 }
121124
122− let stdout = io::stdout();
123− let mut stdout = stdout.lock();
124−
125125 if config.loop_through {
126126 for lang in languages {
127− writeln!(stdout, "{}:{}", lang.name, lang.file_extensions.join(","))?;
127+ result += &format!("{}:{}\n", lang.name, lang.file_extensions.join(","));
128128 }
129129 } else {
130130 let longest = languages
@@ -145,7 +145,7 @@ pub fn list_languages(config: &Config) -> Result<()> {
145145 };
146146
147147 for lang in languages {
148− write!(stdout, "{:width$}{}", lang.name, separator, width = longest)?;
148+ result += &format!("{:width$}{}", lang.name, separator, width = longest);
149149
150150 // Number of characters on this line so far, wrap before `desired_width`
151151 let mut num_chars = 0;
@@ -156,20 +156,20 @@ pub fn list_languages(config: &Config) -> Result<()> {
156156 let new_chars = word.len() + comma_separator.len();
157157 if num_chars + new_chars >= desired_width {
158158 num_chars = 0;
159− write!(stdout, "\n{:width$}{}", "", separator, width = longest)?;
159+ result += &format!("\n{:width$}{}", "", separator, width = longest);
160160 }
161161
162162 num_chars += new_chars;
163− write!(stdout, "{}", style.paint(&word[..]))?;
163+ result += &format!("{}", style.paint(&word[..]));
164164 if extension.peek().is_some() {
165− write!(stdout, "{}", comma_separator)?;
165+ result += comma_separator;
166166 }
167167 }
168− writeln!(stdout)?;
168+ result += "\n";
169169 }
170170 }
171171
172− Ok(())
172+ Ok(result)
173173}
174174
175175fn theme_preview_file<'a>() -> Input<'a> {
@@ -200,19 +200,19 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
200200 .ok();
201201 writeln!(stdout)?;
202202 }
203+ writeln!(
204+ stdout,
205+ "Further themes can be installed to '{}', \
206+ and are added to the cache with `bat cache --build`. \
207+ For more information, see:\n\n \
208+ https://github.com/sharkdp/bat#adding-new-themes",
209+ config_file().join("themes").to_string_lossy()
210+ )?;
203211 } else {
204212 for theme in assets.themes() {
205213 writeln!(stdout, "{}", theme)?;
206214 }
207215 }
208− writeln!(
209− stdout,
210− "Further themes can be installed to '{}', \
211− and are added to the cache with `bat cache --build`. \
212− For more information, see:\n\n \
213− https://github.com/sharkdp/bat#adding-new-themes",
214− config_file().join("themes").to_string_lossy()
215− )?;
216216
217217 Ok(())
218218}
@@ -248,8 +248,14 @@ fn run() -> Result<bool> {
248248 let config = app.config(&inputs)?;
249249
250250 if app.matches.is_present("list-languages") {
251− list_languages(&config)?;
252− Ok(true)
251+ let languages: String = get_languages(&config)?;
252+ let inputs: Vec<Input> = vec![Input::from_reader(Box::new(languages.as_bytes()))];
253+ let plain_config = Config {
254+ style_components: StyleComponents::new(StyleComponent::Plain.components(false)),
255+ paging_mode: PagingMode::QuitIfOneScreen,
256+ ..Default::default()
257+ };
258+ run_controller(inputs, &plain_config)
253259 } else if app.matches.is_present("list-themes") {
254260 list_themes(&config)?;
255261 Ok(true)
src/controller.rs+3−1
@@ -197,6 +197,8 @@ impl<'b> Controller<'b> {
197197 let mut first_range: bool = true;
198198 let mut mid_range: bool = false;
199199
200+ let style_snip = self.config.style_components.snip();
201+
200202 while reader.read_line(&mut line_buffer)? {
201203 match line_ranges.check(line_number) {
202204 RangeCheckResult::BeforeOrBetweenRanges => {
@@ -207,7 +209,7 @@ impl<'b> Controller<'b> {
207209 }
208210
209211 RangeCheckResult::InRange => {
210− if self.config.style_components.snip() {
212+ if style_snip {
211213 if first_range {
212214 first_range = false;
213215 mid_range = true;
src/lib.rs+2
@@ -19,6 +19,8 @@
1919//! .unwrap();
2020//! ```
2121
22+mod macros;
23+
2224pub mod assets;
2325pub mod assets_metadata;
2426pub mod config;
src/macros.rsnew file+7
@@ -0,0 +1,7 @@
1+#[macro_export]
2+macro_rules! bat_warning {
3+ ($($arg:tt)*) => ({
4+ use ansi_term::Colour::Yellow;
5+ eprintln!("{}: {}", Yellow.paint("[bat warning]"), format!($($arg)*));
6+ })
7+}
src/preprocessor.rs+1−1
@@ -72,7 +72,7 @@ pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String {
7272 }
7373 }
7474 // line feed
75− '\x0A' => output.push('␊'),
75+ '\x0A' => output.push_str("␊\x0A"),
7676 // carriage return
7777 '\x0D' => output.push('␍'),
7878 // null
src/printer.rs+18−15
@@ -91,9 +91,6 @@ impl<'a> Printer for SimplePrinter<'a> {
9191 if self.config.show_nonprintable {
9292 let line = replace_nonprintable(line_buffer, self.config.tab_width);
9393 write!(handle, "{}", line)?;
94− if line_buffer.last() == Some(&b'\n') {
95− writeln!(handle)?;
96− }
9794 } else {
9895 handle.write_all(line_buffer)?
9996 };
@@ -451,7 +448,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
451448 if text.len() != text_trimmed.len() {
452449 if let Some(background_color) = background_color {
453450 let mut ansi_style = Style::default();
454− ansi_style.background = Some(to_ansi_color(background_color, true_color));
451+ ansi_style.background = to_ansi_color(background_color, true_color);
455452 let width = if cursor_total <= cursor_max {
456453 cursor_max - cursor_total + 1
457454 } else {
@@ -463,7 +460,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
463460 }
464461 }
465462
466− if line.bytes().next_back() != Some(b'\n') {
463+ if !self.config.style_components.plain() && line.bytes().next_back() != Some(b'\n') {
467464 writeln!(handle)?;
468465 }
469466 } else {
@@ -592,8 +589,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
592589
593590 if let Some(background_color) = background_color {
594591 let mut ansi_style = Style::default();
595− ansi_style.background =
596− Some(to_ansi_color(background_color, self.config.true_color));
592+ ansi_style.background = to_ansi_color(background_color, self.config.true_color);
597593
598594 write!(
599595 handle,
@@ -627,20 +623,27 @@ impl Colors {
627623 }
628624
629625 fn colored(theme: &Theme, true_color: bool) -> Self {
630− let gutter_color = theme
631− .settings
632− .gutter_foreground
633− .map(|c| to_ansi_color(c, true_color))
634− .unwrap_or(Fixed(DEFAULT_GUTTER_COLOR));
626+ let gutter_style = Style {
627+ foreground: match theme.settings.gutter_foreground {
628+ // If the theme provides a gutter foreground color, use it.
629+ // Note: It might be the special value #00000001, in which case
630+ // to_ansi_color returns None and we use an empty Style
631+ // (resulting in the terminal's default foreground color).
632+ Some(c) => to_ansi_color(c, true_color),
633+ // Otherwise, use a specific fallback color.
634+ None => Some(Fixed(DEFAULT_GUTTER_COLOR)),
635+ },
636+ ..Style::default()
637+ };
635638
636639 Colors {
637− grid: gutter_color.normal(),
638− rule: gutter_color.normal(),
640+ grid: gutter_style,
641+ rule: gutter_style,
639642 filename: Style::new().bold(),
640643 git_added: Green.normal(),
641644 git_removed: Red.normal(),
642645 git_modified: Yellow.normal(),
643− line_number: gutter_color.normal(),
646+ line_number: gutter_style,
644647 }
645648 }
646649}
src/terminal.rs+19−9
@@ -3,13 +3,13 @@ use ansi_term::{self, Style};
33
44use syntect::highlighting::{self, FontStyle};
55
6−pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> ansi_term::Color {
6+pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> Option<ansi_term::Color> {
77 if color.a == 0 {
88 // Themes can specify one of the user-configurable terminal colors by
99 // encoding them as #RRGGBBAA with AA set to 00 (transparent) and RR set
10− // to the 8-bit color palette number. The built-in themes ansi-light,
11− // ansi-dark, base16, and base16-256 use this.
12− match color.r {
10+ // to the 8-bit color palette number. The built-in themes ansi, base16,
11+ // and base16-256 use this.
12+ Some(match color.r {
1313 // For the first 8 colors, use the Color enum to produce ANSI escape
1414 // sequences using codes 30-37 (foreground) and 40-47 (background).
1515 // For example, red foreground is \x1b[31m. This works on terminals
@@ -31,11 +31,18 @@ pub fn to_ansi_color(color: highlighting::Color, true_color: bool) -> ansi_term:
3131 // 90-97 (foreground) and 100-107 (background), we should use those
3232 // for values 0x08 to 0x0f and only use Fixed for 0x10 to 0xff.
3333 n => Fixed(n),
34− }
34+ })
35+ } else if color.a == 1 {
36+ // Themes can specify the terminal's default foreground/background color
37+ // (i.e. no escape sequence) using the encoding #RRGGBBAA with AA set to
38+ // 01. The built-in theme ansi uses this.
39+ None
3540 } else if true_color {
36− RGB(color.r, color.g, color.b)
41+ Some(RGB(color.r, color.g, color.b))
3742 } else {
38− Fixed(ansi_colours::ansi256_from_rgb((color.r, color.g, color.b)))
43+ Some(Fixed(ansi_colours::ansi256_from_rgb((
44+ color.r, color.g, color.b,
45+ ))))
3946 }
4047}
4148
@@ -54,7 +61,10 @@ pub fn as_terminal_escaped(
5461 let mut style = if !colored {
5562 Style::default()
5663 } else {
57− let mut color = Style::from(to_ansi_color(style.foreground, true_color));
64+ let mut color = Style {
65+ foreground: to_ansi_color(style.foreground, true_color),
66+ ..Style::default()
67+ };
5868 if style.font_style.contains(FontStyle::BOLD) {
5969 color = color.bold();
6070 }
@@ -67,6 +77,6 @@ pub fn as_terminal_escaped(
6777 color
6878 };
6979
70− style.background = background_color.map(|c| to_ansi_color(c, true_color));
80+ style.background = background_color.and_then(|c| to_ansi_color(c, true_color));
7181 style.paint(text).to_string()
7282}
tests/assets.rs+2−4
@@ -30,13 +30,11 @@ fn all_themes_are_present() {
3030 "Solarized (light)",
3131 "Sublime Snazzy",
3232 "TwoDark",
33− "ansi-dark",
34− "ansi-light",
33+ "ansi",
3534 "base16",
3635 "base16-256",
37− "gruvbox",
36+ "gruvbox-dark",
3837 "gruvbox-light",
39− "gruvbox-white",
4038 "zenburn"
4139 ]
4240 );
tests/benchmarks/comparison.sh+2−2
@@ -1,8 +1,8 @@
11#!/usr/bin/env bash
22
3−cd "$(dirname "${BASH_SOURCE[0]}")"
3+cd "$(dirname "${BASH_SOURCE[0]}")" || exit
44
5−if ! which hyperfine > /dev/null 2>&1; then
5+if ! command -v hyperfine > /dev/null 2>&1; then
66 echo "'hyperfine' does not seem to be installed."
77 echo "You can get it here: https://github.com/sharkdp/hyperfine"
88 exit 1
tests/benchmarks/run-benchmarks.sh+2−2
@@ -1,8 +1,8 @@
11#!/usr/bin/env bash
22
3−cd "$(dirname "${BASH_SOURCE[0]}")"
3+cd "$(dirname "${BASH_SOURCE[0]}")" || exit
44
5−if ! which hyperfine > /dev/null 2>&1; then
5+if ! command -v hyperfine > /dev/null 2>&1; then
66 echo "'hyperfine' does not seem to be installed."
77 echo "You can get it here: https://github.com/sharkdp/hyperfine"
88 exit 1
tests/integration_tests.rs+38
@@ -837,3 +837,41 @@ fn show_all_mode() {
837837 .stdout("hello·world␊\n├──┤␍␀␇␈␛")
838838 .stderr("");
839839}
840+
841+#[test]
842+fn plain_mode_does_not_add_nonexisting_newline() {
843+ bat()
844+ .arg("--paging=never")
845+ .arg("--color=never")
846+ .arg("--decorations=always")
847+ .arg("--style=plain")
848+ .arg("single-line.txt")
849+ .assert()
850+ .success()
851+ .stdout("Single Line");
852+}
853+
854+// Regression test for https://github.com/sharkdp/bat/issues/299
855+#[test]
856+fn grid_for_file_without_newline() {
857+ bat()
858+ .arg("--paging=never")
859+ .arg("--color=never")
860+ .arg("--terminal-width=80")
861+ .arg("--wrap=never")
862+ .arg("--decorations=always")
863+ .arg("--style=full")
864+ .arg("single-line.txt")
865+ .assert()
866+ .success()
867+ .stdout(
868+ "\
869+───────┬────────────────────────────────────────────────────────────────────────
870+ │ File: single-line.txt
871+───────┼────────────────────────────────────────────────────────────────────────
872+ 1 │ Single Line
873+───────┴────────────────────────────────────────────────────────────────────────
874+",
875+ )
876+ .stderr("");
877+}
tests/syntax-tests/highlighted/Plaintext/plaintext.txt+1−1
@@ -175,4 +175,4 @@
175175\u{ad}␊
176176\u{ae}␊
177177␊
178−Here's·a·line·with·multiple·characters.
178+Here's·a·line·with·multiple·characters.␊
tests/syntax-tests/highlighted/VimL/source.vimnew file+92
@@ -0,0 +1,92 @@
1+if &compatible
2+ set nocompatible
3+endif
4+
5+if has('win32') || has ('win64')
6+ let $VIMHOME = $HOME . "/vimfiles"
7+elseif v:false && v:true
8+ echo "Can't get here"
9+else
10+ let $VIMHOME = $HOME . "/.vim"
11+endif
12+
13+" show existing tab with 2 spaces width
14+set tabstop=2
15+" when indenting with '>', use 2 spaces width
16+set shiftwidth=2
17+" always set autoindenting on
18+set autoindent
19+
20+autocmd VimEnter * echo "Hello Vim"
21+
22+" Allow :W and :Wq to save too
23+command! Wq :wq
24+command! W :w
25+
26+augroup vimrc
27+ autocmd!
28+ autocmd FileType * echo "New filetype"
29+augroup END
30+
31+function! s:echo(what)
32+ return a:what
33+endfunction
34+
35+function! HelloWorld(name)
36+ let l:function_local = "function_local_var"
37+ let l:parts = split(l:function_local, "_")
38+ let l:greeting = "Hello " . a:name
39+ return s:echo(l:greeting)
40+endfunction
41+
42+function! source#Hello()
43+ return "Hello from namespace"
44+endfunction
45+
46+function! EchoFunc(...)
47+ for s in a:000
48+ echon ' ' . s
49+ endfor
50+endfunction
51+
52+imap <C-h> <C-r>=HelloWorld("World")<CR>
53+
54+command! -nargs=? Echo :call EchoFunc(<args>)
55+
56+" TODO test stuff
57+let g:global = "global var"
58+let s:script_var = "script var"
59+let w:window_var = "window war"
60+let b:buffer_var = "buffer war"
61+let t:tab_var = "tab war"
62+echo v:false
63+
64+3 + 5
65+
66+echo "Hello" ==# "Hello2"
67+echo "Hello" ==? "Hello2"
68+echo "Hello" == "Hello2"
69+echo "Hello" is "Hello2"
70+echo "Hello" isnot "Hello2"
71+echo "Hello" =~ 'xx*'
72+echo "Hello" !~ "Hello2"
73+echo "Hello" !~ "Hello2"
74+
75+echo "/This/should/not/be/a/regex"
76+
77+" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064)
78+set runtimepath=~/foo/bar
79+
80+silent g/Aap/p
81+
82+let g:dict = {}
83+let g:dict.item = ['l1', 'l2']
84+
85+let g:dict2 = {'dict_item': ['l1', 'l2'], 'di2': 'x'}
86+
87+silent g/regex/
88+silent v/regex/
89+silent %s/regex/not_regex/
90+
91+filetype plugin indent on
92+syntax enable
tests/syntax-tests/regression_test.sh+1−1
@@ -4,7 +4,7 @@ set -eou pipefail
44
55script_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
66
7−output_directory=$(mktemp -d --suffix=.bat-syntax-regression-test)
7+output_directory=$(mktemp -d)
88
99"$script_directory"/create_highlighted_versions.py --output="$output_directory"
1010
tests/syntax-tests/source/ActionScript/test.as+1−1
@@ -72,4 +72,4 @@ package TestSyntax {
7272 var sndChannel:SoundChannel = mySound.play();
7373 }
7474 }
75−}
75+}
tests/syntax-tests/source/Batch/build.bat+1−1
@@ -56,4 +56,4 @@ set LDLIBS= ^
5656 @set "LINK_FILES=%LINK_FILES% %%~f"
5757)
5858
59−lld-link.exe %LINK_FILES% -out:"%OUTPUT%" %LDFLAGS% %LDLIBS%
59+lld-link.exe %LINK_FILES% -out:"%OUTPUT%" %LDFLAGS% %LDLIBS%
tests/syntax-tests/source/Clojure/test.clj+1−1
@@ -55,4 +55,4 @@
5555 (println (factorial 5))
5656 (log)
5757 (log "Message"))
58−
58+
tests/syntax-tests/source/Dockerfile/Dockerfile+1−1
@@ -16,4 +16,4 @@ EXPOSE 80/tcp
1616
1717VOLUME [/var/lib/mysql/data]
1818
19−ENTRYPOINT ["/usr/bin/entrypoint.sh"]
19+ENTRYPOINT ["/usr/bin/entrypoint.sh"]
tests/syntax-tests/source/Git Attributes/example.gitattributes+1−1
@@ -13,4 +13,4 @@
1313*.patch -text
1414
1515.gitattributes linguist-language=gitattributes
16−.gitkeep export-ignore
16+.gitkeep export-ignore
tests/syntax-tests/source/Git Config/text.gitconfig+1−1
@@ -104,4 +104,4 @@
104104[user]
105105 email = f.nord@example.com
106106 name = Frank Nord
107− signingkey = AAAAAAAAAAAAAAAA
107+ signingkey = AAAAAAAAAAAAAAAA
tests/syntax-tests/source/Hosts/hosts+1−1
@@ -5,4 +5,4 @@
55192.160.0.200 try.sample.test try #another comment
66216.58.223.238 google.com
77
8−::1 localhost.try ip6-localhost
8+::1 localhost.try ip6-localhost
tests/syntax-tests/source/Makefile/Makefile+1−1
@@ -382,4 +382,4 @@ install: all
382382 @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
383383
384384uninstall:
385− rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME)}
385+ rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME)}
tests/syntax-tests/source/PHP/test.php+1−1
@@ -108,4 +108,4 @@ $doe->setName('John Doe');
108108
109109$ending = 2 > 3 ? "yep" : "nah";
110110
111−?>
111+?>
tests/syntax-tests/source/Plaintext/plaintext.txt

Binary file not shown.

tests/syntax-tests/source/PowerShell/test.ps1

Binary file not shown.

tests/syntax-tests/source/RequirementsTXT/requirements.txt+1−1
@@ -5,4 +5,4 @@ pywheels>=12.4 #a whitespace followed by comments
55Nuitka<0.6.8.4
66wxPython>=1.0, <=2.1
77
8−#this is another comment
8+#this is another comment
tests/syntax-tests/source/VimL/source.vimnew file+92
@@ -0,0 +1,92 @@
1+if &compatible
2+ set nocompatible
3+endif
4+
5+if has('win32') || has ('win64')
6+ let $VIMHOME = $HOME . "/vimfiles"
7+elseif v:false && v:true
8+ echo "Can't get here"
9+else
10+ let $VIMHOME = $HOME . "/.vim"
11+endif
12+
13+" show existing tab with 2 spaces width
14+set tabstop=2
15+" when indenting with '>', use 2 spaces width
16+set shiftwidth=2
17+" always set autoindenting on
18+set autoindent
19+
20+autocmd VimEnter * echo "Hello Vim"
21+
22+" Allow :W and :Wq to save too
23+command! Wq :wq
24+command! W :w
25+
26+augroup vimrc
27+ autocmd!
28+ autocmd FileType * echo "New filetype"
29+augroup END
30+
31+function! s:echo(what)
32+ return a:what
33+endfunction
34+
35+function! HelloWorld(name)
36+ let l:function_local = "function_local_var"
37+ let l:parts = split(l:function_local, "_")
38+ let l:greeting = "Hello " . a:name
39+ return s:echo(l:greeting)
40+endfunction
41+
42+function! source#Hello()
43+ return "Hello from namespace"
44+endfunction
45+
46+function! EchoFunc(...)
47+ for s in a:000
48+ echon ' ' . s
49+ endfor
50+endfunction
51+
52+imap <C-h> <C-r>=HelloWorld("World")<CR>
53+
54+command! -nargs=? Echo :call EchoFunc(<args>)
55+
56+" TODO test stuff
57+let g:global = "global var"
58+let s:script_var = "script var"
59+let w:window_var = "window war"
60+let b:buffer_var = "buffer war"
61+let t:tab_var = "tab war"
62+echo v:false
63+
64+3 + 5
65+
66+echo "Hello" ==# "Hello2"
67+echo "Hello" ==? "Hello2"
68+echo "Hello" == "Hello2"
69+echo "Hello" is "Hello2"
70+echo "Hello" isnot "Hello2"
71+echo "Hello" =~ 'xx*'
72+echo "Hello" !~ "Hello2"
73+echo "Hello" !~ "Hello2"
74+
75+echo "/This/should/not/be/a/regex"
76+
77+" Error case from issue #1604 (https://github.com/sharkdp/bat/issues/1064)
78+set runtimepath=~/foo/bar
79+
80+silent g/Aap/p
81+
82+let g:dict = {}
83+let g:dict.item = ['l1', 'l2']
84+
85+let g:dict2 = {'dict_item': ['l1', 'l2'], 'di2': 'x'}
86+
87+silent g/regex/
88+silent v/regex/
89+silent %s/regex/not_regex/
90+
91+filetype plugin indent on
92+syntax enable
tests/syntax-tests/source/YAML/example.yaml+1−1
@@ -31,4 +31,4 @@ emails:
3131 - bob@example.com
3232 - bill@example.com
3333 supervisors:
34− - george@example.com
34+ - george@example.com
tests/syntax-tests/source/reStructuredText/reference.rst+1−1
@@ -317,4 +317,4 @@ blank lines before and after.)
317317..
318318
319319 So this block is not "lost",
320− despite its indentation.
320+ despite its indentation.
tests/syntax-tests/update.sh+1−1
@@ -1,6 +1,6 @@
11#!/usr/bin/env bash
22
3−cd "$(dirname "${BASH_SOURCE[0]}")"
3+cd "$(dirname "${BASH_SOURCE[0]}")" || exit
44
55python="python3"
66if ! command -v python3 &>/dev/null; then python="python"; fi