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

Compare commits

...

466 Commits

Author SHA1 Message Date
sharkdp 6258dda0f8 v0.16.0 2020-10-02 23:27:29 +02:00
sharkdp e6565b2134 Update syntaxes 2020-10-02 22:53:31 +02:00
sharkdp 2f9ecf9044 Bump version to 0.16.0 2020-10-02 20:45:29 +02:00
sharkdp a74d35582e Update CHANGELOG for 0.16 2020-10-02 20:45:29 +02:00
sharkdp 8886faa019 Update dependencies 2020-10-02 20:45:29 +02:00
sharkdp 4bd1b157ae Add comment about Mandoc, closes #1145 2020-10-02 20:45:29 +02:00
sharkdp 1ecb70e082 Update email syntax output 2020-10-01 22:58:30 +02:00
sharkdp 9eed16beb4 Add Email example code 2020-10-01 22:58:30 +02:00
dependabot-preview[bot] c432a064a4 Bump assets/syntaxes/02_Extra/Email from ee3e68f to e89d09d
Bumps [assets/syntaxes/02_Extra/Email](https://github.com/mariozaizar/email.sublime-syntax) from `ee3e68f` to `e89d09d`.
- [Release notes](https://github.com/mariozaizar/email.sublime-syntax/releases)
- [Commits](https://github.com/mariozaizar/email.sublime-syntax/compare/ee3e68fce26cb7ab6ad8c8bf7ca45cfe2a70c07a...e89d09d440f342b753a490918f2c9777c64836b3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 22:58:30 +02:00
Kienyew 2d1a92b7cc Fix zsh completion path 2020-10-01 22:09:59 +02:00
dependabot-preview[bot] cb31127b32 Bump semver from 0.10.0 to 0.11.0
Bumps [semver](https://github.com/steveklabnik/semver) from 0.10.0 to 0.11.0.
- [Release notes](https://github.com/steveklabnik/semver/releases)
- [Commits](https://github.com/steveklabnik/semver/compare/v0.10.0...v0.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 21:54:51 +02:00
sharkdp 2beec1f3ea Add comment about missing man page / completions, see #1198 2020-10-01 21:16:10 +02:00
sharkdp 8d531b6436 Update CHANGELOG 2020-10-01 21:09:46 +02:00
sharkdp 30993a8bfc Simplify code 2020-10-01 21:06:37 +02:00
sharkdp 2258fb2713 Remove .unwrap() in insert call to prevent crashes 2020-10-01 21:06:37 +02:00
sharkdp a46191b8bf Remove .unwrap() to prevent crashes 2020-10-01 21:06:37 +02:00
sharkdp 9c4c3e965b Remove non-working unit test 2020-10-01 21:06:37 +02:00
Ahmed El Gabri 31acbe20d3 Support XDG_CONFIG_HOME git config files 2020-10-01 21:06:37 +02:00
Ethan P fd52c01e78 Add custom languages/themes sections to manpage 2020-10-01 20:57:18 +02:00
dependabot-preview[bot] 6ca5543648 Bump assets/syntaxes/02_Extra/Elixir from d223f67 to 4ee539b
Bumps [assets/syntaxes/02_Extra/Elixir](https://github.com/princemaple/elixir-sublime-syntax) from `d223f67` to `4ee539b`.
- [Release notes](https://github.com/princemaple/elixir-sublime-syntax/releases)
- [Commits](https://github.com/princemaple/elixir-sublime-syntax/compare/d223f67612fcc3ee2edd3336ffc285a9ee673406...4ee539b43d82388f449535f7316d69f5dfeaabb5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 20:46:32 +02:00
dependabot-preview[bot] 83afcdcf49 Bump assets/syntaxes/02_Extra/Nginx from dc70858 to 15a1db1
Bumps [assets/syntaxes/02_Extra/Nginx](https://github.com/brandonwamboldt/sublime-nginx) from `dc70858` to `15a1db1`.
- [Release notes](https://github.com/brandonwamboldt/sublime-nginx/releases)
- [Commits](https://github.com/brandonwamboldt/sublime-nginx/compare/dc7085829fb772be2cdb285d4684176322691e9a...15a1db15106fb668b3b1396a725ab002a8ef286c)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 20:46:15 +02:00
dependabot-preview[bot] 59ca0069a6 Bump git2 from 0.13.8 to 0.13.11
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.8 to 0.13.11.
- [Release notes](https://github.com/rust-lang/git2-rs/releases)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.8...0.13.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 20:38:44 +02:00
dependabot-preview[bot] 6d6184500e Bump serde from 1.0.114 to 1.0.116
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.114 to 1.0.116.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.114...v1.0.116)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-01 20:37:22 +02:00
sharkdp 1c24ec16e2 Update CHANGELOG 2020-09-30 19:53:36 +02:00
sharkdp 5efc0033a1 Add updated, highlighted output 2020-09-30 19:50:19 +02:00
sharkdp c9237cccab Add AWK file for syntax tests 2020-09-30 19:50:19 +02:00
dependabot-preview[bot] 02cd68db37 Bump assets/syntaxes/02_Extra/AWK from 1ce5f90 to e593eb6
Bumps [assets/syntaxes/02_Extra/AWK](https://github.com/JohnNilsson/awk-sublime) from `1ce5f90` to `e593eb6`.
- [Release notes](https://github.com/JohnNilsson/awk-sublime/releases)
- [Commits](https://github.com/JohnNilsson/awk-sublime/compare/1ce5f90d444d80b12af41bc051507e914730d4ef...e593eb6d42a5f1881ba6c75698bd0fb78a9b8871)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-30 19:50:19 +02:00
sharkdp e4df5643dc Highlight crypttab files with fstab highlighting, closes #1073 2020-09-20 21:43:18 +02:00
sharkdp 89b62d579f Add update script 2020-09-20 21:43:18 +02:00
sharkdp 436a16aba6 Add syntax test for /etc/fstab 2020-09-20 21:43:18 +02:00
sharkdp 32d22f464d Improve --style help text, closes #1146 2020-09-20 21:00:04 +02:00
sharkdp 71b2089384 Code formatting 2020-09-20 20:47:21 +02:00
sharkdp 57aa88a13a Improve --file-name help text, closes #1109 2020-09-20 20:43:30 +02:00
sharkdp 5ef35a10cf Re-enable LTO 2020-09-20 19:55:01 +02:00
sharkdp f84aceec3d Fix unwrap error 2020-09-20 19:54:05 +02:00
sharkdp f18009e5d5 Remove 'liquid' dependency 2020-09-20 19:50:39 +02:00
Kienyew 83c7750656 Use unwrap 2020-09-20 12:14:21 +02:00
Kienyew c477e23fe9 Handle file extension conflicts in --list-languages 2020-09-20 12:14:21 +02:00
Kienyew 31fb7087f1 Revert to previous commit 2020-09-20 12:14:21 +02:00
Kienyew 6bc477e88f Update CHANGELOG.md 2020-09-20 12:14:21 +02:00
Kienyew 52d6701f8f Fix undesired behavior 2020-09-20 12:14:21 +02:00
Kienyew f97634011e Handle file extension conflicts in --list-languages (#1076) 2020-09-20 12:14:21 +02:00
sharkdp a4ffc9d5ed Update CHANGELOG 2020-09-14 11:30:47 +02:00
Kienyew a86f3e5b81 Fix packaging and Use parameterized names for zsh completion 2020-09-14 11:28:09 +02:00
Kienyew d9e8bbcb10 Handle zsh completion when packaging 2020-09-14 11:28:09 +02:00
Kienyew 8b0886ac32 Fix typo 2020-09-14 11:28:09 +02:00
Kienyew aa182dad76 Update CHANGELOG.md 2020-09-14 11:28:09 +02:00
Kienyew 41a1952928 use _describe instead of _values on subcommand 2020-09-14 11:28:09 +02:00
Kienyew 9885d4ebf0 add completion for 'cache' subcommand 2020-09-14 11:28:09 +02:00
Kienyew 222e080ce7 Fix character escape problem 2020-09-14 11:28:09 +02:00
Kienyew 046409d7c9 Add zsh completion 2020-09-14 11:28:09 +02:00
sharkdp 5df449bcf3 Remove unnecessary parenthesis 2020-09-14 11:24:14 +02:00
Alexander Karlis 6017989c4c removed printlns, updated Changelog, updated man 2020-09-14 11:24:14 +02:00
Alexander Karlis d349974089 updated PR based on comments 2020-09-14 11:24:14 +02:00
Alexander Karlis ccdea6a429 remove println 2020-09-14 11:24:14 +02:00
Alexander Karlis fdf11326ef added additional alias for color=always when always-decorations flag is triggered 2020-09-14 11:24:14 +02:00
Alexander Karlis 565a80305c Added new alias for 'decoration=always' 2020-09-14 11:24:14 +02:00
Niklas Mohrin 57a8122a6b Document PR in CHANGELOG.md 2020-09-14 10:36:22 +02:00
Niklas Mohrin bc5517da78 Document manual change in Apache sublime syntax file 2020-09-14 10:36:22 +02:00
Niklas Mohrin ad18f070ae Adds custom mapping for nginx and apache config files 2020-09-14 10:36:22 +02:00
Niklas Mohrin e305402212 Add manually generated sublime syntax file for apache configs 2020-09-14 10:36:22 +02:00
Niklas Mohrin d62b99f543 Adds Apache config file syntax highlighting 2020-09-14 10:36:22 +02:00
Niklas Mohrin 4d8133eb34 Adds Nginx config file syntax highlighting 2020-09-14 10:36:22 +02:00
dependabot-preview[bot] 5cba5b9989 Bump assets/syntaxes/02_Extra/SCSS_Sass from b98a3f3 to bc6332c
Bumps [assets/syntaxes/02_Extra/SCSS_Sass](https://github.com/braver/SublimeSass) from `b98a3f3` to `bc6332c`.
- [Release notes](https://github.com/braver/SublimeSass/releases)
- [Commits](https://github.com/braver/SublimeSass/compare/b98a3f3ccff0134c38544d9bc41caf7f61048cdf...bc6332c1be2c5590d334a2a58d3b83a8d07ac7ef)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-08 21:24:28 +02:00
dependabot-preview[bot] 31f23123ef Bump clap from 2.33.1 to 2.33.3
Bumps [clap](https://github.com/clap-rs/clap) from 2.33.1 to 2.33.3.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v2.33.3/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v2.33.1...v2.33.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-08 21:23:54 +02:00
dependabot-preview[bot] b9dac6ca5d Bump syntect from 4.2.0 to 4.4.0
Bumps [syntect](https://github.com/trishume/syntect) from 4.2.0 to 4.4.0.
- [Release notes](https://github.com/trishume/syntect/releases)
- [Changelog](https://github.com/trishume/syntect/blob/master/CHANGELOG.md)
- [Commits](https://github.com/trishume/syntect/compare/v4.2.0...v4.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-08 20:20:50 +02:00
sharkdp c3f85c8372 Add Less file for syntax tests 2020-09-07 22:25:14 +02:00
sharkdp 7f5d6d9791 Add SASS file for syntax tests 2020-09-07 22:25:14 +02:00
dependabot-preview[bot] 96d4cdb7cb Bump assets/syntaxes/02_Extra/ssh-config from bee376c to 1ddcb32
Bumps [assets/syntaxes/02_Extra/ssh-config](https://github.com/robballou/sublimetext-sshconfig) from `bee376c` to `1ddcb32`.
- [Release notes](https://github.com/robballou/sublimetext-sshconfig/releases)
- [Commits](https://github.com/robballou/sublimetext-sshconfig/compare/bee376c89655dc6a2e19468ac3d2874a7709bc9d...1ddcb320aca1bf31b0048a3109540475d5af64e2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-07 22:18:10 +02:00
dependabot-preview[bot] 9f1f3ab5e3 Bump error-chain from 0.12.3 to 0.12.4
Bumps [error-chain](https://github.com/rust-lang-nursery/error-chain) from 0.12.3 to 0.12.4.
- [Release notes](https://github.com/rust-lang-nursery/error-chain/releases)
- [Changelog](https://github.com/rust-lang-nursery/error-chain/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang-nursery/error-chain/compare/0.12.3...0.12.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-07 22:17:19 +02:00
dependabot-preview[bot] 6e90f17a15 Bump console from 0.11.3 to 0.12.0
Bumps [console](https://github.com/mitsuhiko/console) from 0.11.3 to 0.12.0.
- [Release notes](https://github.com/mitsuhiko/console/releases)
- [Commits](https://github.com/mitsuhiko/console/compare/v0.11.3...v0.12.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-07 22:17:03 +02:00
dependabot-preview[bot] 5b654480f4 Bump liquid from 0.21.1 to 0.21.4
Bumps [liquid](https://github.com/cobalt-org/liquid-rust) from 0.21.1 to 0.21.4.
- [Release notes](https://github.com/cobalt-org/liquid-rust/releases)
- [Changelog](https://github.com/cobalt-org/liquid-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/cobalt-org/liquid-rust/compare/liquid-lib-v0.21.1...v0.21.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-07 22:01:48 +02:00
Nikolay Shuyskiy 803447e2a1 Stylistic, spelling and punctuation fixes in README-ru 2020-08-30 19:47:02 +02:00
apotheon 99c04a8740 update README to clarify disjunctive licensing 2020-08-29 10:59:08 +02:00
chris48s e4370d8d3f change docs dir name to match package name
i.e: docs for bat-musl go in /usr/share/doc/bat-musl
not /usr/share/doc/bat
2020-08-12 06:47:58 +02:00
chris48s 883cc964ae add Depends line
Use dpkg-shlibdeps to work out shared library dependencies
and include them in a "Depends:" line

resolves missing-depends-line
https://lintian.debian.org/tags/missing-depends-line.html
2020-08-12 06:47:58 +02:00
chris48s 1d4cee11b7 include changelog in package
in line with debian changelog/release notes guidance
https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
resolves changelog-file-missing-in-native-package
https://lintian.debian.org/tags/changelog-file-missing-in-native-package.html
2020-08-12 06:47:58 +02:00
chris48s 9f91a7d797 include years in copyright notice
This brings the copyright notice into line with the expected format
resolves copyright-without-copyright-notice
https://lintian.debian.org/tags/copyright-without-copyright-notice.html
2020-08-12 06:47:58 +02:00
chris48s 4a6b4fb632 ensure copyright is mode 644
resolves non-standard-file-perm
https://lintian.debian.org/tags/non-standard-file-perm.html
2020-08-12 06:47:58 +02:00
chris48s 7c730d11c3 remove leading article from description
resolves description-synopsis-starts-with-article
https://lintian.debian.org/tags/description-synopsis-starts-with-article.html
2020-08-12 06:47:58 +02:00
chris48s 21de52ebea invoke gzip with -n
resolves package-contains-timestamped-gzip
https://lintian.debian.org/tags/package-contains-timestamped-gzip.html
2020-08-12 06:47:58 +02:00
Kienyew cab5ddf6ae Fix Typo 2020-08-12 06:45:24 +02:00
dependabot-preview[bot] b3657aef2b Bump assets/syntaxes/02_Extra/ssh-config from 3ec06d0 to bee376c
Bumps [assets/syntaxes/02_Extra/ssh-config](https://github.com/robballou/sublimetext-sshconfig) from `3ec06d0` to `bee376c`.
- [Release notes](https://github.com/robballou/sublimetext-sshconfig/releases)
- [Commits](https://github.com/robballou/sublimetext-sshconfig/compare/3ec06d0e9c2d20e7bb31f0149364d25f77503d97...bee376c89655dc6a2e19468ac3d2874a7709bc9d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-03 21:52:58 +02:00
David Peter b0f8841217 Fix typo 2020-08-03 17:48:16 +02:00
Mehrad Mahmoudian febe335831 Clarified which pager is used in docs 2020-08-03 17:48:16 +02:00
sharkdp cbe68ba84c Make sure that environment is properly set up 2020-08-03 15:59:53 +02:00
sharkdp 9110b00e2e Rebuild bat with new assets 2020-08-03 15:59:53 +02:00
sharkdp 4b012de7db Make test script executable 2020-08-03 15:59:53 +02:00
sharkdp 49370e2175 Add CI job 2020-08-03 15:59:53 +02:00
sharkdp 02a89d8ee8 Add comparison script 2020-08-03 15:59:53 +02:00
sharkdp a70efae79b Add proper CLI 2020-08-03 15:59:53 +02:00
sharkdp 78a681f027 Initial version of syntax regression tests 2020-08-03 15:59:53 +02:00
sharkdp 3a85fd767b Update themes.bin 2020-08-03 11:39:49 +02:00
sharkdp 2ffbe08eb1 Add base16-256 theme to unit test 2020-08-03 11:39:49 +02:00
Mitchell Kember f9d5e81f0e Add new theme: base16-256
Bat already has a base16 theme. The new base16-256 theme is for users
of base16-shell, who configure their terminal with a 256-color variant
of a base16 theme. These variants put some of the base16 colors in
elsewhere in the 256-color table to avoid clobbering bright color slots
(ansi codes 8 to 15) with colors that don't respect the ordinary meaning
of that slot (e.g. bright green in ordinary base16 is not green).

For more details, see https://github.com/chriskempson/base16-shell
2020-08-03 11:39:49 +02:00
dependabot-preview[bot] 00d1267bdd Bump dirs from 2.0.2 to 3.0.1
Bumps [dirs](https://github.com/soc/dirs-rs) from 2.0.2 to 3.0.1.
- [Release notes](https://github.com/soc/dirs-rs/releases)
- [Commits](https://github.com/soc/dirs-rs/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-03 11:38:09 +02:00
dependabot-preview[bot] 001ee34d01 Bump assets/themes/onehalf from 970abdf to 3aa42a3
Bumps [assets/themes/onehalf](https://github.com/sonph/onehalf) from `970abdf` to `3aa42a3`.
- [Release notes](https://github.com/sonph/onehalf/releases)
- [Commits](https://github.com/sonph/onehalf/compare/970abdf26b399100cbb59c6b6e693c4ff877c59d...3aa42a39ed3cddde0c53976a700b81b8a7067890)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-02 22:53:04 +02:00
David Peter db157567fd Use GitHub Actions badge 2020-08-02 21:53:59 +02:00
sharkdp 9e0fab16ff Fix here-doc indentation, part 2 2020-08-02 21:51:23 +02:00
sharkdp a9af4f4ca1 Fix spelling of LICENSE 2020-08-02 21:51:23 +02:00
sharkdp 96d682ca49 Use ansi-dark theme in GA output 2020-08-02 21:51:23 +02:00
sharkdp 7056bea9e0 Add list of languages/themes 2020-08-02 21:51:23 +02:00
sharkdp 63e13d8e54 Colored output 2020-08-02 21:51:23 +02:00
sharkdp 81587b3578 Add checks for all feature combinations 2020-08-02 21:51:23 +02:00
sharkdp 663c7cf1d7 Add bat test run 2020-08-02 21:51:23 +02:00
sharkdp 8705d018fd Fix here-doc indentation 2020-08-02 21:51:23 +02:00
sharkdp 8c33a32256 Add old copyright, control files; add man page and autocompletions 2020-08-02 21:51:23 +02:00
sharkdp 37a720be06 Use recursive checkout 2020-08-02 21:51:23 +02:00
sharkdp aacbdcfc44 Add --path argument 2020-08-02 21:51:23 +02:00
sharkdp 794f3d08f4 Remove --release argument 2020-08-02 21:51:23 +02:00
sharkdp 3147f0536a Add job to run tests with new syntaxes/themes 2020-08-02 21:51:23 +02:00
sharkdp 42de486e94 Adapt job step names 2020-08-02 21:51:23 +02:00
sharkdp 54c9d7cdb2 Remove unneeded i586-* jobs 2020-08-02 21:51:23 +02:00
sharkdp c8e394f3f0 Remove TravisCI and AppVeyor configuration files 2020-08-02 21:51:23 +02:00
sharkdp 4b65e6e443 Change MinSRV => Minimum supported Rust version 2020-08-02 21:51:23 +02:00
sharkdp 5a6c65c589 Disable code-coverage comments 2020-08-02 21:51:23 +02:00
dependabot-preview[bot] 75246fb25b Bump liquid from 0.20.1 to 0.21.1
Bumps [liquid](https://github.com/cobalt-org/liquid-rust) from 0.20.1 to 0.21.1.
- [Release notes](https://github.com/cobalt-org/liquid-rust/releases)
- [Changelog](https://github.com/cobalt-org/liquid-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/cobalt-org/liquid-rust/compare/liquid-bin-v0.20.1...liquid-lib-v0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-01 23:06:25 +02:00
dependabot-preview[bot] 0cc1084819 Bump git2 from 0.13.6 to 0.13.8
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.6 to 0.13.8.
- [Release notes](https://github.com/rust-lang/git2-rs/releases)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.6...0.13.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-01 23:06:14 +02:00
dependabot-preview[bot] 21eedaf76e Bump error-chain from 0.12.2 to 0.12.3
Bumps [error-chain](https://github.com/rust-lang-nursery/error-chain) from 0.12.2 to 0.12.3.
- [Release notes](https://github.com/rust-lang-nursery/error-chain/releases)
- [Changelog](https://github.com/rust-lang-nursery/error-chain/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang-nursery/error-chain/commits/0.12.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-01 10:17:49 +02:00
dependabot-preview[bot] 2656c503a4 Bump predicates from 1.0.4 to 1.0.5
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v1.0.4...v1.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-01 09:54:43 +02:00
sharkdp 2b3457e8d6 Update --help text for --color 2020-07-25 22:32:34 +02:00
sharkdp f5d606c4fc Always use 'batcat' in info.sh, if needed 2020-07-25 22:28:22 +02:00
Dash Peters 0e38c1728e Update changelog 2020-07-09 08:15:04 +02:00
Dash Peters 6faf61552e Fix integration test 2020-07-09 08:15:04 +02:00
Dash Peters fcf5ec2f77 Add syntaxes.bin changes 2020-07-09 08:15:04 +02:00
Dash Peters 99819087f1 Switch to "·" (U+00B7) Middle Dot from "•" (U+2022) Bullet 2020-07-09 08:15:04 +02:00
Attila Gonda 3956e96e74 Add clarification about how the indentation works 2020-07-09 08:13:52 +02:00
Attila Gonda a0b89a68d9 Update generated config to reflect pager argument behaviour 2020-07-09 08:13:52 +02:00
AJ ONeal 62014c1094 Make Windows 10 dependencies more clear 2020-07-05 12:20:59 +02:00
David Peter 58dcabffe6 Merge pull request #1082 from LordFlashmeow/master
Add alias for --paging=never
2020-07-02 21:08:23 +02:00
Dash Peters c264f74771 Hide alias in help, update man and completions
A long alias doesn't make sense, since `--paging=never` already exists
2020-07-02 00:07:37 -07:00
Dash Peters f53ea60ed4 Merge remote-tracking branch 'sharkdp/master' 2020-07-02 00:04:55 -07:00
David Peter 05027b7c74 Remove outdated Docker installation method 2020-07-02 08:36:01 +02:00
David Peter 3a62e3d188 Merge pull request #1066 from gsomix/feature/1061-show-all-redirected
Enable non-printable characters for redirected output
2020-07-02 08:21:50 +02:00
David Peter 963d9ee584 Merge pull request #1069 from KyleOndy/add_gruvbox_theme
add peaceant's port of gruvbox themes
2020-07-02 08:07:15 +02:00
David Peter 12e4fd138b Add updated themes.bin
Branch: add_gruvbox_theme
2020-07-02 07:37:00 +02:00
Evgeniy Andreev (gsomix) 3c5ce9f86c Enable non-printable chars for redirected output (#1061) 2020-07-02 09:36:58 +04:00
David Peter 2461d22212 Add new themes to unit test
Branch: add_gruvbox_theme
2020-07-02 07:17:57 +02:00
David Peter 611c6e9c74 Merge branch 'master' into add_gruvbox_theme 2020-07-02 07:02:04 +02:00
dependabot-preview[bot] 38efdb5148 Bump serde_yaml from 0.8.12 to 0.8.13
Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.12 to 0.8.13.
- [Release notes](https://github.com/dtolnay/serde-yaml/releases)
- [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.12...0.8.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-02 06:50:28 +02:00
Dash Peters 5fdeeabb44 Change to name no-paging, add long flag and alias 2020-07-01 21:35:45 -07:00
Dash Peters b0d19752c6 Merge remote-tracking branch 'sharkdp/master' 2020-07-01 21:33:56 -07:00
David Peter a95a577622 Merge pull request #1090 from sharkdp/dependabot/cargo/liquid-0.20.1
Bump liquid from 0.20.0 to 0.20.1
2020-07-01 16:45:51 +02:00
dependabot-preview[bot] ca44a80a42 Bump unicode-width from 0.1.7 to 0.1.8
Bumps [unicode-width](https://github.com/unicode-rs/unicode-width) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/unicode-rs/unicode-width/releases)
- [Commits](https://github.com/unicode-rs/unicode-width/commits/v0.1.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-01 16:45:35 +02:00
dependabot-preview[bot] bf841e63bd Bump liquid from 0.20.0 to 0.20.1
Bumps [liquid](https://github.com/cobalt-org/liquid-rust) from 0.20.0 to 0.20.1.
- [Release notes](https://github.com/cobalt-org/liquid-rust/releases)
- [Changelog](https://github.com/cobalt-org/liquid-rust/blob/master/CHANGELOG.md)
- [Commits](https://github.com/cobalt-org/liquid-rust/compare/liquid-bin-v0.20.0...liquid-bin-v0.20.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-01 13:02:54 +00:00
dependabot-preview[bot] d357227e57 Bump serde from 1.0.111 to 1.0.114
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.111 to 1.0.114.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.111...v1.0.114)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-01 15:01:17 +02:00
David Peter 993d703ba0 Merge pull request #1088 from sharkdp/dependabot/cargo/wild-2.0.4
Bump wild from 2.0.3 to 2.0.4
2020-07-01 09:11:36 +02:00
dependabot-preview[bot] b449b82191 Bump wild from 2.0.3 to 2.0.4
Bumps [wild](https://gitlab.com/kornelski/wild) from 2.0.3 to 2.0.4.
- [Release notes](https://gitlab.com/kornelski/wild/tags)
- [Commits](https://gitlab.com/kornelski/wild/commits/master)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-01 02:30:41 +00:00
Dash Peters bfac6fd85c Add integration tests 2020-06-30 12:41:50 -07:00
Dash Peters 2575aae945 Add short flag for --paging=never 2020-06-30 12:19:22 -07:00
David Peter b0191cdf2c Merge pull request #1070 from caioalonso/master
Adds GLSL syntax
2020-06-29 06:10:19 +02:00
Caio Alonso fc121f0c87 Defaults *.fs to F# 2020-06-26 21:42:05 -03:00
Sergey fa10b48c71 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey d4db1c6af3 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey f651e2cfca Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 9d9f99c2d1 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 9c8dda1f9d Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 89521a5134 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey d11355f985 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 7ccda6e6e9 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 1de423c78b Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 3943857087 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 27bb5c5976 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 3f614cb274 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 1e407d972f Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 52b3c5fce4 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 5d53273ef4 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey bf9faa9c28 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 0356b7f2c3 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 19c8558152 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey a137db86a4 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 2a28f04e09 Update doc/README-ru.md
Co-authored-by: Evgeniy Andreev <gsomix@gmail.com>
2020-06-26 19:19:26 +02:00
Sergey 8dfa69fde4 Update README-ru.md 2020-06-26 19:19:26 +02:00
Kyle Ondy 541f014d50 add peaceant's port of gruvbox themes
This adds Martin Radimec's [1] port [2] of the gruvbox theme [3].

Brian Reilly (Briles) [4] has a pretty complete collection of gruvbox
ports [5] but they are all in `sublime-color-scheme` which is not yet
supported in bat, see #759 [6].

[1] https://github.com/peaceant
[2] https://github.com/peaceant/gruvbox
[3] https://github.com/morhetz/gruvbox
[4] https://github.com/Briles
[5] https://github.com/Briles/gruvbox
[6] https://github.com/sharkdp/bat/issues/759
2020-06-22 21:25:51 -04:00
Caio Alonso 233d375983 Adds GLSL syntax 2020-06-22 22:19:48 -03:00
t-mangoe b09d245dea modify japanese doc. 2020-06-21 10:58:59 +02:00
Guido Cella 44deddbbfe Highlight pacman hooks as ini 2020-06-21 10:58:32 +02:00
Guido Cella aa8a2b1769 Highlight systemd files as ini 2020-06-21 10:58:32 +02:00
Guido Cella 4cdac180d8 Revert "Highlight systemd files and Pacman hooks as .ini files"
This reverts commit cde430a1e7.
2020-06-21 10:58:32 +02:00
Guido Cella d079bf86b1 Highlight systemd files and Pacman hooks as .ini files 2020-06-21 10:58:32 +02:00
gemmaro 62b4452057 fix typo in Japanese readme
* typo
* more natural expression
2020-06-14 09:18:53 +02:00
David Peter c3ec92a13f Remove outdated Ansible installation method 2020-06-07 22:55:32 +02:00
David Peter c3230a68bb README layout 2020-06-05 22:42:32 +02:00
Sergey Duck d9f163f466 translation update with commit #6e3e7dafcaa840ed72748f2ca1e99e420769907b 2020-06-03 22:21:13 +02:00
Sergey Duck d0da5af810 fix link to translation 2020-06-03 22:21:13 +02:00
Sergey Duck a2b2ec467a minor fixes 2020-06-03 22:21:13 +02:00
Sergey Duck 83b3009f0f full translated 2020-06-03 22:21:13 +02:00
Sergey Duck 4ea70f8409 customization is translated 2020-06-03 22:21:13 +02:00
Sergey Duck 0d2ef02c9e Installation is translated 2020-06-03 22:21:13 +02:00
Sergey Duck 2d7796284b First part of russian translation 2020-06-03 22:21:13 +02:00
sharkdp 19aa878a08 Remove explicit type annotation 2020-06-03 19:44:41 +02:00
sharkdp 9f52012443 Prevent allocation of additional Strings 2020-06-03 19:44:41 +02:00
sharkdp e57e9b6dbb Use 'or_insert_with' 2020-06-03 19:44:41 +02:00
sharkdp 74e8373e34 Return mappings as a slice 2020-06-03 19:44:41 +02:00
sharkdp ec2722d465 Use 'if let' instead of 'match' 2020-06-03 19:44:41 +02:00
Alex Novak 9e2ea5fdd4 Incorporating feedback 2020-06-03 19:44:41 +02:00
Alex Novak 48b4a6a906 Adds a little logic to main to get other mappings from config 2020-06-03 19:44:41 +02:00
Roy Ivy III 92e93682c6 Revert f8ed8aa7 (add test instrumentation to help understand failing tests) per PR feedback/owner request
- reverts commit f8ed8aa74b
2020-06-03 09:13:47 +02:00
Roy Ivy III 99226b745f Revert 9ed8db22c ('windows' pager process execution fix) based on PR feedback/owner request 2020-06-03 09:13:47 +02:00
Roy Ivy III 4840c7cd78 Tests ~ add predicate normalization for tests using echo 2020-06-03 09:13:47 +02:00
Roy Ivy III 71ab4a2058 Tests ~ revert to echo (after fixed 'windows' pager process execution) 2020-06-03 09:13:47 +02:00
Roy Ivy III a2c09b41bc Fix pager process execution under 'windows'
## [why]

For 'windows' platforms, directly spawning a process (eg, called PATHNAME) bypasses the
usual windows shell machinery for determining which process to execute. Specifically,
the extensions in PATHEXT will not be used to determine the final executable. So,
`PATHNAME.bat`, `PATHNAME.cmd`, ... will *not* be executed even if on they exist on the
PATH; and this is counter to the usual expectation of a Windows user. Additionally,
built-in commands, such as `echo` and `dir`, will never be accessible as they do not
have a PATH to execute and, so, will never be found.

To use the usual machinery, giving access to PATHNAME.bat and `echo`, execute the PATHNAME
using the windows shell, eg `cmd /d/c PATHNAME`. Note this may expose the constructed
command line to the windows shell quoting vagaries (sadly, that may be part of the price).

Following Windows standards, the ComSpec environment variable is used to determine which
shell to use, with a fallback to the "modern", built-in `cmd` shell.
2020-06-03 09:13:47 +02:00
Roy Ivy III 0ef792ac1e Tests ~ (fix) always check out test fixtures with known LF line endings
- fixes windows test failures
- avoids `git` platform-dependent conversion of line endings for checkout of test fixtures (*tests/examples/...*)
2020-06-03 09:13:47 +02:00
Roy Ivy III 01af28b781 Tests ~ add instrumentation to visualize text differences in failing tests 2020-06-03 09:13:47 +02:00
Roy Ivy III 3a7743ffc5 Tests ~ echo has portability issues; for CI, replace with printf
- using `echo` on 'windows' platforms requires process execution indirectly via the shell
- `printf` is available on all GHA CI platforms
  - `printf` is *not* available on usual 'windows' platforms; so this is just temporizing, awaiting a true fix
2020-06-03 09:13:47 +02:00
Roy Ivy III 9cc8e52512 Fix compiler warning for 'windows' tests (dead_code) 2020-06-03 09:13:47 +02:00
Roy Ivy III 698a6b5acf Maint/CICD ~ GHA - add additional linux builds and packaging support 2020-06-03 09:13:47 +02:00
Roy Ivy III 7a51c7fd30 Maint/CICD ~ GHA - disable windows-gnu builds with unresolvable linker errors
- `undefined reference to `_imp____acrt_iob_func'`

- ref: <https://github.com/rust-lang/rust/issues/68887#issuecomment-615877016>
- ref: <https://users.rust-lang.org/t/linking-with-gcc-failed-exit-code-1/34124>
- ref: <https://www.gitmemory.com/issue/rust-lang/rust/47048/530376978>
- ref: <https://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/?limit=250&page=7>
2020-06-03 09:13:47 +02:00
Roy Ivy III 7c3e9f81cb Maint/CI ~ add GitHub-Actions CI (aka GHA) 2020-06-03 09:13:47 +02:00
Alexander Jackson 6e3e7dafca Clarify more wording when reading from stdin
Update the word 'initial' to be 'first', as this is more ubiquitous and
potentially easier for non-native speakers.

Clarify that it is the highlighting that may not work, and the input
will still be displayed regardless.
2020-06-03 09:01:23 +02:00
Alexander Jackson fca83bf79a Clarify stdin syntax highlighting in the README
Clarify the requirements for automatic syntax highlighting when reading
input from stdin. Fixes #1028.
2020-06-03 09:01:23 +02:00
vwvw b8ffb8d463 fix typo in readme 2020-06-02 21:53:50 +02:00
dependabot-preview[bot] 1dae5bbc95 Bump semver from 0.9.0 to 0.10.0
Bumps [semver](https://github.com/steveklabnik/semver) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/steveklabnik/semver/releases)
- [Commits](https://github.com/steveklabnik/semver/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 10:40:05 +02:00
dependabot-preview[bot] 1a1932b67a Bump console from 0.11.2 to 0.11.3
Bumps [console](https://github.com/mitsuhiko/console) from 0.11.2 to 0.11.3.
- [Release notes](https://github.com/mitsuhiko/console/releases)
- [Commits](https://github.com/mitsuhiko/console/compare/0.11.2...v0.11.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 10:39:23 +02:00
dependabot-preview[bot] 8be375e75b Bump git2 from 0.13.5 to 0.13.6
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.5 to 0.13.6.
- [Release notes](https://github.com/rust-lang/git2-rs/releases)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.5...0.13.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:56:01 +02:00
dependabot-preview[bot] e63e4232db Bump serde from 1.0.110 to 1.0.111
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.110 to 1.0.111.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.110...v1.0.111)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:55:32 +02:00
sharkdp cef04665eb Manually convert Crystal.sublime-syntax 2020-06-01 09:54:46 +02:00
dependabot-preview[bot] 76569b9527 Bump assets/syntaxes/02_Extra/Crystal from 2ee9d66 to 5e032ff
Bumps [assets/syntaxes/02_Extra/Crystal](https://github.com/crystal-lang-tools/sublime-crystal) from `2ee9d66` to `5e032ff`.
- [Release notes](https://github.com/crystal-lang-tools/sublime-crystal/releases)
- [Commits](https://github.com/crystal-lang-tools/sublime-crystal/compare/2ee9d667aeb9e90846244b5a74e78826014676de...5e032ff5f5d98c9d5d2984a1bd43b43230cd3d0a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:54:46 +02:00
sharkdp 1d46eb8ea3 Manually convert TypeScript.sublime-syntax 2020-06-01 09:50:30 +02:00
dependabot-preview[bot] 6b79ac995e Bump assets/syntaxes/02_Extra/TypeScript from 9cd994a to f21aba5
Bumps [assets/syntaxes/02_Extra/TypeScript](https://github.com/Microsoft/TypeScript-Sublime-Plugin) from `9cd994a` to `f21aba5`.
- [Release notes](https://github.com/Microsoft/TypeScript-Sublime-Plugin/releases)
- [Commits](https://github.com/Microsoft/TypeScript-Sublime-Plugin/compare/9cd994af73c58371a14dbe64fd69fcaa782bb321...f21aba57c58e9434df8fc29e1bd2feddfea83b21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:50:30 +02:00
dependabot-preview[bot] ee928b034e Bump assets/syntaxes/02_Extra/Elixir from 1f010d5 to d223f67
Bumps [assets/syntaxes/02_Extra/Elixir](https://github.com/princemaple/elixir-sublime-syntax) from `1f010d5` to `d223f67`.
- [Release notes](https://github.com/princemaple/elixir-sublime-syntax/releases)
- [Commits](https://github.com/princemaple/elixir-sublime-syntax/compare/1f010d5f63f20aa8eafa57aaaeafe736e0748dca...d223f67612fcc3ee2edd3336ffc285a9ee673406)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:31:28 +02:00
dependabot-preview[bot] fc5790eb4a Bump assets/syntaxes/02_Extra/LESS from 3020993 to 44632e1
Bumps [assets/syntaxes/02_Extra/LESS](https://github.com/danro/LESS-sublime) from `3020993` to `44632e1`.
- [Release notes](https://github.com/danro/LESS-sublime/releases)
- [Commits](https://github.com/danro/LESS-sublime/compare/302099365866daca49d25288111696a30a4b4e03...44632e19af8370b39643dd60cd76deb7a13c63ee)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 09:30:26 +02:00
dependabot-preview[bot] 5213ffee0e Bump clap from 2.33.0 to 2.33.1
Bumps [clap](https://github.com/clap-rs/clap) from 2.33.0 to 2.33.1.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/v2.33.1/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v2.33.0...v2.33.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 08:44:09 +02:00
sharkdp 5ebf0215c5 Update CHANGELOG 2020-05-29 22:14:20 +02:00
Ethan P 9957da6b93 Remove <font> tag from CHANGELOG.md 2020-05-29 22:13:10 +02:00
Ethan P 342cae2dc6 Change use of 'BatInput' to 'input::Input' 2020-05-29 22:13:10 +02:00
Ethan P d2b26a5f1f Remove unnecessary '-> ()'s 2020-05-29 22:13:10 +02:00
Ethan P 9d08c0102e Replace Input::stdin_as_file with bat-application functions 2020-05-29 22:13:10 +02:00
Ethan P a3357547ea Remove unused with_name for theme preview file 2020-05-29 22:13:10 +02:00
Ethan P 7a9decad70 Remove Input.as_file and add Input::stdin_as_file 2020-05-29 22:13:10 +02:00
Ethan P c4d0d068e4 Update input API example 2020-05-29 22:13:10 +02:00
Ethan P c03a027240 Move PR changes in README to unreleased section 2020-05-29 22:13:10 +02:00
Ethan P a8d7141c4c Improve documentation for Input API 2020-05-29 22:13:10 +02:00
Ethan P 3eb704e016 Update examples 2020-05-29 22:13:10 +02:00
Ethan P 0f06d3b90d Reexport bat::pretty_printer::Input as bat::Input 2020-05-29 22:13:10 +02:00
Ethan P 589c94aa93 Fix regression with --list-themes and --language 2020-05-29 22:13:10 +02:00
Ethan P 798b742617 Refactor InputDescription API into Input API 2020-05-29 22:13:10 +02:00
Ethan P 11a72ab765 Fix a typo 2020-05-29 22:13:10 +02:00
Ethan P 0319149b4d [breaking] Remove special handling for theme previews 2020-05-29 22:13:10 +02:00
Ethan P 2f823d59b0 Add PrettyPrinter::input function 2020-05-29 22:13:10 +02:00
Ethan P 981352992b Add InputDescription API 2020-05-29 22:13:10 +02:00
Ethan P 384ea38bd9 Add documentation to InputDescription 2020-05-29 22:13:10 +02:00
Ryan Tolboom 268c0963b4 Updated AsciiDoc syntax submodule 2020-05-29 22:12:28 +02:00
Ethan P 8b481dd41f Add support for NO_COLOR env var (#1021) 2020-05-28 21:49:10 +02:00
David Peter 6f88ba0e6f Update CHANGELOG.md 2020-05-27 12:04:31 +02:00
sharkdp 9e65ecd03e Updates for v0.15.4 2020-05-27 10:14:32 +02:00
sharkdp 9cb43ef64d Update tests 2020-05-27 10:09:57 +02:00
sharkdp bb18ece8a4 Remove 'Haskell (improved) syntax' 2020-05-27 10:09:57 +02:00
sharkdp 2ab6474761 Add unit test to make sure we are not missing any themes 2020-05-27 09:50:22 +02:00
David Peter fe20328ab7 Revert "Bump assets/themes/Solarized from 87e0109 to 3707f68"
This reverts commit a265242e6e.
2020-05-27 09:50:22 +02:00
sharkdp d84ac09abd Update .gitattributes 2020-05-26 12:14:27 +02:00
sharkdp 69e6cae0a7 Fix CHANGELOG 2020-05-26 08:38:12 +02:00
sharkdp 302707f3ce Bump version to 0.15.3 2020-05-26 08:11:41 +02:00
sharkdp 2e2043971b Update CHANGELOG for 0.15.3 2020-05-26 08:11:41 +02:00
sharkdp e54e218e3b Update binary assets 2020-05-26 08:11:41 +02:00
sharkdp bd17fd571f Switch from path-absolutize to path_abs
closes #1022
2020-05-26 08:11:26 +02:00
sharkdp 3f6e88b4be Remove dummy line from CHANGELOG 2020-05-25 17:30:19 +02:00
sharkdp 28af18ba27 Bump version to 0.15.2 2020-05-25 17:27:27 +02:00
sharkdp 8f1babf346 Mark 'vcs_modification_markers' as deprecated 2020-05-25 11:51:10 +02:00
sharkdp fa25695b74 Make 'vcs_modification_markers' change non-breaking 2020-05-25 11:51:10 +02:00
sharkdp 943b1f82b6 Fix syntax detection for symlinks
closes #1001
2020-05-24 17:32:43 +02:00
sharkdp b7a09516e7 Update CHANGELOG 2020-05-24 11:30:10 +02:00
sharkdp c4031ad65c Fix syntax detection for files called 'rails'
closes #1008
2020-05-24 11:27:42 +02:00
dependabot-preview[bot] 2eaced4d30 Bump wild from 2.0.2 to 2.0.3
Bumps [wild](https://gitlab.com/kornelski/wild) from 2.0.2 to 2.0.3.
- [Release notes](https://gitlab.com/kornelski/wild/tags)
- [Commits](https://gitlab.com/kornelski/wild/commits/master)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-24 10:51:02 +02:00
dependabot-preview[bot] bdea2fe94c Bump serde from 1.0.106 to 1.0.110
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.106 to 1.0.110.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.106...v1.0.110)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-24 10:50:48 +02:00
dependabot-preview[bot] c96ff30876 Bump serde_yaml from 0.8.11 to 0.8.12
Bumps [serde_yaml](https://github.com/dtolnay/serde-yaml) from 0.8.11 to 0.8.12.
- [Release notes](https://github.com/dtolnay/serde-yaml/releases)
- [Commits](https://github.com/dtolnay/serde-yaml/compare/0.8.11...0.8.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-24 10:48:31 +02:00
dependabot-preview[bot] 4c100cffdb Bump shell-words from 0.1.0 to 1.0.0
Bumps [shell-words](https://github.com/tmiasko/shell-words) from 0.1.0 to 1.0.0.
- [Release notes](https://github.com/tmiasko/shell-words/releases)
- [Commits](https://github.com/tmiasko/shell-words/commits/v1.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-24 10:41:50 +02:00
sharkdp d6abad908a Update README and CHANGELOG, see #650 2020-05-24 10:01:53 +02:00
dependabot-preview[bot] f1129189ea Bump syntect from 4.1.1 to 4.2.0
Bumps [syntect](https://github.com/trishume/syntect) from 4.1.1 to 4.2.0.
- [Release notes](https://github.com/trishume/syntect/releases)
- [Changelog](https://github.com/trishume/syntect/blob/master/CHANGELOG.md)
- [Commits](https://github.com/trishume/syntect/compare/v4.1.1...v4.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-24 10:00:15 +02:00
sharkdp 7e84477408 Add CHANGELOG entry 2020-05-19 06:40:24 +02:00
sharkdp 6b86ab5cd0 Move syntax to 02_Extra folder 2020-05-19 06:40:24 +02:00
Cooper Pierce 5074b96cd5 Add syntax highlighting for SML
Converted from
https://github.com/seanjames777/SML-Language-Definition/blob/master/sml.tmLanguage
and removed `ml` filetype to fix an (assumed) possible conflict with
existing OCaml support.
2020-05-19 06:40:24 +02:00
sharkdp 3094ac90b7 Update CHANGELOG entry 2020-05-16 13:44:26 +02:00
Ethan P 35b6067496 Print error message when invalid syntax is specified 2020-05-16 13:44:26 +02:00
Ethan P 5aa20c090b Refactor HighlightingAssets::get_syntax to return Result type 2020-05-16 13:44:26 +02:00
Ethan P 9c371ed8a2 Merge pull request #997 from eth-p/misc-fixes-1
Allow 'bat' application to built without git feature, remove PrettyPrint git support when feature not enabled.
2020-05-15 16:41:13 -07:00
Ethan P f03ab11623 Update CHANGELOG.md 2020-05-15 14:03:04 -07:00
Ethan P 887e61a99d Allow application to be built without git support
Caveats:
The help descriptions aren't changed with you remove the "git" feature.
2020-05-15 13:58:48 -07:00
Ethan P 0aca8cab0b Remove vcs_modification_markers from PrettyPrinter 'git' feature disabled 2020-05-15 13:58:48 -07:00
Ethan P d08d1f8c45 Merge pull request #985 from eth-p/string-input
Unify syntax detection for all variants of InputKind, fix #983
2020-05-15 13:57:44 -07:00
Ethan P 403ab6e443 Update CHANGELOG.md 2020-05-15 13:23:24 -07:00
Ethan P b8687bc969 Merge branch 'master' of github.com:sharkdp/bat into string-input 2020-05-15 13:22:24 -07:00
Ethan P 9166c9dd35 Remove unnecessary clone in integration tests 2020-05-15 12:29:01 -07:00
Ethan P cc52f79e42 Add helper fn for checking if opened input is theme preview file 2020-05-15 12:20:20 -07:00
Ethan P 59140b458c Consolidate syntax detection behavior for all InputKind types 2020-05-13 02:53:30 -07:00
Ethan P 82981c9663 Add regression test for detected syntax differing for stdin and files 2020-05-13 02:53:19 -07:00
Ethan P 157b8dd848 Rename test for checking if inputkinds are consistent 2020-05-13 00:47:18 -07:00
Ethan P 1fb669ae1a Test that OrdinaryFile consistent with CustomReader 2020-05-13 00:38:56 -07:00
Ethan P 7d07aa395a Change assets.rs tests to use InputKind::CustomReader
This should avoid errors in filesystems that don't
support UTF-8 or invalid UTF-8.
2020-05-13 00:38:41 -07:00
dependabot-preview[bot] c2c7070712 Bump assets/syntaxes/02_Extra/Julia from 0ca4cc2 to 6c0d770
Bumps [assets/syntaxes/02_Extra/Julia](https://github.com/JuliaEditorSupport/Julia-sublime) from `0ca4cc2` to `6c0d770`.
- [Release notes](https://github.com/JuliaEditorSupport/Julia-sublime/releases)
- [Commits](https://github.com/JuliaEditorSupport/Julia-sublime/compare/0ca4cc29907e9476cb603fed00d1d5fd9dc13c9c...6c0d770fc74e6bc037c70cae1f94fe113b60fd95)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:31:26 +02:00
dependabot-preview[bot] daf06bb026 Bump assets/syntaxes/02_Extra/Email from fc034fb to ee3e68f
Bumps [assets/syntaxes/02_Extra/Email](https://github.com/mariozaizar/email.sublime-syntax) from `fc034fb` to `ee3e68f`.
- [Release notes](https://github.com/mariozaizar/email.sublime-syntax/releases)
- [Commits](https://github.com/mariozaizar/email.sublime-syntax/compare/fc034fb85ae8a277627f1148769924dbc115dbe4...ee3e68fce26cb7ab6ad8c8bf7ca45cfe2a70c07a)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:22:27 +02:00
dependabot-preview[bot] 5b11b1ba47 Bump assets/themes/onehalf from fdcbffe to 970abdf
Bumps [assets/themes/onehalf](https://github.com/sonph/onehalf) from `fdcbffe` to `970abdf`.
- [Release notes](https://github.com/sonph/onehalf/releases)
- [Commits](https://github.com/sonph/onehalf/compare/fdcbffe3175c29bb78d19dcaf9b2a456482fcf1e...970abdf26b399100cbb59c6b6e693c4ff877c59d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:22:13 +02:00
sharkdp ee287447c5 Update CHANGELOG 2020-05-13 08:21:58 +02:00
dependabot-preview[bot] 257f978ceb Bump assets/syntaxes/02_Extra/ssh-config from 16e19d5 to 3ec06d0
Bumps [assets/syntaxes/02_Extra/ssh-config](https://github.com/robballou/sublimetext-sshconfig) from `16e19d5` to `3ec06d0`.
- [Release notes](https://github.com/robballou/sublimetext-sshconfig/releases)
- [Commits](https://github.com/robballou/sublimetext-sshconfig/compare/16e19d5da48a7c4d30fdded8ac4c97ff643f5d7b...3ec06d0e9c2d20e7bb31f0149364d25f77503d97)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 08:19:17 +02:00
dependabot-preview[bot] 8e803bdb02 Bump assets/themes/dracula-sublime from 811a634 to 26c57ec
Bumps [assets/themes/dracula-sublime](https://github.com/dracula/sublime) from `811a634` to `26c57ec`.
- [Release notes](https://github.com/dracula/sublime/releases)
- [Commits](https://github.com/dracula/sublime/compare/811a634420a0cb9023bb7afd1c8968a5aaf6a753...26c57ec282abcaa76e57e055f38432bd827ac34e)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 07:58:49 +02:00
dependabot-preview[bot] a265242e6e Bump assets/themes/Solarized from 87e0109 to 3707f68
Bumps [assets/themes/Solarized](https://github.com/braver/Solarized) from `87e0109` to `3707f68`.
- [Release notes](https://github.com/braver/Solarized/releases)
- [Commits](https://github.com/braver/Solarized/compare/87e01090cf5fb821a234265b3138426ae84900e7...3707f68ddc535723c02c65cbc97187c1aa99ad4d)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 07:58:32 +02:00
dependabot-preview[bot] 3aa9b31bda Bump assets/syntaxes/02_Extra/Elm from dfbb8bd to e266d27
Bumps [assets/syntaxes/02_Extra/Elm](https://github.com/elm-community/SublimeElmLanguageSupport) from `dfbb8bd` to `e266d27`.
- [Release notes](https://github.com/elm-community/SublimeElmLanguageSupport/releases)
- [Commits](https://github.com/elm-community/SublimeElmLanguageSupport/compare/dfbb8bdc9a8403092c884d3eb893a270538cfa72...e266d279c8074aa342f106554cfa87ebe839a782)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 07:58:15 +02:00
dependabot-preview[bot] c692c4770a Bump assets/syntaxes/02_Extra/Elixir from 89b3bad to 1f010d5
Bumps [assets/syntaxes/02_Extra/Elixir](https://github.com/princemaple/elixir-sublime-syntax) from `89b3bad` to `1f010d5`.
- [Release notes](https://github.com/princemaple/elixir-sublime-syntax/releases)
- [Commits](https://github.com/princemaple/elixir-sublime-syntax/compare/89b3bada3262bc58e0a5393d12a82f725d5063ad...1f010d5f63f20aa8eafa57aaaeafe736e0748dca)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-13 07:58:02 +02:00
sharkdp 6ceba56288 Add 'mkdir -p …' to Ubuntu instructions, see #982 2020-05-12 18:35:35 +02:00
David Peter 4be66f8b88 Update README.md 2020-05-12 17:42:52 +02:00
David Peter 54a85d98f1 Add instructions for ~/.local/bin/bat symlink 2020-05-12 17:41:15 +02:00
Prat T 491a5a17f3 Update CHANGELOG 2020-05-12 16:37:29 +02:00
Prat T b3373398e8 Remove padding if the header style is not enabled 2020-05-12 16:37:29 +02:00
Prat T 0040fef215 Add padding above headers when no grid 2020-05-12 16:37:29 +02:00
Ethan P 1a6e8d297f Update README to mention batcat for Debian/Ubuntu 2020-05-12 11:08:21 +02:00
Ethan P f39487fca9 Make syntax detection more consistent for Reader and File inputs 2020-05-11 19:44:09 -07:00
sharkdp 2596bfe7a7 Bump version to v0.15.1 2020-05-11 20:30:45 +02:00
sharkdp 406bffa8c8 Update syntaxes and themes 2020-05-11 20:29:49 +02:00
sharkdp 48441b99ef Patch Markdown syntax
closes #963
see #977
2020-05-11 20:22:50 +02:00
sharkdp ce4717144a Update CHANGELOG 2020-05-11 19:33:13 +02:00
Mitchell Kember f59d00d4c7 Fix base16, and combine 00 and 0f alpha encodings
This changes the base16 theme back from #RRGGBB0f to #RRGGBB00,
reverting part of #934. That PR used the 0f encoding to produce ANSI
escape sequences 30-37 and 40-47 rather than 38;5 and 48;5 which require
256-color support. Unfortunately, it resulted in base16 using the wrong
colors becuase ansi_term does not support the bright variants (90-97 and
100-107) so it simply mapped them to the non-bright colors.

This PR makes combines the 00 and 0f alpha encodings into 00, and makes
them use the Color enum for the first 8 colors and Fixed otherwise. This
means the ansi-light and ansi-dark themes will work on terminals without
256-color support, and base16 will render bright colors correctly.
2020-05-11 19:29:19 +02:00
Ethan P dcfdbf82dd Do not warn if both 'bat' and 'batcat' are available in info.sh 2020-05-02 10:39:58 +02:00
Ethan P 0cb884d501 Prevent batcat warning from being in output of info.sh 2020-05-02 10:39:58 +02:00
Ethan P 7bc4020a92 Check for 'batcat' in info.sh 2020-05-02 10:39:58 +02:00
sharkdp 0792195156 Properly add QML submodule 2020-05-01 10:24:19 +02:00
dependabot-preview[bot] 83f24ffcfb Bump git2 from 0.13.3 to 0.13.5
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.13.3 to 0.13.5.
- [Release notes](https://github.com/rust-lang/git2-rs/releases)
- [Commits](https://github.com/rust-lang/git2-rs/compare/0.13.3...0.13.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-01 10:21:19 +02:00
pylipp 74ec390770 Add QML syntax
QML.sublime-syntax file generated from Support/QML.tmLanguage using
Sublime's built-in converter.
Fix sharkdp/bat#962
2020-04-30 09:59:14 +02:00
Mario Zaizar 9014ffcfd8 Adds Email (https://github.com/mariozaizar/email.sublime-syntax) 2020-04-29 19:38:39 +02:00
sharkdp 81af375289 Use console 0.11.2, see #955 2020-04-28 21:18:48 +02:00
sharkdp d707eab95c Revert "Use console 0.11.1, see #955"
This reverts commit d64c55ef11.
The build on Windows failed due to two broken tests:

    line_numbers
    tabs_numbers
2020-04-28 09:22:19 +02:00
sharkdp d64c55ef11 Use console 0.11.1, see #955 2020-04-28 00:00:59 +02:00
sharkdp 2b1d53fb27 Add '--locked' flag to all 'cargo install' commands 2020-04-27 23:43:18 +02:00
sharkdp bf696f58c8 Pin version of console to 0.10.0 2020-04-27 23:37:06 +02:00
sharkdp 296bad8ffd Update CHANGELOG 2020-04-27 22:01:41 +02:00
sharkdp 94310af30c Add Fortran syntax, closes #957 2020-04-27 21:45:36 +02:00
sharkdp 38c096bf79 Update CHANGELOG 2020-04-25 15:19:42 +02:00
sharkdp 696d1b3ed3 Update CHANGELOG 2020-04-25 13:17:07 +02:00
sharkdp 17d98724a5 Bump version to v0.15.0 2020-04-25 13:09:24 +02:00
sharkdp 7d7ee1b594 Update cached verison of themes 2020-04-25 13:08:30 +02:00
sharkdp 682b4209f2 Update solarized themes to braver/Solarized, closes #941 2020-04-25 13:08:30 +02:00
sharkdp 41ddcbd240 Remove old Sublime themes 2020-04-25 13:08:30 +02:00
sharkdp 48a7ce3bf2 Write error messages to pager, if attached
closes #946
2020-04-25 13:08:00 +02:00
Lzu Tao 3bcc4d0d55 lto=true and codegen-units=1 together 2020-04-24 17:39:25 +02:00
Lzu Tao 8821bca656 appveyor: Use rustup minimal profile 2020-04-24 17:39:25 +02:00
Lzu Tao 56111aa20d simplify build.rs 2020-04-24 17:39:25 +02:00
sharkdp 5fe8a8342b Add annotations again 2020-04-24 16:51:11 +02:00
sharkdp 989109145a Add '-d' for '--diff' 2020-04-24 16:12:38 +02:00
sharkdp 23afc8e90c Skip non-file inputs when using --diff 2020-04-24 16:12:38 +02:00
sharkdp 8e18786556 Run 'cargo fmt' 2020-04-24 16:11:05 +02:00
sharkdp 81488adf8b Use unreachable!(…) 2020-04-24 16:11:05 +02:00
Lzu Tao e37e9c1214 Fix some clippy lints
Some might actually improve perf
2020-04-24 16:11:05 +02:00
Lzu Tao a4828387c1 simplify build.rs 2020-04-24 16:11:05 +02:00
sharkdp abeac8b12e Bump min. required Rust version to 1.40 2020-04-24 09:57:57 +02:00
sharkdp 82e7786e74 Implementation of 'bat --diff'
This adds a new `--diff` option that can be used to only show lines
close to Git changes (added/removed/modified lines). The amount of
additional context can be controlled with `--diff-context=N`.

closes #23
2020-04-24 09:57:57 +02:00
sharkdp 0064321323 cargo fmt 2020-04-23 00:56:35 +02:00
sharkdp 9e622a1a5f Update version in README 2020-04-23 00:56:27 +02:00
sharkdp 59ca933aee Update dependencies 2020-04-22 23:59:35 +02:00
sharkdp 793af6b911 Add a syntax mapping for bats own config file 2020-04-22 23:58:41 +02:00
sharkdp c8abe3f235 Update CHANGELOG 2020-04-22 23:56:20 +02:00
sharkdp 5d71056209 Fix import in app 2020-04-22 23:55:28 +02:00
sharkdp eb7d4d002a Update documentation 2020-04-22 23:55:28 +02:00
sharkdp 62b32bd848 Make module private 2020-04-22 23:55:28 +02:00
sharkdp 8961f7aef8 Move PagingMode to separate module 2020-04-22 23:55:28 +02:00
sharkdp 17f3a3b95d Simpler highlight method 2020-04-22 23:55:28 +02:00
sharkdp 261a7ea154 Add *_with_name methods 2020-04-22 23:55:28 +02:00
sharkdp 53a973e9dd Add syntaxes and themes method 2020-04-22 23:55:28 +02:00
sharkdp cba9df746e Add paging to advanced example 2020-04-22 23:55:28 +02:00
sharkdp 12eee0c590 Fix warnings for --no-default-features mode 2020-04-22 23:55:28 +02:00
sharkdp b76f5e72d4 Use unwrap 2020-04-22 23:55:28 +02:00
sharkdp 702cb198da Rename error module 2020-04-22 23:55:28 +02:00
sharkdp 5f826419d1 Add YAML example 2020-04-22 23:55:28 +02:00
sharkdp 13f671b499 Update examples 2020-04-22 23:55:28 +02:00
sharkdp 49f4322054 Fix example 2020-04-22 23:55:28 +02:00
sharkdp 0c9e044e41 Update 'cat' example 2020-04-22 23:55:28 +02:00
sharkdp 74d4377ed2 Add advanced example 2020-04-22 23:55:28 +02:00
sharkdp 6a124591df Easier configuration of style components 2020-04-22 23:55:28 +02:00
sharkdp 7a87315b94 Fix #937 2020-04-22 23:55:28 +02:00
sharkdp 0cde4e9121 Numbers => LineNumbers 2020-04-22 23:55:28 +02:00
sharkdp 36dde9275a Simplify style_components 2020-04-22 23:55:28 +02:00
sharkdp a8f759c080 Rename wrap => wrapping 2020-04-22 23:55:28 +02:00
sharkdp f034be71e7 rename run => print 2020-04-22 23:55:28 +02:00
sharkdp eee35e54e9 Update documentation 2020-04-22 23:55:28 +02:00
sharkdp ec0ce05455 Better API for highlighting lines 2020-04-22 23:55:28 +02:00
sharkdp 13e6b3fac7 Reduce public API 2020-04-22 23:55:28 +02:00
sharkdp 26c951fec4 Fix warnings, sort imports, input from string 2020-04-22 23:55:28 +02:00
sharkdp 590960f7f5 Completely refactor 'input' module 2020-04-22 23:55:28 +02:00
sharkdp b4d54106fe Fix comment 2020-04-22 23:55:28 +02:00
sharkdp f3b90ddb38 Add InputDescription 2020-04-22 23:55:28 +02:00
sharkdp 3bacfc5184 Allow fluent style 2020-04-22 23:55:28 +02:00
sharkdp f8d0956893 Rename InputFile => Input 2020-04-22 23:55:28 +02:00
sharkdp 1dc328ad49 Separate inputs from config 2020-04-22 23:55:28 +02:00
sharkdp 5e5cb89da6 Add all builder options 2020-04-22 23:55:28 +02:00
sharkdp 057e4eced1 Large refactoring towards a better builder structure 2020-04-22 23:55:28 +02:00
sharkdp 27974616bf Initial verison of PrettyPrinter builder 2020-04-22 23:55:28 +02:00
sharkdp 319ab779ee Use 4-bit ANSI codes for base16 theme
closes #865
2020-04-22 10:22:11 +02:00
Brice Dutheil 37831cdcb3 Fix README phrasing about dark mode 2020-04-21 22:37:24 +02:00
sharkdp 70480ee9d4 Bump version to v0.14.0 2020-04-21 18:21:22 +02:00
sharkdp 371c929ede Update CHANGELOG 2020-04-21 18:21:12 +02:00
sharkdp 864656bd11 Pass --no-init on Windows if less version < 559
We used to call `less` with
``` bash
less --RAW-CONTROL-CHARS --quit-if-one-screen --no-init
```
We only passed `--no-init` because there was a bug with previous versions
of `less` which required the use of `--no-init` in combination with
`--quit-if-one-screen` to prevent this "no output" issue from happening.

Since bat 0.13, [we omit the `--no-init` option](https://github.com/sharkdp/bat/blob/0ecc94956b88beed27ca13a130c8ba09f1a220d8/src/output.rs#L85-L97)
if we can detect that the version of `less` is higher than or equal to 530. We
did that because `--no-init` breaks mouse support and because [less 530 fixed
the above-mentioned bug](http://www.greenwoodsoftware.com/less/news.530.html).
However, it seems that this bug was *not* fixed on Windows!

According to @gwsw, the issue should be fixed with less 559 on Windows.

closes #887
2020-04-21 18:18:03 +02:00
sharkdp 2e9cf63a5f Fix compilation of library 2020-04-21 18:14:31 +02:00
sharkdp 886b22e0ee Do not store metadata.yaml file in git 2020-04-21 18:14:31 +02:00
sharkdp 72618db179 Add metadata information to cached assets
When saving/reading user-provided syntaxes or themes, `bat` will now maintain a
`metadata.yaml` file which includes information about the `bat` version which was
used to create the cached files. When loading cached files, we now print an error
if they have been created with an incompatible version

closes #882
2020-04-21 18:14:31 +02:00
sharkdp c8273369cc Make get_cache_dir private 2020-04-21 18:14:31 +02:00
sharkdp 95a56a2795 Typo in CHANGELOG 2020-04-21 17:49:36 +02:00
sharkdp 859ff50766 Update default config file, add comment about tmux mouse scrolling support 2020-04-21 17:45:14 +02:00
sharkdp ce583eb9bf Revert "Pass '--mouse' to less versions >= 551"
This reverts commit cb21b74ecd.
2020-04-21 17:29:01 +02:00
sharkdp 3a195be14e Revert "Only enable --mouse when running from tmux, see #904"
This reverts commit 5f6e310152.
2020-04-21 17:28:37 +02:00
sharkdp 5f6e310152 Only enable --mouse when running from tmux, see #904 2020-04-21 16:15:02 +02:00
sharkdp 5449472f15 Remove invalid UTF-8 file from repo, use temp file instead 2020-04-21 16:02:28 +02:00
sharkdp 82e20bfe14 Fix bug for file with invalid-utf8 filenames 2020-04-21 14:09:18 +02:00
sharkdp 47abb192bc Patch Rust syntax file
closes #924
2020-04-21 13:45:26 +02:00
sharkdp 03a7d6be92 Disable Travis caching 2020-04-21 13:44:51 +02:00
sharkdp a927815292 Update CHANGELOG 2020-04-21 11:50:26 +02:00
sharkdp 3447a03433 Update dependencies 2020-04-21 11:50:26 +02:00
sharkdp 03c2281828 Add do-not-panic! regression tests 2020-04-21 11:50:26 +02:00
sharkdp c386cb35fb Pass '--mouse' to less versions >= 551
When using `less` version 551 or newer, `bat` will now pass the `--mouse` argument, allowing
for (better) mouse scrolling support in some terminals.

closes #904
2020-04-21 10:00:32 +02:00
sharkdp 97ea3dd4dc Update CHANGELOG 2020-04-21 08:58:38 +02:00
sharkdp a6d9d1551f Improve error message 2020-04-21 08:57:15 +02:00
sharkdp 34619a2e89 Small refactoring, handle invalid UTF-8 filenames 2020-04-21 08:57:15 +02:00
Kyle Criddle 83d408bab3 Extract common syntax functionality to helper fns 2020-04-21 08:57:15 +02:00
sharkdp 8067fd9eda Fix build on 1.37 2020-04-21 08:57:15 +02:00
sharkdp 98ba9e0101 Use to_string_lossy 2020-04-21 08:57:15 +02:00
sharkdp 1b8ce60054 Pass stdin as a generic BufRead, fix stdin tests 2020-04-21 08:57:15 +02:00
sharkdp d5a31dc2ec Remove commented-out code 2020-04-21 08:57:15 +02:00
sharkdp 051dd4ba87 Make filename method private 2020-04-21 08:57:15 +02:00
sharkdp 2ad1848859 Do not take optional as argument 2020-04-21 08:57:15 +02:00
sharkdp 90e7d2fe33 Rename field name, new constructors 2020-04-21 08:57:15 +02:00
Kyle Criddle 04fa84aea7 Moved user_provided_filename to be contained within OrdinaryFile struct 2020-04-21 08:57:15 +02:00
Kyle Criddle a3f8140fbe Use --file-name to detect syntax highlighting
Closes #891
2020-04-21 08:57:15 +02:00
Ethan P 96aedf6240 Add cat alias detection to info.sh (#911) 2020-04-21 08:33:44 +02:00
Michael Diamond 4cc2989fe9 Clarify the Ubuntu/Debian install instructions
A cursory reading of the existing text would lead a reader to think `bat`should be available on Debian, which isn't really true. Most users are not running Sid, so `bat` isn't yet available to them.
2020-04-17 14:10:08 +02:00
sharkdp 0ecc94956b Add performance patch for Makefile syntax
Thanks to @keith-hall!

closes #750
2020-04-13 10:38:22 +02:00
David Peter 61e47e0c13 Add Stylus syntax (#917)
closes #915
2020-04-12 19:42:36 +02:00
sharkdp f5145ef130 Move Rego syntax 2020-04-12 19:20:28 +02:00
sharkdp edd27645d0 Add a way to directly search for a pattern 2020-04-12 19:19:33 +02:00
sharkdp fc6f4f31dd Add documentation 2020-04-12 19:19:33 +02:00
sharkdp f2cef702a0 Add script to find slow-to-highlight files 2020-04-12 19:19:33 +02:00
sharkdp 8b3d54ce29 Update CHANGELOG 2020-04-11 23:55:27 +02:00
sharkdp 47a3721890 Add patch for C# syntax 2020-04-11 23:55:27 +02:00
sharkdp 495fab24a5 cargo fmt 2020-04-11 19:40:04 +02:00
sharkdp fccbe4f4f2 Add regex-onig feature to 'cargo check' tests 2020-04-11 10:33:53 +02:00
sharkdp 9793bb3938 Update to syntect 4.1, fancy-regex support 2020-04-11 10:33:53 +02:00
sharkdp 496dd29cb9 Add -i option for bash/zsh to output wrapper function 2020-04-09 09:20:03 +02:00
Ethan P 116d76a00f Reformat info.sh 2020-04-09 09:20:03 +02:00
Ethan P dd336e6fb2 Fix wrapper detection failing on non-English LANG in info.sh 2020-04-09 09:20:03 +02:00
Ethan P c33af3581a Fix missing shell '-i' option when checking for wrapper in info.sh 2020-04-09 09:20:03 +02:00
Ethan P 2f4ecf8fc5 Add zsh wrapper detection to info.sh 2020-04-09 09:20:03 +02:00
Ethan P e037afeaca Add custom theme/syntax detection to info.sh 2020-04-09 09:02:23 +02:00
sharkdp 7b87af1748 Update dependencies, closes #476 2020-04-08 09:31:50 +02:00
dependabot-preview[bot] 0eee26fb09 Bump assert_cmd from 0.12.0 to 1.0.1
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 0.12.0 to 1.0.1.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v0.12.0...v1.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-01 07:50:24 +02:00
sharkdp 3355aeba22 Update CHANGELOG 2020-03-31 09:33:58 +02:00
David Tolnay 42e3825daf Updates for review of PR 899 2020-03-31 09:27:56 +02:00
David Tolnay 014d754588 Move paging support behind a feature 2020-03-31 09:27:56 +02:00
David Tolnay 4e11abdf9b Move git changes support behind a feature 2020-03-31 09:27:56 +02:00
David Tolnay 570805bc98 Strip dependencies of bat-as-a-library 2020-03-31 09:27:56 +02:00
David Tolnay e7e1967bb0 Allow using bat-as-a-library with older syntect 2020-03-30 22:01:18 +02:00
sharkdp 9a050cd87f Update CHANGELOG 2020-03-27 07:33:56 +01:00
Patrick East d39507889a Add OPA Rego syntax
This adds syntax support for Rego, the declarative policy language
used by the Open Policy Agent:

https://github.com/open-policy-agent/opa

Generated from:

https://github.com/open-policy-agent/opa/blob/master/misc/syntax/textmate/Rego.tmLanguage

Using:

https://github.com/aziz/SublimeSyntaxConvertor

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-03-27 07:33:07 +01:00
sharkdp 3e8d444c78 Fix for Rust 1.37 2020-03-26 10:01:02 +01:00
sharkdp 522ab7a83c CHANGELOG: Add entries for upcoming release 2020-03-26 09:55:21 +01:00
David Peter 0c5b4fcd4a Add CHANGELOG to the repository 2020-03-26 09:55:21 +01:00
David Peter 37b3b8730d Merge pull request #871 from neuronull/fix_654_stdin_filename
Implement --file-name<name> option
2020-03-26 09:35:01 +01:00
Josh Mickley 7c50fe5fec Document the --generate-config-file option 2020-03-26 09:14:40 +01:00
Josh Mickley 40a827ebcb Graceful handling of error conditions 2020-03-26 09:14:40 +01:00
Josh Mickley 376c556862 Add option to generate a default config file, fixes #870 2020-03-26 09:14:40 +01:00
Kyle Criddle 83772bd2cf Minor --file-name code hygeine 2020-03-25 18:58:05 -06:00
Marco Ieni 4aef8c180a README: fix manpage syntax link 2020-03-25 20:07:50 +01:00
Kyle Criddle 131d113ff5 Merge branch 'fix_654_stdin_filename' of github.com:neuronull/bat into fix_654_stdin_filename 2020-03-24 19:14:07 -06:00
Kyle Criddle 38178fedf4 Merge branch 'master' into fix_654_stdin_filename 2020-03-24 19:08:43 -06:00
Kyle Criddle 59f2e2d58d Implemented --file-name for multiple files + tests 2020-03-24 18:26:00 -06:00
Samuel FORESTIER 8d3136eb6f Adds Homepage to Debian package control file 2020-03-24 08:36:13 +01:00
Igor Raits 136a745c5d chore: Update liquid to 0.20
Signed-off-by: Igor Raits <i.gnatenko.brain@gmail.com>
2020-03-22 21:37:14 +01:00
Kyle Criddle fb3c775c8b --file-name for normal files. integration tests. 2020-03-22 11:10:27 +01:00
Kyle Criddle 8adce9fae8 Implement --file-name<name> option
- can specify filename to be displayed when printing.
- useful for when piping data from STDIN

Closes #654
2020-03-22 11:10:27 +01:00
Kyle Criddle cfa2cb6ec7 --file-name for normal files. integration tests. 2020-03-19 20:46:19 -06:00
Kyle Criddle 517be5c7bc Implement --file-name<name> option
- can specify filename to be displayed when printing.
- useful for when piping data from STDIN

Closes #654
2020-03-17 20:29:01 -06:00
138 changed files with 9200 additions and 2256 deletions
+1
View File
@@ -0,0 +1 @@
comment: false
+456
View File
@@ -0,0 +1,456 @@
name: CICD
env:
PROJECT_NAME: bat
PROJECT_DESC: "A `cat` clone with wings"
PROJECT_MAINTAINER: "David Peter <mail@david-peter.de>"
PROJECT_HOMEPAGE: "https://github.com/sharkdp/bat"
MIN_SUPPORTED_RUST_VERSION: "1.40.0"
on: [push, pull_request]
jobs:
min_version:
name: Minimum supported rust version
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v1
- name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }})
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
default: true
profile: minimal # minimal component installation (ie, no documentation)
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
test_with_new_syntaxes_and_themes:
name: Test with new syntaxes and themes
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v1
with:
submodules: true # we need all syntax and theme submodules
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
default: true
profile: minimal
- name: Build and install bat
uses: actions-rs/cargo@v1
with:
command: install
args: --locked --path .
- name: Rebuild binary assets (syntaxes and themes)
run: bash assets/create.sh
- name: Build and install bat with updated assets
uses: actions-rs/cargo@v1
with:
command: install
args: --locked --path .
- name: Run unit tests with new syntaxes and themes
uses: actions-rs/cargo@v1
with:
command: test
args: --release
- name: Syntax highlighting regression test
run: tests/syntax-tests/regression_test.sh
- name: List of languages
run: bat --list-languages
- name: List of themes
run: bat --list-themes
build:
name: Build
runs-on: ${{ matrix.job.os }}
strategy:
fail-fast: false
matrix:
job:
# { os, target, cargo-options, features, use-cross, toolchain }
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , use-cross: use-cross }
- { os: ubuntu-18.04 , target: aarch64-unknown-linux-gnu , use-cross: use-cross }
- { os: ubuntu-18.04 , target: i686-unknown-linux-gnu , use-cross: use-cross }
- { os: ubuntu-18.04 , target: i686-unknown-linux-musl , use-cross: use-cross }
- { os: ubuntu-18.04 , target: x86_64-unknown-linux-gnu , use-cross: use-cross }
- { os: ubuntu-18.04 , target: x86_64-unknown-linux-musl , use-cross: use-cross }
- { os: ubuntu-16.04 , target: x86_64-unknown-linux-gnu , use-cross: use-cross }
- { os: macos-latest , target: x86_64-apple-darwin }
# - { os: windows-latest , target: i686-pc-windows-gnu } ## disabled; linker errors (missing '_imp____acrt_iob_func')
- { os: windows-latest , target: i686-pc-windows-msvc }
# - { os: windows-latest , target: x86_64-pc-windows-gnu } ## disabled; linker errors (missing '_imp____acrt_iob_func')
- { os: windows-latest , target: x86_64-pc-windows-msvc }
steps:
- name: Git checkout
uses: actions/checkout@v1
- name: Install prerequisites
shell: bash
run: |
case ${{ matrix.job.target }} in
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Initialize workflow variables
id: vars
shell: bash
run: |
# toolchain
TOOLCHAIN="stable" ## default to "stable" toolchain
# * specify alternate TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: <https://github.com/rust-lang/rust/issues/47048>, <https://github.com/rust-lang/rust/issues/53454>, <https://github.com/rust-lang/cargo/issues/6754>)
case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac;
# * use requested TOOLCHAIN if specified
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
echo set-output name=TOOLCHAIN::${TOOLCHAIN}
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
# staging directory
STAGING='_staging'
echo set-output name=STAGING::${STAGING}
echo ::set-output name=STAGING::${STAGING}
# determine EXE suffix
EXE_suffix="" ; case ${{ matrix.job.target }} in *-pc-windows-*) EXE_suffix=".exe" ;; esac;
echo set-output name=EXE_suffix::${EXE_suffix}
echo ::set-output name=EXE_suffix::${EXE_suffix}
# parse commit reference info
REF_NAME=${GITHUB_REF#refs/*/}
unset REF_BRANCH ; case ${GITHUB_REF} in refs/heads/*) REF_BRANCH=${GITHUB_REF#refs/heads/} ;; esac;
unset REF_TAG ; case ${GITHUB_REF} in refs/tags/*) REF_TAG=${GITHUB_REF#refs/tags/} ;; esac;
REF_SHAS=${GITHUB_SHA:0:8}
echo set-output name=REF_NAME::${REF_NAME}
echo set-output name=REF_BRANCH::${REF_BRANCH}
echo set-output name=REF_TAG::${REF_TAG}
echo set-output name=REF_SHAS::${REF_SHAS}
echo ::set-output name=REF_NAME::${REF_NAME}
echo ::set-output name=REF_BRANCH::${REF_BRANCH}
echo ::set-output name=REF_TAG::${REF_TAG}
echo ::set-output name=REF_SHAS::${REF_SHAS}
# parse target
unset TARGET_ARCH ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) TARGET_ARCH=arm ;; i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac;
echo set-output name=TARGET_ARCH::${TARGET_ARCH}
echo ::set-output name=TARGET_ARCH::${TARGET_ARCH}
unset TARGET_OS ; case ${{ matrix.job.target }} in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac;
echo set-output name=TARGET_OS::${TARGET_OS}
echo ::set-output name=TARGET_OS::${TARGET_OS}
# package name
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
PKG_BASENAME=${PROJECT_NAME}-${REF_TAG:-$REF_SHAS}-${{ matrix.job.target }}
PKG_NAME=${PKG_BASENAME}${PKG_suffix}
echo set-output name=PKG_suffix::${PKG_suffix}
echo set-output name=PKG_BASENAME::${PKG_BASENAME}
echo set-output name=PKG_NAME::${PKG_NAME}
echo ::set-output name=PKG_suffix::${PKG_suffix}
echo ::set-output name=PKG_BASENAME::${PKG_BASENAME}
echo ::set-output name=PKG_NAME::${PKG_NAME}
# deployable tag? (ie, leading "vM" or "M"; M == version number)
unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi
echo set-output name=DEPLOY::${DEPLOY:-<empty>/false}
echo ::set-output name=DEPLOY::${DEPLOY}
# DPKG architecture?
unset DPKG_ARCH
case ${{ matrix.job.target }} in
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
i686-*-linux-*) DPKG_ARCH=i686 ;;
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
esac;
echo set-output name=DPKG_ARCH::${DPKG_ARCH}
echo ::set-output name=DPKG_ARCH::${DPKG_ARCH}
# DPKG version?
unset DPKG_VERSION ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DPKG_VERSION=${REF_TAG/#[vV]/} ; fi
echo set-output name=DPKG_VERSION::${DPKG_VERSION}
echo ::set-output name=DPKG_VERSION::${DPKG_VERSION}
# DPKG base name/conflicts?
DPKG_BASENAME=${PROJECT_NAME}
DPKG_CONFLICTS=${PROJECT_NAME}-musl
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
echo set-output name=DPKG_BASENAME::${DPKG_BASENAME}
echo set-output name=DPKG_CONFLICTS::${DPKG_CONFLICTS}
echo ::set-output name=DPKG_BASENAME::${DPKG_BASENAME}
echo ::set-output name=DPKG_CONFLICTS::${DPKG_CONFLICTS}
# DPKG name
unset DPKG_NAME;
if [[ -n $DPKG_ARCH && -n $DPKG_VERSION ]]; then DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb" ; fi
echo set-output name=DPKG_NAME::${DPKG_NAME}
echo ::set-output name=DPKG_NAME::${DPKG_NAME}
# target-specific options
# * CARGO_USE_CROSS (truthy)
CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac;
echo set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS:-<empty>/false}
echo ::set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS}
# # * `arm` cannot be tested on ubuntu-* hosts (b/c testing is currently primarily done via comparison of target outputs with built-in outputs and the `arm` target is not executable on the host)
JOB_DO_TESTING="true"
case ${{ matrix.job.target }} in arm-*) unset JOB_DO_TESTING ;; esac;
echo set-output name=JOB_DO_TESTING::${JOB_DO_TESTING:-<empty>/false}
echo ::set-output name=JOB_DO_TESTING::${JOB_DO_TESTING}
# # * test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac;
echo set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
# * executable for `strip`?
STRIP="strip" ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; *-pc-windows-msvc) STRIP="" ;; esac;
echo set-output name=STRIP::${STRIP}
echo ::set-output name=STRIP::${STRIP}
- name: Create all needed build/work directories
shell: bash
run: |
mkdir -p '${{ steps.vars.outputs.STAGING }}'
mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}'
mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/autocomplete'
mkdir -p '${{ steps.vars.outputs.STAGING }}/dpkg'
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ steps.vars.outputs.TOOLCHAIN }}
target: ${{ matrix.job.target }}
override: true
profile: minimal # minimal component installation (ie, no documentation)
- name: Info
shell: bash
run: |
gcc --version || true
rustup -V
rustup toolchain list
rustup default
cargo -V
rustc -V
- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: build
args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }}
- name: Test
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: test
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }}
- name: bat test run
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: run
args: --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} -- --paging=never --color=always --theme=ansi-dark Cargo.toml src/config.rs
- name: Check features regex-onig
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig
- name: Check features regex-onig,git
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git
- name: Check features regex-onig,paging
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,paging
- name: Check features regex-onig,git,paging
uses: actions-rs/cargo@v1
with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git,paging
- name: Upload build artifacts
uses: actions/upload-artifact@master
with:
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
- name: Package
shell: bash
run: |
ARCHIVE_DIR='${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
COPYRIGHT_YEARS="2018 - "$(date "+%Y")
# Binary
cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' "$ARCHIVE_DIR"
# `strip` binary (if needed)
if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" "$ARCHIVE_DIR/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}" ; fi
# Man page
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "$ARCHIVE_DIR"
# README, LICENSE and CHANGELOG files
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
# Autocompletion files
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish"
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.zsh"
# base compressed package
pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null
case ${{ matrix.job.target }} in
*-pc-windows-*) 7z -y a '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* | tail -2 ;;
*) tar czf '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* ;;
esac;
popd >/dev/null
# Debian package
if [ -n "${{ steps.vars.outputs.DPKG_NAME }}" ]; then
DPKG_DIR="${{ steps.vars.outputs.STAGING }}/dpkg"
# Binary
install -Dm755 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}"
if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}" ; fi
# Work out shared library dependencies
# dpkg-shlibdeps requires debian/control file. Dummy it and clean up
mkdir "./debian"
touch "./debian/control"
case ${{ matrix.job.target }} in
aarch64-*-linux-*) DEPENDS="$(dpkg-shlibdeps -l/usr/aarch64-linux-gnu/lib -O "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}" 2> /dev/null | sed 's/^shlibs:Depends=//')" ;;
arm-*-linux-*hf) DEPENDS="$(dpkg-shlibdeps -l/usr/arm-linux-gnueabihf/lib -O "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}" 2> /dev/null | sed 's/^shlibs:Depends=//')" ;;
i686-*-linux-*) DEPENDS="$(dpkg-shlibdeps -O "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}" 2> /dev/null | sed 's/^shlibs:Depends=//')" ;;
x86_64-*-linux-*) DEPENDS="$(dpkg-shlibdeps -O "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}" 2> /dev/null | sed 's/^shlibs:Depends=//')" ;;
esac;
rm -rf "./debian"
# Man page
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/bat.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
# Autocompletion files
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish"
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/bat.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}"
# README and LICENSE
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/README.md"
install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/LICENSE-MIT"
install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/LICENSE-APACHE"
install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/changelog"
gzip -n --best "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/changelog"
cat > "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/copyright" <<EOF
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: ${{ env.PROJECT_NAME }}
Source: ${{ env.PROJECT_HOMEPAGE }}
Files: *
Copyright: ${{ env.PROJECT_MAINTAINER }}
Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
License: Apache-2.0 or MIT
License: Apache-2.0
On Debian systems, the complete text of the Apache-2.0 can be found in the
file /usr/share/common-licenses/Apache-2.0.
License: MIT
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
.
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
EOF
chmod 644 "${DPKG_DIR}/usr/share/doc/${{ steps.vars.outputs.DPKG_BASENAME }}/copyright"
# control file
mkdir -p "${DPKG_DIR}/DEBIAN"
cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
Package: ${{ steps.vars.outputs.DPKG_BASENAME }}
Version: ${{ steps.vars.outputs.DPKG_VERSION }}
Section: utils
Priority: optional
Maintainer: ${{ env.PROJECT_MAINTAINER }}
Homepage: ${{ env.PROJECT_HOMEPAGE }}
Architecture: ${{ steps.vars.outputs.DPKG_ARCH }}
Depends: $DEPENDS
Provides: ${{ env.PROJECT_NAME }}
Conflicts: ${{ steps.vars.outputs.DPKG_CONFLICTS }}
Description: cat(1) clone with wings.
A cat(1) clone with syntax highlighting and Git integration.
EOF
# build dpkg
fakeroot dpkg-deb --build "${DPKG_DIR}" "${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.DPKG_NAME }}"
fi
- name: Publish archives and packages
uses: softprops/action-gh-release@v1
if: steps.vars.outputs.DEPLOY
with:
files: |
${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }}
${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.DPKG_NAME }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
coverage:
name: Code Coverage
runs-on: ${{ matrix.job.os }}
strategy:
fail-fast: true
matrix:
# job: [ { os: ubuntu-latest }, { os: macos-latest }, { os: windows-latest } ]
job:
- { os: ubuntu-latest , toolchain: nightly-2020-04-29 }
- { os: macos-latest , toolchain: nightly-2020-04-29 }
- { os: windows-latest , toolchain: nightly-2020-04-29-x86_64-pc-windows-gnu }
steps:
- uses: actions/checkout@v1
- name: Initialize workflow variables
id: vars
shell: bash
run: |
# toolchain
TOOLCHAIN="nightly" ## default to "nightly" toolchain
# * use requested TOOLCHAIN if specified
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
# * use requested TOOLCHAIN if specified
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
echo set-output name=TOOLCHAIN::${TOOLCHAIN}
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
# target-specific options
# * CODECOV_FLAGS
CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' )
echo set-output name=CODECOV_FLAGS::${CODECOV_FLAGS}
echo ::set-output name=CODECOV_FLAGS::${CODECOV_FLAGS}
- name: rust toolchain ~ install
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ steps.vars.outputs.TOOLCHAIN }}
override: true
profile: minimal # minimal component installation (ie, no documentation)
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
args: --no-fail-fast
env:
CARGO_INCREMENTAL: '0'
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads'
- name: Generate coverage data
id: coverage
uses: actions-rs/grcov@v0.1
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@v1
with:
file: ${{ steps.coverage.outputs.report }}
flags: ${{ steps.vars.outputs.CODECOV_FLAGS }}
name: codecov-umbrella
fail_ci_if_error: false
+2
View File
@@ -3,4 +3,6 @@
# Generated files
/assets/completions/bat.fish
/assets/completions/bat.zsh
/assets/manual/bat.1
/assets/metadata.yaml
+30 -9
View File
@@ -70,9 +70,6 @@
[submodule "assets/syntaxes/JavaScript (Babel)"]
path = assets/syntaxes/02_Extra/JavaScript (Babel)
url = https://github.com/babel/babel-sublime
[submodule "assets/syntaxes/Cabal"]
path = assets/syntaxes/02_Extra/Cabal
url = https://github.com/SublimeHaskell/SublimeHaskell
[submodule "assets/syntaxes/Dart"]
path = assets/syntaxes/02_Extra/Dart
url = https://github.com/guillermooo/dart-sublime-bundle
@@ -97,9 +94,6 @@
[submodule "assets/themes/sublime-snazzy"]
path = assets/themes/sublime-snazzy
url = https://github.com/greggb/sublime-snazzy
[submodule "assets/syntaxes/AsciiDoc"]
path = assets/syntaxes/02_Extra/AsciiDoc
url = https://github.com/SublimeText/AsciiDoc.git
[submodule "assets/syntaxes/Assembly (ARM)"]
path = assets/syntaxes/02_Extra/Assembly (ARM)
url = https://github.com/tvi/Sublime-ARM-Assembly
@@ -166,9 +160,6 @@
[submodule "assets/themes/Nord-sublime"]
path = assets/themes/Nord-sublime
url = https://github.com/crabique/Nord-plist.git
[submodule "assets/themes/solarized-sublime"]
path = assets/themes/solarized-sublime
url = https://github.com/paulcpederson/solarized-sublime.git
[submodule "assets/syntaxes/Vue"]
path = assets/syntaxes/02_Extra/Vue
url = https://github.com/vuejs/vue-syntax-highlight.git
@@ -176,3 +167,33 @@
[submodule "assets/syntaxes/CoffeeScript"]
path = assets/syntaxes/02_Extra/CoffeeScript
url = https://github.com/sustained/CoffeeScript-Sublime-Plugin
[submodule "assets/syntaxes/02_Extra/Stylus"]
path = assets/syntaxes/02_Extra/Stylus
url = https://github.com/billymoon/Stylus
[submodule "assets/themes/Solarized"]
path = assets/themes/Solarized
url = https://github.com/braver/Solarized
[submodule "assets/syntaxes/02_Extra/Fortran"]
path = assets/syntaxes/02_Extra/Fortran
url = https://github.com/315234/SublimeFortran
[submodule "assets/syntaxes/02_Extra/Email"]
path = assets/syntaxes/02_Extra/Email
url = https://github.com/mariozaizar/email.sublime-syntax.git
[submodule "assets/syntaxes/02_Extra/QML"]
path = assets/syntaxes/02_Extra/QML
url = https://github.com/skozlovf/Sublime-QML
[submodule "assets/syntaxes/02_Extra/AsciiDoc"]
path = assets/syntaxes/02_Extra/AsciiDoc
url = https://github.com/asciidoctor/sublimetext-asciidoc.git
[submodule "assets/themes/gruvbox"]
path = assets/themes/gruvbox
url = https://github.com/peaceant/gruvbox.git
[submodule "assets/syntaxes/02_Extra/GLSL"]
path = assets/syntaxes/02_Extra/GLSL
url = https://github.com/euler0/sublime-glsl
[submodule "assets/syntaxes/02_Extra/Nginx"]
path = assets/syntaxes/02_Extra/Nginx
url = https://github.com/brandonwamboldt/sublime-nginx
[submodule "assets/syntaxes/02_Extra/Apache"]
path = assets/syntaxes/02_Extra/Apache
url = https://github.com/colinta/ApacheConf.tmLanguage
-107
View File
@@ -1,107 +0,0 @@
language: rust
cache: cargo
matrix:
include:
# Stable channel.
- os: linux
rust: stable
env: TARGET=x86_64-unknown-linux-gnu
- os: linux
rust: stable
env:
- TARGET=x86_64-unknown-linux-musl
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
- os: linux
rust: stable
env: TARGET=i686-unknown-linux-gnu
- os: osx
rust: stable
env: TARGET=x86_64-apple-darwin
- os: linux
rust: stable
env:
- TARGET=arm-unknown-linux-gnueabihf
- CC_arm_unknown_linux_gnueabihf=/usr/bin/arm-linux-gnueabihf-gcc-4.8
- CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc-4.8
- os: linux
rust: stable
env:
- TARGET=aarch64-unknown-linux-gnu
- CC_aarch64-unknown-linux-gnu=/usr/bin/aarch64-linux-gnu-gcc-4.8
- CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc-4.8
# Minimum Rust supported channel.
- os: linux
rust: 1.36.0
env: TARGET=x86_64-unknown-linux-gnu
- os: linux
rust: 1.36.0
env:
- TARGET=x86_64-unknown-linux-musl
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
- os: osx
rust: 1.36.0
env: TARGET=x86_64-apple-darwin
# Disable nightly for now
# # Code formatting check
# - os: linux
# rust: nightly
# # skip the global install step
# install:
# - cargo install --debug --force rustfmt-nightly
# script: cargo fmt -- --check
sudo: required
before_install:
- ci/before_install.bash
env:
global:
# Default target on travis-ci.
# Used as conditional check in the install stage
- HOST=x86_64-unknown-linux-gnu
# Used on the deployment script
- PROJECT_NAME=bat
install:
# prevent target re-add error from rustup
- if [[ $TRAVIS_OS_NAME = linux && $HOST != $TARGET ]]; then rustup target add $TARGET; fi
script:
- ci/script.bash
before_deploy:
- bash ci/before_deploy.bash
deploy:
provider: releases
# NOTE updating the `api_key.secure`
# - go to: https://github.com/settings/tokens/new
# - generate new token using `public_repo` scope
# - encrypt it using: `travis encrypt API_KEY_HERE`
# - paste the output below
api_key:
secure: "GZL8nYk+/MZGEqejpP0UMMGVmwUEdxiF9CflFIGccu+/tznDyHnHOpyJmbH3M5IKWIxa7xFgqOE8pHuD4oQXt4mzyJGB0KMKKEFLW7ckbTYKya5bw0heKznaqGnS0Yz+vpfqYR25eiPFYCz7mDsGsCzH5QZqt3cdn9MDQGu1D0IaxPjuBNH3T9kBblR0ifBd3Diy0JYhiVcMSI3V1rkel18F1yBHO2GQ95hkWxVgjANQnefq5+zdzbx4ki539ewYENShA8N0w6ULJVY9LmWRWJIp90ggOD3JCH6Nz/fBpYBqwfABO6Dr7Csw7IRm7pM4IVkFZS1taiDYFX9thxZh3UTmI4YYtSTPxH9NGV47kxPipbf4vAXFwW+1VcHKMpBzz+5IVsHnk1Pfx9/GZsXbqXM3PUWCStec36Xtqh5vQapDKEg9khkEs4b1X7/E73gvpRuQl9gbnyufSVWgDsXIWqM+0aDbqQz1FpLmVxz6eij0cB9vR+8kbNoe/CEPHPO9ZllvAHseukOeHPzSBd8rILORXaaGmQausXz2wWgSsffUSYz4705P8joI0zFCfmkHjL+kA1ZUx5SxLCc1ID7CFFZChhAxHoPL7xc21snswwr8QeheERdwvuzKNaerBGZEw8dmMMx98YkjftIj65DDySr2mRZuufBQeQpmMhFyIT4="
# for uploading multiple files
file_glob: true
# NOTE explanation on each env variable
# - PROJECT_NAME: name of the project, set on the `env.global` above
# - TRAVIS_TAG: tag name that the build is being deployed for, usually the version number
# - TARGET: target triple of the build
file:
- $PROJECT_NAME-$TRAVIS_TAG-$TARGET.*
- $PROJECT_NAME*.deb
# don't delete artifacts from previous stage
skip_cleanup: true
on:
# deploy only if we push a tag
tags: true
# deploy only on stable channel that has TARGET env variable sets
condition: $TRAVIS_RUST_VERSION = stable && $TARGET != ""
notifications:
email:
on_success: never
+755
View File
@@ -0,0 +1,755 @@
# unreleased
## Features
## Bugfixes
## Other
## Syntaxes
## New themes
## `bat` as a library
## Packaging
# v0.16.0
## Features
- Added support for the `NO_COLOR` environment variable, see #1021 and #1031 (@eth-p)
- Added `-P` short flag to disable paging, see #1075 and #1082 (@LordFlashmeow)
- Added `--force-colorization`/`-f` flag to provide an alias for forced color and decoration output, see #1141 (@alexanderkarlis)
## Bugfixes
- Fixed non-printable characters display for redirected output, see #1061 (@gsomix)
- Handle file extension conflicts in `--list-languages`, see #1076 and #1135 (@Kienyew)
## Other
- Switched to "·" (U+00B7) Middle Dot from "•" (U+2022) Bullet for non-printing spaces, see #1056 and #1100 (@LordFlashmeow)
- Added zsh shell completion script, see #1136 (@Kienyew)
- Improved `--help` text (@sharkdp)
- Added custom languages/themes sections to manpage (@eth-p)
## Syntaxes
- Update AsciiDoc syntax, see #1034 (@rxt1077)
- GLSL (@caioalonso)
- Add Nginx and Apache config file syntax, see #1137 (@kjmph, @niklasmohrin)
- Use `fstab` syntax for `crypttab` files, see #1073 (@sharkdp)
- Support syntax highlighting for files in `$XDG_CONFIG_HOME/git/`, see #1191 (@ahmedelgabri)
## New themes
- Gruvbox, see #1069 (@kyleondy)
- base16-256 for [base16-shell](https://github.com/chriskempson/base16-shell) users, see #1111 (@mk12)
## `bat` as a library
- Add APIs to provide `Input` descriptions with `InputDescription` (@eth-p)
- Add function to directly provide `Input`s to `PrettyPrinter` (@eth-p)
- **Breaking:** `Input::theme_preview_file` is no longer available. (@eth-p)
## Packaging
- Removed build dependency on `liquid` (@sharkdp).
# v0.15.4
## Bugfixes
- Added missing Solarized themes, see #1027
- Fixed highlighting bug in Haskell source files, see #1026
# v0.15.3
## Bugfixes
- Cannot run `bat` with relative paths, see #1022
- bat mishighlights Users that start with digits in SSH config, see #984
## New syntaxes
- SML, see #1005 (@kopecs)
## Other
- Some syntaxes and themes have been updated to the latest version
# v0.15.2
## Bugfixes
- Fix syntax detection for files called 'rails', see #1008
- Fix potential errors with syntax detection for symlinked files, see #1001
- `--map-syntax` doesn't work with names provided through `--file-name` (@eth-p)
## Other
- Add padding above headers when not using a grid, see #968 and #981 (@pt2121)
- bat now prints an error if an invalid syntax is specified via `-l` or `--map-syntax`, see #1004 (@eth-p)
## `bat` as a library
- `PrettyPrinter::vcs_modification_markers` has been marked deprecated when building without the `git` feature, see #997 and #1020 (@eth-p, @sharkdp)
## Packaging
- Compilation problems with `onig_sys` on various platforms have been resolved by upgrading to `syntect 4.2`, which includes a new `onig` version that allows to build `onig_sys` without the `bindgen` dependency. This removes the need for `libclang(-dev)` to be installed to compile `bat`. Package maintainers might want to remove `clang` as a build dependency. See #650 for more details.
# v0.15.1
## Bugfixes
- Fix highlighting of Markdown files, see #963 and #977
- Fix `base16` theme (was broken since in v0.14), see #972, #934 and #979 (@mk12).
Users suffering from #865 ("no color for bat in ssh from a Windows client") can use the `ansi-dark` and `ansi-light` themes from now on.
## New syntaxes
- Fortran, see #957
- Email (@mariozaizar)
- QML, see #962 (@pylipp)
# v0.15.0
## Features
- Add a new `--diff`/`-d` option that can be used to only show lines surrounding
Git changes, i.e. added, removed or modified lines. The amount of additional
context can be controlled with `--diff-context=N`. See #23 and #940
## Bugfixes
- Error message printed in the middle of the output for another file, see #946
- Performance improvements when using custom caches (via `bat cache --build`): the `bat` startup time should now be twice as fast (@lzutao).
## Themes
- Updated version of the Solarized dark/light themes, see #941
## `bat` as a library
- There are a few changes in the "low level" API (the `Config` struct has changed and
the error handler needs a new `&mut dyn Write` argument). The high-level API is not
affected.
# v0.14.0
## Features
- Added a new `--file-name <name>…` option to overwrite the displayed filename(s)
in the header. This is useful when piping input into `bat`. See #654 and #892 (@neuronull).
- Added a new `--generate-config-file` option to create an initial configuration file
at the right place. See #870 (@jmick414)
## Bugfixes
- Performance problems with C# source code have been fixed, see #677 (@keith-hall)
- Performance problems with Makefiles have been fixed, see #750 (@keith-hall)
- Fix bug when highlighting Ruby files with unindented heredocs, see #914 (@keith-hall)
- A highlighting problem with Rust source code has been fixed, see #924 (@keith-hall)
- Windows: short files that do not require paging are displayed and then lost, see #887
- `--highlight-line` did not work correctly in combination with `--tabs=0` and `--wrap=never`,
see #937
## Other
- When saving/reading user-provided syntaxes or themes, `bat` will now maintain a
`metadata.yaml` file which includes information about the `bat` version which was
used to create the cached files. When loading cached files, we now print an error
if they have been created with an incompatible version. See #882
- Updated `liquid` dependency to 0.20, see #880 (@ignatenkobrain)
## `bat` as a library
- A completely new "high level" API has been added that is much more convenient
to use. See the `examples` folder for the updated code. The older "low level"
API is still available (basically everything that is not in the root `bat`
module), but has been refactored quite a bit. It is recommended to only use
the new "high level" API, if possible. This will be much easier to keep stable.
Note that this should still be considered a "beta" release of `bat`-as-a-library.
For more details and some screenshots of the example programs, see #936.
- Stripped out a lot of binary-only dependencies, see #895 and #899 (@dtolnay)
This introduces a `features = ["application"]` which is enabled by default and pulls in
everything required by `bat` the application. When depending on bat as a library, downstream
`Cargo.toml` should disable this feature to cut out inapplicable heavy dependencies:
``` toml
[dependencies]
bat = { version = "0.14", default-features = false }
```
Other optional functionality has also been put behind features: `paging` and `git` support.
- Allow using the library with older syntect, see #896 and #898 (@dtolnay)
## New syntaxes
- Rego, see #872 (@patrick-east)
- Stylo, see #917
# v0.13.0
## `bat` as a library
Beginning with this release, `bat` can be used as a library (#423).
This was a huge effort and I want to thank all people who made this possible: @DrSensor, @mitsuhiko, @mre, @eth-p!
- Initial attempt in #469 (@mitsuhiko)
- Second attempt, complete restructuring of the `bat` crate, see #679 (@DrSensor)
- Updates to example, public API, error handling, further refactoring: #693 #873 #875 (@sharkdp)
I want to stress that this is the very first release of the library. Things are very likely to change. A lot of things are still missing (including the documentation).
That being said, you can start using it! See the example programs in [`examples/`](https://github.com/sharkdp/bat/tree/master/examples).
You can see the API documentation here: https://docs.rs/bat/
## Features
- (**Breaking change**) Glob-based syntax mapping, see #877 and #592. With this change,
users need to update their bat config files (`bat --config-file`), if they have any `--map-syntax` settings
present.
The option now works like this:
```bash
--map-syntax <glob-pattern>:<syntax-name>
```
For more information, see the `--help` text, the man page or the README.
This new feature allows us to properly highlight files like:
* `/etc/profile`
* `~/.ssh/config`
- `--highlight-line` now accepts line ranges, see #809 (@lkalir)
- Proper wrapping support for output with wide Unicode characters, see #811 #787 and #815 (@Kogia-sima)
- A lot of updates to existing syntaxes via #644 (@benwaffle, @keith-hall)
- `BAT_CACHE_PATH` can be used to place cached `bat` assets in a non-standard path, see #829 (@neuronull)
- Support combination of multiple styles at the same time, see #857 (@aslpavel)
## Bugfixes
- Do not pass '--no-init' on newer less versions, see #749 and #786 (@sharkdp)
- 'bat cache' still takes precedence over existing files, see #666 (@sharkdp)
- `.sc` files should be treated as scala files, see #443 (@benwaffle)
- Allow underscores and dashes in page names, see #670 (@LunarLambda)
- Keep empty lines empty, see #601 (@mbarbar)
- Wrapping does not work when piping, see #758 (@fusillicode, @allevo, @gildo)
- Allow for non-unicode filenames, see #225 (@sharkdp)
- Empty file without header produces incomplete grid, see #798 (@eth-p)
- Files named `build` don't respect shebang lines, see #685 (@sharkdp)
## Other
- Parametrizable names for man page and shell completion files, see #659 #673 #656 (@eth-p)
- Enabled LTO, making `bat` about 10% faster, see #719 (@bolinfest, @sharkdp)
- Suggestions non how to configure `bat` for MacOS dark mode, see README (@jerguslejko)
- Extended ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section (@eth-p)
- Updated [instrutions on how to use `bat` as a `man`-pager](https://github.com/sharkdp/bat#man), see #652, see #667 (@sharkdp)
- Add section concerning file encodings, see #688 and #568 (@sharkdp)
- Updated sort order of command-line options in `--help` text and manpage, see #653 and #700 (@hrlmartins)
- Updates to the man page syntax, see #718 (@sharkdp)
- Japanese documentation updates, see #863 (@k-ta-yamada, @sorairolake and @wt-l00)
- Accept "default" as a theme, see #757 (@fvictorio)
- Updated Windows installation instructions, see #852 (@sorenbug)
- Updated man page, see #573 (@sharkdp)
## New syntaxes
- Jinja2, see #648 (@Martin819)
- SaltStack SLS, see #658 (@Martin819)
- `/etc/fstab`, see #696 (@flopp and @eth-p)
- `/etc/group` and `/etc/passwd`, see #698 (@argentite)
- `/proc/cpuinfo` and `/proc/meminfo`, see #593 (@sharkdp)
- Nim, see #542 (@sharkdp)
- Vue, see #826 (@chaaaaarlotte)
- CoffeScript, see #833 (@sharkdp)
## New themes
- Dracula, see #687 (@clarfon)
- Nord, see #760 (@crabique)
- Solarized light and dark, see #768 (@hakamadare)
## Packaging
- `bat` is now in the official Ubuntu and Debian repositories, see #323 and #705 (@MarcoFalke)
- `bat` can now be installed via MacPorts, see #675 (@bn3t)
- Install fish completions into 'vendor_completions.d', see #651 (@sharkdp)
## Thanks
- To @eth-p for joining me as a maintainer! I'm very grateful for all the work you put into
managing and responding to issues, improving our deployment, adding PR/issue templates (#837) as
well as fixing bugs and implementing new features.
# v0.12.1
## Bugfixes
- Fixes a bug for older Windows versions (*"The procedure entry point `CreateFile2` could not be located"*), see #643 (@rivy)
# v0.12.0
## Features
- Binary file content can now be viewed with `bat -A`, see #623, #640 (@pjsier and @sharkdp)
- `bat` can now be used as a man pager. Take a look at the README and #523 for more details.
- Add new style component to separate multiple `--line-range`s, see #570 (@eth-p)
- Added `-L` as an alias for `--list-languages`
## Bugfixes
- Output looks unbalanced when using '--style=grid,numbers' without 'header', see #571 (@eth-p)
- issues with filenames starting with "cache", see #584
- Can't build cache with new theme without creating cache dir, see #576 (@frm)
- `--terminal-width -10` is parsed incorrectly, see #611
## Other
- Added fish completions to DEB package, see #554
## New syntaxes
- Emacs Org mode, see #36 (@bricewge)
- `requirements.txt`
- DotENV `.env`
- SSH config syntax (`-l ssh_config`), see #582 (@issmirnov)
- `/etc/hosts`, see #583 (@issmirnov)
- GraphQL, see #625 (@dandavison)
- Verilog, see #616
- SCSS and Sass, see #637
- `strace` syntax, see #599
## Packaging
- `bat` is now in the official Gentoo repositories, see #588 (@toku-sa-n)
- `bat` is now in the official Alpine Linux repositories, see #586 (@5paceToast)
- `bat` is in the official Fedora repositories, see #610 (@ignatenkobrain)
# v0.11.0
## Features
- Three new special color themes are available: `ansi-light`, `ansi-dark` and `base16`. These
are useful for people that often switch from dark to light themes in their terminal emulator
or for people that want the colors to match their terminal theme colors. For more details,
see #543 and #490 (@mk12, implementation idea by @trishume)
- Hand-written auto completion script for Fish shell, see #524 and #555 (@ev-dev and @eth-p)
- The `-p`/`--plain` option can now be used twice (typically `-pp`). The first `-p` switches the
`--style` to "plain". The second `-p` disables the pager. See #560 and #552 (@eth-p)
## Bugfixes
- Do not replace arguments to `less` when using `--pager`, see #509
- Binary files will now be indicated by a warning in interactive mode, see #530 #466 #550 (@maxfilov)
- Empty files are (once again) printed with a single header line, see #504 and #566 (@reidwagner
and @sharkdp)
- `--terminal-width=0` is now disallowed, see #559 (@eth-p)
- Accidental printing of files named `cache`, see #557
## Other
- New integration tests, see #500 and #502 (@reidwagner and @sharkdp)
- New ["Integration with other tools"](https://github.com/sharkdp/bat#integration-with-other-tools) section in the README.
- Migrated to Rust 2018 (@expobrain)
## New syntaxes
- F# syntax has been updated, see #531 (@stroborobo)
- Fish shell, see #548 (@sanga)
## Packaging
- `bat` is now available on Chocolatey, see #541 (@rasmuskriest)
# v0.10.0
## Features
- Added new `--highlight-line <N>` option, see #453, #346 and #175 (@tskinn and @sharkdp)
## Changes
- **Change the default configuration directory on macOS** to `~/.config/bat`, see #442 (@lavifb). If you are on macOS, you need to copy your configuration directory from the previous place (`~/Library/Preferences/bat`) to the new place (`~/.config/bat`).
- Completely disabled the generation of shell completion files, see #372
- Properly set arguments to `less` if `PAGER` environment variable contains something like `less -F` (which is missing the `-R` option), see #430 (@majecty)
- Report the name of missing files, see #444 (@ufuji1984)
- Don't start pager if file doesn't exist, see #387
- Rename `bat cache --init` to `bat cache --build`, see #498
- Move the `--config-dir` and `--cache-dir` options from `bat cache` to `bat` and hide them from the help text.
## Bugfixes
- Blank line at the end of output when using `--style=plain`, see #379
- EOF must be sent twice on stdin if no other input is sent, see #477 (@reidwagner)
## New syntaxes
- Twig (@ahmedelgabri)
- `.desktop` files (@jleclanche)
- AsciiDoc (@markusthoemmes)
- Assembly (x86_64 and ARM)
- Log files (@caos21)
- Protobuf and ProtobufText (@caos21)
- Terraform (@caos21)
- Jsonnet (@hfm)
- Varlink (@haraldh)
## Other
- Added Japanese version of README (@sh-tech and @object1037)
- Code improvements (@barskern)
# v0.9.0
## Features
- A new `-A`/`--show-all` option has been added to show and highlight non-printable characters (in analogy to GNU `cat`s option):
![](https://camo.githubusercontent.com/c3e769482ef3184f6be6adaa34bdc8d19c378254/68747470733a2f2f692e696d6775722e636f6d2f324b54486859542e706e67)
see #395 and #381 for more details.
- Added `--pager` option (to configure the pager from the configuration file), see #362 (@majecty)
- Added `BAT_CONFIG_PATH` environment variable to set a non-default path for `bat`s configuration file, see #375 (@deg4uss3r)
- Allow for multiple occurences of `--style` to allow for the configuration
of styles from the config file, see #367 (@sindreij)
- Allow for multiple `--line-range` arguments, see #23
- The `--terminal-width` option can now also accept offsets, see #376
## Changes
- Use of italics is now *disabled by default* (see #389 for details). They can be
re-enabled by adding `--italic-text=always` to your configuration file.
- The default tab-width has been set to 4.
- Added new "Sublime Snazzy" theme.
- Shell completions are currently *not* shipped anymore, see #372 for details.
## Bugfixes
- Avoid endless recursion when `PAGER="bat"`, see #383 (@rodorgas)
## Other
- `bat` is now available on openSUSE, see #405 (@dmarcoux)
- Added section about the new configuration file in the README (@deg4uss3r)
- Chinese translation of README (@chinanf-boy)
- Re-written tests for `--tabs` (@choznerol)
- Speed up integration tests, see #394
# v0.8.0
## Features
- Support for a configuration file with the following simple format:
```bash
--tabs=4
--theme="Sublime Snazzy"
# A line-comment
--map-syntax .ignore:.gitignore
--map-syntax PKGBUILD:bash
--map-syntax Podfile:ruby
# Flags and options can also be on a single line:
--wrap=never --paging=never
```
The configuration file path can be accessed via `bat --config-file`. On Linux,
it is stored in `~/.config/bat/config`.
- Support for the `BAT_OPTS` environment variable with the same format as specified
above (in a single line). This takes precedence over the configuration file.
See also #310.
- Support for custom syntax mappings via the `-m`/`--max-syntax` option.
This allows users to (re)map certain file extensions or file names to an existing syntax:
``` bash
bat --map-syntax .config:json ...
```
The option can be use multiple times. Note that you can easily make these mappings permanent by using bats new configuration file.
See #169
- Support pager command-line arguments in `PAGER` and `BAT_PAGER`, see #352 (@Foxboron)
- Add support for wildcards in Windows CMD, see #309 (@zxey)
- First-line syntax detection for all input types, see #205
- Encoding support for UTF-16LE and UTF-16BE, see #285
- New syntaxes: Robot framework (@sanga)
## Changes
- Binary files are now detected and not displayed when the output goes to an interactive terminal, see #205
## Bugfixes
- JavaDoc comments break syntax highlighting in .java files, see #81
- Bat Panics on Haskell Source Code, see #314
## Other
- Better `-h` and `--help` texts.
- Updated documentation on how to configure `bat`s pager
- Updated documentation for light backgrounds, see #328 (@russtaylor)
- Generate shell completions during build, see #115 (@davideGiovannini)
- A lot of new tests have been written
- `bat` is now available via [Termux](https://termux.com/), see #341 (@fornwall)
- `bat` is now available via [nix](https://nixos.org/nix), see #344 (@mgttlinger)
- `bat` is now available via [Docker](https://hub.docker.com/r/danlynn/bat/), see #331 (@danlynn)
# v0.7.1
## Features
- Use the `ansi_colours` package by @mina86 for better true-color approximation on 8 bit color terminals, see #319 and #202.
## Bugfixes
- Bat Panics on Haskell Source Code, see #314
- Disable wrapping when `--style=plain`/`-p` is used, see #289
## Other
- Added Ansible install instructions (@aeimer)
- Added section about Cygwin to the README (@eth-p)
# v0.7.0
## Features
- Tabs are now (optionally) expanded to spaces. This can be controlled with the new
`--tabs` command-line option or the `BAT_TABS` environment variable. The
new feature also closes two bugs #166 and #184. For more information, see #302 (@eth-p).
- Added support for the `BAT_STYLE` environment variable, see #208 (@ms2300)
- Added `OneHalf` theme for terminals with a light-gray background, see #256
- Added new syntaxes for CSV, JSX in JavaScript and TypeScript, Cabal, Dart,
F#, PureScript, Swift, Crystal, PowerShell (Many Thanks to @tobenna and @mimadrid)
## Changes
- Query `git diff` only when needed, see #303 (@ShikChen)
- Disable wrapping when `--plain` is used, see #289 (@eth-p)
## Bugfixes
- Can read files named `cache`, see #275 (@BK1603)
- A lot of bugfixes for Windows, see #252, #264
- Detect `less` reliably and in a portable way, see #271 and #290 (@Aankhen)
- last decoration line is not formatted properly with `--wrap never`, see #299 (@Rogach)
- Do not show file header for directories, see #292
## Other
- Enabled a new `aarch64` build target, see #258 (@rachitchokshi)
- Provide Debian packages for `armhf`, see #280 (@rachitchokshi)
- Added README section about "`bat` on Windows" (@Aankhen)
- Windows installation via scoop (@meltinglava)
# v0.6.1
## Bugfixes
- Fixed panic when running `bat --list-languages | head`, see #232 (@mchlrhw)
- Respect `--color` settings for `--list-themes` and `--list-languages`, see #233
- Git modifications now work on Windows
## Other
- There will be auto-generated Windows releases, starting with this version (@anykao)
# v0.6.0
## Features
- The `--list-themes` option now shows a preview for each highlighting theme (@ms2300)
- Added `-p`/`--plain` as an alias for `--style=plain`, see #212 (@ms2300)
- Major refactorings, enabling some progress on #150. In non-interactive mode, `bat` will now copy input bytes 1:1.
- New languages: Elm, Kotlin, Puppet, TypeScript, see #215 #216 #217 #218
- New syntax highlighting theme: zenburn (@colindean)
## Changes
- New themes in `$BAT_CONFIG_DIR/themes` are now loaded *in addition* to
the default themes (they may also override), see #172
- The `Default.tmTheme` symlink is not necessary anymore.
## Bugfixes
* Using `bat cache --init` leads to duplicated syntaxes, see #206
## Other
* Extended and cleaned-up `--help` text.
* Added initial version of a man page, see #52
* New README sections: *Development* and *Troubleshooting*, see #220
# v0.5.0
## Features
- Added `--line-range n:m` option to print a range of lines, see #159 (@tskinn)
- The syntax highlighting theme can now be controlled by the `BAT_THEME` environment variable, see [README](https://github.com/sharkdp/bat#highlighting-theme) and #177 (@mandx)
- The `PAGER` and `BAT_PAGER` environment variables can be used to control the pager that `bat` uses, see #158 and the [new README section](https://github.com/sharkdp/bat#using-a-different-pager)
- Added syntax highlighting for Nix, see #180
- Added syntax highlighting for AWK (Gert Hulselmans)
## Changes
- The customization of syntax sets and theme sets is now separated. Syntax definitions are now loaded *in addition* to the ones that are stored in the `bat` binary by default. Please refer to these new sections in the README: [Adding new syntaxes](https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions), [Adding new themes](https://github.com/sharkdp/bat#adding-new-themes), also see #172
- The color for the filename is now the default foreground color. The colors for the grid and the line numbers is now determined from the syntax highlighting theme, which now also works for light backgrounds, see #178.
## Bugfixes
- Escape Sequences get partially stripped, see #182 (@eth-p)
- Use separate Git repository for snapshot testing, see #165 and #161
- Markdown breaking on JavaScript, see #183
## Other
- Binaries for armv7 are now provided, see #196
- `bat` is now in the official [Arch package repositories](https://www.archlinux.org/packages/community/x86_64/bat/).
- Optimizations in the RGB => 8-bit conversion (@mina86)
# v0.4.1
(this is just a small bugfix release, see 0.4.0 for all features and changes)
## Bugfixes
- Fix problem with `cargo test` when `bat` is not checked out in a Git repository, see #161
# v0.4.0
## Features
* Support for line-wrapping, see #54 and #102 (@eth-p)
* New and updated `--style` parameter, see #74 and README (@pitkley)
* Added `--theme` and `--list-themes` options, see #89 (@rleungx)
* Added syntax highlighting for: Julia (@iamed2), Dockerfiles, VimL, CMake, INI, Less
* Added a few popular Sublime Text highlighting themes, see #133
* Support for bold, italic and underline font styles, see #96
* Support for 32bit systems is now available, see #84
* Added `-u` and `-n` options, see #134
* ANSI color support on Windows 10
## Changes
* The customization folder for own syntaxes has been renamed from `syntax` to `syntaxes`, see README.
* Changed Markdown syntax to the default Sublime Text syntax, see #157
* Sorted language listing (@rleungx)
* Command line arguments like `--theme` or `--color` can now override themselves.
* Improved `--help` text.
## Bugfixes
- Fixed crash for (really) small terminal sizes, see #117 (@eth-p)
- Syntax detection for `.bashrc`, `CMakeLists.txt` etc., see #100
- Properly handle lines with invalid UTF-8, see #7 (@BrainMaestro)
- Better error handling, see #17 (@rleungx and @sharkdp)
- Proper handling of UTF-8 characters in `less`, see #98 (@ghuls)
- Build fix on nightly, see #148 (@tathanhdinh)
## Other
- [Comparison with alternative projects](https://github.com/sharkdp/bat/blob/master/doc/alternatives.md).
- New "bat" logo in the README, see #119 (@jraulhernandezi)
- Output test cases (@BrainMaestro)
- Lots of great refactoring work (@BrainMaestro)
# v0.3.0
## Features
* Automatic paging by integrating with `less`, see #29 (@BrainMaestro)
* Added support for reading from standard input, see #2
* Added support for writing to non-interactive terminals (pipes, files, ..); new
`--color=auto/always/never` option, see #26 (@BrainMaestro)
* Added `--list-languages` option to print all available syntaxes, see #69 (@connorkuehl)
* New option to specify the syntax via `-l`/`--language`, see #19 (@BrainMaestro)
* New option to control the output style (`--style`), see #5 (@nakulcg)
* Added syntax highlighting support for TOML files, see #37
## Changes
* The `init-cache` sub-command has been removed. The cache can now be controlled via
`bat cache`. See `bat cache -h` for all available commands.
## Bug fixes
* Get git repository from file path instead of current directory, see #22 (@nakulcg)
* Process substitution can now be used with bat (`bat <(echo a) <(echo b)`), see #80
## Thanks
I'd like to say a big THANK YOU to all contributors and everyone that has given us
some form of feedback.
Special thanks go to @BrainMaestro for his huge support with new features, bug reports
and code reviews!
# v0.2.3
- Added a new statically linked version of bat (`..-musl-..`)
# v0.2.2
- Remove openssl dependency completely, see #30.
# v0.2.1
- Added Elixir syntax, see #25.
- Use libcurl-openssl instead of libcurl-gnutls, see #30.
# v0.2.0
- Support for custom syntaxes, add 'Markdown extended' theme
- Bugfix: Git modifications not shown from child folder
# v0.1.0
Initial release
Generated
+358 -674
View File
File diff suppressed because it is too large Load Diff
+38 -15
View File
@@ -7,7 +7,7 @@ license = "MIT/Apache-2.0"
name = "bat"
readme = "README.md"
repository = "https://github.com/sharkdp/bat"
version = "0.13.0"
version = "0.16.0"
exclude = [
"assets/syntaxes/*",
"assets/themes/*",
@@ -15,48 +15,71 @@ exclude = [
build = "build.rs"
edition = '2018'
[features]
default = ["application"]
# Feature required for bat the application. Should be disabled when depending on
# bat as a library.
application = [
"atty",
"clap",
"dirs",
"git",
"lazy_static",
"paging",
"wild",
"regex-onig",
]
git = ["git2"] # Support indicating git modifications
paging = ["shell-words"] # Support applying a pager on the output
regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine
regex-fancy = ["syntect/regex-fancy"] # Use the rust-only "fancy-regex" engine
[dependencies]
atty = "0.2.14"
atty = { version = "0.2.14", optional = true }
ansi_term = "^0.12.1"
ansi_colours = "^1.0"
console = "0.10"
dirs = "2.0"
lazy_static = "1.4"
wild = "2.0"
console = "0.12.0"
dirs = { version = "3.0", optional = true }
lazy_static = { version = "1.4", optional = true }
wild = { version = "2.0", optional = true }
content_inspector = "0.2.4"
encoding = "0.2"
shell-words = "0.1.0"
unicode-width = "0.1.7"
shell-words = { version = "1.0.0", optional = true }
unicode-width = "0.1.8"
globset = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
semver = "0.11"
path_abs = { version = "0.5", default-features = false }
[dependencies.git2]
version = "0.13"
optional = true
default-features = false
features = []
[dependencies.syntect]
version = "3.3.0"
version = "4.4.0"
default-features = false
features = ["parsing", "yaml-load", "dump-load", "dump-create"]
[dependencies.clap]
version = "2.33"
optional = true
default-features = false
features = ["suggestions", "color", "wrap_help"]
[dependencies.error-chain]
version = "0.12"
default-features = false
features = []
[dev-dependencies]
tempdir = "0.3"
assert_cmd = "0.12.0"
assert_cmd = "1.0.1"
predicates = "1.0.5"
[build-dependencies]
clap = "2.33"
liquid = "0.19"
lazy_static = "1.4"
clap = { version = "2.33", optional = true }
[profile.release]
lto = true
codegen-units = 1
+88 -61
View File
@@ -1,7 +1,6 @@
<p align="center">
<img src="doc/logo-header.svg" alt="bat - a cat clone with wings"><br>
<a href="https://travis-ci.org/sharkdp/bat"><img src="https://travis-ci.org/sharkdp/bat.svg?branch=master" alt="Build Status"></a>
<a href="https://ci.appveyor.com/project/sharkdp/bat"><img src="https://ci.appveyor.com/api/projects/status/cptsmtbiwbnr2vhf/branch/master?svg=true"></a>
<a href="https://github.com/sharkdp/bat/actions?query=workflow%3ACICD"><img src="https://github.com/sharkdp/bat/workflows/CICD/badge.svg" alt="Build Status"></a>
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
A <i>cat(1)</i> clone with syntax highlighting and Git integration.
@@ -12,8 +11,8 @@
<a href="#how-to-use">How To Use</a> •
<a href="#installation">Installation</a> •
<a href="#customization">Customization</a> •
<a href="#project-goals-and-alternatives">Project goals, alternatives</a>
Translation [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="doc/README-ja.md">日本語</a>][<a href="doc/README-ko.md">한국어</a>]
<a href="#project-goals-and-alternatives">Project goals, alternatives</a><br>
[<a href="https://github.com/chinanf-boy/bat-zh">中文</a>] [<a href="doc/README-ja.md">日本語</a>] [<a href="doc/README-ko.md">한국어</a>] [<a href="doc/README-ru.md">Русский</a>]
</p>
### Syntax highlighting
@@ -39,7 +38,7 @@ characters:
### Automatic paging
`bat` can pipe its own output to `less` if the output is too large for one screen.
`bat` can pipe its own output to a pager (e.g `less`) if the output is too large for one screen.
### File concatenation
@@ -62,7 +61,9 @@ Display multiple files at once
> bat src/*.rs
```
Read from stdin, determine the syntax automatically
Read from stdin, determine the syntax automatically (note, highlighting will
only work if the syntax can be determined from the first line of the file,
usually through a shebang such as `#!/bin/sh`)
```bash
> curl -s https://sh.rustup.rs | bat
@@ -157,7 +158,9 @@ 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/Manpage.sublime-syntax) is developed in this repository and still needs some work.
Note that the [Manpage syntax](assets/syntaxes/02_Extra/Manpage.sublime-syntax) is developed in this repository and still needs some work.
Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145) with Mandocs `man` implementation.
#### `prettier` / `shfmt` / `rustfmt`
@@ -168,19 +171,36 @@ The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### On Ubuntu
### On Ubuntu (using `apt`)
*... and other Debian-based Linux distributions.*
You can install [the Ubuntu `bat` package](https://packages.ubuntu.com/eoan/bat) or [the Debian `bat` package](https://packages.debian.org/sid/bat) since Ubuntu Eoan 19.10 or Debian unstable sid.
`bat` is making its way through the [Ubuntu](https://packages.ubuntu.com/eoan/bat) and
[Debian](https://packages.debian.org/sid/bat) package release process, and is available
for Ubuntu as of Eoan 19.10. On Debian `bat` is currently only available on the unstable
"Sid" branch.
If your Ubuntu/Debian installation is new enough you can simply run:
```bash
apt install bat
```
If you want to run the latest release of bat or if you are on older versions of Ubuntu/Debian, download the latest `.deb` package from the [release page](https://github.com/sharkdp/bat/releases)
and install it via:
If you install `bat` this way, please note that the executable may be installed as `batcat` instead of `bat` (due to [a name
clash 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:
``` bash
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
```
### On Ubuntu (using most recent `.deb` packages)
*... and other Debian-based Linux distributions.*
If the package has not yet been promoted to your Ubuntu/Debian installation, or you want
the most recent release of `bat`, download the latest `.deb` package from the
[release page](https://github.com/sharkdp/bat/releases) and install it via:
```bash
sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
sudo dpkg -i bat_0.16.0_amd64.deb # adapt version number and architecture
```
### On Alpine Linux
@@ -275,6 +295,10 @@ port install bat
There are a few options to install `bat` on Windows. Once you have installed `bat`,
take a look at the ["Using `bat` on Windows"](#using-bat-on-windows) section.
#### Prerequisites
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
#### With Chocolatey
You can install `bat` via [Chocolatey](https://chocolatey.org/packages/Bat):
@@ -289,50 +313,12 @@ You can install `bat` via [scoop](https://scoop.sh/):
scoop install bat
```
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
#### From prebuilt binaries:
You can download prebuilt binaries from the [Release page](https://github.com/sharkdp/bat/releases),
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
### Via Docker
There is a [Docker image](https://hub.docker.com/r/danlynn/bat/) that you can use to run `bat` in a container:
```bash
docker pull danlynn/bat
alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat'
```
### Via Ansible
You can install `bat` with [Ansible](https://www.ansible.com/):
```bash
# Install role on local machine
ansible-galaxy install aeimer.install_bat
```
```yaml
---
# Playbook to install bat
- host: all
roles:
- aeimer.install_bat
```
- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat)
- [GitHub](https://github.com/aeimer/ansible-install-bat)
This should work with the following distributions:
- Debian/Ubuntu
- ARM (eg. Raspberry PI)
- Arch Linux
- Void Linux
- FreeBSD
- MacOS
### From binaries
Check out the [Release page](https://github.com/sharkdp/bat/releases) for
@@ -341,14 +327,15 @@ 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.36 or
If you want to build `bat` from source, you need Rust 1.40 or
higher. You can then use `cargo` to build everything:
```bash
cargo install bat
cargo install --locked bat
```
On some platforms, you might need to install `llvm` and/or `libclang-dev`.
Note that addition 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`).
## Customization
@@ -372,6 +359,26 @@ light background, some themes like `GitHub` or `OneHalfLight` will work better f
You can also use a custom theme by following the
['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes).
### 8-bit themes
`bat` has four themes that always use [8-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors),
even when truecolor support is available:
- `ansi-dark` looks decent on any terminal with a dark background. It uses 3-bit colors: black, red,
green, yellow, blue, magenta, cyan, and white.
- `ansi-light` is like `ansi-dark`, but for terminals with a light background.
- `base16` is designed for [base16](https://github.com/chriskempson/base16) terminal themes. It uses
4-bit colors (3-bit colors plus bright variants) in accordance with the
[base16 styling guidelines](https://github.com/chriskempson/base16/blob/master/styling.md).
- `base16-256` is designed for [base16-shell](https://github.com/chriskempson/base16-shell).
It replaces certain bright colors with 8-bit colors from 16 to 21. **Do not** use this simply
because you have a 256-color terminal but are not using base16-shell.
Although these themes are more restricted, they have two advantages over truecolor themes:
- They harmonize better with other terminal software using 3-bit or 4-bit colors.
- When you change your terminal theme, `bat` output already on the screen will update to match.
### Output style
You can use the `--style` option to control the appearance of `bat`s output.
@@ -461,11 +468,21 @@ If you want to enable mouse-wheel scrolling on older versions of `less`, you can
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.
### Indentation
`bat` expands tabs to 4 spaces by itself, not relying on the pager. To change this, simply add the
`--tabs` argument with the number of spaces you want to be displayed.
**Note**: Defining tab stops for the pager (via the `--pager` argument by `bat`, or via the `LESS`
environment variable for `less`) won't be taken into account because the pager will already get
expanded spaces instead of tabs. This behaviour is added to avoid indentation issues caused by the
sidebar. Calling `bat` with `--tabs=0` will override it and let tabs be consumed by the pager.
### Dark mode
If you make use of the dark mode feature in macOS, you might want to configure `bat` to use a different
theme based on the OS theme. The following snippet uses the `default` theme when in the light mode
and the `GitHub` theme when in the dark mode.
theme based on the OS theme. The following snippet uses the `default` theme when in the _dark mode_
and the `GitHub` theme when in the _light mode_.
```bash
alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)"
@@ -485,6 +502,11 @@ non-default location of the configuration file:
export BAT_CONFIG_PATH="/path/to/bat.conf"
```
A default configuration file can be created with the `--generate-config-file` option.
```bash
bat --generate-config-file
```
### Format
The configuration file is a simple list of command line arguments. Use `bat --help` to see a full list of possible options and values. In addition, you can add comments by prepending a line with the `#` character.
@@ -511,6 +533,10 @@ Example configuration file:
`bat` mostly works out-of-the-box on Windows, but a few features may need extra configuration.
### Prerequisites
You will need to install the [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) package.
### Paging
Windows only includes a very limited pager in the form of `more`. You can download a Windows binary
@@ -553,9 +579,10 @@ bat() {
### Terminals & colors
`bat` handles terminals *with* and *without* truecolor support. However, the colors in the syntax
highlighting themes are not optimized for 8-bit colors and it is therefore strongly recommended
that you use a terminal with 24-bit truecolor support (`terminator`, `konsole`, `iTerm2`, ...).
`bat` handles terminals *with* and *without* truecolor support. However, the colors in most syntax
highlighting themes are not optimized for 8-bit colors. It is therefore strongly recommended
that you use a terminal with 24-bit truecolor support (`terminator`, `konsole`, `iTerm2`, ...),
or use one of the basic [8-bit themes](#8-bit-themes) designed for a restricted set of colors.
See [this article](https://gist.github.com/XVilka/8346728) for more details and a full list of
terminals with truecolor support.
@@ -594,11 +621,11 @@ cargo build --bins
cargo test
# Install (release version)
cargo install
cargo install --locked
# Build a bat binary with modified syntaxes and themes
bash assets/create.sh
cargo install -f
cargo install --locked --force
```
## Maintainers
@@ -621,6 +648,6 @@ There are a lot of alternatives, if you are looking for similar programs. See
## License
Copyright (c) 2018-2020 [bat-developers](https://github.com/sharkdp/bat).
`bat` is distributed under the terms of both the MIT License and the Apache License 2.0.
`bat` is made available under the terms of either the MIT License or the Apache License 2.0, at your option.
See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details.
-49
View File
@@ -1,49 +0,0 @@
environment:
global:
TARGET: x86_64-pc-windows-msvc
RUST_VERSION: stable
CRATE_NAME: bat
CARGO_HOME: "c:\\cargo"
RUSTUP_HOME: "c:\\rustup"
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init.exe -y --default-host %TARGET%
- set PATH=%PATH%;C:\cargo\bin
- rustc -Vv
- cargo -V
build: false
test_script:
- cargo test --target %TARGET% --verbose
- cargo run --target %TARGET% -- src/bin/bat/main.rs README.md --paging=never
before_deploy:
# Generate artifacts for release
- cargo build --bins --release --verbose
- ps: ci\before_deploy.ps1
deploy:
description: 'Automatically deployed release'
artifact: /.*\.zip/
# Here's how:
# - Go to 'https://github.com/settings/tokens/new' and generate a Token with only the
# `public_repo` scope enabled
# - Then go to 'https://ci.appveyor.com/tools/encrypt' and enter the newly generated token.
# - Enter the "encrypted value" below
auth_token:
secure: oO4/J+hcFXgXcEqEc8gzlQNqLG0IxU78s4EyH+uczGdsyWajb3yipxPR6nXUvmoj
provider: GitHub
on:
RUST_VERSION: stable
appveyor_repo_tag: true
cache:
- C:\Users\appveyor\.cargo\registry
- target
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
+11
View File
@@ -31,11 +31,22 @@ themes (`bat cache --clear`).
The following files have been manually modified after converting from a `.tmLanguage` file:
* `Apache.sublime_syntax`=> removed `.conf` and `.CONF` file types.
* `Dart.sublime-syntax` => removed `#regex.dart` include.
* `INI.sublime-syntax` => added `.hgrc`, `hgrc`, and `desktop` file types.
* `Org mode.sublime-syntax` => removed `task` file type.
* `SML.sublime_syntax` => removed `ml` file type.
### Non-submodule additions
* `Assembly (x86_64)` has been manually added from https://github.com/13xforever/x86-assembly-textmate-bundle due to `git clone` recursion problems
* `Nim.sublime-syntax` has been added manually from https://github.com/getzola/zola/blob/master/sublime_syntaxes/Nim.sublime-syntax as there was no suitable Git repository for it. The original syntax seems to originate from https://github.com/Varriount/NimLime
* `Rego.sublime-syntax` has been added manually from https://github.com/open-policy-agent/opa/blob/master/misc/syntax/sublime/rego.sublime-syntax
as it is not kept in a standalone repository. The file is generated from
https://github.com/open-policy-agent/opa/blob/master/misc/syntax/textmate/Rego.tmLanguage
* `SML.sublime_syntax` has been added manually from
https://github.com/seanjames777/SML-Language-Definitiona as it is not
kept in a standalone repository. The file generated is from
https://github.com/seanjames777/SML-Language-Definition/blob/master/sml.tmLanguage
* `Cabal.sublime_syntax` has been added manually from
https://github.com/SublimeHaskell/SublimeHaskell/ - we don't want to include the whole submodule because it includes other syntaxes ("Haskell improved") as well.
+2
View File
@@ -52,6 +52,8 @@ complete -c {{PROJECT_EXECUTABLE}} -l paging -xka "auto never always" -d "Specif
complete -c {{PROJECT_EXECUTABLE}} -s p -l plain -d "Only show plain style, no decorations. Alias for '--style=plain'" -n "not __fish_seen_subcommand_from cache"
complete -c {{PROJECT_EXECUTABLE}} -s P -d "Disable paging. Alias for '--paging=never'" -n "not __fish_seen_subcommand_from cache"
complete -c {{PROJECT_EXECUTABLE}} -s A -l show-all -d "Show non-printable characters like space/tab/newline" -n "not __fish_seen_subcommand_from cache"
complete -c {{PROJECT_EXECUTABLE}} -l style -xka "auto full plain changes header grid numbers" -d "Comma-separated list of style elements or presets to display with file contents" -n "not __fish_seen_subcommand_from cache"
+93
View File
@@ -0,0 +1,93 @@
#compdef {{PROJECT_EXECUTABLE}}
local context state state_descr line
typeset -A opt_args
(( $+functions[_cache_subcommand] )) ||
_cache_subcommand() {
local -a args
args=(
'(-b --build -c --clear)'{-b,--build}'[Initialize or update the syntax/theme cache]'
'(-b --build -c --clear)'{-c,--clear}'[Remove the cached syntax definitions and themes]'
'(--source)'--source='[Use a different directory to load syntaxes and themes from]:directory:_files -/'
'(--target)'--target='[Use a different directory to store the cached syntax and theme set]:directory:_files -/'
'(--blank)'--blank'[Create completely new syntax and theme sets]'
'(: -)'{-h,--help}'[Prints help information]'
'*: :'
)
_arguments -S -s $args
}
(( $+functions[_main] )) ||
_main() {
local -a args
args=(
'(-A --show-all)'{-A,--show-all}'[Show non-printable characters (space, tab, newline, ..)]'
{-p,--plain}'[Show plain style (alias for `--style=plain`)]:When `-p` is used twice (`-pp`), it also disables automatic paging (alias for `--style=plain --paging=never`)'
'(-l --language)'{-l+,--language=}'[Set the language for syntax highlighting]:<language>:->language'
'(-H --highlight-line)'{-H,--highlight-line}'[Highlight lines N through M]:<N\:M>...'
'(--file-name)'--file-name'[Specify the name to display for a file]:<name>...:_files'
'(-d --diff)'--diff'[Only show lines that have been added/removed/modified]'
'(--diff-context)'--diff-context'[Include N lines of context around added/removed/modified lines when using `--diff`]:<N> (lines):()'
'(--tabs)'--tabs'[Set the tab width to T spaces]:<T> (tab width):()'
'(--wrap)'--wrap='[Specify the text-wrapping mode]:<when>:(auto never character)'
'(--terminal-width)'--terminal-width'[Explicitly set the width of the terminal instead of determining it automatically]:<width>'
'(-n --number)'{-n,--number}'[Show line numbers]'
'(--color)'--color='[When to use colors]:<when>:(auto never always)'
'(--italic-text)'--italic-text='[Use italics in output]:<when>:(always never)'
'(--decorations)'--decorations='[When to show the decorations]:<when>:(auto never always)'
'(--paging)'--paging='[Specify when to use the pager]:<when>:(auto never always)'
'(-m --map-syntax)'{-m+,--map-syntax=}'[Use the specified syntax for files matching the glob pattern]:<glob\:syntax>...'
'(--theme)'--theme='[Set the color theme for syntax highlighting]:<theme>:->theme'
'(: --list-themes --list-languages -L)'--list-themes'[Display all supported highlighting themes]'
'(--style)'--style='[Comma-separated list of style elements to display]:<components>:->style'
'(-r --line-range)'{-r+,--line-range=}'[Only print the lines from N to M]:<N\:M>...'
'(: --list-themes --list-languages -L)'{-L,--list-languages}'[Display all supported languages]'
'(: -)'{-h,--help}'[Print this help message]'
'(: -)'{-V,--version}'[Show version information]'
'*: :_files'
)
_arguments -S -s $args
case "$state" in
language)
local IFS=$'\n'
local -a languages
languages=( $({{PROJECT_EXECUTABLE}} --list-languages | awk -F':|,' '{ for (i = 1; i <= NF; ++i) printf("%s:%s\n", $i, $1) }') )
_describe 'language' languages
;;
theme)
local IFS=$'\n'
local -a themes
themes=( $({{PROJECT_EXECUTABLE}} --list-themes | sort) )
_values 'theme' $themes
;;
style)
_values -s , 'style' auto full plain changes header grid numbers snip
;;
esac
}
# first positional argument
if (( ${#words} == 2 )); then
local -a subcommands
subcommands=('cache:Modify the syntax-definition and theme cache')
_describe subcommand subcommands
_main
else
case $words[2] in
cache)
_cache_subcommand
;;
*)
_main
;;
esac
fi
+16 -6
View File
@@ -42,12 +42,22 @@ fi
# Always remove the local cache to avoid any confusion
bat cache --clear
# TODO: Remove this (and the reverse part below) when
# https://github.com/trishume/syntect/issues/222 has been fixed
JAVADOC_FILE="${ASSET_DIR}/syntaxes/01_Packages/Java/JavaDoc.sublime-syntax"
JAVADOC_PATCH="${ASSET_DIR}/JavaDoc.sublime-syntax.patch"
patch "$JAVADOC_FILE" "$JAVADOC_PATCH"
# TODO:
# - Remove the JavaDoc patch once https://github.com/trishume/syntect/issues/222 has been fixed
# - Remove the C# patch once https://github.com/sublimehq/Packages/pull/2331 has been merged
(
cd "$ASSET_DIR"
for patch in patches/*.patch; do
patch --strip=0 < "$patch"
done
)
bat cache --build --blank --source="$ASSET_DIR" --target="$ASSET_DIR"
patch -R "$JAVADOC_FILE" "$JAVADOC_PATCH"
(
cd "$ASSET_DIR"
for patch in patches/*.patch; do
patch --strip=0 --reverse < "$patch"
done
)
+48 -7
View File
@@ -1,4 +1,4 @@
.TH {{PROJECT_EXECUTABLE | upcase}} "1"
.TH {{PROJECT_EXECUTABLE_UPPERCASE}} "1"
.SH NAME
{{PROJECT_EXECUTABLE}} \- a cat(1) clone with syntax highlighting and Git integration.
.SH "USAGE"
@@ -87,17 +87,22 @@ Specify when to use the decorations that have been specified via '\-\-style'. Th
automatic mode only enables decorations if an interactive terminal is detected. Possible
values: *auto*, never, always.
.HP
\fB\-f\fR, \fB\-\-force\-colorization\fR
.IP
Alias for '--decorations=always --color=always'. This is useful \
if the output of bat is piped to another program, but you want \
to keep the colorization/decorations.
.HP
\fB\-\-paging\fR <when>
.IP
Specify when to use the pager. To control which pager is used, set the PAGER or
BAT_PAGER environment variables (the latter takes precedence) or use the '\-\-pager'
option. To disable the pager permanently, set BAT_PAGER to an empty string or set
\&'\-\-paging=never' in the configuration file. Possible values: *auto*, never, always.
Specify when to use the pager. To disable the pager, use \&'\-\-paging=never' or its alias,
\fB-P\fR. To disable the pager permanently, set BAT_PAGER to an empty string. To control
which pager is used, see the '\-\-pager' option. Possible values: *auto*, never, always.
.HP
\fB\-\-pager\fR <command>
.IP
Determine which pager is used. This option will overwrite the PAGER and BAT_PAGER
environment variables. The default pager is 'less'. To disable the pager completely, use
Determine which pager is used. This option will override the PAGER and BAT_PAGER
environment variables. The default pager is 'less'. To control when the pager is used, see
the '\-\-paging' option. Example: '\-\-pager "less \fB\-RF\fR"'.
.HP
\fB\-m\fR, \fB\-\-map\-syntax\fR <glob-pattern:syntax-name>...
@@ -171,3 +176,39 @@ is dependent on your operating system. To get the default path for your system,
Alternatively, you can use the BAT_CONFIG_PATH environment variable to point bat to a non-default
location of 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-snytax\fR language
files to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes\fR` and run `\fBbat cache --build\fR`.
\fBExample:\fR
.RS 0.5i
mkdir -p "$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes"
.br
cd "$({{PROJECT_EXECUTABLE}} --config-dir)/syntaxes"
# Put new '.sublime-syntax' language definition files
.br
# in this folder (or its subdirectories), for example:
.br
git clone https://github.com/tellnobody1/sublime-purescript-syntax
# And then build the cache.
.br
{{PROJECT_EXECUTABLE}} cache --build
.RE
Once the cache is built, the new language will be visible in `\fBbat --list-languages\fR`.
.br
If you ever want to remove the custom languages, you can clear the cache with `\fBbat cache --clear\fR`.
.SH "ADDING CUSTOM THEMES"
Similarly to custom languages, {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.tmTheme\fR themes.
These can be installed to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/themes\fR`, and are added to the cache with
`\fB{{PROJECT_EXECUTABLE}} cache --build`.
.SH "MORE INFORMATION"
For more information and up-to-date documentation, visit the {{PROJECT_EXECUTABLE}} repo:
.br
\fBhttps://github.com/sharkdp/bat\fR
+13
View File
@@ -0,0 +1,13 @@
diff --git syntaxes/01_Packages/C#/C#.sublime-syntax syntaxes/01_Packages/C#/C#.sublime-syntax
index ed494f8b..01b710e8 100644
--- syntaxes/01_Packages/C#/C#.sublime-syntax
+++ syntaxes/01_Packages/C#/C#.sublime-syntax
@@ -1312,7 +1312,7 @@ contexts:
2: punctuation.separator.cs
3: punctuation.section.brackets.end.cs
4: keyword.operator.pointer.cs
- - match: \((?=(?:[^,)(]*|\([^\)]*\))*,)
+ - match: \((?=(?:[^,)(]|\([^\)]*\))*,)
scope: punctuation.section.group.begin.cs
push:
- meta_scope: meta.group.tuple.cs
+81
View File
@@ -0,0 +1,81 @@
diff --git syntaxes/01_Packages/Makefile/Makefile.sublime-syntax syntaxes/01_Packages/Makefile/Makefile.sublime-syntax
index 3cc3a97e..0c7a3f24 100644
--- syntaxes/01_Packages/Makefile/Makefile.sublime-syntax
+++ syntaxes/01_Packages/Makefile/Makefile.sublime-syntax
@@ -44,64 +44,50 @@ variables:
# variable substitutions anywhere. We try to remedy this by hacking in a
# regex that matches up to four levels of nested parentheses, and ignores
# whatever's inside the parentheses.
- nps: '[^()]*'
- open: '(?:\('
- close: '\))?' # ignore this invalid.illegal
+ nps_unnested: '[^()]*'
+ nps: '[^()]*(?=[()])'
+ open: '(?:{{nps}}\('
+ close: '\){{nps_unnested}})?' # ignore this invalid.illegal
just_eat: | # WARNING: INSANITY FOLLOWS!
- (?x) # ignore whitespace in this regex
- {{nps}} # level 0
+ (?x)(?: # ignore whitespace in this regex
{{open}} # start level 1 __
- {{nps}} # level 1 _______ /*_>-<
{{open}} # start level 2 ___/ _____ \__/ /
- {{nps}} # level 2 <____/ \____/
{{open}} # start level 3 is like snek... (by Valerie Haecky)
- {{nps}} # level 3
{{open}} # start level 4
{{nps}} # level 4
{{close}} # end level 4
- {{nps}} # level 3
{{close}} # end level 3
- {{nps}} # level 2
{{open}} # start level 3
- {{nps}} # level 3
{{open}} # start level 4
{{nps}} # level 4
{{close}} # end level 4
- {{nps}} # level 3
{{close}} # end level 3
- {{nps}} # level 2
+ {{nps}}
{{close}} # end level 2
- {{nps}} # level 1
{{open}} # start level 2
- {{nps}} # level 2
{{open}} # start level 3
- {{nps}} # level 3
{{open}} # start level 4
{{nps}} # level 4
{{close}} # end level 4
- {{nps}} # level 3
+ {{nps}}
{{close}} # end level 3
- {{nps}} # level 2
{{open}} # start level 3
- {{nps}} # level 3
{{open}} # start level 4
{{nps}} # level 4
{{close}} # end level 4
- {{nps}} # level 3
+ {{nps}}
{{close}} # end level 3
- {{nps}} # level 2
{{open}} # start level 3
- {{nps}} # level 3
{{open}} # start level 4
{{nps}} # level 4
{{close}} # end level 4
- {{nps}} # level 3
+ {{nps}}
{{close}} # end level 3
- {{nps}} # level 2
+ {{nps}}
{{close}} # end level 2
- {{nps}} # level 1
+ {{nps}}
{{close}} # end level 1
- {{nps}} # level 0
+ |{{nps_unnested}})
rule_lookahead: '{{just_eat}}{{ruleassign}}{{just_eat}}'
var_lookahead_base: '{{just_eat}}({{varassign}}|{{shellassign}}){{just_eat}}'
+168
View File
@@ -0,0 +1,168 @@
diff --git syntaxes/01_Packages/Markdown/Markdown.sublime-syntax syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
index 19dc685d..6afd87ae 100644
--- syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
+++ syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
@@ -24,7 +24,6 @@ variables:
)
[ \t]*$ # followed by any number of tabs or spaces, followed by the end of the line
)
- setext_escape: ^(?=\s{0,3}(?:---+|===+)\s*$)
block_quote: (?:[ ]{,3}>(?:.|$)) # between 0 and 3 spaces, followed by a greater than sign, followed by any character or the end of the line
atx_heading: (?:[#]{1,6}\s*) # between 1 and 6 hashes, followed by any amount of whitespace
indented_code_block: (?:[ ]{4}|\t) # 4 spaces or a tab
@@ -277,69 +276,40 @@ contexts:
8: markup.underline.link.markdown
push: [link-ref-def, after-link-title, link-title]
- match: '^(?=\S)(?![=-]{3,}\s*$)'
- branch_point: heading2-branch
- branch:
- - not-heading2
- - heading2
-
- not-paragraph:
- - match: |-
- (?x) # pop out of this context when one of the following conditions are met:
- ^(?:
- \s*$ # the line is blank (or only contains whitespace)
- | (?=
- {{block_quote}} # a block quote begins the line
- | [ ]{,3}[*+-][ ] # an unordered list item begins the line
- | [ ]{,3}1[.][ ] # an ordered list item with number "1" begins the line
- | \# # an ATX heading begins the line
- | [ ]{,3}<( # all types of HTML blocks except type 7 may interrupt a paragraph
- {{html_tag_block_end_at_close_tag}} # 1
- | !-- # 2
- | \? # 3
- | ![A-Z] # 4
- | !\[CDATA\[ # 5
- | {{html_tag_block_end_at_blank_line}} # 6
+ push:
+ - meta_scope: meta.paragraph.markdown
+ - match: |-
+ (?x) # pop out of this context when one of the following conditions are met:
+ ^(?:
+ \s*$ # the line is blank (or only contains whitespace)
+ | (?=
+ {{block_quote}} # a block quote begins the line
+ | [ ]{,3}[*+-][ ] # an unordered list item begins the line
+ | [ ]{,3}1[.][ ] # an ordered list item with number "1" begins the line
+ | \# # an ATX heading begins the line
+ | [ ]{,3}<( # all types of HTML blocks except type 7 may interrupt a paragraph
+ {{html_tag_block_end_at_close_tag}} # 1
+ | !-- # 2
+ | \? # 3
+ | ![A-Z] # 4
+ | !\[CDATA\[ # 5
+ | {{html_tag_block_end_at_blank_line}} # 6
+ )
)
)
- )
- pop: true
-
- not-heading2:
- - include: not-paragraph
- - match: (?=\S)
- branch_point: heading1-branch
- branch:
- - paragraph
- - heading1
- - match: ''
- pop: true
-
- paragraph:
- - meta_scope: meta.paragraph.markdown
- - match: ^\s{0,3}===+\s*$
- fail: heading1-branch
- - match: ^\s{0,3}---+\s*$
- fail: heading2-branch
- - include: not-paragraph
- - include: inline-bold-italic-linebreak
- - include: scope:text.html.basic
-
- heading1:
- - meta_scope: markup.heading.1.markdown
- - include: inline-bold-italic-linebreak
- - match: '^[ \t]{0,3}(={3,})(?=[ \t]*$)'
- captures:
- 1: markup.heading.1.setext.markdown punctuation.definition.heading.setext.markdown
- pop: true
-
- heading2:
- - meta_scope: markup.heading.2.markdown
- - include: inline-bold-italic-linebreak
- - match: '^[ \t]{0,3}(-{3,})(?=[ \t]*$)'
- captures:
- 1: markup.heading.2.setext.markdown punctuation.definition.heading.setext.markdown
- pop: true
-
+ pop: true
+ - include: inline-bold-italic-linebreak
+ - include: scope:text.html.basic
+ - match: '^(={3,})(?=[ \t]*$)'
+ scope: markup.heading.1.setext.markdown
+ captures:
+ 1: punctuation.definition.heading.setext.markdown
+ pop: true
+ - match: '^(-{3,})(?=[ \t]*$)'
+ scope: markup.heading.2.setext.markdown
+ captures:
+ 1: punctuation.definition.heading.setext.markdown
+ pop: true
link-ref-def:
- meta_scope: meta.link.reference.def.markdown
- match: ''
@@ -430,8 +400,6 @@ contexts:
push:
- meta_scope: markup.bold.markdown
- meta_content_scope: markup.italic.markdown
- - match: '{{setext_escape}}'
- pop: true
- match: |-
(?x)
[ \t]*\*{4,} # if there are more than 3 its not applicable to be bold or italic
@@ -446,8 +414,6 @@ contexts:
scope: punctuation.definition.bold.end.markdown
set:
- meta_content_scope: markup.italic.markdown
- - match: '{{setext_escape}}'
- pop: true
- match: |-
(?x)
[ \t]*\*{3,} # if there are more than 3 its not applicable to be bold or italic
@@ -463,8 +429,6 @@ contexts:
scope: punctuation.definition.italic.end.markdown
set:
- meta_content_scope: markup.bold.markdown
- - match: '{{setext_escape}}'
- pop: true
- match: |-
(?x)
[ \t]*\*{3,} # if there are more than 3 its not applicable to be bold or italic
@@ -727,8 +691,6 @@ contexts:
scope: punctuation.definition.italic.begin.markdown
push:
- meta_scope: markup.italic.markdown
- - match: '{{setext_escape}}'
- pop: true
- match: |-
(?x)
[ \t]*\*{4,} # if there are more than 3 its not applicable to be bold or italic
@@ -745,8 +707,6 @@ contexts:
scope: punctuation.definition.italic.begin.markdown
push:
- meta_scope: markup.italic.markdown
- - match: '{{setext_escape}}'
- pop: true
- match: |-
(?x)
[ \t]*_{4,} # if there are more than 3 its not applicable to be bold or italic
@@ -773,8 +733,6 @@ contexts:
- include: bold-italic-trailing
bold-italic-trailing:
- include: scope:text.html.basic
- - match: '{{setext_escape}}'
- pop: true
- match: ^\s*$\n?
scope: invalid.illegal.non-terminated.bold-italic.markdown
pop: true
+13
View File
@@ -0,0 +1,13 @@
diff --git syntaxes/01_Packages/Rust/Rust.sublime-syntax syntaxes/01_Packages/Rust/Rust.sublime-syntax
index 3c354486..24727a4e 100644
--- syntaxes/01_Packages/Rust/Rust.sublime-syntax
+++ syntaxes/01_Packages/Rust/Rust.sublime-syntax
@@ -907,6 +907,8 @@ contexts:
- include: type-any-identifier
- match: ':'
scope: punctuation.separator.rust
+ - match: (?=;)
+ pop: true
fn-body:
- meta_scope: meta.function.rust
BIN
View File
Binary file not shown.
+221
View File
@@ -0,0 +1,221 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Apache Conf
file_extensions:
- envvars
- htaccess
- HTACCESS
- htgroups
- HTGROUPS
- htpasswd
- HTPASSWD
- .htaccess
- .HTACCESS
- .htgroups
- .HTGROUPS
- .htpasswd
- .HTPASSWD
scope: source.apacheconf
contexts:
main:
- match: ^(\s)*(#).*$\n?
scope: comment.line.hash.ini
captures:
1: punctuation.definition.comment.apacheconf
- match: (<)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost|Macro|If|Else|ElseIf)(\s(.+?))?(>)
captures:
1: punctuation.definition.tag.apacheconf
2: entity.tag.apacheconf
4: string.value.apacheconf
5: punctuation.definition.tag.apacheconf
- match: (</)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost|Macro|If|Else|ElseIf)(>)
captures:
1: punctuation.definition.tag.apacheconf
2: entity.tag.apacheconf
3: punctuation.definition.tag.apacheconf
- match: (?<=(Rewrite(Rule|Cond)))\s+(.+?)\s+(.+?)($|\s)
captures:
3: string.regexp.apacheconf
4: string.replacement.apacheconf
- match: (?<=RedirectMatch)(\s+(\d\d\d|permanent|temp|seeother|gone))?\s+(.+?)\s+((.+?)($|\s))?
captures:
2: entity.status.apacheconf
3: string.regexp.apacheconf
5: string.path.apacheconf
- match: (?<=Redirect)(\s+(\d\d\d|permanent|temp|seeother|gone))?\s+(.+?)\s+((.+?)($|\s))?
captures:
2: entity.status.apacheconf
3: string.path.apacheconf
5: string.path.apacheconf
- match: (?<=ScriptAliasMatch|AliasMatch)\s+(.+?)\s+((.+?)\s)?
captures:
1: string.regexp.apacheconf
3: string.path.apacheconf
- match: (?<=RedirectPermanent|RedirectTemp|ScriptAlias|Alias)\s+(.+?)\s+((.+?)($|\s))?
captures:
1: string.path.apacheconf
3: string.path.apacheconf
- match: \b(AcceptPathInfo|AccessFileName|AddDefaultCharset|AddOutputFilterByType|AllowEncodedSlashes|AllowOverride|AuthName|AuthType|CGIMapExtension|ContentDigest|DefaultType|Define|DocumentRoot|EnableMMAP|EnableSendfile|ErrorDocument|ErrorLog|FileETag|ForceType|HostnameLookups|IdentityCheck|Include(Optional)?|KeepAlive|KeepAliveTimeout|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|LogLevel|MaxKeepAliveRequests|Mutex|NameVirtualHost|Options|Require|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScriptInterpreterSource|ServerAdmin|ServerAlias|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|SetHandler|SetInputFilter|SetOutputFilter|Time(O|o)ut|TraceEnable|UseCanonicalName|Use|ErrorLogFormat|GlobalLog|PHPIniDir|SSLHonorCipherOrder|SSLCompression|SSLUseStapling|SSLStapling\w+|SSLCARevocationCheck|SSLSRPVerifierFile|SSLSessionTickets|RequestReadTimeout|ProxyHTML\w+|MaxRanges)\b
captures:
1: keyword.core.apacheconf
- match: \b(AcceptMutex|AssignUserID|BS2000Account|ChildPerUserID|CoreDumpDirectory|EnableExceptionHook|Group|Listen|ListenBacklog|LockFile|MaxClients|MaxConnectionsPerChild|MaxMemFree|MaxRequestsPerChild|MaxRequestsPerThread|MaxRequestWorkers|MaxSpareServers|MaxSpareThreads|MaxThreads|MaxThreadsPerChild|MinSpareServers|MinSpareThreads|NumServers|PidFile|ReceiveBufferSize|ScoreBoardFile|SendBufferSize|ServerLimit|StartServers|StartThreads|ThreadLimit|ThreadsPerChild|ThreadStackSize|User|Win32DisableAcceptEx)\b
captures:
1: keyword.mpm.apacheconf
- match: \b(Allow|Deny|Order)\b
captures:
1: keyword.access.apacheconf
- match: \b(Action|Script)\b
captures:
1: keyword.actions.apacheconf
- match: \b(Alias|AliasMatch|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ScriptAlias|ScriptAliasMatch)\b
captures:
1: keyword.alias.apacheconf
- match: \b(AuthAuthoritative|AuthGroupFile|AuthUserFile|AuthBasicProvider|AuthBasicFake|AuthBasicAuthoritative|AuthBasicUseDigestAlgorithm)\b
captures:
1: keyword.auth.apacheconf
- match: \b(Anonymous|Anonymous_Authoritative|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail)\b
captures:
1: keyword.auth_anon.apacheconf
- match: \b(AuthDBMAuthoritative|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile)\b
captures:
1: keyword.auth_dbm.apacheconf
- match: \b(AuthDigestAlgorithm|AuthDigestDomain|AuthDigestFile|AuthDigestGroupFile|AuthDigestNcCheck|AuthDigestNonceFormat|AuthDigestNonceLifetime|AuthDigestQop|AuthDigestShmemSize|AuthDigestProvider)\b
captures:
1: keyword.auth_digest.apacheconf
- match: \b(AuthLDAPAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPEnabled|AuthLDAPFrontPageHack|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPRemoteUserIsDN|AuthLDAPUrl)\b
captures:
1: keyword.auth_ldap.apacheconf
- match: \b(AddAlt|AddAltByEncoding|AddAltByType|AddDescription|AddIcon|AddIconByEncoding|AddIconByType|DefaultIcon|HeaderName|IndexIgnore|IndexOptions|IndexOrderDefault|IndexStyleSheet|IndexHeadInsert|ReadmeName)\b
captures:
1: keyword.autoindex.apacheconf
- match: \b(BalancerMember|BalancerGrowth|BalancerPersist|BalancerInherit)\b
captures:
1: keyword.filter.apacheconf
- match: \b(CacheDefaultExpire|CacheDisable|CacheEnable|CacheForceCompletion|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheLastModifiedFactor|CacheMaxExpire)\b
captures:
1: keyword.cache.apacheconf
- match: \b(MetaDir|MetaFiles|MetaSuffix)\b
captures:
1: keyword.cern_meta.apacheconf
- match: \b(ScriptLog|ScriptLogBuffer|ScriptLogLength)\b
captures:
1: keyword.cgi.apacheconf
- match: \b(ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock)\b
captures:
1: keyword.cgid.apacheconf
- match: \b(CharsetDefault|CharsetOptions|CharsetSourceEnc)\b
captures:
1: keyword.charset_lite.apacheconf
- match: \b(Dav|DavDepthInfinity|DavMinTimeout|DavLockDB)\b
captures:
1: keyword.dav.apacheconf
- match: \b(DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateMemLevel|DeflateWindowSize)\b
captures:
1: keyword.deflate.apacheconf
- match: \b(DirectoryIndex|DirectorySlash|FallbackResource)\b
captures:
1: keyword.dir.apacheconf
- match: \b(CacheDirLength|CacheDirLevels|CacheExpiryCheck|CacheGcClean|CacheGcDaily|CacheGcInterval|CacheGcMemUsage|CacheGcUnused|CacheMaxFileSize|CacheMinFileSize|CacheRoot|CacheSize|CacheTimeMargin)\b
captures:
1: keyword.disk_cache.apacheconf
- match: \b(DumpIOInput|DumpIOOutput)\b
captures:
1: keyword.dumpio.apacheconf
- match: \b(PassEnv|SetEnv|UnsetEnv)\b
captures:
1: keyword.env.apacheconf
- match: \b(ExpiresActive|ExpiresByType|ExpiresDefault)\b
captures:
1: keyword.expires.apacheconf
- match: \b(ExtFilterDefine|ExtFilterOptions)\b
captures:
1: keyword.ext_filter.apacheconf
- match: \b(CacheFile|MMapFile)\b
captures:
1: keyword.file_cache.apacheconf
- match: \b(AddOutputFilterByType|FilterChain|FilterDeclare|FilterProtocol|FilterProvider|FilterTrace)\b
captures:
1: keyword.filter.apacheconf
- match: \b(Header|RequestHeader)\b
captures:
1: keyword.headers.apacheconf
- match: \b(ImapBase|ImapDefault|ImapMenu)\b
captures:
1: keyword.imap.apacheconf
- match: \b(SSIEndTag|SSIErrorMsg|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|XBitHack)\b
captures:
1: keyword.include.apacheconf
- match: \b(ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer)\b
captures:
1: keyword.isapi.apacheconf
- match: \b(LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionTimeout|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTrustedCA|LDAPTrustedCAType)\b
captures:
1: keyword.ldap.apacheconf
- match: \b(BufferedLogs|CookieLog|CustomLog|LogFormat|TransferLog|ForensicLog)\b
captures:
1: keyword.log.apacheconf
- match: \b(MCacheMaxObjectCount|MCacheMaxObjectSize|MCacheMaxStreamingBuffer|MCacheMinObjectSize|MCacheRemovalAlgorithm|MCacheSize)\b
captures:
1: keyword.mem_cache.apacheconf
- match: \b(AddCharset|AddEncoding|AddHandler|AddInputFilter|AddLanguage|AddOutputFilter|AddType|DefaultLanguage|ModMimeUsePathInfo|MultiviewsMatch|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|TypesConfig)\b
captures:
1: keyword.mime.apacheconf
- match: \b(ProtocolEcho|Example|AddModuleInfo|MimeMagicFile|CheckSpelling|ExtendedStatus|SuexecUserGroup|UserDir)\b
captures:
1: keyword.misc.apacheconf
- match: \b(CacheNegotiatedDocs|ForceLanguagePriority|LanguagePriority)\b
captures:
1: keyword.negotiation.apacheconf
- match: \b(NWSSLTrustedCerts|NWSSLUpgradeable|SecureListen)\b
captures:
1: keyword.nw_ssl.apacheconf
- match: \b(AllowCONNECT|NoProxy|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyFtpDirCharset|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassMatch|ProxyPassReverse|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxyTimeout|ProxyVia)\b
captures:
1: keyword.proxy.apacheconf
- match: \b(RewriteBase|RewriteCond|RewriteEngine|RewriteLock|RewriteLog|RewriteLogLevel|RewriteMap|RewriteOptions|RewriteRule)\b
captures:
1: keyword.rewrite.apacheconf
- match: \b(BrowserMatch|BrowserMatchNoCase|SetEnvIf|SetEnvIfNoCase)\b
captures:
1: keyword.setenvif.apacheconf
- match: \b(LoadFile|LoadModule)\b
captures:
1: keyword.so.apacheconf
- match: \b(SSLCACertificateFile|SSLCACertificatePath|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLEngine|SSLMutex|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLUserName|SSLVerifyClient|SSLVerifyDepth|SSLInsecureRenegotiation|SSLOpenSSLConfCmd)\b
captures:
1: keyword.ssl.apacheconf
- match: \b(Substitute|SubstituteInheritBefore|SubstituteMaxLineLength)\b
captures:
1: keyword.substitute.apacheconf
- match: \b(CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking)\b
captures:
1: keyword.usertrack.apacheconf
- match: \b(VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP)\b
captures:
1: keyword.vhost_alias.apacheconf
- match: \b(php_value|php_flag|php_admin_value|php_admin_flag)\b(\s+(.+?)(\s+(".+?"|.+?))?)?\s
captures:
1: keyword.php.apacheconf
3: entity.property.apacheconf
5: string.value.apacheconf
- match: '(%\{)((HTTP_USER_AGENT|HTTP_REFERER|HTTP_COOKIE|HTTP_FORWARDED|HTTP_HOST|HTTP_PROXY_CONNECTION|HTTP_ACCEPT|REMOTE_ADDR|REMOTE_HOST|REMOTE_PORT|REMOTE_USER|REMOTE_IDENT|REQUEST_METHOD|SCRIPT_FILENAME|PATH_INFO|QUERY_STRING|AUTH_TYPE|DOCUMENT_ROOT|SERVER_ADMIN|SERVER_NAME|SERVER_ADDR|SERVER_PORT|SERVER_PROTOCOL|SERVER_SOFTWARE|TIME_YEAR|TIME_MON|TIME_DAY|TIME_HOUR|TIME_MIN|TIME_SEC|TIME_WDAY|TIME|API_VERSION|THE_REQUEST|REQUEST_URI|REQUEST_FILENAME|IS_SUBREQ|HTTPS)|(.*?))(\})'
captures:
1: punctuation.variable.apacheconf
3: variable.env.apacheconf
4: variable.misc.apacheconf
5: punctuation.variable.apacheconf
- match: \b((text|image|application|video|audio)/.+?)\s
captures:
1: entity.mime-type.apacheconf
- match: \b(?i)(export|from|unset|set|on|off)\b
captures:
1: entity.helper.apacheconf
- match: \b(\d+)\b
captures:
1: constant.numeric.integer.decimal.apacheconf
- match: '\s(\[)(.*?)(\])\s'
captures:
1: punctuation.definition.flag.apacheconf
2: string.flag.apacheconf
3: punctuation.definition.flag.apacheconf
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -108,7 +108,7 @@ contexts:
- match: (?<!\.)\belse(\s)+if\b
comment: else if is a common mistake carried over from other languages. it works if you put in a second end, but its never what you want.
scope: invalid.deprecated.crystal
- match: '(?<!\.)\b(BEGIN|alias|as|begin|case|select|abstract|class|END|ensure|for|fun|if|ifdef|in|lib|module|of|out|private|protected|rescue|struct|with|union|enum|macro|then|type|unless|until|while)\b(?![?!])'
- match: '(?<!\.)\b(BEGIN|alias|as|begin|case|select|abstract|class|END|ensure|for|fun|if|ifdef|in|lib|module|of|out|private|protected|rescue|struct|with|union|enum|macro|then|unless|until|while)\b(?![?!])|(?<!\.)\btype\b\s*(?=[A-Z])'
comment: everything being a reserved word, not a value and needing a 'end' is a..
scope: keyword.control.primary.crystal
- match: '(?<!\.)\b(when|else|elsif)\b(?![?!])'
@@ -131,7 +131,7 @@ contexts:
scope: keyword.control.pseudo-method.crystal
- match: '\b(nil|true|false)\b(?![?!])'
scope: constant.language.crystal
- match: '\b(__(DIR|FILE|LINE|END_LINE)__|self)\b(?![?!])'
- match: '\b(__(DIR|FILE|LINE|END_LINE)__|self)\b(?![?!])|self[?]'
scope: variable.language.crystal
- match: '\b(initialize|new|loop|include|extend|raise|getter|setter|property|class_getter|class_setter|class_property|describe|context|it|with|delegate|def_hash|def_equals|def_equals_and_hash|forward_missing_to|record|assert_responds_to|spawn|annotation|verbatim)\b[!?]?'
comment: everything being a method but having a special function is a..
@@ -190,7 +190,7 @@ contexts:
push:
- meta_scope: meta.function.method.with-arguments.crystal
- meta_content_scope: variable.parameter.function.crystal
- match: \)\s*$|\)\s*:|\)\s*;
- match: \)
captures:
0: punctuation.definition.parameters.crystal
pop: true
@@ -705,6 +705,7 @@ contexts:
0: punctuation.definition.string.end.crystal
pop: true
- include: heredoc
- include: scope:text.html.basic
- include: scope:source.js
- include: interpolated_crystal
- include: escaped_char
+1
View File
@@ -4,6 +4,7 @@
name: fstab
file_extensions:
- fstab
- crypttab
scope: source.fstab
contexts:
+103
View File
@@ -0,0 +1,103 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: QML
file_extensions:
- qml
- qmlproject
scope: source.qml
contexts:
main:
- match: /\*(?!/)
comment: Block comment.
push:
- meta_scope: comment.block.documentation.qml
- match: \*/
pop: true
- match: //.*$
comment: Line comment.
scope: comment.line.double-slash.qml
- match: \b(import)\s+
comment: import statement.
captures:
1: keyword.other.import.qml
push:
- meta_scope: meta.import.qml
- match: $
pop: true
- match: '([\w\d\.]+)\s+(\d+\.\d+)(?:\s+(as)\s+([A-Z][\w\d]*))?'
comment: "import Namespace VersionMajor.VersionMinor [as SingletonTypeIdentifier]"
scope: meta.import.namespace.qml
captures:
1: entity.name.class.qml
2: constant.numeric.qml
3: keyword.other.import.qml
4: entity.name.class.qml
- match: '(\"[^\"]+\")(?:\s+(as)\s+([A-Z][\w\d]*))?'
comment: "import <string> [as Script]"
scope: meta.import.dirjs.qml
captures:
1: string.quoted.double.qml
2: keyword.other.import.qml
3: entity.name.class.qml
- match: '\b[A-Z]\w*\b'
comment: Capitalized word (class or enum).
scope: support.class.qml
- match: '(((^|\{)\s*)|\b)on[A-Z]\w*\b'
comment: onSomething - handler.
scope: support.class.qml
- match: '(?:^|\{)\s*(id)\s*\:\s*([^;\s]+)\b'
comment: "id: <something>"
scope: meta.id.qml
captures:
1: keyword.other.qml
2: storage.modifier.qml
- match: '^\s*(?:(default|readonly)\s+)?(property)\s+(?:(alias)|([\w\<\>]+))\s+(\w+)'
comment: property definition.
scope: meta.propertydef.qml
captures:
1: keyword.other.qml
2: keyword.other.qml
3: keyword.other.qml
4: storage.type.qml
5: entity.other.attribute-name.qml
- match: \b(signal)\s+(\w+)\s*
comment: "signal <signalName>[([<type> <parameter>[, ...]])]"
captures:
1: keyword.other.qml
2: support.function.qml
push:
- meta_scope: meta.signal.qml
- match: ;|(?=/)|$
pop: true
- match: (\w+)\s+(\w+)
scope: meta.signal.parameters.qml
captures:
1: storage.type.qml
2: variable.parameter.qml
- match: (?:\b|\s+)(?:(true|false|null|undefined)|(var|void)|(on|as|enum|connect|break|case|catch|continue|debugger|default|delete|do|else|finally|for|if|in|instanceof|new|return|switch|this|throw|try|typeof|while|with))\b
comment: js keywords.
scope: meta.keyword.qml
captures:
1: constant.language.qml
2: storage.type.qml
3: keyword.control.qml
- match: '\b(function)\s+([\w_]+)\s*(?=\()'
comment: function definition.
scope: meta.function.qml
captures:
1: storage.type.qml
2: entity.name.function.untitled
- match: '\b[\w_]+\s*(?=\()'
comment: function call.
scope: support.function.qml
- match: '(?:^|\{|;)\s*[a-z][\w\.]*\s*(?=\:)'
comment: "property (property: <something>)."
scope: entity.other.attribute-name.qml
- match: (?<=\.)\b\w*
comment: property of the variable (name.property).
scope: entity.other.attribute-name.qml
- match: '\b([a-z_]\w*)\b'
comment: All non colored words are assumed to be variables.
scope: variable.parameter
- include: scope:source.js
+97
View File
@@ -0,0 +1,97 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Rego
file_extensions:
- rego
scope: source.rego
contexts:
main:
- include: comment
- include: keyword
- include: operator
- include: head
- include: term
comment:
- match: (#).*$\n?
scope: comment.line.number-sign.rego
captures:
1: punctuation.definition.comment.rego
call:
- match: '([a-zA-Z_][a-zA-Z0-9_]*)\('
scope: meta.function-call.rego
captures:
1: support.function.any-method.rego
constant:
- match: \b(?:true|false|null)\b
scope: constant.language.rego
head:
- match: "^([[:alpha:]_][[:alnum:]_]*)"
captures:
1: entity.name.function.declaration
push:
- meta_scope: meta.function.rego
- match: '(=|{|\n)'
pop: true
- include: term
keyword:
- match: (^|\s+)(?:(default|not|package|import|as|with|else|some))\s+
scope: keyword.other.rego
number:
- match: |-
(?x: # turn on extended mode
-? # an optional minus
(?:
0 # a zero
| # ...or...
[1-9] # a 1-9 character
\d* # followed by zero or more digits
)
(?:
(?:
\. # a period
\d+ # followed by one or more digits
)?
(?:
[eE] # an e character
[+-]? # followed by an option +/-
\d+ # followed by one or more digits
)? # make exponent optional
)? # make decimal portion optional
)
scope: constant.numeric.rego
operator:
- match: \=|\!\=|>|<|<\=|>\=|\+|-|\*|%|/|\||&|:\=
scope: keyword.operator.comparison.rego
string:
- match: '"'
captures:
0: punctuation.definition.string.begin.rego
push:
- meta_scope: string.quoted.double.rego
- match: '"'
captures:
0: punctuation.definition.string.end.rego
pop: true
- match: |-
(?x: # turn on extended mode
\\ # a literal backslash
(?: # ...followed by...
["\\/bfnrt] # one of these characters
| # ...or...
u # a u
[0-9a-fA-F]{4} # and four hex digits
)
)
scope: constant.character.escape.rego
- match: \\.
scope: invalid.illegal.unrecognized-string-escape.rego
term:
- include: constant
- include: string
- include: number
- include: call
- include: variable
variable:
- match: '\b[[:alpha:]_][[:alnum:]_]*\b'
scope: meta.identifier.rego
+33
View File
@@ -0,0 +1,33 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: SML
file_extensions:
- sml
- cm
- sig
scope: source.sml
contexts:
main:
- match: \b(EQUAL|GREATER|LESS|NONE|SOME|abstraction|abstype|and|andalso|array|as|before|bool|case|char|datatype|do|else|end|eqtype|exception|exn|false|fn|fun|functor|handle|if|in|include|infix|infixr|int|let|list|local|nil|nonfix|not|o|of|op|open|option|orelse|overload|print|raise|real|rec|ref|sharing|sig|signature|string|struct|structure|substring|then|true|type|unit|val|vector|where|while|with|withtype|word)\b
comment: SML keywords
scope: keyword.source.sml
- match: '\b[0-9]+\b'
comment: Numeric constants
scope: constant.numeric.sml
- match: '\b[A-Z]([A-z0-9]*)\b'
comment: Built in types
scope: support.type.sml
- match: '"(\\"|[^"])*"'
comment: String constant
scope: string.sml
- match: \(\*
comment: Comment
push:
- meta_scope: comment.sml
- match: \*\)
pop: true
- match: '(\(\)|=>|::|\[\]|->|:>)'
comment: Character
scope: constant.character.sml
+711
View File
@@ -0,0 +1,711 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Stylus
file_extensions:
- styl
- stylus
scope: source.stylus
contexts:
main:
- include: comments
- match: '^\s*(@(?:import|charset|css|font-face|(?:-webkit-)?keyframes)(?:\s+([\w-]+))?)\b'
captures:
1: keyword.control.at-rule.other.stylus
2: variable.other.animation-name.stylus
push:
- match: '$|;|(?=\{)'
pop: true
- include: string-quoted
- match: ^\s*(@media)\s*
captures:
1: keyword.control.at-rule.media.stylus
push:
- match: '$|(?=\{)'
pop: true
- include: media-query
- match: |-
(?x)
(?<=^|;|})
\s*
(?=
[\[\]'".\w$-]+
\s*
([?:]?=)
(?![^\[]*\])
)
push:
- match: $|;
pop: true
- include: expression
- include: iteration
- include: conditionals
- include: return
- match: |-
(?x) # multi-line regex definition mode
^(\s*) # starts at the beginning of line
([\w$-]+) # identifier (name)
(\() # start of argument list
(?=
.*?
\)\s*\{ # we see a curly brace afterwards
) # which means this is a function definition
captures:
2: entity.name.function.stylus
3: punctuation.definition.parameters.start.stylus
push:
- meta_scope: meta.function-call.stylus
- match: (\))
captures:
1: punctuation.definition.parameters.end.stylus
pop: true
- include: expression
- match: |-
(?x) # multi-line regex definition mode
(
(^|;) # starts at the beginning of line or at a ;
\s*
(\+?\s* # for block mixins
[\w$-]+) # identifier (name)
(\() # start of argument list
(?=
.*?
\)\s*;?\s* # if there are only spaces and semicolons
$|; # then this a
)
)
captures:
3: entity.other.attribute-name.mixin.stylus
4: punctuation.definition.parameters.start.stylus
push:
- meta_scope: meta.function-call.stylus
- match: (\))
captures:
1: punctuation.definition.parameters.end.stylus
pop: true
- include: expression
- match: |-
(?x) # multi-line regex definition mode
(^|(?<=\*/|\}))\s*
(?=
font(?!
\s*:\s
|
-
|
.*?
(?:
\/|normal|bold|light(er?)|serif|sans|monospace|
\b\d+(?:\b|px|r?em|%)|
var\s*\(|
['"][^\]]*$
)
) | # we need to distinguish between tag and property `cursor`
cursor(?!
\s*[:;]\s
|
-
|
.*?
(?:
(?:url\s*\()|
(?:-moz-|-webkit-|-ms-)?
(?:auto|default|none|context-menu|help|pointer|progress|
wait|cell|crosshair|text|vertical-text|alias|copy|
move|no-drop|not-allowed|e-resize|n-resize|ne-resize|
nw-resize|s-resize|se-resize|sw-resize|w-resize|
ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|
row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing
normal|bold|light(er?)|serif|sans|monospace)
)
) | (
(
altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|
animateMotion|animateTransform|circle|clipPath|color-profile|
defs|desc|ellipse|feBlend|feColorMatrix|
feComponentTransfer|feComposite|feConvolveMatrix|
feDiffuseLighting|feDisplacementMap|feDistantLight|feFlood|
feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|
feMergeNode|feMorphology|feOffset|fePointLight|
feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|
font-face|font-face-format|font-face-name|font-face-src|
font-face-uri|foreignObject|g|glyph|glyphRef|hkern|image|line|
linearGradient|marker|mask|metadata|missing-glyph|mpath|path|
pattern|polygon|polyline|radialGradient|rect|set|stop|svg|
switch|symbol|text|textPath|tref|tspan|use|view|vkern|
a|abbr|acronym|address|applet|area|article|aside|audio|b|base|
basefont|bdi|bdo|bgsound|big|blink|blockquote|body|br|button|
canvas|caption|center|cite|code|col|colgroup|data|
datalist|dd|decorator|del|details|dfn|dir|div|dl|dt|element|
em|embed|fieldset|figcaption|figure|footer|form|frame|
frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|
img|input|ins|isindex|kbd|keygen|label|legend|li|link|listing|
main|map|mark|marquee|menu|menuitem|meta|meter|nav|nobr|
noframes|noscript|object|ol|optgroup|option|output|p|param|
plaintext|pre|progress|q|rp|rt|ruby|s|samp|script|section|
select|shadow|small|source|spacer|span|strike|strong|style|
sub|summary|sup|table|tbody|td|template|textarea|tfoot|th|
thead|time|title|tr|track|tt|u|ul|var|video|wbr|xmp)
\s*([\s,.#\[]|:[^\s]|(?=\{|$))
) | (
[:~>\[*\/] # symbols but they are valid for selector
) | (
\+\s*[\w$-]+\b\s* # are an identifier starting with $
(?!\() # and they can't have anything besides
) | ( # for animtions
\d+(\.\d+)?%|(from|to)\b
) | ( # Placeholder selectors
\$[\w$-]+\b\s* # are an identifier starting with $
(?=$|\{) # and they can't have anything besides
) | ( # CSS class
\.[a-zA-Z0-9_-]+
) | ( # CSS id
\#[a-zA-Z0-9_-]+
) | ( # Reference to parent
([\w\d_-]+)? # matching any word right before &
(&) # & itself, escaped because of plist
([\w\d_-]+)? # matching any word right after &
)
)
push:
- meta_scope: meta.selector.stylus
- match: |-
|$|(?=\{\s*\}.*$)|(?=\{.*?[:;])|(?=\{)(?!.+\}.*$)
pop: true
- include: comma
- match: \d+(\.\d+)?%|from|to
scope: entity.other.animation-keyframe.stylus
- include: selector-components
- match: .
scope: entity.other.attribute-name.stylus
- match: |-
(?x) # multi-line regex definition mode
(?<=^|;|{)\s* # starts after begining of line, '{' or ';''
(?= # lookahead for
(
[a-zA-Z0-9_-] # then a letter
| # or
(\{(.*?)\}) # interpolation
| # or
(/\*.*?\*/) # comment
)+
\s*[:\s]\s* # value is separted by colon or space
(?!(\s*\{)) # if there are only spaces afterwards
(?!
[^}]*? # checking for an unclosed curly braces on this
\{ # line because if one exists it means that
[^}]* # this is a selector and not a property
($|\})
)
)
push:
- match: '(?=\}|;)|(?<!,)\s*\n'
pop: true
- include: comments
- include: interpolation
- match: '(?<!^|;|{)\s*(?:(:)|\s)'
captures:
1: punctuation.separator.key-value.stylus
push:
- match: '(;)|(?=\})|(?=(?<!\,)\s*\n)'
captures:
1: punctuation.terminator.rule.stylus
pop: true
- include: comments
- include: expression
- match: "-(moz|o|ms|webkit|khtml)-"
scope: support.type.vendor-prefix.stylus
- match: .
scope: meta.property-name.stylus support.type.property-name.stylus
- match: '@extends?\s'
captures:
0: keyword.language.stylus
push:
- match: (?=$|;)
pop: true
- include: selector-components
- include: string-quoted
- include: escape
- include: language-constants
- include: language-operators
- include: language-keywords
- include: property-reference
- include: function-call
- match: '\{'
scope: punctuation.section.start.stylus
- match: '\}'
scope: punctuation.section.end.stylus
attribute-selector:
- match: '\[(?=[^\]]*\])'
captures:
0: punctuation.definition.entity.start.stylus
push:
- meta_scope: meta.attribute-selector.stylus
- match: '\]'
captures:
0: punctuation.definition.entity.end.stylus
pop: true
- match: '(?<=\[)|(?<=\{)'
push:
- match: '(?=[|~=\]\s])'
pop: true
- include: interpolation
- match: .
captures:
0: entity.other.attribute-name.stylus
- include: interpolation
- match: "([|~]?=)"
captures:
1: keyword.operator.stylus
- include: string-quoted
- match: .
captures:
0: string.unquoted.stylus
color-values:
- match: \b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b
scope: constant.color.w3c-standard-color-name.stylus
- match: (hsla?|rgba?)\s*(\()
captures:
1: keyword.language.function.misc.stylus
2: punctuation.definition.parameters.start.stylus
push:
- match: \)
captures:
0: punctuation.definition.parameters.end.stylus
pop: true
- match: |-
(?x) # multi-line regex definition mode
\b
(?:0*((?:1?[0-9]{1,2})|(?:2(?:[0-4][0-9]|5[0-5])))\s*(,)\s*)
(?:0*((?:1?[0-9]{1,2})|(?:2(?:[0-4][0-9]|5[0-5])))\s*(,)\s*)
(?:0*((?:1?[0-9]{1,2})|(?:2(?:[0-4][0-9]|5[0-5])))\b)
captures:
1: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.red.stylus
2: punctuation.delimiter.comma.stylus
3: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.green.stylus
4: punctuation.delimiter.comma.stylus
5: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.blue.stylus
- match: |-
(?x) # multi-line regex definition mode
\b
((?:[0-9]{1,2}|100)%)(,) # red
\s*
((?:[0-9]{1,2}|100)%)(,) # green
\s*
((?:[0-9]{1,2}|100)%) # blue
captures:
1: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.red.stylus
2: punctuation.delimiter.comma.stylus
3: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.green.stylus
4: punctuation.delimiter.comma.stylus
5: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.blue.stylus
- match: |-
(?x) # multi-line regex definition mode
(?:\s*(,)\s*((0?\.[0-9]+)|[0-1]))?
captures:
1: punctuation.delimiter.comma.stylus
2: constant.other.color.rgb-value.stylus constant.other.color.rgb-value.alpha.stylus
- include: numeric-values
- include: numeric-values
comma:
- match: \s*,\s*
scope: punctuation.delimiter.comma.stylus
comments:
- include: single-line-comment
- match: \/\*
captures:
0: punctuation.definition.comment.stylus
push:
- meta_scope: comment.block.stylus
- match: \*\/
captures:
0: punctuation.definition.comment.stylus
pop: true
conditionals:
- match: '(^\s*|\s+)(if|unless|else)(?=[\s({]|$)\s*'
captures:
2: keyword.control.stylus
push:
- match: '(?=$|\{)'
pop: true
- include: expression
escape:
- match: \\.
scope: constant.character.escape.stylus
expression:
- include: single-line-comment
- include: comma
- include: iteration
- include: conditionals
- include: language-operators
- include: language-keywords
- include: hash-definition
- include: color-values
- include: url
- include: function-call
- include: string-quoted
- include: escape
- include: hash-access
- include: language-constants
- include: language-property-value-constants
- include: property-reference
- include: variable
function-call:
- match: '([\w$-]+)(\()'
captures:
1: entity.function-name.stylus
2: punctuation.definition.parameters.start.stylus
push:
- meta_scope: meta.function-call.stylus
- match: (\))
captures:
1: punctuation.definition.parameters.end.stylus
pop: true
- include: expression
hash-access:
- match: '(?=[\w$-]+(?:\.|\[[^\]=]*\]))'
push:
- meta_scope: meta.hash-access.stylus
- match: '(?=[^''''""\[\]\w.$-]|\s|$)'
pop: true
- match: \.
scope: punctuation.delimiter.hash.stylus
- match: '\['
scope: punctuation.definition.entity.start.stylus
- match: '\]'
scope: punctuation.definition.entity.end.stylus
- include: string-quoted
- include: variable
hash-definition:
- match: '\{'
captures:
0: punctuation.section.embedded.start.stylus
push:
- meta_scope: meta.hash.stylus
- match: '\}'
captures:
0: punctuation.section.embedded.end.stylus
pop: true
- include: single-line-comment
- match: |-
(?x)
(?:
([\w$-]+)
|
('[^']*')
|
("[^"]*")
)
\s*
(:)
\s*
captures:
1: support.type.property-name.stylus
2: string.quoted.single.stylus
3: string.quoted.double.stylus
4: punctuation.separator.key-value.stylus
push:
- match: '(;)|(?=\}|$)'
captures:
1: punctuation.terminator.statement.stylus
pop: true
- include: expression
interpolation:
- match: '\{'
captures:
0: punctuation.section.embedded.start.stylus
push:
- meta_scope: stylus.embedded.source
- match: '\}'
captures:
0: punctuation.section.embedded.end.stylus
pop: true
- include: expression
iteration:
- match: (^\s*|\s+)(for)\s+(?=.*?\s+in\s+)
captures:
2: keyword.control.stylus
push:
- match: '$|\{'
pop: true
- include: expression
language-constants:
- match: \b(true|false|null)\b
scope: constant.language.stylus
language-keywords:
- match: (\b|\s)(return|else)\b
scope: keyword.control.stylus
- match: (\b|\s)(!important|in|is defined|is a)\b
scope: keyword.other.stylus
- match: \barguments\b
scope: variable.language.stylus
language-operators:
- match: ((?:\?|:|!|~|\+|-|(?:\*)?\*|\/|%|(\.)?\.\.|<|>|(?:=|:|\?|\+|-|\*|\/|%|<|>)?=|!=)|\b(?:in|is(?:nt)?|(?<!:)not)\b)
scope: keyword.operator.stylus
language-property-value-constants:
- match: \b(absolute|all(-scroll)?|always|armenian|auto|avoid|baseline|below|bidi-override|block|bold(er)?|(border|content|padding)-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|crosshair|cursive|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fantasy|fixed|geometricPrecision|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|monospace|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|optimize(Legibility|Quality|Speed)|outset|outside|overline|pointer|pre(-(wrap|line))?|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|(sans-)?serif|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|sub|super|sw-resize|table(-(row|cell|footer-group|header-group))?|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical(-(ideographic|text))?|visible(Painted|Fill|Stroke)?|w-resize|wait|whitespace|zero|smaller|larger|((xx?-)?(small(er)?|large(r)?))|painted|fill|stroke)\b
scope: constant.property-value.stylus
media-query:
- match: '\s*(?![{;]|$)'
push:
- meta_scope: meta.at-rule.media.stylus
- match: '\s*(?=[{;]|$)'
pop: true
- match: '(?i)\s*(only|not)?\s*(all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)?(?![\w\d$-]+)'
captures:
1: keyword.operator.logic.media.stylus
2: support.constant.media.stylus
push:
- match: '\s*(?:(,)|(?=[{;]|$))'
pop: true
- include: media-query-list
- include: variable
media-query-list:
- match: \s*(and)?\s*(\()\s*
captures:
1: keyword.operator.logic.media.stylus
2: punctuation.definition.parameters.start.stylus
push:
- match: \)
captures:
0: punctuation.definition.parameters.end.stylus
pop: true
- include: media-query-properties
- include: numeric-values
media-query-properties:
- match: \s*:\s*
captures:
0: punctuation.separator.key-value.stylus
- match: |-
(?x)
(
((min|max)-)?
(
((device-)?(height|width|aspect-ratio))|
(color(-index)?)|monochrome|resolution
)
)|grid|scan|orientation
captures:
0: support.type.property-name.media.stylus
- match: \b(portrait|landscape|progressive|interlace)\b
captures:
1: support.constant.property-value.stylus
numeric-values:
- match: |-
(?x) # multi-line regex definition mode
(\#)(?:
([0-9a-fA-F])
([0-9a-fA-F])
([0-9a-fA-F])
([0-9a-fA-F])?
| ([0-9a-fA-F]{2})
([0-9a-fA-F]{2})
([0-9a-fA-F]{2})
([0-9a-fA-F]{2})?
)\b
scope: constant.other.color.rgb-value.stylus
captures:
1: punctuation.definition.constant.stylus
2: constant.other.color.rgb-value.red.stylus
3: constant.other.color.rgb-value.green.stylus
4: constant.other.color.rgb-value.blue.stylus
5: constant.other.color.rgb-value.alpha.stylus
6: constant.other.color.rgb-value.red.stylus
7: constant.other.color.rgb-value.green.stylus
8: constant.other.color.rgb-value.blue.stylus
9: constant.other.color.rgb-value.alpha.stylus
- match: |-
(?x) # multi-line regex definition mode
(?:-|\+)? # negative / positive
(?:
(?:
[0-9]+ # integer part
(?:\.[0-9]+)? # fraction
) |
(?:\.[0-9]+) # fraction without leading zero
)
((?: # units
px|pt|ch|cm|mm|in|
r?em|ex|pc|vw|vh|vmin|vmax|deg|
g?rad|turn|dpi|dpcm|dppx|m?s|k?Hz
)\b|%)?
scope: constant.numeric.stylus
captures:
1: keyword.other.unit.stylus
property-reference:
- match: "@[a-z-]+"
scope: variable.other.property.stylus
pseudo:
- match: (:)(active|checked|default|disabled|empty|enabled|first-child|first-of-type|first|fullscreen|focus|hover|indeterminate|in-range|invalid|last-child|last-of-type|left|link|only-child|only-of-type|optional|out-of-range|read-only|read-write|required|right|root|scope|target|valid|visited)\b
scope: entity.other.attribute-name.pseudo-class.stylus
captures:
1: puncutation.definition.entity.stylus
- match: (:?:)(before|after)\b
scope: entity.other.attribute-name.pseudo-element.stylus
captures:
1: puncutation.definition.entity.stylus
- match: (::)(first-letter|first-number|selection)\b
scope: entity.other.attribute-name.pseudo-element.stylus
captures:
1: puncutation.definition.entity.stylus
- match: ((:)dir)\s*(?:(\()(ltr|rtl)?(\)))?
captures:
1: entity.other.attribute-name.pseudo-element.stylus
2: puncutation.definition.entity.stylus
3: puncutation.definition.parameters.start.stylus
4: constant.language.stylus
5: puncutation.definition.parameters.end.stylus
- match: ((:)lang)\s*(?:(\()(\w+(-\w+)?)?(\)))?
captures:
1: entity.other.attribute-name.pseudo-element.stylus
2: puncutation.definition.entity.stylus
3: puncutation.definition.parameters.start.stylus
4: constant.language.stylus
5: puncutation.definition.parameters.end.stylus
- include: pseudo-nth
- include: pseudo-not
pseudo-not:
- match: ((:)not)\s*(\()
captures:
1: entity.other.attribute-name.pseudo-element.stylus
2: puncutation.definition.entity.stylus
3: puncutation.definition.parameters.start.stylus
push:
- match: \)
captures:
0: puncutation.definition.parameters.end.stylus
pop: true
- include: selector-components
pseudo-nth:
- match: ((:)(?:nth-child|nth-last-child|nth-of-type|nth-last-of-type|nth-match|nth-last-match|nth-column|nth-last-column))\s*(\()
captures:
1: entity.other.attribute-name.pseudo-class.stylus
2: puncutation.definition.entity.stylus
3: puncutation.definition.parameters.start.stylus
push:
- match: \)
captures:
0: puncutation.definition.parameters.end.stylus
pop: true
- include: language-operators
- include: interpolation
- match: \b(odd|even)\b
scope: constant.language.stylus
- match: \b(\d+)?n\b
scope: variable.language.stylus
captures:
1: constant.numeric.stylus
- match: \d+
scope: constant.numeric.stylus
return:
- match: ^\s*(return)
captures:
1: keyword.control.stylus
push:
- match: (;)|(?=$)
captures:
1: punctuation.terminator.statement.stylus
pop: true
- include: expression
selector-components:
- include: comments
- include: interpolation
- include: attribute-selector
- include: pseudo
- match: '\$[\w$-]+\b'
scope: entity.other.placeholder.stylus
- match: "[:~>]"
scope: keyword.operator.selector.stylus
- match: |-
(?x) # multi-line regex definition mode
\b(
altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|
animateMotion|animateTransform|circle|clipPath|color-profile|
defs|desc|ellipse|feBlend|feColorMatrix|
feComponentTransfer|feComposite|feConvolveMatrix|
feDiffuseLighting|feDisplacementMap|feDistantLight|feFlood|
feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|
feMergeNode|feMorphology|feOffset|fePointLight|
feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|
font-face|font-face-format|font-face-name|font-face-src|
font-face-uri|foreignObject|g|glyph|glyphRef|hkern|image|line|
linearGradient|marker|mask|metadata|missing-glyph|mpath|path|
pattern|polygon|polyline|radialGradient|rect|set|stop|svg|
switch|symbol|text|textPath|tref|tspan|use|view|vkern|
a|abbr|acronym|address|applet|area|article|aside|audio|b|base|
basefont|bdi|bdo|bgsound|big|blink|blockquote|body|br|button|
canvas|caption|center|cite|code|col|colgroup|content|data|
datalist|dd|decorator|del|details|dfn|dir|div|dl|dt|element|
em|embed|fieldset|figcaption|figure|font|footer|form|frame|
frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|
img|input|ins|isindex|kbd|keygen|label|legend|li|link|listing|
main|map|mark|marquee|menu|menuitem|meta|meter|nav|nobr|
noframes|noscript|object|ol|optgroup|option|output|p|param|
plaintext|pre|progress|q|rp|rt|ruby|s|samp|script|section|
select|shadow|small|source|spacer|span|strike|strong|style|
sub|summary|sup|table|tbody|td|template|textarea|tfoot|th|
thead|time|title|tr|track|tt|u|ul|var|video|wbr|xmp
)\b
scope: entity.name.tag.stylus
- match: '\.[a-zA-Z0-9_-]+'
scope: entity.other.attribute-name.class.stylus
- match: "#[a-zA-Z0-9_-]+"
scope: entity.other.attribute-name.id.stylus
- match: |-
(?x) # multi-line regex definition mode
([\w\d_-]+)? # matching any word right before &
(&) # & itself, escaped because of plist
([\w\d_-]+)? # matching any word right after &
captures:
1: entity.other.attribute-name.stylus
2: variable.language.stylus
3: entity.other.attribute-name.stylus
single-line-comment:
- match: (\/\/).*$
scope: comment.line.stylus
captures:
1: punctuation.definition.comment.stylus
string-quoted:
- match: "'[^']*'"
scope: string.quoted.single.stylus
- match: '"[^"]*"'
scope: string.quoted.double.stylus
url:
- match: (url)\s*(\()
captures:
1: entity.function-name.stylus
2: punctuation.definition.parameters.start.stylus
push:
- meta_scope: meta.function-call.stylus
- match: (\))
captures:
1: punctuation.definition.parameters.end.stylus
pop: true
- include: string-quoted
- include: language-constants
- include: language-property-value-constants
- include: property-reference
- include: variable
variable:
- match: '([\w$-]+\b)'
scope: variable.other.stylus
+56 -35
View File
@@ -9,10 +9,7 @@ contexts:
main:
- include: directives
- include: statements
- match: \A(#!).*(?=$)
scope: comment.line.shebang.ts
captures:
1: punctuation.definition.comment.ts
- include: shebang
comment:
- match: /\*\*(?!/)
captures:
@@ -120,7 +117,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -815,7 +812,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -856,7 +853,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -918,7 +915,7 @@ contexts:
captures:
1: keyword.control.as.ts
push:
- match: '(?=$|^|[;,:})\]]|\|\||\&\&|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(as)\s+)|(\s+\<))'
- match: '(?=^|[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(as)\s+)|(\s+\<))'
pop: true
- include: type
- match: \.\.\.
@@ -933,7 +930,7 @@ contexts:
scope: keyword.operator.comparison.ts
- match: <=|>=|<>|<|>
scope: keyword.operator.relational.ts
- match: '(\!)\s*(/)(?![/*])'
- match: '(?<=[_$[:alnum:]])(\!)\s*(/)(?![/*])'
captures:
1: keyword.operator.logical.ts
2: keyword.operator.arithmetic.ts
@@ -1038,7 +1035,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -1079,7 +1076,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -1125,25 +1122,42 @@ contexts:
- match: \*
scope: keyword.generator.asterisk.ts
function-call:
- match: '(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))\s*(?:(\?\.\s*)|(\!))?(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\()'
- match: '(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))\s*(?:(\?\.\s*)|(\!))?((<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\())'
push:
- match: '(?<=\))(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))\s*(?:(\?\.\s*)|(\!))?(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\()'
- match: '(?<=\))(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))\s*(?:(\?\.\s*)|(\!))?((<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\())'
pop: true
- match: '(?=(([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))'
push:
- meta_scope: meta.function-call.ts
- match: '(?=\s*(?:(\?\.\s*)|(\!))?(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\()'
- match: '(?=\s*(?:(\?\.\s*)|(\!))?((<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?\())'
pop: true
- include: support-function-call-identifiers
- match: '(\#?[_$[:alpha:]][_$[:alnum:]]*)'
scope: entity.name.function.ts
- include: function-call-target
- include: comment
- match: \?\.
scope: meta.function-call.ts punctuation.accessor.optional.ts
- match: \!
scope: meta.function-call.ts keyword.operator.definiteassignment.ts
- include: function-call-optionals
- include: type-arguments
- include: paren-expression
- match: '(?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$))'
push:
- match: '(?<=\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$))'
pop: true
- match: '(?=(([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))'
push:
- meta_scope: meta.function-call.ts
- match: '(?=(<\s*[\{\[\(]\s*$))'
pop: true
- include: function-call-target
- include: comment
- include: function-call-optionals
- include: type-arguments
function-call-optionals:
- match: \?\.
scope: meta.function-call.ts punctuation.accessor.optional.ts
- match: \!
scope: meta.function-call.ts keyword.operator.definiteassignment.ts
function-call-target:
- include: support-function-call-identifiers
- match: '(\#?[_$[:alpha:]][_$[:alnum:]]*)'
scope: entity.name.function.ts
function-declaration:
- match: '(?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(?:(\bexport)\s+)?(?:(\bdeclare)\s+)?(?:(async)\s+)?(function\b)(?:\s*(\*))?(?:(?:\s+|(?<=\*))([_$[:alpha:]][_$[:alnum:]]*))?\s*'
captures:
@@ -1221,7 +1235,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -1431,7 +1445,7 @@ contexts:
captures:
1: keyword.operator.expression.instanceof.ts
push:
- match: '(?<=\))|(?=[;),}\]:?]|\|\||\&\&|$|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))function((\s+[_$[:alpha:]][_$[:alnum:]]*)|(\s*[\(]))))'
- match: '(?<=\))|(?=[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|(([\&\~\^\|]\s*)?[_$[:alpha:]][_$[:alnum:]]*\s+instanceof(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)))|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))function((\s+[_$[:alpha:]][_$[:alnum:]]*)|(\s*[\(]))))'
pop: true
- include: type
interface-declaration:
@@ -1582,7 +1596,7 @@ contexts:
1: keyword.operator.new.ts
push:
- meta_scope: new.expr.ts
- match: '(?<=\))|(?=[;),}\]:\-\+]|\|\||\&\&|$|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))new(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)))|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))function((\s+[_$[:alpha:]][_$[:alnum:]]*)|(\s*[\(]))))'
- match: '(?<=\))|(?=[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))new(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)))|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))function((\s+[_$[:alpha:]][_$[:alnum:]]*)|(\s*[\(]))))'
pop: true
- include: paren-expression
- include: class-declaration
@@ -1864,7 +1878,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -1900,7 +1914,7 @@ contexts:
1: keyword.control.as.ts
push:
- meta_scope: meta.object.member.ts
- match: '(?=$|^|[,}]|\|\||\&\&|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(as)\s+))'
- match: '(?=[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|^|((?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(as)\s+))'
pop: true
- include: type
- match: '(?=[_$[:alpha:]][_$[:alnum:]]*\s*=)'
@@ -2010,7 +2024,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -2051,7 +2065,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -2313,6 +2327,11 @@ contexts:
- include: type-object
- include: type-predicate-operator
- include: type
shebang:
- match: \A(#!).*(?=$)
scope: comment.line.shebang.ts
captures:
1: punctuation.definition.comment.ts
single-line-comment-consuming-line-ending:
- match: '(^[ \t]+)?((//)(?:\s*((@)internal)(?=\s|$))?)'
captures:
@@ -2684,20 +2703,20 @@ contexts:
0: case-clause.expr.ts punctuation.definition.section.case-statement.ts
- include: statements
template:
- match: '(?=(([_$[:alpha:]][_$[:alnum:]]*\s*\??\.\s*)*|(\??\.\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?`)'
- match: '(?=(([_$[:alpha:]][_$[:alnum:]]*\s*\??\.\s*)*|(\??\.\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?`)'
push:
- meta_scope: string.template.ts
- match: (?=`)
pop: true
- match: '(?=(([_$[:alpha:]][_$[:alnum:]]*\s*\??\.\s*)*|(\??\.\s*)?)([_$[:alpha:]][_$[:alnum:]]*))'
push:
- match: '(?=(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?`)'
- match: '(?=(<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)?`)'
pop: true
- include: support-function-call-identifiers
- match: "([_$[:alpha:]][_$[:alnum:]]*)"
scope: entity.name.function.tagged-template.ts
- include: type-arguments
- match: '([_$[:alpha:]][_$[:alnum:]]*)\s*(?=(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''[^\'']*\'')|(\"[^\"]*\")|(\`[^\`]*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)`)'
- match: '([_$[:alpha:]][_$[:alnum:]]*)\s*(?=(<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|awaited|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\''([^\''\\]|\\.)*\'')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(?<==)\>)*(?<!=)\>))*(?<!=)\>)*(?<!=)>\s*)`)'
captures:
1: entity.name.function.tagged-template.ts
push:
@@ -2974,6 +2993,8 @@ contexts:
scope: keyword.operator.ternary.ts
- match: '(?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))infer(?=\s+[_$[:alpha:]])'
scope: keyword.operator.expression.infer.ts
- match: '(?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))awaited(?=\s+[_$[:alpha:]])'
scope: keyword.operator.expression.awaited.ts
- match: '(?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))import(?=\s*\()'
scope: keyword.operator.expression.import.ts
type-parameters:
@@ -3159,7 +3180,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -3200,7 +3221,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -3246,7 +3267,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
@@ -3287,7 +3308,7 @@ contexts:
# arrow function possible to detect only with => on same line
(
(<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<]|\<\s*([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\[([^\[\]]|(\[[^\[\]]*\]))*\]))([^=<>]|=[^<])*\>)*\>)*>\s*)? # typeparameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()]|(\(([^\(\)]|(\([^\(\)]*\)))*\)))*)?\) # parameters
\(\s*(\/\*([^\*]|(\*[^\/]))*\*\/\s*)*(([_$[:alpha:]]|(\{([^\{\}]|(\{[^\{\}]*\}))*\})|(\[([^\[\]]|(\[[^\[\]]*\]))*\])|(\.\.\.\s*[_$[:alpha:]]))([^()\'\"\`]|(\(([^\(\)]|(\([^\(\)]*\)))*\))|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))*)?\) # parameters
(\s*:\s*([^<>\(\)\{\}]|\<([^<>]|\<[^<>]+\>)+\>|\([^\(\)]+\)|\{[^\{\}]+\})+)? # return type
\s*=> # arrow operator
)
+1 -1
View File
@@ -7,7 +7,7 @@ file_extensions:
scope: whitespace
contexts:
main:
- match: ""
- match: "·"
scope: support.function.show-nonprintable.space
- match: "├─*┤"
scope: constant.character.escape.show-nonprintable.tab
BIN
View File
Binary file not shown.
Vendored Submodule
+1
Submodule assets/themes/Solarized added at 87e01090cf
+551
View File
@@ -0,0 +1,551 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!--
Most base16 users should use the base16 theme. This theme, base16-256,
is for users who configure their terminal with a 256-color variant of a
base16 theme, and who use base16-shell. DO NOT use this theme simply
because your terminal supports 256 colors.
base16: https://github.com/chriskempson/base16
base16-shell: https://github.com/chriskempson/base16-shell
The colors in this theme are encoded as #RRGGBBAA where RR is an ANSI
palette number from 00 to ff (the 256 terminal colors), and AA is the
special value 00 to indicate this encoding is being used.
-->
<key>author</key>
<string>Template: Chris Kempson, Scheme: Mitchell Kember</string>
<key>name</key>
<string>Base16 256</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>background</key>
<string>#00000000</string>
<key>caret</key>
<string>#07000000</string>
<key>foreground</key>
<string>#07000000</string>
<key>invisibles</key>
<string>#08000000</string>
<key>lineHighlight</key>
<string>#08000000</string>
<key>selection</key>
<string>#13000000</string>
<key>gutter</key>
<string>#12000000</string>
<key>gutterForeground</key>
<string>#08000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Text</string>
<key>scope</key>
<string>variable.parameter.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comments</string>
<key>scope</key>
<string>comment, punctuation.definition.comment</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#08000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Punctuation</string>
<key>scope</key>
<string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Delimiters</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operators</string>
<key>scope</key>
<string>keyword.operator</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keywords</string>
<key>scope</key>
<string>keyword</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variables</string>
<key>scope</key>
<string>variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Functions</string>
<key>scope</key>
<string>entity.name.function, meta.require, support.function.any-method</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#04000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Labels</string>
<key>scope</key>
<string>entity.name.label</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#11000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Classes</string>
<key>scope</key>
<string>support.class, entity.name.class, entity.name.type.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#03000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Classes</string>
<key>scope</key>
<string>meta.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#0f000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Methods</string>
<key>scope</key>
<string>keyword.other.special-method</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#04000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage</string>
<key>scope</key>
<string>storage</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Support</string>
<key>scope</key>
<string>support.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#06000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Strings, Inherited Class</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#02000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Integers</string>
<key>scope</key>
<string>constant.numeric</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Floats</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Boolean</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Constants</string>
<key>scope</key>
<string>constant</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tags</string>
<key>scope</key>
<string>entity.name.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#01000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Attributes</string>
<key>scope</key>
<string>entity.other.attribute-name</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Attribute IDs</string>
<key>scope</key>
<string>entity.other.attribute-name.id, punctuation.definition.entity</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#04000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Selector</string>
<key>scope</key>
<string>meta.selector</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Values</string>
<key>scope</key>
<string>none</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Headings</string>
<key>scope</key>
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#04000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Units</string>
<key>scope</key>
<string>keyword.other.unit</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Bold</string>
<key>scope</key>
<string>markup.bold, punctuation.definition.bold</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>bold</string>
<key>foreground</key>
<string>#03000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Italic</string>
<key>scope</key>
<string>markup.italic, punctuation.definition.italic</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Code</string>
<key>scope</key>
<string>markup.raw.inline</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#02000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Link Text</string>
<key>scope</key>
<string>string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#01000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Link Url</string>
<key>scope</key>
<string>meta.link</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Quotes</string>
<key>scope</key>
<string>markup.quote</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#10000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#13000000</string>
<key>foreground</key>
<string>#07000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#02000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#01000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Colors</string>
<key>scope</key>
<string>constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#06000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Regular Expressions</string>
<key>scope</key>
<string>string.regexp</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#06000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Escape Characters</string>
<key>scope</key>
<string>constant.character.escape</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#06000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Embedded</string>
<key>scope</key>
<string>punctuation.section.embedded, variable.interpolation</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#05000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Illegal</string>
<key>scope</key>
<string>invalid.illegal</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#01000000</string>
<key>foreground</key>
<string>#0f000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Broken</string>
<key>scope</key>
<string>invalid.broken</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#10000000</string>
<key>foreground</key>
<string>#00000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#11000000</string>
<key>foreground</key>
<string>#0f000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Unimplemented</string>
<key>scope</key>
<string>invalid.unimplemented</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#08000000</string>
<key>foreground</key>
<string>#0f000000</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>uuid</string>
</dict>
</plist>
+9 -2
View File
@@ -3,9 +3,16 @@
<plist version="1.0">
<dict>
<!--
This theme is meant for users who configure their terminal with a base16
color theme. If you use a 256-color variant along with base16-shell, use
the bat theme base16-256 instead.
base16: https://github.com/chriskempson/base16
base16-shell: https://github.com/chriskempson/base16-shell
The colors in this theme are encoded as #RRGGBBAA where RR is an ANSI
palette number from 00 to 0f, and AA is the special value 00 to indicate
that this encoding is being used.
palette number from 00 to 0f (the 8 colors and their bright versions),
and AA is the special value 00 to indicate this encoding is being used.
-->
<key>author</key>
<string>Template: Chris Kempson, Scheme: Mitchell Kember</string>
Vendored Submodule
+1
Submodule assets/themes/gruvbox added at e3db74d0e5
+42 -50
View File
@@ -1,66 +1,53 @@
// TODO: Re-enable generation of shell completion files (below) when clap 3 is out.
// For more details, see https://github.com/sharkdp/bat/issues/372
#[macro_use]
extern crate lazy_static;
extern crate liquid;
// For bat-as-a-library, no build script is required. The build script is for
// the manpage and completions, which are only relevant to the bat application.
#[cfg(not(feature = "application"))]
fn main() {}
use std::error::Error;
use std::fs;
use std::path::Path;
#[cfg(feature = "application")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::path::Path;
// Read environment variables.
lazy_static! {
pub static ref PROJECT_NAME: &'static str = option_env!("PROJECT_NAME").unwrap_or("bat");
pub static ref PROJECT_VERSION: &'static str = option_env!("CARGO_PKG_VERSION").unwrap();
pub static ref EXECUTABLE_NAME: &'static str = option_env!("PROJECT_EXECUTABLE")
.or(option_env!("PROJECT_NAME"))
.unwrap_or("bat");
}
// Read environment variables.
let project_name = option_env!("PROJECT_NAME").unwrap_or("bat");
let executable_name = option_env!("PROJECT_EXECUTABLE").unwrap_or(project_name);
let executable_name_uppercase = executable_name.to_uppercase();
static PROJECT_VERSION: &str = env!("CARGO_PKG_VERSION");
fn init_template() -> liquid::value::Object {
let mut globals = liquid::value::Object::new();
/// Generates a file from a template.
fn template(
variables: &HashMap<&str, &str>,
in_file: &str,
out_file: impl AsRef<Path>,
) -> Result<(), Box<dyn Error>> {
let mut content = fs::read_to_string(in_file)?;
globals.insert(
"PROJECT_NAME".into(),
liquid::value::Value::scalar(PROJECT_NAME.to_owned()),
);
for (variable_name, value) in variables {
// Replace {{variable_name}} by the value
let pattern = format!("{{{{{variable_name}}}}}", variable_name = variable_name);
content = content.replace(&pattern, value);
}
globals.insert(
"PROJECT_EXECUTABLE".into(),
liquid::value::Value::scalar(EXECUTABLE_NAME.to_owned()),
);
fs::write(out_file, content)?;
Ok(())
}
globals.insert(
"PROJECT_VERSION".into(),
liquid::value::Value::scalar(PROJECT_VERSION.to_owned()),
);
globals
}
/// Generates a file from a liquid template.
fn template(
variables: &liquid::value::Object,
in_file: &str,
out_file: impl AsRef<Path>,
) -> Result<(), Box<dyn Error>> {
let template = liquid::ParserBuilder::with_liquid()
.build()?
.parse(&fs::read_to_string(in_file)?)?;
fs::write(out_file, template.render(variables)?)?;
Ok(())
}
fn main() -> Result<(), Box<dyn Error>> {
let variables = init_template();
let mut variables = HashMap::new();
variables.insert("PROJECT_NAME", project_name);
variables.insert("PROJECT_EXECUTABLE", executable_name);
variables.insert("PROJECT_EXECUTABLE_UPPERCASE", &executable_name_uppercase);
variables.insert("PROJECT_VERSION", PROJECT_VERSION);
let out_dir_env = std::env::var_os("OUT_DIR").expect("OUT_DIR to be set in build.rs");
let out_dir = Path::new(&out_dir_env);
std::fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
std::fs::create_dir_all(out_dir.join("assets/completions")).unwrap();
fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
fs::create_dir_all(out_dir.join("assets/completions")).unwrap();
template(
&variables,
@@ -72,6 +59,11 @@ fn main() -> Result<(), Box<dyn Error>> {
"assets/completions/bat.fish.in",
out_dir.join("assets/completions/bat.fish"),
)?;
template(
&variables,
"assets/completions/bat.zsh.in",
out_dir.join("assets/completions/bat.zsh"),
)?;
Ok(())
}
-187
View File
@@ -1,187 +0,0 @@
#!/usr/bin/env bash
# Building and packaging for release
set -ex
# Ensure environment variables exist.
if [[ -z "$PROJECT_NAME" ]]; then
export PROJECT_NAME="bat"
fi
build() {
cargo build --bins --target "$TARGET" --release --verbose
}
pack() {
local tempdir
local out_dir
local package_name
local gcc_prefix
tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t tmp)
out_dir=$(pwd)
package_name="$PROJECT_NAME-$TRAVIS_TAG-$TARGET"
if [[ $TARGET == "arm-unknown-linux-gnueabihf" ]]; then
gcc_prefix="arm-linux-gnueabihf-"
elif [[ $TARGET == "aarch64-unknown-linux-gnu" ]]; then
gcc_prefix="aarch64-linux-gnu-"
else
gcc_prefix=""
fi
# create a "staging" directory
mkdir "$tempdir/$package_name"
mkdir "$tempdir/$package_name/autocomplete"
# copying the main binary
cp "target/$TARGET/release/$PROJECT_NAME" "$tempdir/$package_name/"
"${gcc_prefix}"strip "$tempdir/$package_name/$PROJECT_NAME"
# manpage, readme and license
cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/manual/bat.1 "$tempdir/$package_name/$PROJECT_NAME.1"
cp README.md "$tempdir/$package_name"
cp LICENSE-MIT "$tempdir/$package_name"
cp LICENSE-APACHE "$tempdir/$package_name"
# various autocomplete
# TODO: disabled for now, see issue #372
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".bash "$tempdir/$package_name/autocomplete/${PROJECT_NAME}.bash-completion"
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".fish "$tempdir/$package_name/autocomplete"
cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/completions/bat.fish "$tempdir/$package_name/autocomplete/$PROJECT_NAME.fish"
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/_"$PROJECT_NAME" "$tempdir/$package_name/autocomplete"
# archiving
pushd "$tempdir"
tar czf "$out_dir/$package_name.tar.gz" "$package_name"/*
popd
rm -r "$tempdir"
}
make_deb() {
local tempdir
local architecture
local version
local dpkgname
local conflictname
local gcc_prefix
local homepage
local maintainer
homepage="https://github.com/sharkdp/bat"
maintainer="David Peter <mail@david-peter.de>"
case $TARGET in
x86_64*)
architecture=amd64
gcc_prefix=""
;;
i686*)
architecture=i386
gcc_prefix=""
;;
aarch64*)
architecture=arm64
gcc_prefix="aarch64-linux-gnu-"
;;
arm*hf)
architecture=armhf
gcc_prefix="arm-linux-gnueabihf-"
;;
*)
echo "make_deb: skipping target '${TARGET}'" >&2
return 0
;;
esac
version=${TRAVIS_TAG#v}
if [[ $TARGET = *musl* ]]; then
dpkgname=$PROJECT_NAME-musl
conflictname=$PROJECT_NAME
else
dpkgname=$PROJECT_NAME
conflictname=$PROJECT_NAME-musl
fi
tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t tmp)
# copy the main binary
install -Dm755 "target/$TARGET/release/$PROJECT_NAME" "$tempdir/usr/bin/$PROJECT_NAME"
"${gcc_prefix}"strip "$tempdir/usr/bin/$PROJECT_NAME"
# manpage
install -Dm644 target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/manual/bat.1 "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
gzip --best "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
# completions
install -Dm644 target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/completions/bat.fish "$tempdir/usr/share/fish/vendor_completions.d/$PROJECT_NAME.fish"
# readme and license
install -Dm644 README.md "$tempdir/usr/share/doc/$PROJECT_NAME/README.md"
install -Dm644 LICENSE-MIT "$tempdir/usr/share/doc/$PROJECT_NAME/LICENSE-MIT"
install -Dm644 LICENSE-APACHE "$tempdir/usr/share/doc/$PROJECT_NAME/LICENSE-APACHE"
cat > "$tempdir/usr/share/doc/$PROJECT_NAME/copyright" <<EOF
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: $PROJECT_NAME
Source: $homepage
Files: *
Copyright: $maintainer
License: Apache-2.0 or MIT
License: Apache-2.0
On Debian systems, the complete text of the Apache-2.0 can be found in the
file /usr/share/common-licenses/Apache-2.0.
License: MIT
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
.
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
EOF
# Control file
mkdir "$tempdir/DEBIAN"
cat > "$tempdir/DEBIAN/control" <<EOF
Package: $dpkgname
Version: $version
Section: utils
Priority: optional
Maintainer: David Peter <mail@david-peter.de>
Architecture: $architecture
Provides: $PROJECT_NAME
Conflicts: $conflictname
Description: A cat(1) clone with wings.
A cat(1) clone with syntax highlighting and Git integration.
EOF
fakeroot dpkg-deb --build "$tempdir" "${dpkgname}_${version}_${architecture}.deb"
}
main() {
build
pack
if [[ $TARGET = *linux* ]]; then
make_deb
fi
}
main
-28
View File
@@ -1,28 +0,0 @@
# This script takes care of packaging the build artifacts that will go in the
# release zipfile
$SRC_DIR = $PWD.Path
$STAGE = [System.Guid]::NewGuid().ToString()
Set-Location $ENV:Temp
New-Item -Type Directory -Name $STAGE
Set-Location $STAGE
$ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip"
Copy-Item "$SRC_DIR\target\release\bat.exe" '.\'
# TODO: disabled for now, see issue #372
# Copy-Item $SRC_DIR\target\release\build\bat-*\out\_bat.ps1 '.\'
# readme and license
Copy-Item $SRC_DIR\README.md '.\'
Copy-Item $SRC_DIR\LICENSE-MIT '.\'
Copy-Item $SRC_DIR\LICENSE-APACHE '.\'
7z a "$ZIP" *
Push-AppveyorArtifact "$ZIP"
Set-Location ..
Remove-Item $STAGE -Force -Recurse
Set-Location $SRC_DIR
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env bash
set -ex
if [ "$TRAVIS_OS_NAME" != linux ]; then
exit 0
fi
sudo apt-get update
# needed for musl targets
sudo apt-get install -y musl-tools
# needed to build deb packages
sudo apt-get install -y fakeroot
# needed for i686 linux gnu target
if [[ $TARGET == i686-unknown-linux-gnu ]]; then
sudo apt-get install -y gcc-multilib
fi
# needed for cross-compiling for arm
if [[ $TARGET == arm-unknown-linux-gnueabihf ]]; then
sudo apt-get install -y \
gcc-4.8-arm-linux-gnueabihf \
binutils-arm-linux-gnueabihf \
libc6-armhf-cross \
libc6-dev-armhf-cross
fi
# needed for cross-compiling for arm64
if [[ $TARGET == aarch64-unknown-linux-gnu ]]; then
sudo apt-get install -y \
gcc-4.8-aarch64-linux-gnu \
binutils-aarch64-linux-gnu \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross
fi
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -ex
# Incorporate TARGET env var to the build and test process
cargo build --target "$TARGET" --verbose
# We cannot run arm executables on linux
if [[ $TARGET != arm-unknown-linux-gnueabihf ]] && [[ $TARGET != aarch64-unknown-linux-gnu ]]; then
cargo test --target "$TARGET" --verbose
# Run 'bat' on its own source code and the README
cargo run --target "$TARGET" -- src/bin/bat/main.rs README.md --paging=never
fi
View File
+102 -37
View File
@@ -2,6 +2,24 @@
_modules=('system' 'bat' 'bat_config' 'bat_wrapper' 'bat_wrapper_function' 'tool')
_modules_consented=()
set -o pipefail
export LC_ALL=C
export LANG=C
BAT="bat"
if ! command -v bat &>/dev/null; then
if command -v batcat &> /dev/null; then
BAT="batcat"
else
tput setaf 1
printf "%s\n%s\n" \
"Unable to find a bat executable on your PATH." \
"Please ensure that 'bat' exists and is not named something else."
tput sgr0
exit 1
fi
fi
# -----------------------------------------------------------------------------
# Modules:
@@ -9,6 +27,7 @@ _modules_consented=()
_bat_:description() {
_collects "Version information for 'bat'."
_collects "Custom syntaxes and themes for 'bat'."
}
_bat_config_:description() {
@@ -33,59 +52,92 @@ _tool_:description() {
_collects "Version information for 'less'."
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_bat_:run() {
_out bat --version
_out "$BAT" --version
_out env | grep '^BAT_\|^PAGER='
local cache_dir="$($BAT --cache-dir)"
if [[ -f "${cache_dir}/syntaxes.bin" ]]; then
_print_command "$BAT" "--list-languages"
echo "Found custom syntax set."
fi
if [[ -f "${cache_dir}/themes.bin" ]]; then
_print_command "$BAT" "--list-themes"
echo "Found custom theme set."
fi
}
_bat_config_:run() {
if [[ -f "$(bat --config-file)" ]]; then
_out_fence cat "$(bat --config-file)";
if [[ -f "$("$BAT" --config-file)" ]]; then
_out_fence cat "$("$BAT" --config-file)"
fi
}
_bat_wrapper_:run() {
if file "$(which bat)" | grep "text executable" &>/dev/null; then
_out_fence cat "$(which bat)"
return
_bat_wrapper_:detect_wrapper() {
local bat="$1"
if file "$(which "${bat}")" | grep "text executable" &> /dev/null; then
_out_fence cat "$(which "${bat}")"
return
fi
printf "\nNo wrapper script for '%s'.\n" "${bat}"
}
_bat_wrapper_:detect_wrapper bat
if [[ "$BAT" != "bat" ]]; then
_bat_wrapper_:detect_wrapper "$BAT"
fi
printf "\nNo wrapper script.\n"
}
_bat_wrapper_function_:run() {
case "$("$SHELL" --version | head -n 1)" in
*fish*)
if "$SHELL" --login -c 'type bat' 2>&1 | grep 'function' &>/dev/null; then
_out_fence "$SHELL" --login -c 'functions bat'
fi ;;
_bat_wrapper_function_:detect_wrapper() {
local command="$1"
case "$("$SHELL" --version | head -n 1)" in
*fish*)
if "$SHELL" --login -i -c "type ${command}" 2>&1 | grep 'function' &> /dev/null; then
_out_fence "$SHELL" --login -i -c "functions ${command}"
return
fi ;;
*bash*)
if "$SHELL" --login -c 'type bat' 2>&1 | grep 'function' &>/dev/null; then
_out_fence "$SHELL" --login -c 'declare -f bat'
fi ;;
*bash* | *zsh*)
local type="$("$SHELL" --login -i -c "type ${command}" 2>&1)"
if grep 'function' <<< "$type" &> /dev/null; then
_out_fence "$SHELL" --login -i -c "declare -f ${command}"
return
elif grep 'alias' <<< "$type" &> /dev/null; then
_out_fence "$SHELL" --login -i -c "type ${command}"
return
fi ;;
*)
echo "Unable to determine if a wrapper function is set."
return ;;
esac
printf "\nNo wrapper function.\n"
*)
echo "Unable to determine if a wrapper function for '${command}' is set."
return ;;
esac
printf "\nNo wrapper function for '%s'.\n" "${command}"
}
_bat_wrapper_function_:detect_wrapper bat
_bat_wrapper_function_:detect_wrapper cat
if [[ "$BAT" != "bat" ]]; then
_bat_wrapper_function_:detect_wrapper "$BAT"
fi
}
_system_:run() {
_out uname -srm
if command -v "sw_vers" &>/dev/null; then _out sw_vers; fi
if command -v "lsb_release" &>/dev/null; then _out lsb_release -a; fi
if command -v "sw_vers" &> /dev/null; then _out sw_vers; fi
if command -v "lsb_release" &> /dev/null; then _out lsb_release -a; fi
}
_tool_:run() {
_out less --version | head -n1
}
# -----------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------
@@ -109,7 +161,7 @@ _out_fence() {
}
_tput() {
tput "$@" 1>&2 2>/dev/null
tput "$@" 1>&2 2> /dev/null
}
_collects() {
@@ -120,7 +172,7 @@ _ask_module() {
_tput clear
_tput cup 0 0
cat 1>&2 <<EOF
cat 1>&2 << EOF
--------------------------------------------------------------------------------
This script runs some harmless commands to collect information about your
system and bat configuration. It will give you a small preview of the commands
@@ -135,7 +187,7 @@ EOF
_tput sgr0
"_$1_:description"
_tput sgr0
# Print preview.
_tput setaf 3
printf "\nThe following commands will be run:\n" 1>&2
@@ -143,19 +195,20 @@ EOF
declare -f "_$1_:run" \
| sed 's/^ *//; s/;$//' \
| grep '^_out[^ ]* ' \
| sed 's/^_out[^ ]* //' 1>&2
| sed 's/^_out[^ ]* //' \
| sed "s/\"\$BAT\"/$BAT/" 1>&2
# Prompt
printf "\n" 1>&2
local response
while true; do
_tput cup "$(( $(tput lines || echo 22) - 2 ))"
_tput cup "$(($( tput lines || echo 22) - 2))"
_tput el
read -er -p "Collect $(sed 's/_/ /' <<< "$1") data? [Y/n] " response
case "$response" in
Y|y|yes|'') return 0 ;;
N|n|no) return 1 ;;
*) continue
Y | y | yes | '') return 0 ;;
N | n | no) return 1 ;;
*) continue ;;
esac
done
}
@@ -166,13 +219,27 @@ _run_module() {
"_$1_:run"
}
# -----------------------------------------------------------------------------
# Functions:
# -----------------------------------------------------------------------------
# Tell the user if their executable isn't named "bat".
if [[ "$BAT" != "bat" ]] && [[ "$1" != '-y' ]]; then
trap '_tput rmcup; exit 1' INT
_tput smcup
_tput clear
_tput cup 0 0
_tput setaf 1
printf "The %s executable on your system is named '%s'.\n%s\n" "bat" "$BAT" \
"If your issue is related to installation, please check that this isn't the issue."
_tput sgr0
printf "Press any key to continue...\n"
read -rsn1
_tput rmcup
fi
# Ask for consent.
if [[ "$1" = '-y' ]]; then
if [[ "$1" == '-y' ]]; then
_modules_consented=("${_modules[@]}")
else
trap '_tput rmcup; exit 1' INT
@@ -190,5 +257,3 @@ for _module in "${_modules_consented[@]}"; do
_run_module "$_module" 2>&1
printf "\n"
done
+32 -23
View File
@@ -43,14 +43,14 @@
### ファイルの連結
あなたはさらにファイルを連結させるに使うことも可能です:wink:。
あなたはさらにファイルを連結させるために使うことも可能です:wink:。
`bat` は非対話型のターミナルを検出すると、
いつでも `cat` の完全互換として振る舞い、
プレーンなファイルを表示します。
## 使い方
単一のファイルを表示させたい
単一のファイルを表示させたい場合
```bash
> bat README.md
@@ -119,8 +119,7 @@ batgrep needle src/
```bash
tail -f /var/log/pacman.log | bat --paging=never -l log
```
Note that we have to switch off paging in order for this to work. We have also specified the syntax
explicitly (`-l log`), as it can not be auto-detected in this case.
注意事項:`tail -f`と組み合わせるには、ページングをオフにしなければなりません。また、この場合は構文が自動検出されないため、明示的に指定(`-l log`)しています。
#### `git`
@@ -168,19 +167,29 @@ man 2 select
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### On Ubuntu
### On Ubuntu (`apt` を使用)
*... や他のDebianベースのLinuxディストリビューション*
Ubuntu Eoan 19.10 または Debian 不安定版 sid 以降の [the Ubuntu `bat` package](https://packages.ubuntu.com/eoan/bat) または [the Debian `bat` package](https://packages.debian.org/sid/bat) インストールできます:
Ubuntu Eoan 19.10 または Debian 不安定版 sid 以降の [the Ubuntu `bat` package](https://packages.ubuntu.com/eoan/bat) または [the Debian `bat` package](https://packages.debian.org/sid/bat) からインストールできます:
```bash
apt install bat
```
`apt` を使用して `bat` をインストールした場合、実行可能ファイルの名前が `bat` ではなく `batcat` になることがあります([他のパッケージとの名前衝突のため](https://github.com/sharkdp/bat/issues/982))。`bat -> batcat` のシンボリックリンクまたはエイリアスを設定することで、実行可能ファイル名が異なることによる問題の発生を防ぎ、他のディストリビューションと一貫性を保てます。
``` bash
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
```
### On Ubuntu (最新の `.deb` パッケージを使用)
*... や他のDebianベースのLinuxディストリビューション
batの最新リリースを実行する場合、または Ubuntu/Debian の古いバージョンを使用している場合は、[release page](https://github.com/sharkdp/bat/releases) から最新の `.deb` パッケージをダウンロードし、
次の方法でインストールします:
```bash
sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
sudo dpkg -i bat_0.16.0_amd64.deb # adapt version number and architecture
```
### On Alpine Linux
@@ -220,7 +229,7 @@ emerge sys-apps/bat
### On Void Linux
xbps-ininstall経由で `bat` をインストールできます。
xbps-install経由で `bat` をインストールできます。
```
xbps-install -S bat
```
@@ -233,7 +242,7 @@ pkg を使用してプリコンパイルされた [`bat` package](https://www.fr
pkg install bat
```
または FreeBSD ポートから自分でビルドする:
または FreeBSD ポートから自分でビルドすることもできます:
```bash
cd /usr/ports/textproc/bat
@@ -336,16 +345,16 @@ ansible-galaxy install aeimer.install_bat
### From binaries
多くの異なるアーキテクチャのためのプレビルドバージョンを[リリースページ](https://github.com/sharkdp/bat/releases)からチェックしてみてください。静的にリンクされている多くのバイナリも利用できます: ファイル名に `musl` を含むアーカイブを探します
多くの異なるアーキテクチャのためのプレビルドバージョンを[リリースページ](https://github.com/sharkdp/bat/releases)からチェックしてみてください。静的にリンクされている多くのバイナリも利用できます: ファイル名に `musl` を含むアーカイブを探してみてください
### From source
`bat` をソースからビルドしたいならば、Rust 1.36 以上の環境が必要です。
そして `cargo` をビルドに対して使用します:
`cargo` を使用してビルドすることができます:
```bash
cargo install bat
cargo install --locked bat
```
一部のプラットフォームでは `llvm` および/または `libclang-dev` のインストールが必要になる場合があります。
@@ -387,7 +396,7 @@ bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
[Sublime Text の `.sublime-syntax` ファイル](https://www.sublimetext.com/docs/3/syntax.html)
とテーマを読み取ることができます。新しい構文を定義するために以下の手順を行います。
構文定義ファイルを入れておくためのフォルダを作:
構文定義ファイルを入れておくためのフォルダを作ります:
```bash
mkdir -p "$(bat --config-dir)/syntaxes"
@@ -428,13 +437,13 @@ git clone https://github.com/greggb/sublime-snazzy
bat cache --build
```
最後に、 `bat --list-themes` で新しいテーマが利用可能チェックします
最後に、 `bat --list-themes` で新しいテーマが利用可能チェックします
### 異なるページャーの使用
`bat` は環境変数 `PAGER` に使用するページャーを明記します。
この環境変数が定義されていない場合、デフォルトで `less` が使用されます。
もし、異なるページャー使用したい場合は、`PAGER` を修正してください。
もし、異なるページャー使用したい場合は、`PAGER` を修正してください。
または、`PAGER` を上書きする環境変数として `BAT_PAGER` を定義することも可能です。
もし、ページャーにコマンドライン引数を渡したい場合は、
@@ -526,14 +535,14 @@ Windows 10では、`conhost.exe` (コマンドプロンプト)と
[ConEmu](https://conemu.github.io/) を含む [Cmder](http://cmder.net/) を使用できます。
**注意:** Git と MSYS の `less` はWindows上で色を正しく解釈しません。
もし、あなたが他のページャーをインストールしていないのであれば、 `--paging=never` オプションを付け加える
または `BAT_PAGER` に空文字を設定することでページングを完全に無効にできます。
もし、あなたが他のページャーをインストールしていないのであれば、 `--paging=never` オプションを付け加える
`BAT_PAGER` に空文字を設定することでページングを完全に無効にできます。
### Cygwin
Windows上の `bat` は Cygwin のunix風のpath(`/cygdrive/*`)をネイティブサポートしていません。絶対的なcygwinパスを引数として受けたときに、 `bat` は以下のエラーを返すでしょう: `The system cannot find the path specified. (os error 3)`
wrapperを作成するまたは以下の関数を `.bash_profile` に追記することでこの問題を解決することができます:
wrapperを作成するか、以下の関数を `.bash_profile` に追記することでこの問題を解決することができます:
```bash
bat() {
@@ -553,7 +562,7 @@ bat() {
### ターミナルと色
`bat` はターミナルがトゥルーカラーをサポートしている/していない関係なくサポートします。
`bat` はターミナルがトゥルーカラーをサポートしている/していない関係なくサポートします。
しかし、シンタックスハイライトのテーマの色が8-bitカラーに最適化されていない場合、
24-bitであるトゥルーカラーをサポートしているターミナルを使用することを強く推奨します(`terminator`, `konsole`, `iTerm2`, ...)。
この [記事](https://gist.github.com/XVilka/8346728) には
@@ -594,11 +603,11 @@ cargo build --bins
cargo test
# Install (release version)
cargo install
cargo install --locked
# Build a bat binary with modified syntaxes and themes
bash assets/create.sh
cargo install -f
cargo install --locked --force
```
## Maintainers
@@ -610,10 +619,10 @@ cargo install -f
`bat` は以下の目標を達成しようと試みています:
- 美し高度なシンタックスハイライトの提供
- 美し高度なシンタックスハイライトの提供
- ファイルの差分を表示するためのGitとの連携
- (POSIX) `cat` との完全互換
- ユーザーフレンドリーコマンドラインインターフェースの提供
- ユーザーフレンドリーコマンドラインインターフェースの提供
あなたが同様のプログラムを探しているなら、多くの選択肢があります。
比較については [このドキュメント](alternatives.md) を参照してください。
+4 -4
View File
@@ -170,7 +170,7 @@ apt install bat
만약 최근 릴리즈된 bat을 사용을 원하거나 buntu/Debian 예전 버전을 사용하는 경우, [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다음과 같이 `.deb` 패키지를 받아 설치 할 수도 있습니다:
```bash
sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
sudo dpkg -i bat_0.16.0_amd64.deb # adapt version number and architecture
```
### On Alpine Linux
@@ -327,7 +327,7 @@ ansible-galaxy install aeimer.install_bat
`bat`의 소스를 직접 빌드하기 위해서는, Rust 1.36 이상이 필요하며 `cargo`를 이용해 빌드할 수 있습니다.
```bash
cargo install bat
cargo install --locked bat
```
일부 플랫폼에서는 `llvm` 그리고/또는 `libclang-dev` 설치가 필요할 수도 있습니다.
@@ -528,11 +528,11 @@ cargo build --bins
cargo test
# Install (release version)
cargo install
cargo install --locked
# Build a bat binary with modified syntaxes and themes
bash assets/create.sh
cargo install -f
cargo install --locked --force
```
## 메인테이너들
+594
View File
@@ -0,0 +1,594 @@
<p align="center">
<img src="doc/logo-header.svg" alt="bat - a cat clone with wings"><br>
<a href="https://travis-ci.org/sharkdp/bat"><img src="https://travis-ci.org/sharkdp/bat.svg?branch=master" alt="Build Status"></a>
<a href="https://ci.appveyor.com/project/sharkdp/bat"><img src="https://ci.appveyor.com/api/projects/status/cptsmtbiwbnr2vhf/branch/master?svg=true"></a>
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
Клон утилиты <i>cat(1)</i> с поддержкой выделения синтаксиса и Git
</p>
<p align="center">
<a href="#выделение-синтаксиса">Ключевые возможности</a> •
<a href="#как-использовать">Использование</a> •
<a href="#установка">Установка</a> •
<a href="#кастомизация">Кастомизация</a> •
<a href="#цели-и-альтернативы">Цели и альтернативы </a> •
Перевод [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="doc/README-ja.md">日本語</a>][<a href="doc/README-ko.md">한국어</a>][<a href="doc/README-ru.md">Русский</a>]
</p>
### Выделение синтаксиса
`bat` поддерживает выделение синтаксиса для огромного количества языков программирования и разметки:
![Пример выделения синтаксиса](https://i.imgur.com/3FGy5tW.png)
### Интеграция с Git
`bat` использует `git`, чтобы показать изменения в коде
(смотрите на левый сайдбар):
![Пример интеграции с Git](https://i.imgur.com/azUAzdx.png)
### Показать непечатаемые символы
Вы можете использовать `-A` / `--show-all` флаг, чтобы показать символы, которые невозможно напечатать:
![Строка с неотображемыми символами](https://i.imgur.com/X0orYY9.png)
### Автоматическое разделение текста
`bat` умеет перенаправлять вывод в `less`, если вывод не помещается на экране полностью.
### Объединение файлов
О... Вы также можете объединять файлы :wink:. Когда
`bat` обнаружит неинтерактивный терминал (например, когда вы перенаправляете вывод в файл или процесс), он будет работать как утилита `cat` и выведет содержимое файлов как обычный текст (без подсветки синтаксиса).
## Как использовать
Вывести единственный файл в терминале
```bash
> bat README.md
```
Отобразить сразу несколько файлов в терминале
```bash
> bat src/*.rs
```
Читаем из stdin и определяем синтаксис автоматически (внимание: это делается по заглавной строке файла, например, `#!/bin/sh`)
```bash
> curl -s https://sh.rustup.rs | bat
```
Прочитать из stdin с явным указанием языка
```bash
> yaml2json .travis.yml | json_pp | bat -l json
```
Вывести и выделить неотображаемые символы
```bash
> bat -A /etc/hosts
```
Использование в качестве замены `cat`
```bash
bat > note.md # мгновенно создаем новый файл
bat header.md content.md footer.md > document.md
bat -n main.rs # показываем только количество строк
bat f - g # выводит 'f' в stdin, а потом 'g'.
```
### Интеграция с другими утилитами
#### `find` или `fd`
Вы можете использовать флаг `-exec` в `find`, чтобы посмотреть превью всех файлов в `bat`
```bash
find … -exec bat {} +
```
Если вы используете [`fd`](https://github.com/sharkdp/fd), применяйте для этого флаг `-X`/`--exec-batch`:
```bash
fd … -X bat
```
#### `ripgrep`
С помощью [`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md), `bat` может быть использован для вывода результата запроса [`ripgrep`](https://github.com/BurntSushi/ripgrep)
```bash
batgrep needle src/
```
#### `tail -f`
`bat` может быть использован вместе с `tail -f`, чтобы выводить содержимое файла с подсветкой синтаксиса в реальном времени.
```bash
tail -f /var/log/pacman.log | bat --paging=never -l log
```
Заметьте, что мы должны отключить пэйджинг, чтобы это заработало. Мы также явно указали синтаксис (`-l log`), так как он не может быть автоматически определен в данном случае.
#### `git`
Вы можете использовать `bat` с `git show`, чтобы просмотреть старую версию файла с выделением синтаксиса:
```bash
git show v0.6.0:src/main.rs | bat -l rs
```
Обратите внимание, что выделение синтаксиса не работает в `git diff` на данный момент. Если вам это нужно, посмотрите [`delta`](https://github.com/dandavison/delta).
#### `xclip`
Нумерация стро и отображение изменений затрудняет копирование содержимого файлов в буфер обмена.
Чтобы спроваиться с этим, используйте флаг `-p`/`--plain` или просто перенаправьте стандартный вывод в `xclip`:
```bash
bat main.cpp | xclip
```
`bat` обнаружит перенаправление вывода и выведет обычный текст без выделения синтаксиса.
#### `man`
`bat` может быть использован в виде выделения цвета для `man`, для этого установите переменную окружения
`MANPAGER`:
```bash
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
man 2 select
```
Возможно вам понадобится также установить `MANROFFOPT="-c"`, если у вас есть проблемы с форматированием.
Если вы хотите сделать этой одной командой, вы можете использовать [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md).
Обратите внимание, что [синтаксис manpage](assets/syntaxes/02_Extra/Manpage.sublime-syntax) разрабатывается в этом репозитории и все еще находится в разработке.
#### `prettier` / `shfmt` / `rustfmt`
[`Prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) — скрипт, который форматирует код и выводит его с помощью `bat`.
## Установка
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### Ubuntu (с помощью `apt`)
*... и другие дистрибутивы основанные на Debian.*
`bat` есть в репозиториях [Ubuntu](https://packages.ubuntu.com/eoan/bat) и
[Debian](https://packages.debian.org/sid/bat) и доступен начиная с Ubuntu Eoan 19.10. На Debian `bat` пока что доступен только с нестабильной веткой "Sid".
Если ваша версия Ubuntu/Debian достаточно новая, вы можете установить `bat` так:
```bash
apt install bat
```
Если вы установили `bat` таким образом, то бинарный файл может быть установлен как `batcat` вместо `bat` (из-за [конфликта имени с другим пакетом](https://github.com/sharkdp/bat/issues/982)). Вы можете сделать симлинк или алиас `bat -> batcat`, чтобы предотвратить подобные проблемы и в других дистрибутивах.
``` bash
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
```
### Ubuntu (С помощью самого нового `.deb` пакета)
*... и другие дистрибутивы Linux основанные на Debian*
Если пакет еще недоступен в вашем Ubuntu/Debian дистрибутиве или вы хотите установить самую последнюю версию `bat`, то вы можете скачать самый последний `deb`-пакет отсюда:
[release page](https://github.com/sharkdp/bat/releases) и установить так:
```bash
sudo dpkg -i bat_0.16.0_amd64.deb # измените архитектуру и версию
```
### Alpine Linux
Вы можете установить [`bat`](https://pkgs.alpinelinux.org/packages?name=bat) из официальных источников:
```bash
apk add bat
```
### Arch Linux
Вы можете установить [`bat`](https://www.archlinux.org/packages/community/x86_64/bat/) из официального источника:
```bash
pacman -S bat
```
### Fedora
Вы можете установить [`bat`](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506) из официального репозитория [Fedora Modular](https://docs.fedoraproject.org/en-US/modularity/using-modules/).
```bash
dnf install bat
```
### Gentoo Linux
Вы можете установить [`bat`](https://packages.gentoo.org/packages/sys-apps/bat) из официальных источников:
```bash
emerge sys-apps/bat
```
### Void Linux
Вы можете установить `bat` с помощью `xbps-install`:
```bash
xbps-install -S bat
```
### FreeBSD
Вы можете установить [`bat`](https://www.freshports.org/textproc/bat) с помощью `pkg`:
```bash
pkg install bat
```
или самому скомпилировать его:
```bash
cd /usr/ports/textproc/bat
make install
```
### С помощью nix
Вы можете установить `bat`, используя [nix package manager](https://nixos.org/nix):
```bash
nix-env -i bat
```
### openSUSE
Вы можете установить `bat` с помощью `zypper`:
```bash
zypper install bat
```
### macOS
Вы можете установить `bat` с помощью [Homebrew](http://braumeister.org/formula/bat):
```bash
brew install bat
```
Или же установить его с помощью [MacPorts](https://ports.macports.org/port/bat/summary):
```bash
port install bat
```
### Windows
Есть несколько способов установить `bat`. Как только вы установили его, посмотрите на секцию ["Использование `bat` в Windows"](#using-bat-on-windows).
#### С помощью Chocolatey
Вы можете установить `bat` с помощью [Chocolatey](https://chocolatey.org/packages/Bat):
```bash
choco install bat
```
#### С помощью Scoop
Вы можете установить `bat` с помощью [scoop](https://scoop.sh/):
```bash
scoop install bat
```
Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
#### Из заранее скомпилированных файлов:
Их вы можете скачать на [странице релизов](https://github.com/sharkdp/bat/releases).
Для этого у вас должен быть установлен [Visual C++ Redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
### С помощью Docker
Вы можете использовать [Docker image](https://hub.docker.com/r/danlynn/bat/), чтобы запустить `bat` в контейнере:
```bash
docker pull danlynn/bat
alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat'
```
### С помощью Ansible
Вы можете установить `bat` с [Ansible](https://www.ansible.com/):
```bash
# Устанавливаем роль на устройстве
ansible-galaxy install aeimer.install_bat
```
```yaml
---
# Playbook для установки bat
- host: all
roles:
- aeimer.install_bat
```
- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat)
- [GitHub](https://github.com/aeimer/ansible-install-bat)
Этот способ должен сработать со следующими дистрибутивами:
- Debian/Ubuntu
- ARM (например Raspberry PI)
- Arch Linux
- Void Linux
- FreeBSD
- macOS
### Из скомпилированных файлов
Перейдите на [страницу релизов](https://github.com/sharkdp/bat/releases) для
скомпилированных файлов `bat` для различных платформ. Бинарные файлы со статической связкой так же доступны: выбирайте архив с `musl` в имени.
### Из исходников
Если вы желаете установить `bat` из исходников, вам понадобится Rust 1.40 или выше. После этого используйте `cargo`, чтобы все скомпилировать:
```bash
cargo install --locked bat
```
## Кастомизация
### Темы для выделения текста
Используйте `bat --list-themes`, чтобы вывести список всех доступных тем. Для выбора темы `TwoDark` используйте `bat` с флагом
`--theme=TwoDark` или выставьте переменную окружения `BAT_THEME` в `TwoDark`. Используйте `export BAT_THEME="TwoDark"` в конфигурационном файле вашей оболочки, чтобы изменить ее навсегда. Или же используйте [конфигурационный файл](https://github.com/sharkdp/bat#configuration-file) `bat`.
Если вы хотите просто просмотреть темы, используйте следующую команду (для этого вам понадобится [`fzf`](https://github.com/junegunn/fzf)):
```bash
bat --list-themes | fzf --preview="bat --theme={} --color=always /путь/к/файлу"
```
`bat` отлично смотрится на темном фоне. Однако если ваш терминал использует светлую тему, то такие темы как `GitHub` или `OneHalfLight` будут смотреться куда лучше!
Вы также можете использовать новую тему, для этого перейдите [в раздел добавления тем](https://github.com/sharkdp/bat#добавление-новых-тем).
### Изменение внешнего вывода
Вы можете использовать флаг `--style`, чтобы изменять внешний вид вывода в `bat`.
Например, вы можете использовать `--style=numbers,changes`, чтобы показать только количество строк и изменений в Git. Установите переменную окружения `BAT_STYLE` чтобы изменить это навсегда, или используйте [конфиг файл](https://github.com/sharkdp/bat#configuration-file) `bat`.
### Добавление новых синтаксисов
`bat` использует [`syntect`](https://github.com/trishume/syntect/) для выделения синтаксиса. `syntect` может читать
[файл `.sublime-syntax`](https://www.sublimetext.com/docs/3/syntax.html)
и темы. Чтобы добавить новый синтаксис, сделайте следующее:
Создайте каталог с синтаксисом:
```bash
mkdir -p "$(bat --config-dir)/syntaxes"
cd "$(bat --config-dir)/syntaxes"
# Разместите файлы '.sublime-syntax'
# в каталоге (или субкаталогах), например:
git clone https://github.com/tellnobody1/sublime-purescript-syntax
```
Теперь используйте следующую команду, чтобы превратить эти файлы в бинарный кеш:
```bash
bat cache --build
```
Теперь вы можете использовать `bat --list-languages`, чтобы проверить, доступны ли новые языки.
Если когда-нибудь вы заходите вернуться к настройкам по умолчанию, введите
```bash
bat cache --clear
```
### Добавление новых тем
Это работает похожим образом, так же как и добавление новых тем выделения синтаксиса
Во-первых, создайте каталог с новыми темами для синтаксиса:
```bash
mkdir -p "$(bat --config-dir)/themes"
cd "$(bat --config-dir)/themes"
# Загрузите тему в формате '.tmTheme':
git clone https://github.com/greggb/sublime-snazzy
# Обновите кеш
bat cache --build
```
Теперь используйте `bat --list-themes`, чтобы проверить доступность новых тем.
### Использование другого пейджера.
`bat` использует пейджер, указанный в переменной окружения `PAGER`. Если она не задана, то используется `less`.
Если вы желаете использовать другой пейджер, вы можете либо изменить переменную `PAGER`, либо `BAT_PAGER` чтобы перезаписать то, что указано в `PAGER`.
Чтобы передать дополнительные аргументы вашему пейджеру, перечислите их в этой переменной:
```bash
export BAT_PAGER="less -RF"
```
Так же вы можете использовать [файл конфигурации](https://github.com/sharkdp/bat#configuration-file) `bat` (флаг `--pager`).
**Внимание**: По умолчанию пейджером является`less` (без каких-либо аргументов),
`bat` задаст следующие флаги для пейджера:
`-R`/`--RAW-CONTROL-CHARS`,
`-F`/`--quit-if-one-screen` и `-X`/`--no-init`. Последний флаг(`-X`) используется только для `less`, чья версия раньше 530.
Флаг `-R` нужен чтобы корректно воспроизвести ANSI цвета. Второй флаг (`-F`) говорит
`less` чтобы тот сразу же завершился, если размер вывода меньше чем вертикальный размер терминала.
Это удобно для небольших файлов, так как вам не надо каждый раз нажимать `q`, чтобы выйти из пейджера. Третий флаг (`-X`) нужен для того, чтобы исправить баг с `--quit-if-one-screen` в старых версиях `less`. К сожалению, это блокирует возможность использования колеса мышки.
Если вы хотите все же его включить, вы можете добавить флаг `-R`.
Для `less` новее чем 530 оно должно работать из коробки.
### Темная тема
Если вы используете темный режим в macOS, возможно вы захотите чтобы `bat` использовал другую тему, основанную на теме вашей ОС. Следующий сниппет использует тему `default`, когда у вас включен темный режим, и тему `GitHub`, когда включен светлый.
```bash
alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)"
```
## Файл конфигурации
`bat` также может быть кастомизирован с помощью файла конфигурации. Его местоположение зависит от вашей ОС: чтобы посмотреть его путь, введите
```
bat --config-file
```
Также вы можете установить переменную окружения `BAT_CONFIG_PATH`, чтобы изменить путь к файлу конфигурации.
```bash
export BAT_CONFIG_PATH="/path/to/bat.conf"
```
Файл конфигурации «по умолчанию» может быть создан с помощью флага `--generate-config-file`.
```bash
bat --generate-config-file
```
### Формат
Файл конфигурации - это всего лишь набор аргументов. Введите `bat --help`, чтобы просмотреть список всех возможных флагов и аргументов. Также вы можете закомментировать строку с помощью `#`.
Пример файла конфигурации:
```bash
# Установить тему "TwoDark"
--theme="TwoDark"
# Показывать количество строк, изменений в Git и заголовок файла
--style="numbers,changes,header"
# Использовать курсив (поддерживается не всеми терминалами)
--italic-text=always
# Использовать синтаксис C++ для всех .ino файлов
--map-syntax "*.ino:C++"
# Использовать синтаксик Git Ignore для всех файлов .ignore
--map-syntax ".ignore:Git Ignore"
```
## Использование `bat` в Windows
`bat` полностью работоспособен "из коробки", но для некоторых возможностей могут понадобиться дополнительные настройки.
### Пейджинг
Windows поддерживает только очень простой пейджер `more`. Вы можете скачать установщик для `less` [с его сайта](http://www.greenwoodsoftware.com/less/download.html) или [через Chocolatey](https://chocolatey.org/packages/Less). Чтобы его использовать, скопируйте исполняемый файл в ваш `PATH` или [используйте переменную окружения](#Использование-другого-пейджера). [Пакет из Chocolatey](#windows) установит все автоматически.
### Цвета
Windows 10 поддерживает цвета и в `conhost.exe` (Command Prompt), и в PowerShell начиная с версии Windows
[v1511](https://ru.wikipedia.org/wiki/Windows_10#Обновления и поддержка), так же как и в bash. На ранних версиях Windows вы можете использовать
[Cmder](http://cmder.net/), в котором есть [ConEmu](https://conemu.github.io/).
**Внимание:** Версия `less` в Git и MSYS2 воспроизводит цвета некорректно. Если у вас нет других пейджеров, мы можете отключить использование пейджеров с помощью флага `--paging=never`
или установить `BAT_PAGER` равным пустой строке.
### Cygwin
Из коробки `bat` не поддерживает пути в стиле Unix (`/cygdrive/*`). Когда указан абсолютный путь cygwin, `bat` выдаст следующую ошибку: `The system cannot find the path specified. (os error 3)`
Она может быть решена добавлением следующей функции в `.bash_profile`:
```bash
bat() {
local index
local args=("$@")
for index in $(seq 0 ${#args[@]}) ; do
case "${args[index]}" in
-*) continue;;
*) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";;
esac
done
command bat "${args[@]}"
}
```
## Проблемы и их решение
### Терминалы и цвета
`bat` поддерживает терминалы *с* и *без* поддержки truecolor. Однако подсветка синтаксиса не оптимизирована для терминалов с 8-битными цветами, и рекомендуется использовать терминалы с поддержкой 24-битных цветов (`terminator`, `konsole`, `iTerm2`, ...).
Смотрите [эту статью](https://gist.github.com/XVilka/8346728) для полного списка терминалов.
Удостовертесь, что переменная `COLORTERM` равна `truecolor` или
`24bit`. Иначе `bat` не сможет определить поддержку 24-битных цветов (и будет использовать 8-битные).
### Текст и номера строк плохо видны
Используйте другую тему (`bat --list-themes` выведет список всех установленных тем). Темы `OneHalfDark` и
`OneHalfLight` имеют более яркие номера строк и тексты.
### Кодировки файлов
`bat` поддерживает UTF-8 и UTF-16. Файлы в других кодировках, возможно, придётся перекодировать, так как кодировка может быть распознана неверно. Используйте `iconv`.
Пример: у вас есть PHP файл в кодировке Latin-1 (ISO-8859-1):
``` bash
iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat
```
Внимание: вам может понадобится флаг `-l`/`--language`, если `bat` не сможет автоматически определить синтаксис.
## Разработка
```bash
# Рекурсивно клонирует все модули
git clone --recursive https://github.com/sharkdp/bat
# Компиляции в режиме разработки
cd bat
cargo build --bins
# Запуск тестов
cargo test
# Установка (релизная версия)
cargo install --locked
# Компилирование исполняего файла bat с другим синтаксисом и темами
bash assets/create.sh
cargo install --locked --force
```
## Разработчики
- [sharkdp](https://github.com/sharkdp)
- [eth-p](https://github.com/eth-p)
## Цели и альтернативы
Цели проекта `bat`:
- Красивая и продвинутая подсветка синтаксиса.
- Интеграция с Git.
- Полноценная замена `cat`.
- Дружелюбный интерфейс и аргументы.
Есть очень много альтернатив `bat`. Смотрите [этот документ](doc/alternatives.md) для сравнения.
## Лицензия
Copyright (c) 2018-2020 [Разработчики bat](https://github.com/sharkdp/bat).
`bat` распостраняется под лицензями MIT License и Apache License 2.0 (на выбор пользователя).
Смотрите [LICENSE-APACHE](LICENSE-APACHE) и [LICENSE-MIT](LICENSE-MIT) для более подробного ознакомления.
+18
View File
@@ -0,0 +1,18 @@
/// A program that prints its own source code using the bat library
use bat::{PagingMode, PrettyPrinter, WrappingMode};
fn main() {
PrettyPrinter::new()
.header(true)
.grid(true)
.line_numbers(true)
.use_italics(true)
// The following line will be highlighted in the output:
.highlight(line!() as usize)
.theme("1337")
.wrapping_mode(WrappingMode::Character)
.paging_mode(PagingMode::QuitIfOneScreen)
.input_file(file!())
.print()
.unwrap();
}
+8 -28
View File
@@ -1,33 +1,13 @@
/// A very simple colorized `cat` clone, using `bat` as a library.
/// See `src/bin/bat` for the full `bat` application.
use bat::{
config::{Config, InputFile, StyleComponent, StyleComponents},
Controller, HighlightingAssets,
};
use console::Term;
use std::process;
use bat::PrettyPrinter;
fn main() {
let files = std::env::args_os().skip(1).collect::<Vec<_>>();
if files.is_empty() {
eprintln!("No input files specified");
process::exit(1);
}
let config = Config {
term_width: Term::stdout().size().1 as usize,
colored_output: true,
true_color: true,
style_components: StyleComponents::new(&[
StyleComponent::Header,
StyleComponent::Grid,
StyleComponent::Numbers,
]),
files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
..Default::default()
};
let assets = HighlightingAssets::from_binary();
Controller::new(&config, &assets).run().expect("no errors");
PrettyPrinter::new()
.header(true)
.grid(true)
.line_numbers(true)
.input_files(std::env::args_os().skip(1))
.print()
.unwrap();
}
+19
View File
@@ -0,0 +1,19 @@
/// A small demonstration of the Input API.
/// This prints embedded bytes with a custom header and then reads from STDIN.
use bat::{Input, PrettyPrinter};
fn main() {
PrettyPrinter::new()
.header(true)
.grid(true)
.line_numbers(true)
.inputs(vec![
Input::from_bytes(b"echo 'Hello World!'")
.name("embedded.sh") // Dummy name provided to detect the syntax.
.kind("Embedded")
.title("An embedded shell script."),
Input::from_stdin().title("Standard Input").kind("FD"),
])
.print()
.unwrap();
}
+18
View File
@@ -0,0 +1,18 @@
/// A simple program that prints its own source code using the bat library
use bat::PrettyPrinter;
fn main() {
let printer = PrettyPrinter::new();
println!("Syntaxes:");
for syntax in printer.syntaxes() {
println!("- {} ({})", syntax.name, syntax.file_extensions.join(", "));
}
println!();
println!("Themes:");
for theme in printer.themes() {
println!("- {}", theme);
}
}
+2 -16
View File
@@ -1,20 +1,6 @@
/// A simple program that prints its own source code using the bat library
use bat::{
config::{Config, InputFile},
Controller, HighlightingAssets,
};
use std::ffi::OsStr;
use bat::PrettyPrinter;
fn main() {
let path_to_this_file = OsStr::new(file!());
let config = Config {
files: vec![InputFile::Ordinary(path_to_this_file)],
colored_output: true,
true_color: true,
..Default::default()
};
let assets = HighlightingAssets::from_binary();
Controller::new(&config, &assets).run().expect("no errors");
PrettyPrinter::new().input_file(file!()).print().unwrap();
}
+35
View File
@@ -0,0 +1,35 @@
/// A program that serializes a Rust structure to YAML and pretty-prints the result
use bat::{Input, PrettyPrinter};
use serde::Serialize;
#[derive(Serialize)]
struct Person {
name: String,
height: f64,
adult: bool,
children: Vec<Person>,
}
fn main() {
let person = Person {
name: String::from("Anne Mustermann"),
height: 1.76f64,
adult: true,
children: vec![Person {
name: String::from("Max Mustermann"),
height: 1.32f64,
adult: false,
children: vec![],
}],
};
let bytes = serde_yaml::to_vec(&person).unwrap();
PrettyPrinter::new()
.language("yaml")
.line_numbers(true)
.grid(true)
.header(true)
.input(Input::from_bytes(&bytes).name("person.yaml").kind("File"))
.print()
.unwrap();
}
+255 -61
View File
@@ -1,4 +1,5 @@
use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::BufReader;
use std::path::Path;
@@ -7,8 +8,11 @@ use syntect::dumps::{dump_to_file, from_binary, from_reader};
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
use crate::errors::*;
use crate::inputfile::{InputFile, InputFileReader};
use path_abs::PathAbs;
use crate::assets_metadata::AssetsMetadata;
use crate::error::*;
use crate::input::{InputReader, OpenedInput, OpenedInputKind};
use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
#[derive(Debug)]
@@ -67,8 +71,11 @@ impl HighlightingAssets {
})
}
pub fn from_cache(theme_set_path: &Path, syntax_set_path: &Path) -> Result<Self> {
let syntax_set_file = File::open(syntax_set_path).chain_err(|| {
pub fn from_cache(cache_path: &Path) -> Result<Self> {
let syntax_set_path = cache_path.join("syntaxes.bin");
let theme_set_path = cache_path.join("themes.bin");
let syntax_set_file = File::open(&syntax_set_path).chain_err(|| {
format!(
"Could not load cached syntax set '{}'",
syntax_set_path.to_string_lossy()
@@ -112,7 +119,7 @@ impl HighlightingAssets {
}
}
pub fn save_to_cache(&self, target_dir: &Path) -> Result<()> {
pub fn save_to_cache(&self, target_dir: &Path, current_version: &str) -> Result<()> {
let _ = fs::create_dir_all(target_dir);
let theme_set_path = target_dir.join("themes.bin");
let syntax_set_path = target_dir.join("syntaxes.bin");
@@ -141,6 +148,13 @@ impl HighlightingAssets {
})?;
println!("okay");
print!(
"Writing metadata to folder {} ... ",
target_dir.to_string_lossy()
);
AssetsMetadata::new(current_version).save_to_folder(target_dir)?;
println!("okay");
Ok(())
}
@@ -152,8 +166,23 @@ impl HighlightingAssets {
self.syntax_set.syntaxes()
}
pub fn themes(&self) -> impl Iterator<Item = &String> {
self.theme_set.themes.keys()
pub fn themes(&self) -> impl Iterator<Item = &str> {
self.theme_set.themes.keys().map(|s| s.as_ref())
}
pub fn syntax_for_file_name(
&self,
file_name: impl AsRef<Path>,
mapping: &SyntaxMapping,
) -> Option<&SyntaxReference> {
let file_name = file_name.as_ref();
match mapping.get_syntax_for(file_name) {
Some(MappingTarget::MapToUnknown) => None,
Some(MappingTarget::MapTo(syntax_name)) => {
self.syntax_set.find_syntax_by_name(syntax_name)
}
None => self.get_extension_syntax(file_name.as_os_str()),
}
}
pub(crate) fn get_theme(&self, theme: &str) -> &Theme {
@@ -168,7 +197,7 @@ impl HighlightingAssets {
theme
);
}
&self.theme_set.themes[self.fallback_theme.unwrap_or(Self::default_theme())]
&self.theme_set.themes[self.fallback_theme.unwrap_or_else(|| Self::default_theme())]
}
}
}
@@ -176,64 +205,99 @@ impl HighlightingAssets {
pub(crate) fn get_syntax(
&self,
language: Option<&str>,
filename: InputFile,
reader: &mut InputFileReader,
input: &mut OpenedInput,
mapping: &SyntaxMapping,
) -> &SyntaxReference {
let syntax = match (language, filename) {
(Some(language), _) => self.syntax_set.find_syntax_by_token(language),
(None, InputFile::Ordinary(filename)) => {
let path = Path::new(filename);
) -> Result<&SyntaxReference> {
if let Some(language) = language {
self.syntax_set
.find_syntax_by_token(language)
.ok_or_else(|| ErrorKind::UnknownSyntax(language.to_owned()).into())
} else {
let line_syntax = self.get_first_line_syntax(&mut input.reader);
let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
let extension = path.extension().and_then(|x| x.to_str()).unwrap_or("");
// Get the path of the file:
// If this was set by the metadata, that will take priority.
// If it wasn't, it will use the real file path (if available).
let path_str =
input
.metadata
.user_provided_name
.as_ref()
.or_else(|| match input.kind {
OpenedInputKind::OrdinaryFile(ref path) => Some(path),
_ => None,
});
let ext_syntax = self
.syntax_set
.find_syntax_by_extension(&file_name)
.or_else(|| self.syntax_set.find_syntax_by_extension(&extension));
let line_syntax = String::from_utf8(reader.first_line.clone())
if let Some(path_str) = path_str {
// If a path was provided, we try and detect the syntax based on extension mappings.
let path = Path::new(path_str);
let absolute_path = PathAbs::new(path)
.ok()
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l));
.map(|p| p.as_path().to_path_buf())
.unwrap_or_else(|| path.to_owned());
let absolute_path = path.canonicalize().ok().unwrap_or(path.to_owned());
match mapping.get_syntax_for(absolute_path) {
Some(MappingTarget::MapTo(syntax_name)) => {
// TODO: we should probably return an error here if this syntax can not be
// found. Currently, we just fall back to 'plain'.
self.syntax_set.find_syntax_by_name(syntax_name)
}
Some(MappingTarget::MapToUnknown) => line_syntax,
None => ext_syntax.or(line_syntax),
}
}
(None, InputFile::StdIn) => String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l)),
(_, InputFile::ThemePreviewFile) => self.syntax_set.find_syntax_by_name("Rust"),
};
Some(MappingTarget::MapToUnknown) => line_syntax.ok_or_else(|| {
ErrorKind::UndetectedSyntax(path.to_string_lossy().into()).into()
}),
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
Some(MappingTarget::MapTo(syntax_name)) => self
.syntax_set
.find_syntax_by_name(syntax_name)
.ok_or_else(|| ErrorKind::UnknownSyntax(syntax_name.to_owned()).into()),
None => {
let file_name = path.file_name().unwrap_or_default();
self.get_extension_syntax(file_name)
.or(line_syntax)
.ok_or_else(|| {
ErrorKind::UndetectedSyntax(path.to_string_lossy().into()).into()
})
}
}
} else {
// If a path wasn't provided, we fall back to the detect first-line syntax.
line_syntax.ok_or_else(|| ErrorKind::UndetectedSyntax("[unknown]".into()).into())
}
}
}
fn get_extension_syntax(&self, file_name: &OsStr) -> Option<&SyntaxReference> {
self.syntax_set
.find_syntax_by_extension(file_name.to_str().unwrap_or_default())
.or_else(|| {
self.syntax_set.find_syntax_by_extension(
Path::new(file_name)
.extension()
.and_then(|x| x.to_str())
.unwrap_or_default(),
)
})
}
fn get_first_line_syntax(&self, reader: &mut InputReader) -> Option<&SyntaxReference> {
String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))
}
}
#[cfg(test)]
mod tests {
use std::ffi::OsStr;
use std::fs::File;
use std::io;
use std::io::Write;
use super::*;
use std::ffi::OsStr;
use std::fs::File;
use std::io::Write;
use tempdir::TempDir;
use crate::assets::HighlightingAssets;
use crate::inputfile::InputFile;
use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
use crate::input::Input;
struct SyntaxDetectionTest<'a> {
assets: HighlightingAssets,
pub syntax_mapping: SyntaxMapping<'a>,
temp_dir: TempDir,
pub temp_dir: TempDir,
}
impl<'a> SyntaxDetectionTest<'a> {
@@ -246,26 +310,80 @@ mod tests {
}
}
fn synax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String {
fn syntax_for_real_file_with_content_os(
&self,
file_name: &OsStr,
first_line: &str,
) -> String {
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();
}
let input_file = InputFile::Ordinary(OsStr::new(&file_path));
let syntax = self.assets.get_syntax(
None,
input_file,
&mut input_file.get_reader(&io::stdin()).unwrap(),
&self.syntax_mapping,
);
let input = Input::ordinary_file(file_path.as_os_str());
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin).unwrap();
syntax.name.clone()
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
}
fn syntax_for_file_with_content_os(&self, file_name: &OsStr, first_line: &str) -> String {
let file_path = self.temp_dir.path().join(file_name);
let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes())))
.with_name(Some(file_path.as_os_str()));
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin).unwrap();
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
}
#[cfg(unix)]
fn syntax_for_file_os(&self, file_name: &OsStr) -> String {
self.syntax_for_file_with_content_os(file_name, "")
}
fn syntax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String {
self.syntax_for_file_with_content_os(OsStr::new(file_name), first_line)
}
fn syntax_for_file(&self, file_name: &str) -> String {
self.synax_for_file_with_content(file_name, "")
self.syntax_for_file_with_content(file_name, "")
}
fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String {
let input = Input::stdin().with_name(Some(OsStr::new(file_name)));
let mut opened_input = input.open(content).unwrap();
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
}
fn syntax_is_same_for_inputkinds(&self, file_name: &str, content: &str) -> bool {
let as_file = self.syntax_for_real_file_with_content_os(file_name.as_ref(), content);
let as_reader = self.syntax_for_file_with_content_os(file_name.as_ref(), content);
let consistent = as_file == as_reader;
// TODO: Compare StdIn somehow?
if !consistent {
eprintln!(
"Inconsistent syntax detection:\nFor File: {}\nFor Reader: {}",
as_file, as_reader
)
}
consistent
}
}
@@ -284,14 +402,48 @@ mod tests {
assert_eq!(test.syntax_for_file("Makefile"), "Makefile");
}
#[cfg(unix)]
#[test]
fn syntax_detection_invalid_utf8() {
use std::os::unix::ffi::OsStrExt;
let test = SyntaxDetectionTest::new();
assert_eq!(
test.syntax_for_file_os(OsStr::from_bytes(b"invalid_\xFEutf8_filename.rs")),
"Rust"
);
}
#[test]
fn syntax_detection_same_for_inputkinds() {
let mut test = SyntaxDetectionTest::new();
test.syntax_mapping
.insert("*.myext", MappingTarget::MapTo("C"))
.ok();
test.syntax_mapping
.insert("MY_FILE", MappingTarget::MapTo("Markdown"))
.ok();
assert!(test.syntax_is_same_for_inputkinds("Test.md", ""));
assert!(test.syntax_is_same_for_inputkinds("Test.txt", "#!/bin/bash"));
assert!(test.syntax_is_same_for_inputkinds(".bashrc", ""));
assert!(test.syntax_is_same_for_inputkinds("test.h", ""));
assert!(test.syntax_is_same_for_inputkinds("test.js", "#!/bin/bash"));
assert!(test.syntax_is_same_for_inputkinds("test.myext", ""));
assert!(test.syntax_is_same_for_inputkinds("MY_FILE", ""));
assert!(test.syntax_is_same_for_inputkinds("MY_FILE", "<?php"));
}
#[test]
fn syntax_detection_well_defined_mapping_for_duplicate_extensions() {
let test = SyntaxDetectionTest::new();
assert_eq!(test.syntax_for_file("test.h"), "C++");
assert_eq!(test.syntax_for_file("test.sass"), "Sass");
assert_eq!(test.syntax_for_file("test.hs"), "Haskell (improved)");
assert_eq!(test.syntax_for_file("test.js"), "JavaScript (Babel)");
assert_eq!(test.syntax_for_file("test.fs"), "F#");
}
#[test]
@@ -299,15 +451,15 @@ mod tests {
let test = SyntaxDetectionTest::new();
assert_eq!(
test.synax_for_file_with_content("my_script", "#!/bin/bash"),
test.syntax_for_file_with_content("my_script", "#!/bin/bash"),
"Bourne Again Shell (bash)"
);
assert_eq!(
test.synax_for_file_with_content("build", "#!/bin/bash"),
test.syntax_for_file_with_content("build", "#!/bin/bash"),
"Bourne Again Shell (bash)"
);
assert_eq!(
test.synax_for_file_with_content("my_script", "<?php"),
test.syntax_for_file_with_content("my_script", "<?php"),
"PHP"
);
}
@@ -333,4 +485,46 @@ mod tests {
.ok();
assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
}
#[test]
fn syntax_detection_stdin_filename() {
let test = SyntaxDetectionTest::new();
// from file extension
assert_eq!(test.syntax_for_stdin_with_content("test.cpp", b"a"), "C++");
// from first line (fallback)
assert_eq!(
test.syntax_for_stdin_with_content("my_script", b"#!/bin/bash"),
"Bourne Again Shell (bash)"
);
}
#[cfg(unix)]
#[test]
fn syntax_detection_for_symlinked_file() {
use std::os::unix::fs::symlink;
let test = SyntaxDetectionTest::new();
let file_path = test.temp_dir.path().join("my_ssh_config_filename");
{
File::create(&file_path).unwrap();
}
let file_path_symlink = test.temp_dir.path().join(".ssh").join("config");
std::fs::create_dir(test.temp_dir.path().join(".ssh"))
.expect("creation of directory succeeds");
symlink(&file_path, &file_path_symlink).expect("creation of symbolic link succeeds");
let input = Input::ordinary_file(file_path_symlink.as_os_str());
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin).unwrap();
assert_eq!(
test.assets
.get_syntax(None, &mut opened_input, &test.syntax_mapping)
.unwrap_or_else(|_| test.assets.syntax_set.find_syntax_plain_text())
.name,
"SSH Config"
);
}
}
+81
View File
@@ -0,0 +1,81 @@
use std::fs::File;
use std::path::Path;
use std::time::SystemTime;
use semver::Version;
use serde::{Deserialize, Serialize};
use crate::error::*;
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct AssetsMetadata {
bat_version: Option<String>,
creation_time: Option<SystemTime>,
}
const FILENAME: &str = "metadata.yaml";
impl AssetsMetadata {
pub(crate) fn new(current_version: &str) -> AssetsMetadata {
AssetsMetadata {
bat_version: Some(current_version.to_owned()),
creation_time: Some(SystemTime::now()),
}
}
pub(crate) fn save_to_folder(&self, path: &Path) -> Result<()> {
let file = File::create(path.join(FILENAME))?;
serde_yaml::to_writer(file, self)?;
Ok(())
}
fn try_load_from_folder(path: &Path) -> Result<Self> {
let file = File::open(path.join(FILENAME))?;
Ok(serde_yaml::from_reader(file)?)
}
/// Load metadata about the stored cache file from the given folder.
///
/// There are several possibilities:
/// - We find a metadata.yaml file and are able to parse it
/// => return the contained information
/// - We find a metadata.yaml file and but are not able to parse it
/// => return a SerdeYamlError
/// - We do not find a metadata.yaml file but a syntaxes.bin or themes.bin file
/// => assume that these were created by an old version of bat and return
/// AssetsMetadata::default() without version information
/// - We do not find a metadata.yaml file and no cached assets
/// => no user provided assets are available, return None
pub fn load_from_folder(path: &Path) -> Result<Option<Self>> {
match Self::try_load_from_folder(path) {
Ok(metadata) => Ok(Some(metadata)),
Err(e) => match e.kind() {
ErrorKind::SerdeYamlError(_) => Err(e),
_ => {
if path.join("syntaxes.bin").exists() || path.join("themes.bin").exists() {
Ok(Some(Self::default()))
} else {
Ok(None)
}
}
},
}
}
pub fn is_compatible_with(&self, current_version: &str) -> bool {
let current_version =
Version::parse(current_version).expect("bat follows semantic versioning");
let stored_version = self
.bat_version
.as_ref()
.and_then(|ver| Version::parse(ver).ok());
if let Some(stored_version) = stored_version {
current_version.major == stored_version.major
&& current_version.minor == stored_version.minor
} else {
false
}
}
}
+95 -51
View File
@@ -1,5 +1,6 @@
use std::collections::HashSet;
use std::env;
use std::ffi::OsStr;
use std::str::FromStr;
use atty::{self, Stream};
@@ -9,20 +10,18 @@ use crate::{
config::{get_args_from_config_file, get_args_from_env_var},
};
use clap::ArgMatches;
use wild;
use console::Term;
#[cfg(windows)]
use ansi_term;
use crate::input::{new_file_input, new_stdin_input};
use bat::{
config::{
Config, HighlightedLineRanges, InputFile, LineRange, LineRanges, MappingTarget, OutputWrap,
PagingMode, StyleComponent, StyleComponents, SyntaxMapping,
},
errors::*,
HighlightingAssets,
assets::HighlightingAssets,
config::{Config, VisibleLines},
error::*,
input::Input,
line_range::{HighlightedLineRanges, LineRange, LineRanges},
style::{StyleComponent, StyleComponents},
MappingTarget, PagingMode, SyntaxMapping, WrappingMode,
};
fn is_truecolor_terminal() -> bool {
@@ -76,18 +75,19 @@ impl App {
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
}
pub fn config(&self) -> Result<Config> {
let files = self.files();
pub fn config(&self, inputs: &[Input]) -> Result<Config> {
let style_components = self.style_components()?;
let paging_mode = match self.matches.value_of("paging") {
Some("always") => PagingMode::Always,
Some("never") => PagingMode::Never,
Some("auto") | _ => {
Some("auto") | None => {
if self.matches.occurrences_of("plain") > 1 {
// If we have -pp as an option when in auto mode, the pager should be disabled.
PagingMode::Never
} else if files.contains(&InputFile::StdIn) {
} else if self.matches.is_present("no-paging") {
PagingMode::Never
} else if inputs.iter().any(Input::is_stdin) {
// If we are reading from stdin, only enable paging if we write to an
// interactive terminal and if we do not *read* from an interactive
// terminal.
@@ -102,6 +102,7 @@ impl App {
PagingMode::Never
}
}
_ => unreachable!("other values for --paging are not allowed"),
};
let mut syntax_mapping = SyntaxMapping::builtin();
@@ -146,34 +147,38 @@ impl App {
}
}),
show_nonprintable: self.matches.is_present("show-all"),
output_wrap: if self.interactive_output || maybe_term_width.is_some() {
wrapping_mode: if self.interactive_output || maybe_term_width.is_some() {
match self.matches.value_of("wrap") {
Some("character") => OutputWrap::Character,
Some("never") => OutputWrap::None,
Some("auto") | _ => {
Some("character") => WrappingMode::Character,
Some("never") => WrappingMode::NoWrapping,
Some("auto") | None => {
if style_components.plain() {
OutputWrap::None
WrappingMode::NoWrapping
} else {
OutputWrap::Character
WrappingMode::Character
}
}
_ => unreachable!("other values for --paging are not allowed"),
}
} else {
// We don't have the tty width when piping to another program.
// There's no point in wrapping when this is the case.
OutputWrap::None
},
colored_output: match self.matches.value_of("color") {
Some("always") => true,
Some("never") => false,
Some("auto") | _ => self.interactive_output,
WrappingMode::NoWrapping
},
colored_output: self.matches.is_present("force-colorization")
|| match self.matches.value_of("color") {
Some("always") => true,
Some("never") => false,
Some("auto") | _ => {
env::var_os("NO_COLOR").is_none() && self.interactive_output
}
},
paging_mode,
term_width: maybe_term_width.unwrap_or(Term::stdout().size().1 as usize),
loop_through: !(self.interactive_output
|| self.matches.value_of("color") == Some("always")
|| self.matches.value_of("decorations") == Some("always")),
files,
|| self.matches.value_of("decorations") == Some("always")
|| self.matches.is_present("force-colorization")),
tab_width: self
.matches
.value_of("tabs")
@@ -200,13 +205,24 @@ impl App {
}
})
.unwrap_or_else(|| String::from(HighlightingAssets::default_theme())),
line_ranges: self
.matches
.values_of("line-range")
.map(|vs| vs.map(LineRange::from).collect())
.transpose()?
.map(LineRanges::from)
.unwrap_or_default(),
visible_lines: match self.matches.is_present("diff") {
#[cfg(feature = "git")]
true => VisibleLines::DiffContext(
self.matches
.value_of("diff-context")
.and_then(|t| t.parse().ok())
.unwrap_or(2),
),
_ => VisibleLines::Ranges(
self.matches
.values_of("line-range")
.map(|vs| vs.map(LineRange::from).collect())
.transpose()?
.map(LineRanges::from)
.unwrap_or_default(),
),
},
style_components,
syntax_mapping,
pager: self.matches.value_of("pager"),
@@ -225,21 +241,49 @@ impl App {
})
}
fn files(&self) -> Vec<InputFile> {
self.matches
.values_of_os("FILE")
.map(|values| {
values
.map(|filename| {
if filename == "-" {
InputFile::StdIn
} else {
InputFile::Ordinary(filename)
}
})
.collect()
})
.unwrap_or_else(|| vec![InputFile::StdIn])
pub fn inputs(&self) -> Result<Vec<Input>> {
// verify equal length of file-names and input FILEs
match self.matches.values_of("file-name") {
Some(ref filenames)
if self.matches.values_of_os("FILE").is_some()
&& filenames.len() != self.matches.values_of_os("FILE").unwrap().len() =>
{
return Err("Must be one file name per input type.".into());
}
_ => {}
}
let filenames: Option<Vec<&str>> = self
.matches
.values_of("file-name")
.map(|values| values.collect());
let mut filenames_or_none: Box<dyn Iterator<Item = _>> = match filenames {
Some(ref filenames) => Box::new(filenames.iter().map(|name| Some(OsStr::new(*name)))),
None => Box::new(std::iter::repeat(None)),
};
let files: Option<Vec<&OsStr>> = self.matches.values_of_os("FILE").map(|vs| vs.collect());
if files.is_none() {
return Ok(vec![new_stdin_input(
filenames_or_none.next().unwrap_or(None),
)]);
}
let files_or_none: Box<dyn Iterator<Item = _>> = match files {
Some(ref files) => Box::new(files.iter().map(|name| Some(*name))),
None => Box::new(std::iter::repeat(None)),
};
let mut file_input = Vec::new();
for (filepath, provided_name) in files_or_none.zip(filenames_or_none) {
if let Some(filepath) = filepath {
if filepath.to_str().unwrap_or_default() == "-" {
file_input.push(new_stdin_input(provided_name));
} else {
file_input.push(new_file_input(filepath, provided_name));
}
}
}
Ok(file_input)
}
fn style_components(&self) -> Result<StyleComponents> {
@@ -248,7 +292,7 @@ impl App {
if matches.value_of("decorations") == Some("never") {
HashSet::new()
} else if matches.is_present("number") {
[StyleComponent::Numbers].iter().cloned().collect()
[StyleComponent::LineNumbers].iter().cloned().collect()
} else if matches.is_present("plain") {
[StyleComponent::Plain].iter().cloned().collect()
} else {
+35 -15
View File
@@ -1,18 +1,13 @@
use std::borrow::Cow;
use std::fs;
use std::path::PathBuf;
use clap::crate_version;
use crate::directories::PROJECT_DIRS;
use bat::HighlightingAssets;
fn theme_set_path() -> PathBuf {
PROJECT_DIRS.cache_dir().join("themes.bin")
}
fn syntax_set_path() -> PathBuf {
PROJECT_DIRS.cache_dir().join("syntaxes.bin")
}
use bat::assets::HighlightingAssets;
use bat::assets_metadata::AssetsMetadata;
use bat::error::*;
pub fn config_dir() -> Cow<'static, str> {
PROJECT_DIRS.config_dir().to_string_lossy()
@@ -23,16 +18,41 @@ pub fn cache_dir() -> Cow<'static, str> {
}
pub fn clear_assets() {
let theme_set_path = PROJECT_DIRS.cache_dir().join("themes.bin");
let syntax_set_path = PROJECT_DIRS.cache_dir().join("syntaxes.bin");
let metadata_file = PROJECT_DIRS.cache_dir().join("metadata.yaml");
print!("Clearing theme set cache ... ");
fs::remove_file(theme_set_path()).ok();
fs::remove_file(theme_set_path).ok();
println!("okay");
print!("Clearing syntax set cache ... ");
fs::remove_file(syntax_set_path()).ok();
fs::remove_file(syntax_set_path).ok();
println!("okay");
print!("Clearing metadata file ... ");
fs::remove_file(metadata_file).ok();
println!("okay");
}
pub fn assets_from_cache_or_binary() -> HighlightingAssets {
HighlightingAssets::from_cache(&theme_set_path(), &syntax_set_path())
.unwrap_or(HighlightingAssets::from_binary())
pub fn assets_from_cache_or_binary() -> Result<HighlightingAssets> {
let cache_dir = PROJECT_DIRS.cache_dir();
if let Some(metadata) = AssetsMetadata::load_from_folder(&cache_dir)? {
if !metadata.is_compatible_with(crate_version!()) {
return Err(format!(
"The binary caches for the user-customized syntaxes and themes \
in '{}' are not compatible with this version of bat ({}). To solve this, \
either rebuild the cache (bat cache --build) or remove \
the custom syntaxes/themes (bat cache --clear).\n\
For more information, see:\n\n \
https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions",
cache_dir.to_string_lossy(),
crate_version!()
)
.into());
}
}
Ok(HighlightingAssets::from_cache(&cache_dir)
.unwrap_or_else(|_| HighlightingAssets::from_binary()))
}
+129 -39
View File
@@ -1,14 +1,15 @@
use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
use clap::{crate_name, crate_version, App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
use std::env;
use std::path::Path;
pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
let clap_color_setting = if interactive_output {
let clap_color_setting = if interactive_output && env::var_os("NO_COLOR").is_none() {
AppSettings::ColoredHelp
} else {
AppSettings::ColorNever
};
let app = ClapApp::new(crate_name!())
let mut app = ClapApp::new(crate_name!())
.version(crate_version!())
.global_setting(clap_color_setting)
.global_setting(AppSettings::DeriveDisplayOrder)
@@ -44,7 +45,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.long_help(
"Show non-printable characters like space, tab or newline. \
This option can also be used to print binary files. \
Use '--tabs' to control the width of the tab-placeholders."
Use '--tabs' to control the width of the tab-placeholders.",
),
)
.arg(
@@ -90,29 +91,79 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
'--highlight-line 40' highlights line 40\n \
'--highlight-line 30:40' highlights lines 30 to 40\n \
'--highlight-line :40' highlights lines 1 to 40\n \
'--highlight-line 40:' highlights lines 40 to the end of the file"
'--highlight-line 40:' highlights lines 40 to the end of the file",
),
)
.arg(
Arg::with_name("tabs")
.long("tabs")
.overrides_with("tabs")
Arg::with_name("file-name")
.long("file-name")
.takes_value(true)
.value_name("T")
.validator(
|t| {
t.parse::<u32>()
.map_err(|_t| "must be a number")
.map(|_t| ()) // Convert to Result<(), &str>
.map_err(|e| e.to_string())
}, // Convert to Result<(), String>
)
.help("Set the tab width to T spaces.")
.number_of_values(1)
.multiple(true)
.value_name("name")
.help("Specify the name to display for a file.")
.long_help(
"Set the tab width to T spaces. Use a width of 0 to pass tabs through \
directly",
"Specify the name to display for a file. Useful when piping \
data to bat from STDIN when bat does not otherwise know \
the filename. Note that the provided file name is also \
used for syntax detection.",
),
)
);
#[cfg(feature = "git")]
{
app = app
.arg(
Arg::with_name("diff")
.long("diff")
.short("d")
.help("Only show lines that have been added/removed/modified.")
.long_help(
"Only show lines that have been added/removed/modified with respect \
to the Git index. Use --diff-context=N to control how much context you want to see.",
),
)
.arg(
Arg::with_name("diff-context")
.long("diff-context")
.overrides_with("diff-context")
.takes_value(true)
.value_name("N")
.validator(
|n| {
n.parse::<usize>()
.map_err(|_| "must be a number")
.map(|_| ()) // Convert to Result<(), &str>
.map_err(|e| e.to_string())
}, // Convert to Result<(), String>
)
.hidden_short_help(true)
.long_help(
"Include N lines of context around added/removed/modified lines when using '--diff'.",
),
)
}
app = app.arg(
Arg::with_name("tabs")
.long("tabs")
.overrides_with("tabs")
.takes_value(true)
.value_name("T")
.validator(
|t| {
t.parse::<u32>()
.map_err(|_t| "must be a number")
.map(|_t| ()) // Convert to Result<(), &str>
.map_err(|e| e.to_string())
}, // Convert to Result<(), String>
)
.help("Set the tab width to T spaces.")
.long_help(
"Set the tab width to T spaces. Use a width of 0 to pass tabs through \
directly",
),
)
.arg(
Arg::with_name("wrap")
.long("wrap")
@@ -140,7 +191,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
t.parse::<i32>()
.map_err(|_e| "must be an offset or number")
.and_then(|v| if v == 0 && !is_offset {
Err("terminal width cannot be zero".into())
Err("terminal width cannot be zero")
} else {
Ok(())
})
@@ -175,7 +226,8 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.help("When to use colors (*auto*, never, always).")
.long_help(
"Specify when to use colored output. The automatic mode \
only enables colors if an interactive terminal is detected. \
only enables colors if an interactive terminal is detected - \
colors are automatically disabled if the output goes to a pipe.\n\
Possible values: *auto*, never, always.",
),
)
@@ -206,6 +258,18 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
an interactive terminal is detected. Possible values: *auto*, never, always.",
),
)
.arg(
Arg::with_name("force-colorization")
.long("force-colorization")
.short("f")
.conflicts_with("color")
.conflicts_with("decorations")
.overrides_with("force-colorization")
.hidden_short_help(true)
.long_help("Alias for '--decorations=always --color=always'. This is useful \
if the output of bat is piped to another program, but you want \
to keep the colorization/decorations.")
)
.arg(
Arg::with_name("paging")
.long("paging")
@@ -215,16 +279,23 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.hide_default_value(true)
.help("Specify when to use the pager (*auto*, never, always).")
.help("Specify when to use the pager, or use `-P` to disable (*auto*, never, always).")
.long_help(
"Specify when to use the pager. To control which pager \
is used, set the PAGER or BAT_PAGER environment \
variables (the latter takes precedence) or use the '--pager' option. \
To disable the pager permanently, set BAT_PAGER to an empty string \
or set '--paging=never' in the configuration file. \
Possible values: *auto*, never, always.",
"Specify when to use the pager. To disable the pager, use \
--paging=never' or its alias,'-P'. To disable the pager permanently, \
set BAT_PAGER to an empty string. To control which pager is used, see the \
'--pager' option. Possible values: *auto*, never, always."
),
)
.arg(
Arg::with_name("no-paging")
.short("P")
.alias("no-pager")
.overrides_with("no-paging")
.hidden(true)
.hidden_short_help(true)
.help("Alias for '--paging=never'")
)
.arg(
Arg::with_name("pager")
.long("pager")
@@ -234,11 +305,10 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.hidden_short_help(true)
.help("Determine which pager to use.")
.long_help(
"Determine which pager is used. This option will overwrite \
the PAGER and BAT_PAGER environment variables. The default \
pager is 'less'. To disable the pager completely, use the \
'--paging' option. \
Example: '--pager \"less -RF\"'.",
"Determine which pager is used. This option will override the \
PAGER and BAT_PAGER environment variables. The default pager is 'less'. \
To control when the pager is used, see the '--paging' option. \
Example: '--pager \"less -RF\"'."
),
)
.arg(
@@ -289,11 +359,13 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.overrides_with("style")
.overrides_with("plain")
.overrides_with("number")
// Cannot use clap's built in validation because we have to turn off clap's delimiters
// Cannot use claps built in validation because we have to turn off clap's delimiters
.validator(|val| {
let mut invalid_vals = val.split(',').filter(|style| {
!&[
"auto", "full", "plain", "changes", "header", "grid", "numbers", "snip"
"auto", "full", "plain", "header", "grid", "numbers", "snip",
#[cfg(feature = "git")]
"changes",
]
.contains(style)
});
@@ -315,8 +387,17 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
components to display (e.g. 'numbers,changes,grid') or a \
pre-defined style ('full'). To set a default style, add the \
'--style=\"..\"' option to the configuration file or export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\"). \
Possible values: *auto*, full, plain, changes, header, grid, numbers, snip.",
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\
Possible values:\n\n \
* full: enables all available components.\n \
* auto: same as 'full', unless the output is piped (default).\n \
* plain: disables all available components.\n \
* changes: show Git modification markers.\n \
* header: show filenames before the content.\n \
* grid: vertical/horizontal lines to separate side bar\n \
and the header from the content.\n \
* numbers: show line numbers in the side bar.\n \
* snip: draw separation lines between distinct line ranges.",
),
)
.arg(
@@ -327,6 +408,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.takes_value(true)
.number_of_values(1)
.value_name("N:M")
.conflicts_with("diff")
.help("Only print the lines from N to M.")
.long_help(
"Only print the specified range of lines for each file. \
@@ -370,6 +452,14 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.hidden(true)
.help("Show path to the configuration file."),
)
.arg(
Arg::with_name("generate-config-file")
.long("generate-config-file")
.conflicts_with("list-languages")
.conflicts_with("list-themes")
.hidden(true)
.help("Generates a default configuration file."),
)
.arg(
Arg::with_name("config-dir")
.long("config-dir")
+68 -2
View File
@@ -1,10 +1,9 @@
use std::env;
use std::ffi::OsString;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;
use shell_words;
use crate::directories::PROJECT_DIRS;
pub fn config_file() -> PathBuf {
@@ -15,6 +14,73 @@ pub fn config_file() -> PathBuf {
.unwrap_or_else(|| PROJECT_DIRS.config_dir().join("config"))
}
pub fn generate_config_file() -> bat::error::Result<()> {
let config_file = config_file();
if config_file.exists() {
println!(
"A config file already exists at: {}",
config_file.to_string_lossy()
);
print!("Overwrite? (y/N): ");
io::stdout().flush()?;
let mut decision = String::new();
io::stdin().read_line(&mut decision)?;
if !decision.trim().eq_ignore_ascii_case("Y") {
return Ok(());
}
} else {
let config_dir = config_file.parent();
match config_dir {
Some(path) => fs::create_dir_all(path)?,
None => {
return Err(format!(
"Unable to write config file to: {}",
config_file.to_string_lossy()
)
.into());
}
}
}
let default_config =
r#"# This is `bat`s configuration file. Each line either contains a comment or
# a command-line option that you want to pass to `bat` by default. You can
# run `bat --help` to get a list of all possible configuration options.
# Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes`
# for a list of all available themes
#--theme="TwoDark"
# Enable this to use italic text on the terminal. This is not supported on all
# terminal emulators (like tmux, by default):
#--italic-text=always
# Uncomment the following line to disable automatic paging:
#--paging=never
# Uncomment the following line if you are using less version >= 551 and want to
# enable mouse scrolling support in `bat` when running inside tmux. This might
# disable text selection, unless you press shift.
#--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse"
# Syntax mappings: map a certain filename pattern to a language.
# Example 1: use the C++ syntax for .ino files
# Example 2: Use ".gitignore"-style highlighting for ".ignore" files
#--map-syntax "*.ino:C++"
#--map-syntax ".ignore:Git Ignore"
"#;
fs::write(&config_file, default_config)?;
println!(
"Success! Config file written to {}",
config_file.to_string_lossy()
);
Ok(())
}
pub fn get_args_from_config_file() -> Result<Vec<OsString>, shell_words::ParseError> {
Ok(fs::read_to_string(config_file())
.ok()
+1 -2
View File
@@ -1,7 +1,6 @@
use std::env;
use std::path::{Path, PathBuf};
use dirs;
use lazy_static::lazy_static;
/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
@@ -33,7 +32,7 @@ impl BatProjectDirs {
})
}
pub fn get_cache_dir() -> Option<PathBuf> {
fn get_cache_dir() -> Option<PathBuf> {
// on all OS prefer BAT_CACHE_PATH if set
let cache_dir_op = env::var_os("BAT_CACHE_PATH").map(PathBuf::from);
if cache_dir_op.is_some() {
+20
View File
@@ -0,0 +1,20 @@
use bat::input::Input;
use std::ffi::OsStr;
pub fn new_file_input<'a>(file: &'a OsStr, name: Option<&'a OsStr>) -> Input<'a> {
named(Input::ordinary_file(file), name.or_else(|| Some(file)))
}
pub fn new_stdin_input(name: Option<&OsStr>) -> Input {
named(Input::stdin(), name)
}
fn named<'a>(input: Input<'a>, name: Option<&OsStr>) -> Input<'a> {
if let Some(provided_name) = name {
let mut input = input.with_name(Some(provided_name));
input.description_mut().set_kind(Some("File".to_owned()));
input
} else {
input
}
}
+93 -30
View File
@@ -1,38 +1,45 @@
// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]
#[macro_use]
extern crate clap;
extern crate dirs as dirs_rs;
mod app;
mod assets;
mod clap_app;
mod config;
mod directories;
mod input;
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::io;
use std::io::Write;
use std::io::{BufReader, Write};
use std::path::Path;
use std::process;
use ansi_term::Colour::Green;
use ansi_term::Style;
use crate::{app::App, config::config_file};
use crate::{
app::App,
config::{config_file, generate_config_file},
};
use assets::{assets_from_cache_or_binary, cache_dir, clear_assets, config_dir};
use bat::Controller;
use clap::crate_version;
use directories::PROJECT_DIRS;
use globset::GlobMatcher;
use bat::{
config::{Config, InputFile, StyleComponent, StyleComponents},
errors::*,
HighlightingAssets,
assets::HighlightingAssets,
config::Config,
controller::Controller,
error::*,
input::Input,
style::{StyleComponent, StyleComponents},
MappingTarget,
};
const THEME_PREVIEW_DATA: &[u8] = include_bytes!("../../../assets/theme_preview.rs");
fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
if matches.is_present("build") {
let source_dir = matches
@@ -47,7 +54,7 @@ fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
let blank = matches.is_present("blank");
let assets = HighlightingAssets::from_files(source_dir, !blank)?;
assets.save_to_cache(target_dir)?;
assets.save_to_cache(target_dir, crate_version!())?;
} else if matches.is_present("clear") {
clear_assets();
}
@@ -55,21 +62,69 @@ fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
Ok(())
}
fn get_syntax_mapping_to_paths<'a>(
mappings: &[(GlobMatcher, MappingTarget<'a>)],
) -> HashMap<&'a str, Vec<String>> {
let mut map = HashMap::new();
for mapping in mappings {
match mapping {
(_, MappingTarget::MapToUnknown) => {}
(matcher, MappingTarget::MapTo(s)) => {
let globs = map.entry(*s).or_insert_with(Vec::new);
globs.push(matcher.glob().glob().into());
}
}
}
map
}
pub fn list_languages(config: &Config) -> Result<()> {
let assets = assets_from_cache_or_binary();
let assets = assets_from_cache_or_binary()?;
let mut languages = assets
.syntaxes()
.iter()
.filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty())
.cloned()
.collect::<Vec<_>>();
// Handling of file-extension conflicts, see issue #1076
for lang in languages.iter_mut() {
let lang_name = lang.name.clone();
lang.file_extensions.retain(|extension| {
// The 'extension' variable is not certainly a real extension.
//
// Skip if 'extension' starts with '.', likely a hidden file like '.vimrc'
// Also skip if the 'extension' contains another real extension, likely
// that is a full match file name like 'CMakeLists.txt' and 'Cargo.lock'
if extension.starts_with('.') || Path::new(extension).extension().is_some() {
true
} else {
let test_file = Path::new("test").with_extension(extension);
match assets.syntax_for_file_name(test_file, &config.syntax_mapping) {
Some(syntax) => syntax.name == lang_name,
None => false,
}
}
});
}
languages.sort_by_key(|lang| lang.name.to_uppercase());
let configured_languages = get_syntax_mapping_to_paths(config.syntax_mapping.mappings());
for lang in languages.iter_mut() {
if let Some(additional_paths) = configured_languages.get(lang.name.as_str()) {
lang.file_extensions
.extend(additional_paths.iter().cloned());
}
}
let stdout = io::stdout();
let mut stdout = stdout.lock();
if config.loop_through {
for lang in languages {
write!(stdout, "{}:{}\n", lang.name, lang.file_extensions.join(","))?;
writeln!(stdout, "{}:{}", lang.name, lang.file_extensions.join(","))?;
}
} else {
let longest = languages
@@ -117,12 +172,16 @@ pub fn list_languages(config: &Config) -> Result<()> {
Ok(())
}
fn theme_preview_file<'a>() -> Input<'a> {
Input::from_reader(Box::new(BufReader::new(THEME_PREVIEW_DATA)))
}
pub fn list_themes(cfg: &Config) -> Result<()> {
let assets = assets_from_cache_or_binary();
let assets = assets_from_cache_or_binary()?;
let mut config = cfg.clone();
let mut style = HashSet::new();
style.insert(StyleComponent::Plain);
config.files = vec![InputFile::ThemePreviewFile];
config.language = Some("Rust");
config.style_components = StyleComponents(style);
let stdout = io::stdout();
@@ -136,7 +195,9 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
Style::new().bold().paint(theme.to_string())
)?;
config.theme = theme.to_string();
let _controller = Controller::new(&config, &assets).run();
Controller::new(&config, &assets)
.run(vec![theme_preview_file()])
.ok();
writeln!(stdout)?;
}
} else {
@@ -148,10 +209,10 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
Ok(())
}
fn run_controller(config: &Config) -> Result<bool> {
let assets = assets_from_cache_or_binary();
fn run_controller(inputs: Vec<Input>, config: &Config) -> Result<bool> {
let assets = assets_from_cache_or_binary()?;
let controller = Controller::new(&config, &assets);
controller.run()
controller.run(inputs)
}
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and
@@ -168,26 +229,27 @@ fn run() -> Result<bool> {
run_cache_subcommand(cache_matches)?;
Ok(true)
} else {
let mut config = app.config()?;
config.files = vec![InputFile::Ordinary(OsStr::new("cache"))];
let inputs = vec![Input::ordinary_file(OsStr::new("cache"))];
let config = app.config(&inputs)?;
run_controller(&config)
run_controller(inputs, &config)
}
}
_ => {
let config = app.config()?;
let inputs = app.inputs()?;
let config = app.config(&inputs)?;
if app.matches.is_present("list-languages") {
list_languages(&config)?;
Ok(true)
} else if app.matches.is_present("list-themes") {
list_themes(&config)?;
Ok(true)
} else if app.matches.is_present("config-file") {
println!("{}", config_file().to_string_lossy());
Ok(true)
} else if app.matches.is_present("generate-config-file") {
generate_config_file()?;
Ok(true)
} else if app.matches.is_present("config-dir") {
writeln!(io::stdout(), "{}", config_dir())?;
@@ -196,7 +258,7 @@ fn run() -> Result<bool> {
writeln!(io::stdout(), "{}", cache_dir())?;
Ok(true)
} else {
run_controller(&config)
run_controller(inputs, &config)
}
}
}
@@ -207,7 +269,8 @@ fn main() {
match result {
Err(error) => {
default_error_handler(&error);
let stderr = std::io::stderr();
default_error_handler(&error, &mut stderr.lock());
process::exit(1);
}
Ok(false) => {
+32 -23
View File
@@ -1,27 +1,38 @@
pub use crate::inputfile::InputFile;
pub use crate::line_range::{HighlightedLineRanges, LineRange, LineRanges};
pub use crate::style::{StyleComponent, StyleComponents};
pub use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
pub use crate::wrap::OutputWrap;
use crate::line_range::{HighlightedLineRanges, LineRanges};
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
use crate::style::StyleComponents;
use crate::syntax_mapping::SyntaxMapping;
use crate::wrapping::WrappingMode;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PagingMode {
Always,
QuitIfOneScreen,
Never,
#[derive(Debug, Clone)]
pub enum VisibleLines {
/// Show all lines which are included in the line ranges
Ranges(LineRanges),
#[cfg(feature = "git")]
/// Only show lines surrounding added/deleted/modified lines
DiffContext(usize),
}
impl Default for PagingMode {
impl VisibleLines {
pub fn diff_mode(&self) -> bool {
match self {
Self::Ranges(_) => false,
#[cfg(feature = "git")]
Self::DiffContext(_) => true,
}
}
}
impl Default for VisibleLines {
fn default() -> Self {
PagingMode::Never
VisibleLines::Ranges(LineRanges::default())
}
}
#[derive(Debug, Clone, Default)]
pub struct Config<'a> {
/// List of files to print
pub files: Vec<InputFile<'a>>,
/// The explicitly configured language, if any
pub language: Option<&'a str>,
@@ -47,14 +58,15 @@ pub struct Config<'a> {
/// Style elements (grid, line numbers, ...)
pub style_components: StyleComponents,
/// Text wrapping mode
pub output_wrap: OutputWrap,
/// If and how text should be wrapped
pub wrapping_mode: WrappingMode,
/// Pager or STDOUT
#[cfg(feature = "paging")]
pub paging_mode: PagingMode,
/// Specifies the lines that should be printed
pub line_ranges: LineRanges,
/// Specifies which lines should be printed
pub visible_lines: VisibleLines,
/// The syntax highlighting theme
pub theme: String,
@@ -76,10 +88,7 @@ pub struct Config<'a> {
fn default_config_should_include_all_lines() {
use crate::line_range::RangeCheckResult;
assert_eq!(
Config::default().line_ranges.check(17),
RangeCheckResult::InRange
);
assert_eq!(LineRanges::default().check(17), RangeCheckResult::InRange);
}
#[test]
+133 -47
View File
@@ -1,12 +1,17 @@
use std::io::{self, Write};
use std::path::Path;
use crate::assets::HighlightingAssets;
use crate::config::{Config, PagingMode};
use crate::errors::*;
use crate::inputfile::{InputFile, InputFileReader};
use crate::config::{Config, VisibleLines};
#[cfg(feature = "git")]
use crate::diff::{get_git_diff, LineChanges};
use crate::error::*;
use crate::input::{Input, InputReader, OpenedInput};
#[cfg(feature = "git")]
use crate::line_range::LineRange;
use crate::line_range::{LineRanges, RangeCheckResult};
use crate::output::OutputType;
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
pub struct Controller<'a> {
@@ -19,54 +24,117 @@ impl<'b> Controller<'b> {
Controller { config, assets }
}
pub fn run(&self) -> Result<bool> {
self.run_with_error_handler(default_error_handler)
pub fn run(&self, inputs: Vec<Input>) -> Result<bool> {
self.run_with_error_handler(inputs, default_error_handler)
}
pub fn run_with_error_handler(&self, handle_error: impl Fn(&Error)) -> Result<bool> {
// Do not launch the pager if NONE of the input files exist
let mut paging_mode = self.config.paging_mode;
if self.config.paging_mode != PagingMode::Never {
let call_pager = self.config.files.iter().any(|file| {
if let InputFile::Ordinary(path) = file {
return Path::new(path).exists();
} else {
return true;
pub fn run_with_error_handler(
&self,
inputs: Vec<Input>,
handle_error: impl Fn(&Error, &mut dyn Write),
) -> Result<bool> {
let mut output_type;
#[cfg(feature = "paging")]
{
use crate::input::InputKind;
use std::path::Path;
// Do not launch the pager if NONE of the input files exist
let mut paging_mode = self.config.paging_mode;
if self.config.paging_mode != PagingMode::Never {
let call_pager = inputs.iter().any(|ref input| {
if let InputKind::OrdinaryFile(ref path) = input.kind {
Path::new(path).exists()
} else {
true
}
});
if !call_pager {
paging_mode = PagingMode::Never;
}
});
if !call_pager {
paging_mode = PagingMode::Never;
}
output_type = OutputType::from_mode(paging_mode, self.config.pager)?;
}
let mut output_type = OutputType::from_mode(paging_mode, self.config.pager)?;
#[cfg(not(feature = "paging"))]
{
output_type = OutputType::stdout();
}
let attached_to_pager = output_type.is_pager();
let writer = output_type.handle()?;
let mut no_errors: bool = true;
let stdin = io::stdin();
let stderr = io::stderr();
let print_error = |error: &Error, write: &mut dyn Write| {
if attached_to_pager {
handle_error(error, write);
} else {
handle_error(error, &mut stderr.lock());
}
};
for input_file in &self.config.files {
match input_file.get_reader(&stdin) {
for (index, input) in inputs.into_iter().enumerate() {
match input.open(io::stdin().lock()) {
Err(error) => {
handle_error(&error);
print_error(&error, writer);
no_errors = false;
}
Ok(mut reader) => {
let result = if self.config.loop_through {
let mut printer = SimplePrinter::new();
self.print_file(reader, &mut printer, writer, *input_file)
Ok(mut opened_input) => {
#[cfg(feature = "git")]
let line_changes = if self.config.visible_lines.diff_mode()
|| (!self.config.loop_through && self.config.style_components.changes())
{
match opened_input.kind {
crate::input::OpenedInputKind::OrdinaryFile(ref path) => {
let diff = get_git_diff(path);
// Skip files without Git modifications
if self.config.visible_lines.diff_mode()
&& diff
.as_ref()
.map(|changes| changes.is_empty())
.unwrap_or(false)
{
continue;
}
diff
}
_ if self.config.visible_lines.diff_mode() => {
// Skip non-file inputs in diff mode
continue;
}
_ => None,
}
} else {
let mut printer = InteractivePrinter::new(
&self.config,
&self.assets,
*input_file,
&mut reader,
);
self.print_file(reader, &mut printer, writer, *input_file)
None
};
let mut printer: Box<dyn Printer> = if self.config.loop_through {
Box::new(SimplePrinter::new(&self.config))
} else {
Box::new(InteractivePrinter::new(
&self.config,
&self.assets,
&mut opened_input,
#[cfg(feature = "git")]
&line_changes,
)?)
};
let result = self.print_file(
&mut *printer,
writer,
&mut opened_input,
index != 0,
#[cfg(feature = "git")]
&line_changes,
);
if let Err(error) = result {
handle_error(&error);
print_error(&error, writer);
no_errors = false;
}
}
@@ -76,30 +144,48 @@ impl<'b> Controller<'b> {
Ok(no_errors)
}
fn print_file<'a, P: Printer>(
fn print_file<'a>(
&self,
reader: InputFileReader,
printer: &mut P,
printer: &mut dyn Printer,
writer: &mut dyn Write,
input_file: InputFile<'a>,
input: &mut OpenedInput,
add_header_padding: bool,
#[cfg(feature = "git")] line_changes: &Option<LineChanges>,
) -> Result<()> {
if !reader.first_line.is_empty() || self.config.style_components.header() {
printer.print_header(writer, input_file)?;
if !input.reader.first_line.is_empty() || self.config.style_components.header() {
printer.print_header(writer, input, add_header_padding)?;
}
if !reader.first_line.is_empty() {
self.print_file_ranges(printer, writer, reader, &self.config.line_ranges)?;
if !input.reader.first_line.is_empty() {
let line_ranges = match self.config.visible_lines {
VisibleLines::Ranges(ref line_ranges) => line_ranges.clone(),
#[cfg(feature = "git")]
VisibleLines::DiffContext(context) => {
let mut line_ranges: Vec<LineRange> = vec![];
if let Some(line_changes) = line_changes {
for line in line_changes.keys() {
let line = *line as usize;
line_ranges.push(LineRange::new(line - context, line + context));
}
}
LineRanges::from(line_ranges)
}
};
self.print_file_ranges(printer, writer, &mut input.reader, &line_ranges)?;
}
printer.print_footer(writer)?;
printer.print_footer(writer, input)?;
Ok(())
}
fn print_file_ranges<P: Printer>(
fn print_file_ranges(
&self,
printer: &mut P,
printer: &mut dyn Printer,
writer: &mut dyn Write,
mut reader: InputFileReader,
reader: &mut InputReader,
line_ranges: &LineRanges,
) -> Result<()> {
let mut line_buffer = Vec::new();
+12 -8
View File
@@ -1,14 +1,15 @@
#[cfg(feature = "git")]
use crate::diff::LineChange;
use crate::printer::{Colors, InteractivePrinter};
use ansi_term::Style;
#[derive(Debug, Clone)]
pub struct DecorationText {
pub(crate) struct DecorationText {
pub width: usize,
pub text: String,
}
pub trait Decoration {
pub(crate) trait Decoration {
fn generate(
&self,
line_number: usize,
@@ -18,14 +19,14 @@ pub trait Decoration {
fn width(&self) -> usize;
}
pub struct LineNumberDecoration {
pub(crate) struct LineNumberDecoration {
color: Style,
cached_wrap: DecorationText,
cached_wrap_invalid_at: usize,
}
impl LineNumberDecoration {
pub fn new(colors: &Colors) -> Self {
pub(crate) fn new(colors: &Colors) -> Self {
LineNumberDecoration {
color: colors.line_number,
cached_wrap_invalid_at: 10000,
@@ -68,7 +69,8 @@ impl Decoration for LineNumberDecoration {
}
}
pub struct LineChangesDecoration {
#[cfg(feature = "git")]
pub(crate) struct LineChangesDecoration {
cached_none: DecorationText,
cached_added: DecorationText,
cached_removed_above: DecorationText,
@@ -76,6 +78,7 @@ pub struct LineChangesDecoration {
cached_modified: DecorationText,
}
#[cfg(feature = "git")]
impl LineChangesDecoration {
#[inline]
fn generate_cached(style: Style, text: &str) -> DecorationText {
@@ -85,7 +88,7 @@ impl LineChangesDecoration {
}
}
pub fn new(colors: &Colors) -> Self {
pub(crate) fn new(colors: &Colors) -> Self {
LineChangesDecoration {
cached_none: Self::generate_cached(Style::default(), " "),
cached_added: Self::generate_cached(colors.git_added, "+"),
@@ -96,6 +99,7 @@ impl LineChangesDecoration {
}
}
#[cfg(feature = "git")]
impl Decoration for LineChangesDecoration {
fn generate(
&self,
@@ -123,12 +127,12 @@ impl Decoration for LineChangesDecoration {
}
}
pub struct GridBorderDecoration {
pub(crate) struct GridBorderDecoration {
cached: DecorationText,
}
impl GridBorderDecoration {
pub fn new(colors: &Colors) -> Self {
pub(crate) fn new(colors: &Colors) -> Self {
GridBorderDecoration {
cached: DecorationText {
text: colors.grid.paint("").to_string(),
+2
View File
@@ -1,3 +1,5 @@
#![cfg(feature = "git")]
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
+48
View File
@@ -0,0 +1,48 @@
use error_chain::error_chain;
use std::io::Write;
error_chain! {
foreign_links {
Clap(::clap::Error) #[cfg(feature = "application")];
Io(::std::io::Error);
SyntectError(::syntect::LoadingError);
ParseIntError(::std::num::ParseIntError);
GlobParsingError(::globset::Error);
SerdeYamlError(::serde_yaml::Error);
}
errors {
UndetectedSyntax(input: String) {
description("unable to detect syntax"),
display("unable to detect syntax for {}", input)
}
UnknownSyntax(name: String) {
description("unknown syntax"),
display("unknown syntax: '{}'", name)
}
}
}
pub fn default_error_handler(error: &Error, output: &mut dyn Write) {
use ansi_term::Colour::Red;
match error {
Error(ErrorKind::Io(ref io_error), _)
if io_error.kind() == ::std::io::ErrorKind::BrokenPipe =>
{
::std::process::exit(0);
}
Error(ErrorKind::SerdeYamlError(_), _) => {
writeln!(
output,
"{}: Error while parsing metadata.yaml file: {}",
Red.paint("[bat error]"),
error
)
.ok();
}
_ => {
writeln!(output, "{}: {}", Red.paint("[bat error]"), error).ok();
}
};
}
-25
View File
@@ -1,25 +0,0 @@
use error_chain::error_chain;
error_chain! {
foreign_links {
Clap(::clap::Error);
Io(::std::io::Error);
SyntectError(::syntect::LoadingError);
ParseIntError(::std::num::ParseIntError);
GlobParsingError(::globset::Error);
}
}
pub fn default_error_handler(error: &Error) {
match error {
Error(ErrorKind::Io(ref io_error), _)
if io_error.kind() == ::std::io::ErrorKind::BrokenPipe =>
{
::std::process::exit(0);
}
_ => {
use ansi_term::Colour::Red;
eprintln!("{}: {}", Red.paint("[bat error]"), error);
}
};
}
+295
View File
@@ -0,0 +1,295 @@
use std::ffi::{OsStr, OsString};
use std::fs::File;
use std::io::{self, BufRead, BufReader, Read};
use content_inspector::{self, ContentType};
use crate::error::*;
/// A description of an Input source.
/// This tells bat how to refer to the input.
#[derive(Clone)]
pub struct InputDescription {
pub(crate) name: String,
/// The input title.
/// This replaces the name if provided.
title: Option<String>,
/// The input kind.
kind: Option<String>,
/// A summary description of the input.
/// Defaults to "{kind} '{name}'"
summary: Option<String>,
}
impl InputDescription {
/// Creates a description for an input.
pub fn new(name: impl Into<String>) -> Self {
InputDescription {
name: name.into(),
title: None,
kind: None,
summary: None,
}
}
pub fn set_kind(&mut self, kind: Option<String>) {
self.kind = kind;
}
pub fn set_summary(&mut self, summary: Option<String>) {
self.summary = summary;
}
pub fn set_title(&mut self, title: Option<String>) {
self.title = title;
}
pub fn title(&self) -> &String {
match self.title.as_ref() {
Some(ref title) => title,
None => &self.name,
}
}
pub fn kind(&self) -> Option<&String> {
self.kind.as_ref()
}
pub fn summary(&self) -> String {
self.summary.clone().unwrap_or_else(|| match &self.kind {
None => self.name.clone(),
Some(kind) => format!("{} '{}'", kind.to_lowercase(), self.name),
})
}
}
pub(crate) enum InputKind<'a> {
OrdinaryFile(OsString),
StdIn,
CustomReader(Box<dyn Read + 'a>),
}
impl<'a> InputKind<'a> {
pub fn description(&self) -> InputDescription {
match self {
InputKind::OrdinaryFile(ref path) => InputDescription::new(path.to_string_lossy()),
InputKind::StdIn => InputDescription::new("STDIN"),
InputKind::CustomReader(_) => InputDescription::new("READER"),
}
}
}
#[derive(Clone, Default)]
pub(crate) struct InputMetadata {
pub(crate) user_provided_name: Option<OsString>,
}
pub struct Input<'a> {
pub(crate) kind: InputKind<'a>,
pub(crate) metadata: InputMetadata,
pub(crate) description: InputDescription,
}
pub(crate) enum OpenedInputKind {
OrdinaryFile(OsString),
StdIn,
CustomReader,
}
pub(crate) struct OpenedInput<'a> {
pub(crate) kind: OpenedInputKind,
pub(crate) metadata: InputMetadata,
pub(crate) reader: InputReader<'a>,
pub(crate) description: InputDescription,
}
impl<'a> Input<'a> {
pub fn ordinary_file(path: &OsStr) -> Self {
let kind = InputKind::OrdinaryFile(path.to_os_string());
Input {
description: kind.description(),
metadata: InputMetadata::default(),
kind,
}
}
pub fn stdin() -> Self {
let kind = InputKind::StdIn;
Input {
description: kind.description(),
metadata: InputMetadata::default(),
kind,
}
}
pub fn from_reader(reader: Box<dyn Read + 'a>) -> Self {
let kind = InputKind::CustomReader(reader);
Input {
description: kind.description(),
metadata: InputMetadata::default(),
kind,
}
}
pub fn is_stdin(&self) -> bool {
if let InputKind::StdIn = self.kind {
true
} else {
false
}
}
pub fn with_name(mut self, provided_name: Option<&OsStr>) -> Self {
match provided_name {
Some(name) => self.description.name = name.to_string_lossy().to_string(),
None => {}
}
self.metadata.user_provided_name = provided_name.map(|n| n.to_owned());
self
}
pub fn description(&self) -> &InputDescription {
&self.description
}
pub fn description_mut(&mut self) -> &mut InputDescription {
&mut self.description
}
pub(crate) fn open<R: BufRead + 'a>(self, stdin: R) -> Result<OpenedInput<'a>> {
let description = self.description().clone();
match self.kind {
InputKind::StdIn => Ok(OpenedInput {
kind: OpenedInputKind::StdIn,
description,
metadata: self.metadata,
reader: InputReader::new(stdin),
}),
InputKind::OrdinaryFile(path) => Ok(OpenedInput {
kind: OpenedInputKind::OrdinaryFile(path.clone()),
description,
metadata: self.metadata,
reader: {
let file = File::open(&path)
.map_err(|e| format!("'{}': {}", path.to_string_lossy(), e))?;
if file.metadata()?.is_dir() {
return Err(format!("'{}' is a directory.", path.to_string_lossy()).into());
}
InputReader::new(BufReader::new(file))
},
}),
InputKind::CustomReader(reader) => Ok(OpenedInput {
description,
kind: OpenedInputKind::CustomReader,
metadata: self.metadata,
reader: InputReader::new(BufReader::new(reader)),
}),
}
}
}
pub(crate) struct InputReader<'a> {
inner: Box<dyn BufRead + 'a>,
pub(crate) first_line: Vec<u8>,
pub(crate) content_type: Option<ContentType>,
}
impl<'a> InputReader<'a> {
fn new<R: BufRead + 'a>(mut reader: R) -> InputReader<'a> {
let mut first_line = vec![];
reader.read_until(b'\n', &mut first_line).ok();
let content_type = if first_line.is_empty() {
None
} else {
Some(content_inspector::inspect(&first_line[..]))
};
if content_type == Some(ContentType::UTF_16LE) {
reader.read_until(0x00, &mut first_line).ok();
}
InputReader {
inner: Box::new(reader),
first_line,
content_type,
}
}
pub(crate) fn read_line(&mut self, buf: &mut Vec<u8>) -> io::Result<bool> {
if self.first_line.is_empty() {
let res = self.inner.read_until(b'\n', buf).map(|size| size > 0)?;
if self.content_type == Some(ContentType::UTF_16LE) {
self.inner.read_until(0x00, buf).ok();
}
Ok(res)
} else {
buf.append(&mut self.first_line);
Ok(true)
}
}
}
#[test]
fn basic() {
let content = b"#!/bin/bash\necho hello";
let mut reader = InputReader::new(&content[..]);
assert_eq!(b"#!/bin/bash\n", &reader.first_line[..]);
let mut buffer = vec![];
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"#!/bin/bash\n", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"echo hello", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(buffer.is_empty());
}
#[test]
fn utf16le() {
let content = b"\xFF\xFE\x73\x00\x0A\x00\x64\x00";
let mut reader = InputReader::new(&content[..]);
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &reader.first_line[..]);
let mut buffer = vec![];
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"\x64\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(buffer.is_empty());
}
-137
View File
@@ -1,137 +0,0 @@
use std::ffi::OsStr;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use content_inspector::{self, ContentType};
use crate::errors::*;
const THEME_PREVIEW_FILE: &[u8] = include_bytes!("../assets/theme_preview.rs");
pub struct InputFileReader<'a> {
inner: Box<dyn BufRead + 'a>,
pub(crate) first_line: Vec<u8>,
pub(crate) content_type: Option<ContentType>,
}
impl<'a> InputFileReader<'a> {
fn new<R: BufRead + 'a>(mut reader: R) -> InputFileReader<'a> {
let mut first_line = vec![];
reader.read_until(b'\n', &mut first_line).ok();
let content_type = if first_line.is_empty() {
None
} else {
Some(content_inspector::inspect(&first_line[..]))
};
if content_type == Some(ContentType::UTF_16LE) {
reader.read_until(0x00, &mut first_line).ok();
}
InputFileReader {
inner: Box::new(reader),
first_line,
content_type,
}
}
pub(crate) fn read_line(&mut self, buf: &mut Vec<u8>) -> io::Result<bool> {
if self.first_line.is_empty() {
let res = self.inner.read_until(b'\n', buf).map(|size| size > 0)?;
if self.content_type == Some(ContentType::UTF_16LE) {
self.inner.read_until(0x00, buf).ok();
}
Ok(res)
} else {
buf.append(&mut self.first_line);
Ok(true)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum InputFile<'a> {
StdIn,
Ordinary(&'a OsStr),
ThemePreviewFile,
}
impl<'a> InputFile<'a> {
pub(crate) fn get_reader(&self, stdin: &'a io::Stdin) -> Result<InputFileReader> {
match self {
InputFile::StdIn => Ok(InputFileReader::new(stdin.lock())),
InputFile::Ordinary(filename) => {
let file = File::open(filename)
.map_err(|e| format!("'{}': {}", filename.to_string_lossy(), e))?;
if file.metadata()?.is_dir() {
return Err(format!("'{}' is a directory.", filename.to_string_lossy()).into());
}
Ok(InputFileReader::new(BufReader::new(file)))
}
InputFile::ThemePreviewFile => Ok(InputFileReader::new(THEME_PREVIEW_FILE)),
}
}
}
#[test]
fn basic() {
let content = b"#!/bin/bash\necho hello";
let mut reader = InputFileReader::new(&content[..]);
assert_eq!(b"#!/bin/bash\n", &reader.first_line[..]);
let mut buffer = vec![];
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"#!/bin/bash\n", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"echo hello", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(buffer.is_empty());
}
#[test]
fn utf16le() {
let content = b"\xFF\xFE\x73\x00\x0A\x00\x64\x00";
let mut reader = InputFileReader::new(&content[..]);
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &reader.first_line[..]);
let mut buffer = vec![];
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert_eq!(b"\x64\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(buffer.is_empty());
}
+2
View File
@@ -1,3 +1,5 @@
#![cfg(feature = "paging")]
use std::process::Command;
pub fn retrieve_less_version() -> Option<usize> {
+37 -23
View File
@@ -1,34 +1,48 @@
// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]
//! `bat` is a library to print syntax highlighted content.
//!
//! The main struct of this crate is `PrettyPrinter` which can be used to
//! configure and run the syntax highlighting.
//!
//! If you need more control, you can also use the structs in the submodules
//! (start with `controller::Controller`), but note that the API of these
//! internal modules is much more likely to change. Some or all of these
//! modules might be removed in the future.
//!
//! "Hello world" example:
//! ```
//! use bat::PrettyPrinter;
//!
//! PrettyPrinter::new()
//! .input_from_bytes(b"<span style=\"color: #ff00cc\">Hello world!</span>\n")
//! .language("html")
//! .print()
//! .unwrap();
//! ```
extern crate ansi_term;
extern crate atty;
extern crate console;
extern crate content_inspector;
extern crate dirs as dirs_rs;
extern crate encoding;
extern crate git2;
extern crate shell_words;
extern crate syntect;
extern crate wild;
pub(crate) mod assets;
pub mod assets;
pub mod assets_metadata;
pub mod config;
pub(crate) mod controller;
pub mod controller;
mod decorations;
mod diff;
pub mod errors;
pub(crate) mod inputfile;
pub mod error;
pub mod input;
mod less;
pub(crate) mod line_range;
pub mod line_range;
mod output;
#[cfg(feature = "paging")]
pub(crate) mod paging;
mod preprocessor;
mod pretty_printer;
pub(crate) mod printer;
pub(crate) mod style;
pub mod style;
pub(crate) mod syntax_mapping;
mod terminal;
pub(crate) mod wrap;
pub(crate) mod wrapping;
pub use assets::HighlightingAssets;
pub use controller::Controller;
pub use printer::{InteractivePrinter, Printer, SimplePrinter};
pub use pretty_printer::{Input, PrettyPrinter};
pub use syntax_mapping::{MappingTarget, SyntaxMapping};
pub use wrapping::WrappingMode;
#[cfg(feature = "paging")]
pub use paging::PagingMode;
+11 -4
View File
@@ -1,9 +1,9 @@
use crate::errors::*;
use crate::error::*;
#[derive(Debug, Clone)]
pub struct LineRange {
pub lower: usize,
pub upper: usize,
lower: usize,
upper: usize,
}
impl Default for LineRange {
@@ -16,6 +16,13 @@ impl Default for LineRange {
}
impl LineRange {
pub fn new(from: usize, to: usize) -> Self {
LineRange {
lower: from,
upper: to,
}
}
pub fn from(range_raw: &str) -> Result<LineRange> {
LineRange::parse_range(range_raw)
}
@@ -23,7 +30,7 @@ impl LineRange {
fn parse_range(range_raw: &str) -> Result<LineRange> {
let mut new_range = LineRange::default();
if range_raw.bytes().nth(0).ok_or("Empty line range")? == b':' {
if range_raw.bytes().next().ok_or("Empty line range")? == b':' {
new_range.upper = range_raw[1..].parse()?;
return Ok(new_range);
} else if range_raw.bytes().last().ok_or("Empty line range")? == b':' {
+37 -10
View File
@@ -1,22 +1,22 @@
use std::env;
use std::ffi::OsString;
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
#[cfg(feature = "paging")]
use std::process::Child;
use shell_words;
use crate::config::PagingMode;
use crate::errors::*;
use crate::error::*;
#[cfg(feature = "paging")]
use crate::less::retrieve_less_version;
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
#[derive(Debug)]
pub enum OutputType {
#[cfg(feature = "paging")]
Pager(Child),
Stdout(io::Stdout),
}
impl OutputType {
#[cfg(feature = "paging")]
pub fn from_mode(mode: PagingMode, pager: Option<&str>) -> Result<Self> {
use self::PagingMode::*;
Ok(match mode {
@@ -27,7 +27,13 @@ impl OutputType {
}
/// Try to launch the pager. Fall back to stdout in case of errors.
#[cfg(feature = "paging")]
fn try_pager(quit_if_one_screen: bool, pager_from_config: Option<&str>) -> Result<Self> {
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use std::process::{Command, Stdio};
let mut replace_arguments_to_less = false;
let pager_from_env = match (env::var("BAT_PAGER"), env::var("PAGER")) {
@@ -80,11 +86,16 @@ impl OutputType {
// versions of 'less'. Unfortunately, it also breaks mouse-wheel support.
//
// See: http://www.greenwoodsoftware.com/less/news.530.html
//
// For newer versions (530 or 558 on Windows), we omit '--no-init' as it
// is not needed anymore.
match retrieve_less_version() {
None => {
p.arg("--no-init");
}
Some(version) if version < 530 => {
Some(version)
if (version < 530 || (cfg!(windows) && version < 558)) =>
{
p.arg("--no-init");
}
_ => {}
@@ -110,12 +121,27 @@ impl OutputType {
}
}
fn stdout() -> Self {
pub(crate) fn stdout() -> Self {
OutputType::Stdout(io::stdout())
}
#[cfg(feature = "paging")]
pub(crate) fn is_pager(&self) -> bool {
if let OutputType::Pager(_) = self {
true
} else {
false
}
}
#[cfg(not(feature = "paging"))]
pub(crate) fn is_pager(&self) -> bool {
false
}
pub fn handle(&mut self) -> Result<&mut dyn Write> {
Ok(match *self {
#[cfg(feature = "paging")]
OutputType::Pager(ref mut command) => command
.stdin
.as_mut()
@@ -125,6 +151,7 @@ impl OutputType {
}
}
#[cfg(feature = "paging")]
impl Drop for OutputType {
fn drop(&mut self) {
if let OutputType::Pager(ref mut command) = *self {
+12
View File
@@ -0,0 +1,12 @@
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PagingMode {
Always,
QuitIfOneScreen,
Never,
}
impl Default for PagingMode {
fn default() -> Self {
PagingMode::Never
}
}
+9 -9
View File
@@ -36,15 +36,15 @@ pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
fn try_parse_utf8_char(input: &[u8]) -> Option<(char, usize)> {
let str_from_utf8 = |seq| std::str::from_utf8(seq).ok();
let decoded = None
.or(input.get(0..1).and_then(str_from_utf8).map(|c| (c, 1)))
.or(input.get(0..2).and_then(str_from_utf8).map(|c| (c, 2)))
.or(input.get(0..3).and_then(str_from_utf8).map(|c| (c, 3)))
.or(input.get(0..4).and_then(str_from_utf8).map(|c| (c, 4)));
let decoded = input
.get(0..1)
.and_then(str_from_utf8)
.map(|c| (c, 1))
.or_else(|| input.get(0..2).and_then(str_from_utf8).map(|c| (c, 2)))
.or_else(|| input.get(0..3).and_then(str_from_utf8).map(|c| (c, 3)))
.or_else(|| input.get(0..4).and_then(str_from_utf8).map(|c| (c, 4)));
let decoded_char = decoded.map(|(seq, n)| (seq.chars().next().unwrap(), n));
decoded_char
decoded.map(|(seq, n)| (seq.chars().next().unwrap(), n))
}
pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String {
@@ -60,7 +60,7 @@ pub fn replace_nonprintable(input: &[u8], tab_width: usize) -> String {
match chr {
// space
' ' => output.push(''),
' ' => output.push('·'),
// tab
'\t' => {
if tab_width == 1 {
+373
View File
@@ -0,0 +1,373 @@
use std::ffi::OsStr;
use std::io::Read;
use console::Term;
use syntect::parsing::SyntaxReference;
use crate::{
assets::HighlightingAssets,
config::{Config, VisibleLines},
controller::Controller,
error::Result,
input,
line_range::{HighlightedLineRanges, LineRange, LineRanges},
style::{StyleComponent, StyleComponents},
SyntaxMapping, WrappingMode,
};
#[cfg(feature = "paging")]
use crate::paging::PagingMode;
#[derive(Default)]
struct ActiveStyleComponents {
header: bool,
vcs_modification_markers: bool,
grid: bool,
line_numbers: bool,
snip: bool,
}
pub struct PrettyPrinter<'a> {
inputs: Vec<Input<'a>>,
config: Config<'a>,
assets: HighlightingAssets,
highlighted_lines: Vec<LineRange>,
term_width: Option<usize>,
active_style_components: ActiveStyleComponents,
}
impl<'a> PrettyPrinter<'a> {
pub fn new() -> Self {
let mut config = Config::default();
config.colored_output = true;
config.true_color = true;
PrettyPrinter {
inputs: vec![],
config,
assets: HighlightingAssets::from_binary(),
highlighted_lines: vec![],
term_width: None,
active_style_components: ActiveStyleComponents::default(),
}
}
/// Add an input which should be pretty-printed
pub fn input(&mut self, input: Input<'a>) -> &mut Self {
self.inputs.push(input);
self
}
/// Adds multiple inputs which should be pretty-printed
pub fn inputs(&mut self, inputs: impl IntoIterator<Item = Input<'a>>) -> &mut Self {
for input in inputs {
self.inputs.push(input);
}
self
}
/// Add a file which should be pretty-printed
pub fn input_file(&mut self, path: impl AsRef<OsStr>) -> &mut Self {
self.input(Input::from_file(path).kind("File"))
}
/// Add multiple files which should be pretty-printed
pub fn input_files<I, P>(&mut self, paths: I) -> &mut Self
where
I: IntoIterator<Item = P>,
P: AsRef<OsStr>,
{
self.inputs(paths.into_iter().map(Input::from_file))
}
/// Add STDIN as an input
pub fn input_stdin(&mut self) -> &mut Self {
self.inputs.push(Input::from_stdin());
self
}
/// Add STDIN as an input (with customized name)
#[deprecated]
pub fn input_stdin_with_name(&mut self, name: impl AsRef<OsStr>) -> &mut Self {
self.inputs
.push(Input::from_stdin().name(name).kind("File"));
self
}
/// Add a byte string as an input
pub fn input_from_bytes(&mut self, content: &'a [u8]) -> &mut Self {
self.input_from_reader(content)
}
/// Add a byte string as an input (with customized name)
#[deprecated]
#[allow(deprecated)]
pub fn input_from_bytes_with_name(
&mut self,
content: &'a [u8],
name: impl AsRef<OsStr>,
) -> &mut Self {
self.input_from_reader_with_name(content, name)
}
/// Add a custom reader as an input
pub fn input_from_reader<R: Read + 'a>(&mut self, reader: R) -> &mut Self {
self.inputs.push(Input::from_reader(reader));
self
}
/// Add a custom reader as an input (with customized name)
#[deprecated]
pub fn input_from_reader_with_name<R: Read + 'a>(
&mut self,
reader: R,
name: impl AsRef<OsStr>,
) -> &mut Self {
self.inputs
.push(Input::from_reader(reader).name(name).kind("File"));
self
}
/// Specify the syntax file which should be used (default: auto-detect)
pub fn language(&mut self, language: &'a str) -> &mut Self {
self.config.language = Some(language);
self
}
/// The character width of the terminal (default: autodetect)
pub fn term_width(&mut self, width: usize) -> &mut Self {
self.term_width = Some(width);
self
}
/// The width of tab characters (default: None - do not turn tabs to spaces)
pub fn tab_width(&mut self, tab_width: Option<usize>) -> &mut Self {
self.config.tab_width = tab_width.unwrap_or(0);
self
}
/// Whether or not the output should be colorized (default: true)
pub fn colored_output(&mut self, yes: bool) -> &mut Self {
self.config.colored_output = yes;
self
}
/// Whether or not to output 24bit colors (default: true)
pub fn true_color(&mut self, yes: bool) -> &mut Self {
self.config.true_color = yes;
self
}
/// Whether to show a header with the file name
pub fn header(&mut self, yes: bool) -> &mut Self {
self.active_style_components.header = yes;
self
}
/// Whether to show line numbers
pub fn line_numbers(&mut self, yes: bool) -> &mut Self {
self.active_style_components.line_numbers = yes;
self
}
/// Whether to paint a grid, separating line numbers, git changes and the code
pub fn grid(&mut self, yes: bool) -> &mut Self {
self.active_style_components.grid = yes;
self
}
/// Whether to show modification markers for VCS changes. This has no effect if
/// the `git` feature is not activated.
#[cfg_attr(
not(feature = "git"),
deprecated(
note = "Using vcs_modification_markers without the 'git' feature has no effect. \
The function will be removed (for non-'git' use cases) in the future."
)
)]
#[allow(unused_variables)]
pub fn vcs_modification_markers(&mut self, yes: bool) -> &mut Self {
#[cfg(feature = "git")]
{
self.active_style_components.vcs_modification_markers = yes;
}
self
}
/// Whether to show "snip" markers between visible line ranges (default: no)
pub fn snip(&mut self, yes: bool) -> &mut Self {
self.active_style_components.snip = yes;
self
}
/// Text wrapping mode (default: do not wrap)
pub fn wrapping_mode(&mut self, mode: WrappingMode) -> &mut Self {
self.config.wrapping_mode = mode;
self
}
/// Whether or not to use ANSI italics (default: off)
pub fn use_italics(&mut self, yes: bool) -> &mut Self {
self.config.use_italic_text = yes;
self
}
/// If and how to use a pager (default: no paging)
#[cfg(feature = "paging")]
pub fn paging_mode(&mut self, mode: PagingMode) -> &mut Self {
self.config.paging_mode = mode;
self
}
/// Specify the command to start the pager (default: use "less")
#[cfg(feature = "paging")]
pub fn pager(&mut self, cmd: &'a str) -> &mut Self {
self.config.pager = Some(cmd);
self
}
/// Specify the lines that should be printed (default: all)
pub fn line_ranges(&mut self, ranges: LineRanges) -> &mut Self {
self.config.visible_lines = VisibleLines::Ranges(ranges);
self
}
/// Specify a line that should be highlighted (default: none).
/// This can be called multiple times to highlight more than one
/// line. See also: highlight_range.
pub fn highlight(&mut self, line: usize) -> &mut Self {
self.highlighted_lines.push(LineRange::new(line, line));
self
}
/// Specify a range of lines that should be highlighted (default: none).
/// This can be called multiple times to highlight more than one range
/// of lines.
pub fn highlight_range(&mut self, from: usize, to: usize) -> &mut Self {
self.highlighted_lines.push(LineRange::new(from, to));
self
}
/// Specify the highlighting theme
pub fn theme(&mut self, theme: impl AsRef<str>) -> &mut Self {
self.config.theme = theme.as_ref().to_owned();
self
}
/// Specify custom file extension / file name to syntax mappings
pub fn syntax_mapping(&mut self, mapping: SyntaxMapping<'a>) -> &mut Self {
self.config.syntax_mapping = mapping;
self
}
pub fn themes(&self) -> impl Iterator<Item = &str> {
self.assets.themes()
}
pub fn syntaxes(&self) -> impl Iterator<Item = &SyntaxReference> {
self.assets.syntaxes().iter()
}
/// Pretty-print all specified inputs. This method will "use" all stored inputs.
/// 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.config.highlighted_lines =
HighlightedLineRanges(LineRanges::from(self.highlighted_lines.clone()));
self.config.term_width = self
.term_width
.unwrap_or_else(|| Term::stdout().size().1 as usize);
let mut style_components = vec![];
if self.active_style_components.grid {
style_components.push(StyleComponent::Grid);
}
if self.active_style_components.header {
style_components.push(StyleComponent::Header);
}
if self.active_style_components.line_numbers {
style_components.push(StyleComponent::LineNumbers);
}
if self.active_style_components.snip {
style_components.push(StyleComponent::Snip);
}
if self.active_style_components.vcs_modification_markers {
#[cfg(feature = "git")]
style_components.push(StyleComponent::Changes);
}
self.config.style_components = StyleComponents::new(&style_components);
// Collect the inputs to print
let mut inputs: Vec<Input> = vec![];
std::mem::swap(&mut inputs, &mut self.inputs);
// Run the controller
let controller = Controller::new(&self.config, &self.assets);
controller.run(inputs.into_iter().map(|i| i.into()).collect())
}
}
/// An input source for the pretty printer.
pub struct Input<'a> {
input: input::Input<'a>,
}
impl<'a> Input<'a> {
/// A new input from a reader.
pub fn from_reader<R: Read + 'a>(reader: R) -> Self {
input::Input::from_reader(Box::new(reader)).into()
}
/// A new input from a file.
pub fn from_file(path: impl AsRef<OsStr>) -> Self {
input::Input::ordinary_file(path.as_ref()).into()
}
/// A new input from bytes.
pub fn from_bytes(bytes: &'a [u8]) -> Self {
Input::from_reader(bytes).into()
}
/// A new input from STDIN.
pub fn from_stdin() -> Self {
input::Input::stdin().into()
}
/// The filename of the input.
/// This affects syntax detection and changes the default header title.
pub fn name(mut self, name: impl AsRef<OsStr>) -> Self {
self.input = self.input.with_name(Some(name.as_ref()));
self
}
/// The description for the type of input (e.g. "File")
pub fn kind(mut self, kind: impl Into<String>) -> Self {
let kind = kind.into();
self.input
.description_mut()
.set_kind(if kind.is_empty() { None } else { Some(kind) });
self
}
/// The title for the input (e.g. "http://example.com/example.txt")
/// This defaults to the file name.
pub fn title(mut self, title: impl Into<String>) -> Self {
self.input.description_mut().set_title(Some(title.into()));
self
}
}
impl<'a> Into<Input<'a>> for input::Input<'a> {
fn into(self) -> Input<'a> {
Input { input: self }
}
}
impl<'a> Into<input::Input<'a>> for Input<'a> {
fn into(self) -> input::Input<'a> {
self.input
}
}
+87 -67
View File
@@ -1,4 +1,3 @@
use std::borrow::Cow;
use std::io::Write;
use std::vec::Vec;
@@ -21,21 +20,26 @@ use unicode_width::UnicodeWidthChar;
use crate::assets::HighlightingAssets;
use crate::config::Config;
use crate::decorations::{
Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration,
};
use crate::diff::get_git_diff;
#[cfg(feature = "git")]
use crate::decorations::LineChangesDecoration;
use crate::decorations::{Decoration, GridBorderDecoration, LineNumberDecoration};
#[cfg(feature = "git")]
use crate::diff::LineChanges;
use crate::errors::*;
use crate::inputfile::{InputFile, InputFileReader};
use crate::error::*;
use crate::input::OpenedInput;
use crate::line_range::RangeCheckResult;
use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::terminal::{as_terminal_escaped, to_ansi_color};
use crate::wrap::OutputWrap;
use crate::wrapping::WrappingMode;
pub trait Printer {
fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()>;
fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()>;
pub(crate) trait Printer {
fn print_header(
&mut self,
handle: &mut dyn Write,
input: &OpenedInput,
add_header_padding: bool,
) -> Result<()>;
fn print_footer(&mut self, handle: &mut dyn Write, input: &OpenedInput) -> Result<()>;
fn print_snip(&mut self, handle: &mut dyn Write) -> Result<()>;
@@ -48,20 +52,27 @@ pub trait Printer {
) -> Result<()>;
}
pub struct SimplePrinter;
pub struct SimplePrinter<'a> {
config: &'a Config<'a>,
}
impl SimplePrinter {
pub fn new() -> Self {
SimplePrinter {}
impl<'a> SimplePrinter<'a> {
pub fn new(config: &'a Config) -> Self {
SimplePrinter { config }
}
}
impl Printer for SimplePrinter {
fn print_header(&mut self, _handle: &mut dyn Write, _file: InputFile) -> Result<()> {
impl<'a> Printer for SimplePrinter<'a> {
fn print_header(
&mut self,
_handle: &mut dyn Write,
_input: &OpenedInput,
_add_header_padding: bool,
) -> Result<()> {
Ok(())
}
fn print_footer(&mut self, _handle: &mut dyn Write) -> Result<()> {
fn print_footer(&mut self, _handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
Ok(())
}
@@ -77,32 +88,41 @@ impl Printer for SimplePrinter {
line_buffer: &[u8],
) -> Result<()> {
if !out_of_range {
handle.write_all(line_buffer)?;
if self.config.show_nonprintable {
let line = replace_nonprintable(line_buffer, self.config.tab_width);
write!(handle, "{}", line)?;
if line_buffer.last() == Some(&b'\n') {
writeln!(handle)?;
}
} else {
handle.write_all(line_buffer)?
};
}
Ok(())
}
}
pub struct InteractivePrinter<'a> {
pub(crate) struct InteractivePrinter<'a> {
colors: Colors,
config: &'a Config<'a>,
decorations: Vec<Box<dyn Decoration>>,
panel_width: usize,
ansi_prefix_sgr: String,
content_type: Option<ContentType>,
pub line_changes: Option<LineChanges>,
#[cfg(feature = "git")]
pub line_changes: &'a Option<LineChanges>,
highlighter: Option<HighlightLines<'a>>,
syntax_set: &'a SyntaxSet,
background_color_highlight: Option<Color>,
}
impl<'a> InteractivePrinter<'a> {
pub fn new(
pub(crate) fn new(
config: &'a Config,
assets: &'a HighlightingAssets,
file: InputFile,
reader: &mut InputFileReader,
) -> Self {
input: &mut OpenedInput,
#[cfg(feature = "git")] line_changes: &'a Option<LineChanges>,
) -> Result<Self> {
let theme = assets.get_theme(&config.theme);
let background_color_highlight = theme.settings.line_highlight;
@@ -120,8 +140,11 @@ impl<'a> InteractivePrinter<'a> {
decorations.push(Box::new(LineNumberDecoration::new(&colors)));
}
if config.style_components.changes() {
decorations.push(Box::new(LineChangesDecoration::new(&colors)));
#[cfg(feature = "git")]
{
if config.style_components.changes() {
decorations.push(Box::new(LineChangesDecoration::new(&colors)));
}
}
let mut panel_width: usize =
@@ -143,41 +166,38 @@ impl<'a> InteractivePrinter<'a> {
panel_width = 0;
}
let mut line_changes = None;
let highlighter = if reader
let highlighter = if input
.reader
.content_type
.map_or(false, |c| c.is_binary() && !config.show_nonprintable)
{
None
} else {
// Get the Git modifications
line_changes = if config.style_components.changes() {
match file {
InputFile::Ordinary(filename) => get_git_diff(filename),
_ => None,
// Determine the type of syntax for highlighting
let syntax = match assets.get_syntax(config.language, input, &config.syntax_mapping) {
Ok(syntax) => syntax,
Err(Error(ErrorKind::UndetectedSyntax(_), _)) => {
assets.syntax_set.find_syntax_plain_text()
}
} else {
None
Err(e) => return Err(e),
};
// Determine the type of syntax for highlighting
let syntax = assets.get_syntax(config.language, file, reader, &config.syntax_mapping);
Some(HighlightLines::new(syntax, theme))
};
InteractivePrinter {
Ok(InteractivePrinter {
panel_width,
colors,
config,
decorations,
content_type: reader.content_type,
content_type: input.reader.content_type,
ansi_prefix_sgr: String::new(),
#[cfg(feature = "git")]
line_changes,
highlighter,
syntax_set: &assets.syntax_set,
background_color_highlight,
}
})
}
fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> {
@@ -209,7 +229,7 @@ impl<'a> InteractivePrinter<'a> {
if self.config.style_components.grid() {
format!("{}", text_filled)
} else {
format!("{}", text_filled)
text_filled
}
}
}
@@ -218,34 +238,31 @@ impl<'a> InteractivePrinter<'a> {
if self.config.tab_width > 0 {
expand_tabs(text, self.config.tab_width, cursor)
} else {
*cursor += text.len();
text.to_string()
}
}
}
impl<'a> Printer for InteractivePrinter<'a> {
fn print_header(&mut self, handle: &mut dyn Write, file: InputFile) -> Result<()> {
fn print_header(
&mut self,
handle: &mut dyn Write,
input: &OpenedInput,
add_header_padding: bool,
) -> Result<()> {
if !self.config.style_components.header() {
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
let input = match file {
InputFile::Ordinary(filename) => {
format!("file '{}'", filename.to_string_lossy())
}
_ => "STDIN".into(),
};
writeln!(
handle,
"{}: Binary content from {} will not be printed to the terminal \
(but will be present if the output of 'bat' is piped). You can use 'bat -A' \
to show the binary file contents.",
Yellow.paint("[bat warning]"),
input
input.description.summary(),
)?;
} else {
if self.config.style_components.grid() {
self.print_horizontal_line(handle, '┬')?;
}
} else if self.config.style_components.grid() {
self.print_horizontal_line(handle, '┬')?;
}
return Ok(());
}
@@ -262,14 +279,12 @@ impl<'a> Printer for InteractivePrinter<'a> {
.paint(if self.panel_width > 0 { "" } else { "" }),
)?;
} else {
if add_header_padding {
writeln!(handle)?;
}
write!(handle, "{}", " ".repeat(self.panel_width))?;
}
let (prefix, name) = match file {
InputFile::Ordinary(filename) => ("File: ", filename.to_string_lossy()),
_ => ("", Cow::from("STDIN")),
};
let mode = match self.content_type {
Some(ContentType::BINARY) => " <BINARY>",
Some(ContentType::UTF_16LE) => " <UTF-16LE>",
@@ -278,11 +293,16 @@ impl<'a> Printer for InteractivePrinter<'a> {
_ => "",
};
let description = &input.description;
writeln!(
handle,
"{}{}{}",
prefix,
self.colors.filename.paint(name),
description
.kind()
.map(|kind| format!("{}: ", kind))
.unwrap_or("".into()),
self.colors.filename.paint(description.title()),
mode
)?;
@@ -297,7 +317,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
Ok(())
}
fn print_footer(&mut self, handle: &mut dyn Write) -> Result<()> {
fn print_footer(&mut self, handle: &mut dyn Write, _input: &OpenedInput) -> Result<()> {
if self.config.style_components.grid()
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
{
@@ -320,9 +340,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
let snip_right =
"".repeat((self.config.term_width - panel_count - snip_left_count - title_count) / 2);
write!(
writeln!(
handle,
"{}\n",
"{}",
self.colors
.grid
.paint(format!("{}{}{}{}", panel, snip_left, title, snip_right))
@@ -397,7 +417,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
}
// Line contents.
if self.config.output_wrap == OutputWrap::None {
if self.config.wrapping_mode == WrappingMode::NoWrapping {
let true_color = self.config.true_color;
let colored_output = self.config.colored_output;
let italics = self.config.use_italic_text;
+11 -6
View File
@@ -1,15 +1,16 @@
use std::collections::HashSet;
use std::str::FromStr;
use crate::errors::*;
use crate::error::*;
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub enum StyleComponent {
Auto,
#[cfg(feature = "git")]
Changes,
Grid,
Header,
Numbers,
LineNumbers,
Snip,
Full,
Plain,
@@ -25,16 +26,18 @@ impl StyleComponent {
StyleComponent::Plain.components(interactive_terminal)
}
}
#[cfg(feature = "git")]
StyleComponent::Changes => &[StyleComponent::Changes],
StyleComponent::Grid => &[StyleComponent::Grid],
StyleComponent::Header => &[StyleComponent::Header],
StyleComponent::Numbers => &[StyleComponent::Numbers],
StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
StyleComponent::Snip => &[StyleComponent::Snip],
StyleComponent::Full => &[
#[cfg(feature = "git")]
StyleComponent::Changes,
StyleComponent::Grid,
StyleComponent::Header,
StyleComponent::Numbers,
StyleComponent::LineNumbers,
StyleComponent::Snip,
],
StyleComponent::Plain => &[],
@@ -48,10 +51,11 @@ impl FromStr for StyleComponent {
fn from_str(s: &str) -> Result<Self> {
match s {
"auto" => Ok(StyleComponent::Auto),
#[cfg(feature = "git")]
"changes" => Ok(StyleComponent::Changes),
"grid" => Ok(StyleComponent::Grid),
"header" => Ok(StyleComponent::Header),
"numbers" => Ok(StyleComponent::Numbers),
"numbers" => Ok(StyleComponent::LineNumbers),
"snip" => Ok(StyleComponent::Snip),
"full" => Ok(StyleComponent::Full),
"plain" => Ok(StyleComponent::Plain),
@@ -68,6 +72,7 @@ impl StyleComponents {
StyleComponents(components.iter().cloned().collect())
}
#[cfg(feature = "git")]
pub fn changes(&self) -> bool {
self.0.contains(&StyleComponent::Changes)
}
@@ -81,7 +86,7 @@ impl StyleComponents {
}
pub fn numbers(&self) -> bool {
self.0.contains(&StyleComponent::Numbers)
self.0.contains(&StyleComponent::LineNumbers)
}
pub fn snip(&self) -> bool {
+99 -3
View File
@@ -1,6 +1,6 @@
use std::path::Path;
use crate::errors::Result;
use crate::error::Result;
use globset::{Candidate, GlobBuilder, GlobMatcher};
@@ -23,12 +23,19 @@ impl<'a> SyntaxMapping<'a> {
pub fn builtin() -> SyntaxMapping<'a> {
let mut mapping = Self::empty();
mapping.insert("*.h", MappingTarget::MapTo("C++")).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",
@@ -36,6 +43,91 @@ impl<'a> SyntaxMapping<'a> {
)
.unwrap();
// See #1008
mapping
.insert("rails", MappingTarget::MapToUnknown)
.unwrap();
// Nginx and Apache syntax files both want to style all ".conf" files
// see #1131 and #1137
mapping
.insert("*.conf", MappingTarget::MapToUnknown)
.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",
]
.iter()
{
mapping.insert(glob, MappingTarget::MapTo("INI")).unwrap();
}
// pacman hooks
mapping
.insert("*.hook", MappingTarget::MapTo("INI"))
.unwrap();
if let Some(xdg_config_home) = std::env::var_os("XDG_CONFIG_HOME") {
let git_config_path = Path::new(&xdg_config_home).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
}
@@ -48,12 +140,16 @@ impl<'a> SyntaxMapping<'a> {
Ok(())
}
pub fn mappings(&self) -> &[(GlobMatcher, MappingTarget<'a>)] {
&self.mappings
}
pub(crate) fn get_syntax_for(&self, path: impl AsRef<Path>) -> Option<MappingTarget<'a>> {
let candidate = Candidate::new(path.as_ref());
let canddidate_filename = path.as_ref().file_name().map(Candidate::new);
let candidate_filename = path.as_ref().file_name().map(Candidate::new);
for (ref glob, ref syntax) in self.mappings.iter().rev() {
if glob.is_match_candidate(&candidate)
|| canddidate_filename
|| candidate_filename
.as_ref()
.map_or(false, |filename| glob.is_match_candidate(filename))
{

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