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

Compare commits

..

68 Commits

Author SHA1 Message Date
sharkdp 30b742e984 --map-syntax takes just one value 2018-10-17 23:27:44 +02:00
sharkdp 671deeef8c Update help text 2018-10-17 23:17:28 +02:00
sharkdp a892caeb33 Bump bat version to 0.8 2018-10-17 23:15:59 +02:00
sharkdp a770cbf25e Update assets 2018-10-17 23:14:07 +02:00
sharkdp 931c6e9414 Update man page 2018-10-17 23:13:50 +02:00
sharkdp 8dc7e2efa3 Add --config-file option 2018-10-17 23:08:37 +02:00
sharkdp 10965a6122 Implement syntax mapping
This adds a `-m`/`--map-syntax` option that allows users to (re)map
certain file extensions or file names to an existing syntax.

For example:
```
bat --map-syntax .config:json
```

The option can be use multiple times. Note that you can easily make
these mappings permanent by using `bat`s new configuration file.

closes #169
2018-10-17 23:08:19 +02:00
sharkdp e43d97dc15 Small cleanup 2018-10-17 21:12:23 +02:00
sharkdp 2c7087b8de Add integration tests for pager handling 2018-10-17 21:08:32 +02:00
sharkdp bb1f5aa841 Add proper handling of empty PAGER variables 2018-10-17 21:08:32 +02:00
sharkdp 2109a7830b Add error handling for parsing errors 2018-10-17 21:08:32 +02:00
sharkdp ec27c78a8a Remove duplicate 'extern crate' 2018-10-17 21:08:32 +02:00
Morten Linderud 67fe833bc8 Add arguments from PAGER/BAT_PAGER
Solves #352

Signed-off-by: Morten Linderud <morten@linderud.pw>
2018-10-17 21:08:32 +02:00
sharkdp e956225b4d Update syntect to 3.0.1
closes #314
2018-10-16 23:06:46 +02:00
sharkdp 314ec881ef Bump Rust version 2018-10-16 22:09:15 +02:00
sharkdp 25a6a55437 Revert "Fix for older version of Rust"
This reverts commit c530fadc44.
2018-10-16 22:09:15 +02:00
sharkdp 5bff4548be Add BAT_OPTS environment variable 2018-10-16 22:09:15 +02:00
sharkdp 866b9e16a8 Add error handling 2018-10-16 22:09:15 +02:00
sharkdp 5af176c94f Move transpose to util module 2018-10-16 22:09:15 +02:00
sharkdp 9e7da05459 Fix for older version of Rust 2018-10-16 22:09:15 +02:00
sharkdp 1ae02c65fb Fix include 2018-10-16 22:09:15 +02:00
sharkdp 495e7fd3b1 Add --no-config option 2018-10-16 22:09:15 +02:00
sharkdp b48f0fe389 Fix tests 2018-10-16 22:09:15 +02:00
sharkdp c19c704a43 Add more tests 2018-10-16 22:09:15 +02:00
sharkdp 693bd5929d Add possibility for spaces on a single line 2018-10-16 22:09:15 +02:00
sharkdp 8275b0436d Add simple configuration file
This allows users to create simple configuration file
(`~/.config/bat/config` on Linux) that has the following format:

    ```bash
    --flag1
    --flag2
    --option1=value1
    # lines beginning with '#' are ignored
    --option2=value2
    # empty lines and trailing whitespace are also ignored

    --option3=value3
    ```
2018-10-16 22:09:15 +02:00
sharkdp 278bde5cee Continue with output after "is directory"-error 2018-10-11 21:54:19 +02:00
Russ Taylor eee7e5a575 Removes duplicate explanation. 2018-10-11 20:58:44 +02:00
Russ Taylor ad7b634ee6 Fixes #328 - adds info for light backgrounds. 2018-10-11 20:58:44 +02:00
David Peter 1310f83c8d Update Docker alias for bat 2018-10-11 20:57:46 +02:00
David Peter 897b9e7030 Add Docker instructions, closes #331 2018-10-11 20:05:17 +02:00
sharkdp 1891e194b5 Add simple integration tests 2018-10-11 07:06:13 +02:00
sharkdp d2d01b9fe8 Always remove the local cache when creating new assets 2018-10-10 21:49:03 +02:00
sharkdp 5842d58c01 Updates for syntect 3.0 2018-10-09 22:04:51 +02:00
Tim Sampson e3c71adba7 syntax: Add robot framework support 2018-10-09 20:27:01 +02:00
Merlin Göttlinger 504f28b3a1 Documented nix availability 2018-10-09 20:07:27 +02:00
Fredrik Fornwall d977ba9194 Update dependencies 2018-10-08 22:33:09 +02:00
Tim Sampson 9c09799e1f misc: add exec bit for create.sh 2018-10-08 20:20:05 +02:00
David Peter d83c93c805 Update README.md 2018-10-07 18:39:52 +02:00
sharkdp fc8fd1e63f cargo fmt 2018-10-07 17:49:38 +02:00
sharkdp 404d6a4a81 Update content_inspector version 2018-10-07 17:49:38 +02:00
sharkdp 25d96da4a2 Add support for UTF-16LE and UTF-16BE 2018-10-07 17:49:38 +02:00
sharkdp e97095b724 Use first-line detection for STDIN 2018-10-07 15:34:37 +02:00
sharkdp ce96df00b6 Do not display binary files in interactive mode
closes #248
2018-10-07 15:34:37 +02:00
sharkdp f98fc5f06a Simplify access to first line 2018-10-07 15:34:37 +02:00
sharkdp 1dbb4ef683 Update minimum Rust version to 1.27 2018-10-07 15:34:37 +02:00
sharkdp 0502a3bd4a Add first-line detection for all input types
closes #205
2018-10-07 15:34:37 +02:00
sharkdp 869cf6368c Add possibility to get first line 2018-10-07 15:34:37 +02:00
sharkdp 078228deac Add unit test for InputFileReader 2018-10-07 15:34:37 +02:00
sharkdp e09d7dabb8 Move snapshot tests into separate module 2018-10-07 15:34:37 +02:00
sharkdp 6d1cc8c2c8 Move read_line functionality to inputfile module 2018-10-07 15:34:37 +02:00
sharkdp 87f021078e Use dyn Trait for trait objects 2018-10-07 15:34:37 +02:00
sharkdp d5b0502419 Move get_reader into inputfile module 2018-10-07 15:34:37 +02:00
sharkdp 860f3e9006 Move InputFile to separate module 2018-10-07 15:34:37 +02:00
sharkdp 1be346a038 Add 'plain' version of bat to the benchmarks 2018-10-07 10:57:08 +02:00
sharkdp f9fd5e4851 Simplify -h help text 2018-10-07 10:43:39 +02:00
sharkdp da09f3877b Remove unnecessary scope 2018-10-07 10:09:10 +02:00
sharkdp e30e1bab2e Move theme-preview section into own paragraph 2018-10-06 21:12:12 +02:00
Russ Taylor f140f6da46 Fixes #273 - describes 'musl' builds. 2018-10-06 21:07:01 +02:00
Grégoire Paris 3446fdf5f2 Document how to rapidly preview theme on a file 2018-10-06 21:06:31 +02:00
sharkdp e1345cdc2a Update VimL syntax 2018-10-05 18:44:51 +02:00
sharkdp a2676ccc55 Workaround for #81 2018-10-04 11:09:41 +02:00
Richard Hozák b39e28d2c8 Add support for wildcards in Windows CMD (#329)
Windows does not support wildcard expansion in cmd, this adds 'wild' crate (as discussed in #309) that handles everything transparently, so wildcards work everywhere.

Fixes #309
2018-10-03 22:59:11 +02:00
davideGiovannini 0d71968615 Generate shell completions with clap during build (#327)
* Generate shell completions with clap during build

* Updated ci release script, added SHELL_COMPLETIONS_DIR override to build.rs and fixed dependency version
2018-10-03 09:39:30 +02:00
sharkdp 80da0dc619 run cargo fmt 2018-09-26 19:16:03 +02:00
sharkdp 64903bb858 Typo 2018-09-26 19:13:32 +02:00
sharkdp 3456ce1187 Add a small tutorial 2018-09-26 18:08:24 +02:00
sharkdp 886a5b3d24 Document the situation with less and scrolling
closes #312
closes #246
2018-09-26 18:03:46 +02:00
37 changed files with 1622 additions and 634 deletions
+3
View File
@@ -91,3 +91,6 @@
[submodule "assets/syntaxes/PowerShell"]
path = assets/syntaxes/PowerShell
url = https://github.com/PowerShell/EditorSyntax
[submodule "assets/syntaxes/Robot"]
path = assets/syntaxes/Robot
url = https://github.com/andriyko/sublime-robot-framework-assistant.git
+4 -4
View File
@@ -29,18 +29,18 @@ matrix:
- 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.26.0
rust: 1.29.0
env: TARGET=x86_64-unknown-linux-gnu
- os: linux
rust: 1.26.0
rust: 1.29.0
env:
- TARGET=x86_64-unknown-linux-musl
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
- os: osx
rust: 1.26.0
rust: 1.29.0
env: TARGET=x86_64-apple-darwin
# Code formatting check
Generated
+254 -97
View File
@@ -22,6 +22,17 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "assert_cmd"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.11"
@@ -34,28 +45,33 @@ dependencies = [
[[package]]
name = "base64"
version = "0.8.0"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bat"
version = "0.7.1"
version = "0.8.0"
dependencies = [
"ansi_colours 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"assert_cmd 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"directories 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"content_inspector 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"shell-words 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"wild 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -87,16 +103,6 @@ name = "cfg-if"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.32.0"
@@ -109,6 +115,7 @@ dependencies = [
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -141,28 +148,107 @@ dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "content_inspector"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "directories"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding-index-japanese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding-index-korean"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding-index-simpchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding-index-singlebyte"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding-index-tradchinese"
version = "1.20141219.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "encoding_index_tests"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "error-chain"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "escargot"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "flate2"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -195,11 +281,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "humantime"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "idna"
version = "0.1.5"
@@ -234,9 +333,14 @@ name = "lazy_static"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazycell"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.43"
@@ -244,18 +348,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libgit2-sys"
version = "0.7.9"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libz-sys"
version = "1.0.22"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -271,7 +375,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lock_api"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -298,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -310,33 +414,20 @@ dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "onig"
version = "3.2.2"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"onig_sys 68.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"onig_sys 69.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "onig_sys"
version = "68.2.1"
version = "69.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -357,7 +448,7 @@ name = "parking_lot"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -385,30 +476,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plist"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "predicates"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "predicates-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "predicates-tree"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.19"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -429,13 +548,21 @@ dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -463,11 +590,6 @@ dependencies = [
"utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex-syntax"
version = "0.6.2"
@@ -499,7 +621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "safemem"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -532,20 +654,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "serde"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.28"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -553,6 +678,11 @@ dependencies = [
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "shell-words"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.6.5"
@@ -573,30 +703,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.5"
version = "0.15.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntect"
version = "2.1.0"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"onig 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plist 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -632,7 +763,7 @@ dependencies = [
[[package]]
name = "termios"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -656,14 +787,9 @@ dependencies = [
]
[[package]]
name = "time"
version = "0.1.40"
name = "treeline"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ucd-util"
@@ -721,9 +847,14 @@ name = "vcpkg"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -741,6 +872,14 @@ dependencies = [
"winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wild"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
@@ -798,82 +937,98 @@ dependencies = [
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
"checksum ansi_colours 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0f302a81afc6a7f4350c04f0ba7cfab529cc009bca3324b3fb5764e6add8b6"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum assert_cmd 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d5db841dcfb4f172f34ec968f71c4a88e69f5421fb33e0daac6bfe4372317526"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2fb9e29e72fd6bc12071533d5dc7664cb01480c59406f656d7ac25c7bd8ff7"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd48adf136733979b49e15bc3b4c43cc0d3c85ece7bd08e6daa414c6fcb13e6"
"checksum directories 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b106a38a9bf6c763c6c2e2c3332ab7635da453a68a6babca776386b3b287d338"
"checksum content_inspector 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f15b971ded7c58a746a1c7441c358800337e08f869f75ddd825672984563fafc"
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
"checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f"
"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
"checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
"checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
"checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
"checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b"
"checksum escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19db1f7e74438642a5018cdf263bb1325b2e792f02dd0a3ca6d6c0f0d7b1d5a5"
"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum libgit2-sys 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "93f2b22fce91fb820363cf88a849a8f8fdfd8be37774b6a9dd6cbda05cf940e6"
"checksum libz-sys 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "65ff614643d7635dfa2151913d95c4ee90ee1fe15d9e0980f4dcb1a7e5837c18"
"checksum libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4916b5addc78ec36cc309acfcdf0b9f9d97ab7b84083118b248709c5b7029356"
"checksum libz-sys 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c7bdca442aa002a930e6eb2a71916cabe46d91ffec8df66db0abfb1bc83469ab"
"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f5eeb268a4620c74ea5768c6d2ccd492d60a47a8754666b91a46bfc35cd4d1ba"
"checksum onig_sys 68.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "195ebddbb56740be48042ca117b8fb6e0d99fe392191a9362d82f5f69e510379"
"checksum onig 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0d9dac9b8a5211103d75f3ce8d0c799e6f4f3f22608eeaefb4419786e4b258"
"checksum onig_sys 69.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c04019a39ebac42dfd8c7822af0a009043720845a812ddbb95e403298b0183"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503"
"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901"
"checksum plist 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7316832d9ac5da02786bdc89a3faf0ca07070212b388766e969078fd593edc"
"checksum predicates 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa984b7cd021a0bf5315bcce4c4ae61d2a535db2a8d288fc7578638690a7b7c3"
"checksum predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
"checksum predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
"checksum serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d30ec34ac923489285d24688c7a9c0898d16edff27fc1f1bd854edeff6ca3b7f"
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
"checksum shell-words 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39acde55a154c4cd3ae048ac78cc21c25f3a0145e44111b523279113dce0d94a"
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
"checksum syn 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5522da8e493dbd7703e88ec5518546ed45c30efa2699f291a7bd0a08fb0a6ab6"
"checksum syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc8a6f0db88d4afc340522c20d260411e746b2225b257c6b238a75de9d7cec78"
"checksum syn 0.15.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b10ee269228fb723234fce98e9aac0eaed2bd5f1ad2f6930e8d5b93f04445a1a"
"checksum syntect 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76ed0acb8b4012c8ed2d3df01f018ac25c3fd916914768b4f4a8b8bebe106ff"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70226acdf12d182df757d9fb07c0257a1558ec48c8059f607d6b38145ce4e2fa"
"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
"checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
@@ -883,9 +1038,11 @@ dependencies = [
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d"
"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35"
"checksum wild 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "690e5dbd46cfaf2f3bd09875ad94e92cc56459fce505807d6ce5332671aa93ae"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+11 -2
View File
@@ -7,11 +7,12 @@ license = "MIT/Apache-2.0"
name = "bat"
readme = "README.md"
repository = "https://github.com/sharkdp/bat"
version = "0.7.1"
version = "0.8.0"
exclude = [
"assets/syntaxes/*",
"assets/themes/*",
]
build = "build.rs"
[dependencies]
atty = "0.2.2"
@@ -20,6 +21,10 @@ ansi_colours = "^1.0"
console = "0.6"
directories = "1.0"
lazy_static = "1.0"
wild = "2.0"
content_inspector = "0.2.3"
encoding = "0.2"
shell-words = "0.1.0"
[dependencies.git2]
version = "0.7"
@@ -27,7 +32,7 @@ default-features = false
features = []
[dependencies.syntect]
version = "2.1"
version = "3.0.1"
default-features = false
features = ["parsing", "yaml-load", "dump-load", "dump-create"]
@@ -43,3 +48,7 @@ features = []
[dev-dependencies]
tempdir = "0.3"
assert_cmd = "0.10.1"
[build-dependencies]
clap = "2.32"
+79 -30
View File
@@ -53,15 +53,18 @@ Display multiple files at once
> bat src/*.rs
```
Read from stdin, explicitly specify the language
Read from stdin, determine the syntax automatically
```bash
> curl -s https://sh.rustup.rs | bat
```
Read from stdin, specify the language explicitly
```bash
> yaml2json .travis.yml | json_pp | bat -l json
```
```bash
> curl -s https://raw.githubusercontent.com/sharkdp/bat/master/src/main.rs | bat -l rs
```
As a replacement for `cat`:
@@ -83,7 +86,7 @@ bat f - g # output 'f', then stdin, then 'g'.
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.7.1_amd64.deb # adapt version number and architecture
sudo dpkg -i bat_0.8.0_amd64.deb # adapt version number and architecture
```
### On Arch Linux
@@ -117,6 +120,41 @@ cd /usr/ports/textproc/bat
make install
```
### Via nix
You can install `bat` using the [nix package manager](https://nixos.org/nix):
```bash
nix-env -i bat
```
### On macOS
You can install `bat` with [Homebrew](http://braumeister.org/formula/bat):
```bash
brew install bat
```
### On Windows
You can download prebuilt binaries from the [Release page](https://github.com/sharkdp/bat/releases),
or install it with [scoop](https://scoop.sh/):
```bash
scoop install bat
```
[See below](#using-bat-on-windows) for notes.
### 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/):
@@ -145,33 +183,16 @@ This should work with the following distributions:
- FreeBSD
- MacOS
### On macOS
You can install `bat` with [Homebrew](http://braumeister.org/formula/bat):
```bash
brew install bat
```
### On Windows
You can download prebuilt binaries from the [Release page](https://github.com/sharkdp/bat/releases),
or install it with [scoop](https://scoop.sh/):
```bash
scoop install bat
```
[See below](#using-bat-on-windows) for notes.
### From binaries
Check out the [Release page](https://github.com/sharkdp/bat/releases) for
prebuilt versions of `bat` for many different architectures.
prebuilt versions of `bat` for many different architectures. Statically-linked
binaries are available, just look for releases with `musl` in the name on the
releases page.
### From source
If you want to build `bat` from source, you need Rust 1.26 or
If you want to build `bat` from source, you need Rust 1.29 or
higher. You can then use `cargo` to build everything:
```bash
@@ -191,6 +212,17 @@ highlighting. To select the `TwoDark` theme, call `bat` with the
`TwoDark`. Use `export BAT_THEME="TwoDark"` in your shell's startup file to
make the change permanent.
If you want to preview the different themes on a custom file, you can use
the following command (you need [`fzf`](https://github.com/junegunn/fzf) for this):
``` bash
bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
```
`bat` looks good on a dark background by default. However, if your terminal uses a
light background, some themes will work better for you. For example, the `GitHub`
theme is made for light backgrounds. You can also make your own theme by following the
['Adding new themes' section below](https://github.com/sharkdp/bat#adding-new-themes).
### Output style
You can use the `--style` option to control the appearance of `bat`s output.
@@ -257,14 +289,31 @@ Finally, use `bat --list-themes` to check if the new themes are available.
`bat` uses the pager that is specified in the `PAGER` environment variable. If this variable is not
set, `less` is used by default. If you want to use a different pager, you can either modify the
`PAGER` variable or set the `BAT_PAGER` environment variable to override what is specified in
`PAGER`. If you want to pass command-line arguments to the pager, you need to create a small shell
script as a wrapper, for example:
`PAGER`.
If you want to pass command-line arguments to the pager, you need to create a small shell
script as a wrapper, for example
```bash
#!/bin/bash
less --tabs 4 -RF "$@"
less --tabs 4 -R "$@"
```
(put this in a file `~/.bat-pager.sh`, make it executable `chmod +x ~/.bat-pager.sh` and use
`export BAT_PAGER="$HOME/.bat-pager.sh"` in your shells `rc` file)
**Note**: By default, if the pager is set to `less`, `bat` will pass the following command line
options to the pager: `-R`/`--RAW-CONTROL-CHARS`, `-F`/`--quit-if-one-screen` and `-X`/`--no-init`.
The first (`-R`) is needed to interpret ANSI colors correctly. The second option (`-F`) instructs
less to exit immediately if the output size is smaller than the vertical size of the terminal.
This is convenient for small files because you do not have to press `q` to quit the pager. The
third option (`-X`) is needed to fix a bug with the `--quit-if-one-screen` feature in old versions
of `less`. Unfortunately, it also breaks mouse-wheel support in `less`. If you want to enable
mouse-wheel scrolling, you can either pass just `-R` (as in the example above, this will disable
the quit-if-one-screen feature), or you can use a recent version of `less` and pass `-RF` which
will hopefully enable both quit-if-one-screen and mouse-wheel scrolling.
If scrolling still doesn't work for you, you can try to pass the `-S` option in addition.
## Using `bat` on Windows
@@ -290,7 +339,7 @@ or by setting `BAT_PAGER` to an empty string.
### Cygwin
`bat` on Windows does not natively support Cygwin's unix-style paths (`/cygdrive/*`). When passed an absolute cygwin path as an argument, `bat` will encounter the following error: `The system cannot find the path specified. (os error 3)`
`bat` on Windows does not natively support Cygwin's unix-style paths (`/cygdrive/*`). When passed an absolute cygwin path as an argument, `bat` will encounter the following error: `The system cannot find the path specified. (os error 3)`
This can be solved by creating a wrapper or adding the following function to your `.bash_profile` file:
+13
View File
@@ -0,0 +1,13 @@
diff --git syntaxes/Packages/Java/JavaDoc.sublime-syntax syntaxes/Packages/Java/JavaDoc.sublime-syntax
index 422a6a9..40a741e 100644
--- syntaxes/Packages/Java/JavaDoc.sublime-syntax
+++ syntaxes/Packages/Java/JavaDoc.sublime-syntax
@@ -13,7 +13,7 @@ variables:
contexts:
prototype:
# https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#leadingasterisks
- - match: ^\s*(\*)\s*(?!\s*@)
+ - match: ^\s*(\*)(?!/)\s*(?!\s*@)
captures:
1: punctuation.definition.comment.javadoc
-1
View File
@@ -28,6 +28,5 @@ themes (`bat cache --clear`).
The following files have been manually modified after converting from a `.tmLanguage` file:
* `VimL.sublime-syntax` => added `.vimrc` file type.
* `Dart.sublime-syntax` => removed `#regex.dart` include.
* `INI.sublime-syntax` => added `.hgrc` and `hgrc` file types.
Regular → Executable
+11
View File
@@ -2,4 +2,15 @@
ASSET_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# 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/160 has been fixed
JAVADOC_FILE="${ASSET_DIR}/syntaxes/Packages/Java/JavaDoc.sublime-syntax"
JAVADOC_PATCH="${ASSET_DIR}/JavaDoc.sublime-syntax.patch"
patch "$JAVADOC_FILE" "$JAVADOC_PATCH"
bat cache --init --blank --source="$ASSET_DIR" --target="$ASSET_DIR"
patch -R "$JAVADOC_FILE" "$JAVADOC_PATCH"
Binary file not shown.
+54
View File
@@ -0,0 +1,54 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Robot Framework syntax highlighting.
file_extensions:
- robot
scope: source.robot
contexts:
main:
- match: '\$\{(\d+|\d+\.\d*|0[bB][01]+|0[oO][0-7]+|0[xX][0-9a-fA-F]+)\}'
comment: "Robot Framework numbers, like ${1} or ${12.3}"
scope: constant.numeric.robot
- match: '(?i)(%\{[\w|\s]+\})'
comment: "Robot Framework environment variable, like %{USER}"
scope: variable.parameter.robot
- match: '((?<!\\)|(?<=\\\\))[$&]{'
comment: Robot Framework scalar and dictionary variables
push:
- meta_scope: entity.name.class
- match: '\}'
pop: true
- match: '((?<!\\)(@{)|(?<=\\\\)(@{))'
comment: Robot Framework list variables
push:
- meta_scope: entity.name.class
- match: '(}\[.+])|(})'
pop: true
- match: '(?i)^(\|\s*)?(\*{1,3} ?)(settings?|variables?|keywords?|test cases?)( ?\*{1,3})?(\s*\|)?'
comment: Robot Framework data tables
scope: string.robot.header
- match: '(?i)(^\|\s*)?\[?Documentation\]?\s+'
comment: Test case, keyword and settings table documentation
push:
- meta_scope: comment
- match: ^(?!\s*+\.\.\.)
pop: true
- match: '(^| {2,}|\t|\\| {1,})(?<!\\\\)#'
comment: Comment character
push:
- meta_scope: comment
- match: $
pop: true
- match: '(?i)\s+\[(Tags|Setup|Teardown|Template|Timeout|Arguments|Return)\]'
comment: Tests case and keyword settings
scope: storage.type
- match: (?i)^(\|\s*)?(Library|Resource|Test Timeout|Test Template|Test Teardown|Test Setup|Default Tags|Force Tags|Metadata|Variables|Suite Setup|Suite Teardown)(?:( )|( \| ))
comment: Settings table settings, like Library
scope: constant.language
- match: '^(\|\s+)?(?!^\.{3})(?![\|$&])\S+'
comment: Keywords and test cases
push:
- meta_scope: keyword.control.robot
- match: '($|\||\s{2,})'
pop: true
+1 -1
View File
@@ -63,7 +63,7 @@ contexts:
- match: \b(if|while|for|try|return|throw|end(if|for|while|try)?|au(g|group)|else(if|)?|do|in|catch|finally|:)\b
scope: keyword.control.viml
number_hex:
- match: "#[0-9a-f]{6}"
- match: "0x[0-9a-f]+"
scope: constant.numeric.hex
number_int:
- match: '-?\d+'
+26
View File
@@ -0,0 +1,26 @@
#[macro_use]
extern crate clap;
use clap::Shell;
use std::fs;
include!("src/clap_app.rs");
const BIN_NAME: &str = "bat";
fn main() {
let outdir = std::env::var_os("SHELL_COMPLETIONS_DIR").or(std::env::var_os("OUT_DIR"));
let outdir = match outdir {
None => return,
Some(outdir) => outdir,
};
fs::create_dir_all(&outdir).unwrap();
let mut app = build_app(true);
app.gen_completions(BIN_NAME, Shell::Bash, &outdir);
app.gen_completions(BIN_NAME, Shell::Fish, &outdir);
app.gen_completions(BIN_NAME, Shell::Zsh, &outdir);
app.gen_completions(BIN_NAME, Shell::PowerShell, &outdir);
}
+6
View File
@@ -27,6 +27,7 @@ pack() {
# 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/"
@@ -38,6 +39,11 @@ pack() {
cp LICENSE-MIT "$tempdir/$package_name"
cp LICENSE-APACHE "$tempdir/$package_name"
# various autocomplete
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/_"$PROJECT_NAME" "$tempdir/$package_name/autocomplete"
# archiving
pushd "$tempdir"
tar czf "$out_dir/$package_name.tar.gz" "$package_name"/*
+1
View File
@@ -11,6 +11,7 @@ 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" '.\'
Copy-Item $SRC_DIR\target\release\build\bat-*\out\_bat.ps1 '.\'
# readme and license
Copy-Item $SRC_DIR\README.md '.\'
+22 -20
View File
@@ -21,6 +21,12 @@ names and file extensions.
.IP
Display a list of supported languages for syntax highlighting.
.HP
\fB\-m\fR, \fB\-\-map\-syntax\fR <from:to>...
.IP
Map a file extension or file name to an existing syntax. For example, to highlight
*.conf files with the INI syntax, use '\-m conf:ini'. To highlight files named
\&'.myignore' with the Git Ignore syntax, use '\-m .myignore:gitignore'.
.HP
\fB\-\-theme\fR <theme>
.IP
Set the theme for syntax highlighting. Use '\-\-list\-themes' to see all
@@ -41,7 +47,7 @@ theme, export the BAT_STYLE environment variable (e.g.: export
BAT_STYLE="numbers"). [possible values: auto, full, plain, changes, header,
grid, numbers]
.HP
\fB\-p\fR
\fB\-p\fR, \fB\-\-plain\fR
.IP
Only show plain style, no decorations. This is an alias for '\-\-style=plain'
.HP
@@ -64,38 +70,34 @@ prints lines 40 to the end of the file
.HP
\fB\-\-color\fR <when>
.IP
Specify when to use colored output. The automatic mode only enables colors if
an interactive terminal is detected. [default: auto] [possible values: auto,
never, always]
Specify when to use colored output. The automatic mode only enables colors if an
interactive terminal is detected. Possible values: *auto*, never, always.
.HP
\fB\-\-decorations\fR <when>
.IP
Specify when to use the decorations that have been specified via '\-\-style'.
The automatic mode only enables decorations if an interactive terminal is
detected. [default: auto] [possible values: auto, never, always]
Specify when to use the decorations that have been specified via '\-\-style'. The
automatic mode only enables decorations if an interactive terminal is detected. Possible
values: *auto*, never, always.
.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). The default
pager is 'less'. To disable the pager permanently, set BAT_PAGER to an empty
string. [default: auto] [possible values: auto, never, always]
Specify when to use the pager. To control which pager is used, set the PAGER or
BAT_PAGER environment variables (the latter takes precedence). The default pager is
\&'less'. To disable the pager permanently, set BAT_PAGER to an empty string. Possible
values: *auto*, never, always.
.HP
\fB\-\-wrap\fR <mode>
.TP
Specify the text\-wrapping mode. [default: auto]
[possible values: auto,
.IP
never, character]
Specify the text\-wrapping mode (*auto*, never, character).
.HP
\fB\-u\fR
\fB\-\-tabs\fR <T>
.IP
This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). The
output is always unbuffered \- this option is simply ignored.
Set the tab width to T spaces. Use a width of 0 to pass tabs through directly
.HP
\fB\-\-tabs\fR <tabs>
\fB\-u\fR, \fB\-\-unbuffered\fR
.IP
Sets the tab width. Use a width of 0 to pass tabs through directly
This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). The output is
always unbuffered \- this option is simply ignored.
.HP
\fB\-h\fR, \fB\-\-help\fR
.IP
+78 -291
View File
@@ -1,11 +1,12 @@
use std::collections::HashSet;
use std::env;
use std::path::Path;
use std::str::FromStr;
use atty::{self, Stream};
use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand};
use clap::ArgMatches;
use clap_app;
use wild;
use console::Term;
@@ -13,9 +14,13 @@ use console::Term;
use ansi_term;
use assets::BAT_THEME_DEFAULT;
use config::{get_args_from_config_file, get_args_from_env_var};
use errors::*;
use inputfile::InputFile;
use line_range::LineRange;
use style::{OutputComponent, OutputComponents, OutputWrap};
use syntax_mapping::SyntaxMapping;
use util::transpose;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PagingMode {
@@ -24,13 +29,6 @@ pub enum PagingMode {
Never,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum InputFile<'a> {
StdIn,
Ordinary(&'a str),
ThemePreviewFile,
}
#[derive(Clone)]
pub struct Config<'a> {
/// List of files to print
@@ -69,6 +67,9 @@ pub struct Config<'a> {
/// The syntax highlighting theme
pub theme: String,
/// File extension/name mappings
pub syntax_mapping: SyntaxMapping,
}
fn is_truecolor_terminal() -> bool {
@@ -77,284 +78,49 @@ fn is_truecolor_terminal() -> bool {
.unwrap_or(false)
}
/// Helper function that should might appear in Rust stable at some point
/// (https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.transpose)
fn transpose<T>(opt: Option<Result<T>>) -> Result<Option<T>> {
opt.map_or(Ok(None), |res| res.map(Some))
}
pub struct App {
pub matches: ArgMatches<'static>,
interactive_output: bool,
}
impl App {
pub fn new() -> Self {
pub fn new() -> Result<Self> {
#[cfg(windows)]
let _ = ansi_term::enable_ansi_support();
let interactive_output = atty::is(Stream::Stdout);
App {
matches: Self::matches(interactive_output),
Ok(App {
matches: Self::matches(interactive_output)?,
interactive_output,
}
})
}
fn matches(interactive_output: bool) -> ArgMatches<'static> {
let clap_color_setting = if interactive_output {
AppSettings::ColoredHelp
fn matches(interactive_output: bool) -> Result<ArgMatches<'static>> {
let args = if wild::args_os().nth(1) == Some("cache".into())
|| wild::args_os().any(|arg| arg == "--no-config")
{
// Skip the arguments in bats config file
wild::args_os().collect::<Vec<_>>()
} else {
AppSettings::ColorNever
let mut cli_args = wild::args_os();
// Read arguments from bats config file
let mut args = get_args_from_env_var()
.unwrap_or_else(|| get_args_from_config_file())
.chain_err(|| "Could not parse configuration file")?;
// Put the zero-th CLI argument (program name) first
args.insert(0, cli_args.next().unwrap());
// .. and the rest at the end
cli_args.for_each(|a| args.push(a));
args
};
// Check if the current directory contains a file name cache, if it does
// do not make the arguements for subcommand 'cache' required.
let arg_group_required = !Path::new("cache").exists();
ClapApp::new(crate_name!())
.version(crate_version!())
.global_setting(clap_color_setting)
.global_setting(AppSettings::DeriveDisplayOrder)
.global_setting(AppSettings::UnifiedHelpMessage)
.global_setting(AppSettings::NextLineHelp)
.setting(AppSettings::InferSubcommands)
.setting(AppSettings::ArgsNegateSubcommands)
.setting(AppSettings::DisableHelpSubcommand)
.setting(AppSettings::VersionlessSubcommands)
.max_term_width(90)
.about(
"A cat(1) clone with wings.\n\n\
Use '--help' instead of '-h' to see a more detailed version of the help text.",
).long_about("A cat(1) clone with syntax highlighting and Git integration.")
.arg(
Arg::with_name("FILE")
.help("File(s) to print / concatenate. Use '-' for standard input.")
.long_help(
"File(s) to print / concatenate. Use a dash ('-') or no argument at all \
to read from standard input.",
).multiple(true)
.empty_values(false),
)
.arg(
Arg::with_name("language")
.short("l")
.long("language")
.overrides_with("language")
.help("Set the language for syntax highlighting.")
.long_help(
"Explicitly set the language for syntax highlighting. The language can be \
specified as a name (like 'C++' or 'LaTeX') or possible file extension \
(like 'cpp', 'hpp' or 'md'). Use '--list-languages' to show all supported \
language names and file extensions."
).takes_value(true),
).arg(
Arg::with_name("list-languages")
.long("list-languages")
.conflicts_with("list-themes")
.help("Display all supported languages.")
.long_help("Display a list of supported languages for syntax highlighting."),
).arg(
Arg::with_name("theme")
.long("theme")
.overrides_with("theme")
.takes_value(true)
.help("Set the color theme for syntax highlighting.")
.long_help(
"Set the theme for syntax highlighting. Use '--list-themes' to \
see all available themes. To set a default theme, export the \
BAT_THEME environment variable (e.g.: export \
BAT_THEME=\"TwoDark\").",
),
).arg(
Arg::with_name("list-themes")
.long("list-themes")
.help("Display all supported highlighting themes.")
.long_help("Display a list of supported themes for syntax highlighting."),
).arg(
Arg::with_name("style")
.long("style")
.value_name("style-components")
.use_delimiter(true)
.takes_value(true)
.possible_values(&[
"auto", "full", "plain", "changes", "header", "grid", "numbers",
])
.help("Comma-separated list of style elements to display.")
.long_help(
"Configure which elements (line numbers, file headers, grid \
borders, Git modifications, ..) to display in addition to the \
file contents. The argument is a comma-separated list of \
components to display (e.g. 'numbers,changes,grid') or a \
pre-defined style ('full'). To set a default theme, export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"numbers\").",
),
).arg(
Arg::with_name("plain")
.overrides_with("plain")
.short("p")
.long("plain")
.conflicts_with("style")
.conflicts_with("number")
.help("Show plain style (alias for '--style=plain').")
.long_help(
"Only show plain style, no decorations. This is an alias for \
'--style=plain'",
),
).arg(
Arg::with_name("number")
.long("number")
.overrides_with("number")
.short("n")
.conflicts_with("style")
.help("Show line numbers (alias for '--style=numbers').")
.long_help(
"Only show line numbers, no other decorations. This is an alias for \
'--style=numbers'",
),
).arg(
Arg::with_name("line-range")
.long("line-range")
.overrides_with("line-range")
.takes_value(true)
.value_name("N:M")
.help("Only print the lines from N to M.")
.long_help(
"Only print the specified range of lines for each file. \
For example:\n \
'--line-range 30:40' prints lines 30 to 40\n \
'--line-range :40' prints lines 1 to 40\n \
'--line-range 40:' prints lines 40 to the end of the file",
),
).arg(
Arg::with_name("color")
.long("color")
.overrides_with("color")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.help("When to use colors.")
.long_help("Specify when to use colored output. The automatic mode \
only enables colors if an interactive terminal is detected."),
).arg(
Arg::with_name("decorations")
.long("decorations")
.overrides_with("decorations")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.help("When to show the decorations specified by '--style'.")
.long_help("Specify when to use the decorations that have been specified \
via '--style'. The automatic mode only enables decorations if \
an interactive terminal is detected."),
).arg(
Arg::with_name("paging")
.long("paging")
.overrides_with("paging")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.help("Specify when to use the pager.")
.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). The default \
pager is 'less'. To disable the pager permanently, set \
BAT_PAGER to an empty string."),
).arg(
Arg::with_name("wrap")
.long("wrap")
.overrides_with("wrap")
.takes_value(true)
.value_name("mode")
.possible_values(&["auto", "never", "character"])
.default_value("auto")
.help("Specify the text-wrapping mode.")
.long_help("Specify the text-wrapping mode."),
).arg(
Arg::with_name("unbuffered")
.short("u")
.hidden_short_help(true)
.long_help(
"This option exists for POSIX-compliance reasons ('u' is for \
'unbuffered'). The output is always unbuffered - this option \
is simply ignored.",
),
).arg(
Arg::with_name("tabs")
.long("tabs")
.takes_value(true)
.value_name("tabs")
.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("Sets the tab width.")
.long_help("Sets the tab width. Use a width of 0 to pass tabs through \
directly"),
).arg(
Arg::with_name("terminal-width")
.long("terminal-width")
.takes_value(true)
.value_name("width")
.hidden(true)
.help("Set the width of the terminal"),
).subcommand(
SubCommand::with_name("cache")
.about("Modify the syntax-definition and theme cache")
.arg(
Arg::with_name("init")
.long("init")
.short("i")
.help("Initialize the syntax/theme cache.")
.long_help(
"Initialize the syntax/theme cache by loading from the \
source directory (default: the configuration directory).",
),
).arg(
Arg::with_name("clear")
.long("clear")
.short("c")
.help("Remove the cached syntax definitions and themes."),
).arg(
Arg::with_name("config-dir")
.long("config-dir")
.short("d")
.help("Show bat's configuration directory."),
).group(
ArgGroup::with_name("cache-actions")
.args(&["init", "clear", "config-dir"])
.required(arg_group_required),
).arg(
Arg::with_name("source")
.long("source")
.requires("init")
.takes_value(true)
.value_name("dir")
.help("Use a different directory to load syntaxes and themes from."),
).arg(
Arg::with_name("target")
.long("target")
.requires("init")
.takes_value(true)
.value_name("dir")
.help(
"Use a different directory to store the cached syntax and theme set.",
),
).arg(
Arg::with_name("blank")
.long("blank")
.requires("init")
.help("Create completely new syntax and theme sets \
(instead of appending to the default sets).")
),
).help_message("Print this help message.")
.version_message("Show version information.")
.get_matches()
Ok(clap_app::build_app(interactive_output).get_matches_from(args))
}
pub fn config(&self) -> Result<Config> {
@@ -364,24 +130,40 @@ impl App {
let paging_mode = match self.matches.value_of("paging") {
Some("always") => PagingMode::Always,
Some("never") => PagingMode::Never,
Some("auto") | _ => if files.contains(&InputFile::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.
if self.interactive_output && !atty::is(Stream::Stdin) {
PagingMode::QuitIfOneScreen
Some("auto") | _ => {
if files.contains(&InputFile::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.
if self.interactive_output && !atty::is(Stream::Stdin) {
PagingMode::QuitIfOneScreen
} else {
PagingMode::Never
}
} else {
PagingMode::Never
if self.interactive_output {
PagingMode::QuitIfOneScreen
} else {
PagingMode::Never
}
}
} else {
if self.interactive_output {
PagingMode::QuitIfOneScreen
} else {
PagingMode::Never
}
},
}
};
let mut syntax_mapping = SyntaxMapping::new();
if let Some(values) = self.matches.values_of("map-syntax") {
for from_to in values {
let parts: Vec<_> = from_to.split(":").collect();
if parts.len() != 2 {
return Err("Invalid syntax mapping. The format of the -m/--map-syntax option is 'from:to'.".into());
}
syntax_mapping.insert(parts[0].into(), parts[1].into());
}
}
Ok(Config {
true_color: is_truecolor_terminal(),
language: self.matches.value_of("language"),
@@ -393,11 +175,13 @@ impl App {
match self.matches.value_of("wrap") {
Some("character") => OutputWrap::Character,
Some("never") => OutputWrap::None,
Some("auto") | _ => if output_components.plain() {
OutputWrap::None
} else {
OutputWrap::Character
},
Some("auto") | _ => {
if output_components.plain() {
OutputWrap::None
} else {
OutputWrap::Character
}
}
}
},
colored_output: match self.matches.value_of("color") {
@@ -436,6 +220,7 @@ impl App {
.unwrap_or(String::from(BAT_THEME_DEFAULT)),
line_range: transpose(self.matches.value_of("line-range").map(LineRange::from))?,
output_components,
syntax_mapping,
})
}
@@ -450,8 +235,10 @@ impl App {
} else {
InputFile::Ordinary(filename)
}
}).collect()
}).unwrap_or_else(|| vec![InputFile::StdIn])
})
.collect()
})
.unwrap_or_else(|| vec![InputFile::StdIn])
}
fn output_components(&self) -> Result<OutputComponents> {
+67 -74
View File
@@ -1,22 +1,18 @@
use directories::ProjectDirs;
use errors::*;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fs::{self, File};
use std::io::BufReader;
use std::path::{Path, PathBuf};
use syntect::dumps::{dump_to_file, from_binary, from_reader};
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::{SyntaxDefinition, SyntaxSet};
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
#[cfg(unix)]
use std::os::unix::fs::FileTypeExt;
use dirs::PROJECT_DIRS;
use app::InputFile;
lazy_static! {
static ref PROJECT_DIRS: ProjectDirs =
ProjectDirs::from("", "", crate_name!()).expect("Could not get home directory");
}
use errors::*;
use inputfile::{InputFile, InputFileReader};
use syntax_mapping::SyntaxMapping;
pub const BAT_THEME_DEFAULT: &str = "Monokai Extended";
@@ -30,31 +26,20 @@ impl HighlightingAssets {
Self::from_cache().unwrap_or_else(|_| Self::from_binary())
}
fn empty() -> Self {
let mut syntax_set = SyntaxSet::new();
syntax_set.load_plain_text_syntax();
let theme_set = ThemeSet {
themes: BTreeMap::new(),
};
HighlightingAssets {
syntax_set,
theme_set,
}
}
pub fn from_files(dir: Option<&Path>, start_empty: bool) -> Result<Self> {
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir());
let mut assets = if start_empty {
Self::empty()
let mut theme_set = if start_empty {
ThemeSet {
themes: BTreeMap::new(),
}
} else {
Self::from_binary_unlinked()
Self::get_integrated_themeset()
};
let theme_dir = source_dir.join("themes");
let res = extend_theme_set(&mut assets.theme_set, &theme_dir);
let res = theme_set.add_from_folder(&theme_dir);
if !res.is_ok() {
println!(
"No themes were found in '{}', using the default set",
@@ -62,9 +47,17 @@ impl HighlightingAssets {
);
}
let mut syntax_set_builder = if start_empty {
let mut builder = SyntaxSetBuilder::new();
builder.add_plain_text_syntax();
builder
} else {
Self::get_integrated_syntaxset().into_builder()
};
let syntax_dir = source_dir.join("syntaxes");
if syntax_dir.exists() {
assets.syntax_set.load_syntaxes(syntax_dir, true)?;
syntax_set_builder.add_from_folder(syntax_dir, true)?;
} else {
println!(
"No syntaxes were found in '{}', using the default set.",
@@ -72,7 +65,10 @@ impl HighlightingAssets {
);
}
Ok(assets)
Ok(HighlightingAssets {
syntax_set: syntax_set_builder.build(),
theme_set,
})
}
fn from_cache() -> Result<Self> {
@@ -83,9 +79,8 @@ impl HighlightingAssets {
syntax_set_path().to_string_lossy()
)
})?;
let mut syntax_set: SyntaxSet =
from_reader(syntax_set_file).chain_err(|| "Could not parse cached syntax set")?;
syntax_set.link_syntaxes();
let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file))
.chain_err(|| "Could not parse cached syntax set")?;
let theme_set_file = File::open(&theme_set_path).chain_err(|| {
format!(
@@ -93,8 +88,8 @@ impl HighlightingAssets {
theme_set_path.to_string_lossy()
)
})?;
let theme_set: ThemeSet =
from_reader(theme_set_file).chain_err(|| "Could not parse cached theme set")?;
let theme_set: ThemeSet = from_reader(BufReader::new(theme_set_file))
.chain_err(|| "Could not parse cached theme set")?;
Ok(HighlightingAssets {
syntax_set,
@@ -102,9 +97,17 @@ impl HighlightingAssets {
})
}
fn from_binary_unlinked() -> Self {
let syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin"));
let theme_set: ThemeSet = from_binary(include_bytes!("../assets/themes.bin"));
fn get_integrated_syntaxset() -> SyntaxSet {
from_binary(include_bytes!("../assets/syntaxes.bin"))
}
fn get_integrated_themeset() -> ThemeSet {
from_binary(include_bytes!("../assets/themes.bin"))
}
fn from_binary() -> Self {
let syntax_set = Self::get_integrated_syntaxset();
let theme_set = Self::get_integrated_themeset();
HighlightingAssets {
syntax_set,
@@ -112,12 +115,6 @@ impl HighlightingAssets {
}
}
fn from_binary() -> Self {
let mut assets = Self::from_binary_unlinked();
assets.syntax_set.link_syntaxes();
assets
}
pub fn save(&self, dir: Option<&Path>) -> Result<()> {
let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
let _ = fs::create_dir(target_dir);
@@ -166,29 +163,40 @@ impl HighlightingAssets {
}
}
pub fn get_syntax(&self, language: Option<&str>, filename: InputFile) -> &SyntaxDefinition {
pub fn get_syntax(
&self,
language: Option<&str>,
filename: InputFile,
reader: &mut InputFileReader,
mapping: &SyntaxMapping,
) -> &SyntaxReference {
let syntax = match (language, filename) {
(Some(language), _) => self.syntax_set.find_syntax_by_token(language),
(None, InputFile::Ordinary(filename)) => {
#[cfg(not(unix))]
let may_read_from_file = true;
let path = Path::new(filename);
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("");
// Do not peek at the file (to determine the syntax) if it is a FIFO because they can
// only be read once.
#[cfg(unix)]
let may_read_from_file = !fs::metadata(filename)
.map(|m| m.file_type().is_fifo())
.unwrap_or(false);
let file_name = mapping.replace(file_name);
let extension = mapping.replace(extension);
if may_read_from_file {
self.syntax_set
.find_syntax_for_file(filename)
.unwrap_or(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 = if ext_syntax.is_none() {
String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))
} else {
None
}
};
let syntax = ext_syntax.or(line_syntax);
syntax
}
(None, InputFile::StdIn) => None,
(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"),
};
@@ -196,21 +204,6 @@ impl HighlightingAssets {
}
}
// TODO: this function will soon be part of syntect's `ThemeSet`.
fn extend_theme_set<P: AsRef<Path>>(theme_set: &mut ThemeSet, folder: P) -> Result<()> {
let paths = ThemeSet::discover_theme_paths(folder)?;
for p in &paths {
let theme = ThemeSet::get_theme(p)?;
let basename = p
.file_stem()
.and_then(|x| x.to_str())
.ok_or("Could not get theme basename")?;
theme_set.themes.insert(basename.to_owned(), theme);
}
Ok(())
}
fn theme_set_path() -> PathBuf {
PROJECT_DIRS.cache_dir().join("themes.bin")
}
+332
View File
@@ -0,0 +1,332 @@
use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
use std::path::Path;
pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
let clap_color_setting = if interactive_output {
AppSettings::ColoredHelp
} else {
AppSettings::ColorNever
};
// Check if the current directory contains a file name cache, if it does
// do not make the arguements for subcommand 'cache' required.
let arg_group_required = !Path::new("cache").exists();
ClapApp::new(crate_name!())
.version(crate_version!())
.global_setting(clap_color_setting)
.global_setting(AppSettings::DeriveDisplayOrder)
.global_setting(AppSettings::UnifiedHelpMessage)
.global_setting(AppSettings::HidePossibleValuesInHelp)
.setting(AppSettings::InferSubcommands)
.setting(AppSettings::ArgsNegateSubcommands)
.setting(AppSettings::DisableHelpSubcommand)
.setting(AppSettings::VersionlessSubcommands)
.max_term_width(100)
.about(
"A cat(1) clone with wings.\n\n\
Use '--help' instead of '-h' to see a more detailed version of the help text.",
)
.long_about("A cat(1) clone with syntax highlighting and Git integration.")
.arg(
Arg::with_name("FILE")
.help("File(s) to print / concatenate. Use '-' for standard input.")
.long_help(
"File(s) to print / concatenate. Use a dash ('-') or no argument at all \
to read from standard input.",
)
.multiple(true)
.empty_values(false),
)
.arg(
Arg::with_name("language")
.short("l")
.long("language")
.overrides_with("language")
.help("Set the language for syntax highlighting.")
.long_help(
"Explicitly set the language for syntax highlighting. The language can be \
specified as a name (like 'C++' or 'LaTeX') or possible file extension \
(like 'cpp', 'hpp' or 'md'). Use '--list-languages' to show all supported \
language names and file extensions.",
)
.takes_value(true),
)
.arg(
Arg::with_name("list-languages")
.long("list-languages")
.conflicts_with("list-themes")
.help("Display all supported languages.")
.long_help("Display a list of supported languages for syntax highlighting."),
)
.arg(
Arg::with_name("map-syntax")
.short("m")
.long("map-syntax")
.multiple(true)
.takes_value(true)
.number_of_values(1)
.value_name("from:to")
.help("Map a file extension or name to an existing syntax.")
.long_help(
"Map a file extension or file name to an existing syntax. For example, \
to highlight *.conf files with the INI syntax, use '-m conf:ini'. \
To highlight files named '.myignore' with the Git Ignore syntax, use \
'-m .myignore:gitignore'.",
)
.takes_value(true),
)
.arg(
Arg::with_name("theme")
.long("theme")
.overrides_with("theme")
.takes_value(true)
.help("Set the color theme for syntax highlighting.")
.long_help(
"Set the theme for syntax highlighting. Use '--list-themes' to \
see all available themes. To set a default theme, export the \
BAT_THEME environment variable (e.g.: export \
BAT_THEME=\"TwoDark\").",
),
)
.arg(
Arg::with_name("list-themes")
.long("list-themes")
.help("Display all supported highlighting themes.")
.long_help("Display a list of supported themes for syntax highlighting."),
)
.arg(
Arg::with_name("style")
.long("style")
.value_name("style-components")
.use_delimiter(true)
.takes_value(true)
.possible_values(&[
"auto", "full", "plain", "changes", "header", "grid", "numbers",
])
.help(
"Comma-separated list of style elements to display \
(*auto*, full, plain, changes, header, grid, numbers).",
)
.long_help(
"Configure which elements (line numbers, file headers, grid \
borders, Git modifications, ..) to display in addition to the \
file contents. The argument is a comma-separated list of \
components to display (e.g. 'numbers,changes,grid') or a \
pre-defined style ('full'). To set a default theme, export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"numbers\"). \
Possible values: *auto*, full, plain, changes, header, grid, numbers.",
),
)
.arg(
Arg::with_name("plain")
.overrides_with("plain")
.short("p")
.long("plain")
.conflicts_with("style")
.conflicts_with("number")
.help("Show plain style (alias for '--style=plain').")
.long_help(
"Only show plain style, no decorations. This is an alias for \
'--style=plain'",
),
)
.arg(
Arg::with_name("number")
.long("number")
.overrides_with("number")
.short("n")
.conflicts_with("style")
.help("Show line numbers (alias for '--style=numbers').")
.long_help(
"Only show line numbers, no other decorations. This is an alias for \
'--style=numbers'",
),
)
.arg(
Arg::with_name("line-range")
.long("line-range")
.overrides_with("line-range")
.takes_value(true)
.value_name("N:M")
.help("Only print the lines from N to M.")
.long_help(
"Only print the specified range of lines for each file. \
For example:\n \
'--line-range 30:40' prints lines 30 to 40\n \
'--line-range :40' prints lines 1 to 40\n \
'--line-range 40:' prints lines 40 to the end of the file",
),
)
.arg(
Arg::with_name("color")
.long("color")
.overrides_with("color")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.hide_default_value(true)
.default_value("auto")
.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. \
Possible values: *auto*, never, always.",
),
)
.arg(
Arg::with_name("decorations")
.long("decorations")
.overrides_with("decorations")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.hide_default_value(true)
.help("When to show the decorations (*auto*, never, always).")
.long_help(
"Specify when to use the decorations that have been specified \
via '--style'. The automatic mode only enables decorations if \
an interactive terminal is detected. Possible values: *auto*, never, always.",
),
)
.arg(
Arg::with_name("paging")
.long("paging")
.overrides_with("paging")
.takes_value(true)
.value_name("when")
.possible_values(&["auto", "never", "always"])
.default_value("auto")
.hide_default_value(true)
.help("Specify when to use the pager (*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). The default \
pager is 'less'. To disable the pager permanently, set \
BAT_PAGER to an empty string. \
Possible values: *auto*, never, always.",
),
)
.arg(
Arg::with_name("wrap")
.long("wrap")
.overrides_with("wrap")
.takes_value(true)
.value_name("mode")
.possible_values(&["auto", "never", "character"])
.default_value("auto")
.hide_default_value(true)
.help("Specify the text-wrapping mode (*auto*, never, character).")
.long_help("Specify the text-wrapping mode (*auto*, never, character)."),
)
.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("unbuffered")
.short("u")
.long("unbuffered")
.hidden_short_help(true)
.long_help(
"This option exists for POSIX-compliance reasons ('u' is for \
'unbuffered'). The output is always unbuffered - this option \
is simply ignored.",
),
)
.arg(
Arg::with_name("terminal-width")
.long("terminal-width")
.takes_value(true)
.value_name("width")
.hidden(true)
.help("Set the width of the terminal"),
)
.arg(
Arg::with_name("no-config")
.long("no-config")
.hidden(true)
.help("Do not use the configuration file"),
)
.arg(
Arg::with_name("config-file")
.long("config-file")
.conflicts_with("list-languages")
.conflicts_with("list-themes")
.hidden(true)
.help("Show path to the configuration file."),
)
.subcommand(
SubCommand::with_name("cache")
.about("Modify the syntax-definition and theme cache")
.arg(
Arg::with_name("init")
.long("init")
.short("i")
.help("Initialize the syntax/theme cache.")
.long_help(
"Initialize the syntax/theme cache by loading from the \
source directory (default: the configuration directory).",
),
)
.arg(
Arg::with_name("clear")
.long("clear")
.short("c")
.help("Remove the cached syntax definitions and themes."),
)
.arg(
Arg::with_name("config-dir")
.long("config-dir")
.short("d")
.help("Show bat's configuration directory."),
)
.group(
ArgGroup::with_name("cache-actions")
.args(&["init", "clear", "config-dir"])
.required(arg_group_required),
)
.arg(
Arg::with_name("source")
.long("source")
.requires("init")
.takes_value(true)
.value_name("dir")
.help("Use a different directory to load syntaxes and themes from."),
)
.arg(
Arg::with_name("target")
.long("target")
.requires("init")
.takes_value(true)
.value_name("dir")
.help(
"Use a different directory to store the cached syntax and theme set.",
),
)
.arg(Arg::with_name("blank").long("blank").requires("init").help(
"Create completely new syntax and theme sets \
(instead of appending to the default sets).",
)),
)
.help_message("Print this help message.")
.version_message("Show version information.")
}
+101
View File
@@ -0,0 +1,101 @@
use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::PathBuf;
use shell_words;
use dirs::PROJECT_DIRS;
use util::transpose;
pub fn config_file() -> PathBuf {
PROJECT_DIRS.config_dir().join("config")
}
pub fn get_args_from_config_file() -> Result<Vec<OsString>, shell_words::ParseError> {
Ok(transpose(
fs::read_to_string(config_file())
.ok()
.map(|content| get_args_from_str(&content)),
)?
.unwrap_or(vec![]))
}
pub fn get_args_from_env_var() -> Option<Result<Vec<OsString>, shell_words::ParseError>> {
env::var("BAT_OPTS").ok().map(|s| get_args_from_str(&s))
}
fn get_args_from_str<'a>(content: &'a str) -> Result<Vec<OsString>, shell_words::ParseError> {
let args_per_line = content
.split('\n')
.map(|line| line.trim())
.filter(|line| !line.is_empty())
.filter(|line| !line.starts_with("#"))
.map(|line| shell_words::split(line))
.collect::<Result<Vec<_>, _>>()?;
Ok(args_per_line
.iter()
.flatten()
.map(|line| line.into())
.collect())
}
#[test]
fn empty() {
let args = get_args_from_str("").unwrap();
assert!(args.is_empty());
}
#[test]
fn single() {
assert_eq!(vec!["--plain"], get_args_from_str("--plain").unwrap());
}
#[test]
fn multiple() {
assert_eq!(
vec!["--plain", "--language=cpp"],
get_args_from_str("--plain --language=cpp").unwrap()
);
}
#[test]
fn quotes() {
assert_eq!(
vec!["--theme", "Sublime Snazzy"],
get_args_from_str("--theme \"Sublime Snazzy\"").unwrap()
);
}
#[test]
fn multi_line() {
let config = "
-p
--style numbers,changes
--color=always
";
assert_eq!(
vec!["-p", "--style", "numbers,changes", "--color=always"],
get_args_from_str(config).unwrap()
);
}
#[test]
fn comments() {
let config = "
# plain style
-p
# show line numbers and Git modifications
--style numbers,changes
# Always show ANSI colors
--color=always
";
assert_eq!(
vec!["-p", "--style", "numbers,changes", "--color=always"],
get_args_from_str(config).unwrap()
);
}
+52 -56
View File
@@ -1,15 +1,13 @@
use std::fs::File;
use std::io::{self, BufRead, BufReader, Write};
use std::io::{self, Write};
use app::{Config, InputFile};
use app::Config;
use assets::HighlightingAssets;
use errors::*;
use inputfile::{InputFile, InputFileReader};
use line_range::LineRange;
use output::OutputType;
use printer::{InteractivePrinter, Printer, SimplePrinter};
const THEME_PREVIEW_FILE: &[u8] = include_bytes!("../assets/theme_preview.rs");
pub struct Controller<'a> {
config: &'a Config<'a>,
assets: &'a HighlightingAssets,
@@ -21,22 +19,37 @@ impl<'b> Controller<'b> {
}
pub fn run(&self) -> Result<bool> {
let mut output_type = OutputType::from_mode(self.config.paging_mode);
let mut output_type = OutputType::from_mode(self.config.paging_mode)?;
let writer = output_type.handle()?;
let mut no_errors: bool = true;
for filename in &self.config.files {
let result = if self.config.loop_through {
let mut printer = SimplePrinter::new();
self.print_file(&mut printer, writer, *filename)
} else {
let mut printer = InteractivePrinter::new(&self.config, &self.assets, *filename);
self.print_file(&mut printer, writer, *filename)
};
let stdin = io::stdin();
if let Err(error) = result {
handle_error(&error);
no_errors = false;
for input_file in &self.config.files {
match input_file.get_reader(&stdin) {
Err(error) => {
handle_error(&error);
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)
} else {
let mut printer = InteractivePrinter::new(
&self.config,
&self.assets,
*input_file,
&mut reader,
);
self.print_file(reader, &mut printer, writer, *input_file)
};
if let Err(error) = result {
handle_error(&error);
no_errors = false;
}
}
}
}
@@ -45,30 +58,15 @@ impl<'b> Controller<'b> {
fn print_file<'a, P: Printer>(
&self,
reader: InputFileReader,
printer: &mut P,
writer: &mut Write,
filename: InputFile<'a>,
input_file: InputFile<'a>,
) -> Result<()> {
let stdin = io::stdin();
{
let reader: Box<BufRead> = match filename {
InputFile::StdIn => Box::new(stdin.lock()),
InputFile::Ordinary(filename) => {
let file = File::open(filename)?;
printer.print_header(writer, input_file)?;
self.print_file_ranges(printer, writer, reader, &self.config.line_range)?;
printer.print_footer(writer)?;
if file.metadata()?.is_dir() {
return Err(format!("'{}' is a directory.", filename).into());
}
Box::new(BufReader::new(file))
}
InputFile::ThemePreviewFile => Box::new(THEME_PREVIEW_FILE),
};
printer.print_header(writer, filename)?;
self.print_file_ranges(printer, writer, reader, &self.config.line_range)?;
printer.print_footer(writer)?;
}
Ok(())
}
@@ -76,35 +74,33 @@ impl<'b> Controller<'b> {
&self,
printer: &mut P,
writer: &mut Write,
mut reader: Box<BufRead + 'a>,
mut reader: InputFileReader,
line_ranges: &Option<LineRange>,
) -> Result<()> {
let mut line_buffer = Vec::new();
let mut line_number: usize = 1;
while reader.read_until(b'\n', &mut line_buffer)? > 0 {
{
match line_ranges {
&Some(ref range) => {
if line_number < range.lower {
// Call the printer in case we need to call the syntax highlighter
// for this line. However, set `out_of_range` to `true`.
printer.print_line(true, writer, line_number, &line_buffer)?;
} else if line_number > range.upper {
// no more lines in range, exit early
break;
} else {
printer.print_line(false, writer, line_number, &line_buffer)?;
}
}
&None => {
while reader.read_line(&mut line_buffer)? {
match line_ranges {
&Some(ref range) => {
if line_number < range.lower {
// Call the printer in case we need to call the syntax highlighter
// for this line. However, set `out_of_range` to `true`.
printer.print_line(true, writer, line_number, &line_buffer)?;
} else if line_number > range.upper {
// no more lines in range, exit early
break;
} else {
printer.print_line(false, writer, line_number, &line_buffer)?;
}
}
line_number += 1;
&None => {
printer.print_line(false, writer, line_number, &line_buffer)?;
}
}
line_number += 1;
line_buffer.clear();
}
Ok(())
+6
View File
@@ -0,0 +1,6 @@
use directories::ProjectDirs;
lazy_static! {
pub static ref PROJECT_DIRS: ProjectDirs =
ProjectDirs::from("", "", crate_name!()).expect("Could not get home directory");
}
+131
View File
@@ -0,0 +1,131 @@
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use content_inspector::{self, ContentType};
use errors::*;
const THEME_PREVIEW_FILE: &[u8] = include_bytes!("../assets/theme_preview.rs");
pub struct InputFileReader<'a> {
inner: Box<dyn BufRead + 'a>,
pub first_line: Vec<u8>,
pub content_type: 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 = content_inspector::inspect(&first_line[..]);
if content_type == ContentType::UTF_16LE {
reader.read_until(0x00, &mut first_line).ok();
}
InputFileReader {
inner: Box::new(reader),
first_line,
content_type,
}
}
pub 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 == 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 str),
ThemePreviewFile,
}
impl<'a> InputFile<'a> {
pub 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)?;
if file.metadata()?.is_dir() {
return Err(format!("'{}' is a directory.", filename).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());
}
+18 -2
View File
@@ -13,21 +13,31 @@ extern crate lazy_static;
extern crate ansi_term;
extern crate atty;
extern crate console;
extern crate content_inspector;
extern crate directories;
extern crate encoding;
extern crate git2;
extern crate shell_words;
extern crate syntect;
extern crate wild;
mod app;
mod assets;
mod clap_app;
mod config;
mod controller;
mod decorations;
mod diff;
mod dirs;
mod inputfile;
mod line_range;
mod output;
mod preprocessor;
mod printer;
mod style;
mod syntax_mapping;
mod terminal;
mod util;
use std::collections::HashSet;
use std::io;
@@ -38,9 +48,11 @@ use std::process;
use ansi_term::Colour::Green;
use ansi_term::Style;
use app::{App, Config, InputFile};
use app::{App, Config};
use assets::{clear_assets, config_dir, HighlightingAssets};
use config::config_file;
use controller::Controller;
use inputfile::InputFile;
use style::{OutputComponent, OutputComponents};
mod errors {
@@ -186,7 +198,7 @@ fn run_controller(config: &Config) -> Result<bool> {
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Some(true)` on full success and
/// `Some(false)` if any intermediate errors occurred (were printed).
fn run() -> Result<bool> {
let app = App::new();
let app = App::new()?;
match app.matches.subcommand() {
("cache", Some(cache_matches)) => {
@@ -213,6 +225,10 @@ fn run() -> Result<bool> {
} 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 {
run_controller(&config)
+37 -25
View File
@@ -4,6 +4,8 @@ use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{Child, Command, Stdio};
use shell_words;
use app::PagingMode;
use errors::*;
@@ -13,42 +15,52 @@ pub enum OutputType {
}
impl OutputType {
pub fn from_mode(mode: PagingMode) -> Self {
pub fn from_mode(mode: PagingMode) -> Result<Self> {
use self::PagingMode::*;
match mode {
Always => OutputType::try_pager(false),
QuitIfOneScreen => OutputType::try_pager(true),
Ok(match mode {
Always => OutputType::try_pager(false)?,
QuitIfOneScreen => OutputType::try_pager(true)?,
_ => OutputType::stdout(),
}
})
}
/// Try to launch the pager. Fall back to stdout in case of errors.
fn try_pager(quit_if_one_screen: bool) -> Self {
fn try_pager(quit_if_one_screen: bool) -> Result<Self> {
let pager = env::var("BAT_PAGER")
.or_else(|_| env::var("PAGER"))
.unwrap_or(String::from("less"));
let less_path = PathBuf::from(&pager);
let is_less = less_path.file_stem() == Some(&OsString::from("less"));
let pagerflags = shell_words::split(&pager)
.chain_err(|| "Could not parse (BAT_)PAGER environment variable.")?;
let mut process = if is_less {
let mut args = vec!["--RAW-CONTROL-CHARS", "--no-init"];
if quit_if_one_screen {
args.push("--quit-if-one-screen");
match pagerflags.split_first() {
Some((pager_name, args)) => {
let pager_path = PathBuf::from(pager_name);
let is_less = pager_path.file_stem() == Some(&OsString::from("less"));
let mut process = if is_less {
let mut p = Command::new(&pager_path);
if args.is_empty() {
p.args(vec!["--RAW-CONTROL-CHARS", "--no-init"]);
if quit_if_one_screen {
p.arg("--quit-if-one-screen");
}
}
p.env("LESSCHARSET", "UTF-8");
p
} else {
Command::new(&pager_path)
};
Ok(process
.args(args)
.stdin(Stdio::piped())
.spawn()
.map(OutputType::Pager)
.unwrap_or_else(|_| OutputType::stdout()))
}
let mut p = Command::new(&less_path);
p.args(&args).env("LESSCHARSET", "UTF-8");
p
} else {
Command::new(pager)
};
process
.stdin(Stdio::piped())
.spawn()
.map(OutputType::Pager)
.unwrap_or_else(|_| OutputType::stdout())
None => Ok(OutputType::stdout()),
}
}
fn stdout() -> Self {
+82 -24
View File
@@ -1,4 +1,3 @@
use std::boxed::Box;
use std::io::Write;
use std::vec::Vec;
@@ -9,13 +8,20 @@ use console::AnsiCodeIterator;
use syntect::easy::HighlightLines;
use syntect::highlighting::Theme;
use syntect::parsing::SyntaxSet;
use app::{Config, InputFile};
use content_inspector::ContentType;
use encoding::all::{UTF_16BE, UTF_16LE};
use encoding::{DecoderTrap, Encoding};
use app::Config;
use assets::HighlightingAssets;
use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
use diff::get_git_diff;
use diff::LineChanges;
use errors::*;
use inputfile::{InputFile, InputFileReader};
use preprocessor::expand;
use style::OutputWrap;
use terminal::{as_terminal_escaped, to_ansi_color};
@@ -66,15 +72,22 @@ impl Printer for SimplePrinter {
pub struct InteractivePrinter<'a> {
colors: Colors,
config: &'a Config<'a>,
decorations: Vec<Box<Decoration>>,
decorations: Vec<Box<dyn Decoration>>,
panel_width: usize,
ansi_prefix_sgr: String,
content_type: ContentType,
pub line_changes: Option<LineChanges>,
highlighter: HighlightLines<'a>,
highlighter: Option<HighlightLines<'a>>,
syntax_set: &'a SyntaxSet,
}
impl<'a> InteractivePrinter<'a> {
pub fn new(config: &'a Config, assets: &'a HighlightingAssets, file: InputFile) -> Self {
pub fn new(
config: &'a Config,
assets: &'a HighlightingAssets,
file: InputFile,
reader: &mut InputFileReader,
) -> Self {
let theme = assets.get_theme(&config.theme);
let colors = if config.colored_output {
@@ -84,7 +97,7 @@ impl<'a> InteractivePrinter<'a> {
};
// Create decorations.
let mut decorations: Vec<Box<Decoration>> = Vec::new();
let mut decorations: Vec<Box<dyn Decoration>> = Vec::new();
if config.output_components.numbers() {
decorations.push(Box::new(LineNumberDecoration::new(&colors)));
@@ -113,28 +126,36 @@ impl<'a> InteractivePrinter<'a> {
panel_width = 0;
}
// Get the Git modifications
let line_changes = if config.output_components.changes() {
match file {
InputFile::Ordinary(filename) => get_git_diff(filename),
_ => None,
}
} else {
None
};
let mut line_changes = None;
// Determine the type of syntax for highlighting
let syntax = assets.get_syntax(config.language, file);
let highlighter = HighlightLines::new(syntax, theme);
let highlighter = if reader.content_type.is_binary() {
None
} else {
// Get the Git modifications
line_changes = if config.output_components.changes() {
match file {
InputFile::Ordinary(filename) => get_git_diff(filename),
_ => None,
}
} else {
None
};
// 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 {
panel_width,
colors,
config,
decorations,
content_type: reader.content_type,
ansi_prefix_sgr: String::new(),
line_changes,
highlighter,
syntax_set: &assets.syntax_set,
}
}
@@ -189,17 +210,34 @@ impl<'a> Printer for InteractivePrinter<'a> {
_ => ("", "STDIN"),
};
writeln!(handle, "{}{}", prefix, self.colors.filename.paint(name))?;
let mode = match self.content_type {
ContentType::BINARY => " <BINARY>",
ContentType::UTF_16LE => " <UTF-16LE>",
ContentType::UTF_16BE => " <UTF-16BE>",
_ => "",
};
writeln!(
handle,
"{}{}{}",
prefix,
self.colors.filename.paint(name),
mode
)?;
if self.config.output_components.grid() {
self.print_horizontal_line(handle, '┼')?;
if self.content_type.is_text() {
self.print_horizontal_line(handle, '┼')?;
} else {
self.print_horizontal_line(handle, '┴')?;
}
}
Ok(())
}
fn print_footer(&mut self, handle: &mut Write) -> Result<()> {
if self.config.output_components.grid() {
if self.config.output_components.grid() && self.content_type.is_text() {
self.print_horizontal_line(handle, '┴')
} else {
Ok(())
@@ -213,8 +251,27 @@ impl<'a> Printer for InteractivePrinter<'a> {
line_number: usize,
line_buffer: &[u8],
) -> Result<()> {
let line = String::from_utf8_lossy(&line_buffer).to_string();
let regions = self.highlighter.highlight(line.as_ref());
let line = match self.content_type {
ContentType::BINARY => {
return Ok(());
}
ContentType::UTF_16LE => UTF_16LE
.decode(&line_buffer, DecoderTrap::Strict)
.unwrap_or("Invalid UTF-16LE".into()),
ContentType::UTF_16BE => UTF_16BE
.decode(&line_buffer, DecoderTrap::Strict)
.unwrap_or("Invalid UTF-16BE".into()),
_ => String::from_utf8_lossy(&line_buffer).to_string(),
};
let regions = {
let highlighter = match self.highlighter {
Some(ref mut highlighter) => highlighter,
_ => {
return Ok(());
}
};
highlighter.highlight(line.as_ref(), self.syntax_set)
};
if out_of_range {
return Ok(());
@@ -319,7 +376,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
.iter()
.map(|ref d| d
.generate(line_number, true, self)
.text).collect::<Vec<String>>()
.text)
.collect::<Vec<String>>()
.join(" ")
))
} else {
+7 -5
View File
@@ -23,11 +23,13 @@ pub enum OutputWrap {
impl OutputComponent {
pub fn components(&self, interactive_terminal: bool) -> &'static [OutputComponent] {
match *self {
OutputComponent::Auto => if interactive_terminal {
OutputComponent::Full.components(interactive_terminal)
} else {
OutputComponent::Plain.components(interactive_terminal)
},
OutputComponent::Auto => {
if interactive_terminal {
OutputComponent::Full.components(interactive_terminal)
} else {
OutputComponent::Plain.components(interactive_terminal)
}
}
OutputComponent::Changes => &[OutputComponent::Changes],
OutputComponent::Grid => &[OutputComponent::Grid],
OutputComponent::Header => &[OutputComponent::Header],
+35
View File
@@ -0,0 +1,35 @@
use std::borrow::Cow;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct SyntaxMapping(HashMap<String, String>);
impl SyntaxMapping {
pub fn new() -> SyntaxMapping {
SyntaxMapping(HashMap::new())
}
pub fn insert(&mut self, from: String, to: String) -> Option<String> {
self.0.insert(from, to)
}
pub fn replace<'a>(&self, input: &'a str) -> Cow<'a, str> {
let mut out = Cow::from(input);
if let Some(value) = self.0.get(input) {
out = Cow::from(value.clone())
}
out
}
}
#[test]
fn basic() {
let mut map = SyntaxMapping::new();
map.insert("Cargo.lock".into(), "toml".into());
map.insert(".ignore".into(), ".gitignore".into());
assert_eq!("toml", map.replace("Cargo.lock"));
assert_eq!("other.lock", map.replace("other.lock"));
assert_eq!(".gitignore", map.replace(".ignore"));
}
+27
View File
@@ -0,0 +1,27 @@
/// Helper function that might appear in Rust stable at some point
/// (https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.transpose)
pub fn transpose<T, E>(opt: Option<Result<T, E>>) -> Result<Option<T>, E> {
opt.map_or(Ok(None), |res| res.map(Some))
}
#[cfg(test)]
mod tests {
use super::transpose;
#[derive(Debug, PartialEq)]
struct TestError;
type TestResult<T> = Result<T, TestError>;
#[test]
fn basic() {
let a: Option<TestResult<i32>> = Some(Ok(2));
assert_eq!(Ok(Some(2)), transpose(a));
let b: Option<TestResult<i32>> = Some(Err(TestError));
assert_eq!(Err(TestError), transpose(b));
let c: Option<TestResult<i32>> = None;
assert_eq!(Ok(None), transpose(c));
}
}
+2
View File
@@ -10,6 +10,7 @@ SRC="test-src/jquery-3.3.1.js"
cmd_bat="bat --style=full --color=always --paging=never '$SRC'"
cmd_bat_simple="bat --plain --wrap=never --tabs=0 --color=always --paging=never '$SRC'"
cmd_pygmentize="pygmentize -g '$SRC'"
cmd_highlight="highlight -O truecolor '$SRC'"
cmd_ccat="ccat --color=always '$SRC'"
@@ -20,6 +21,7 @@ cmd_rouge="rougify '$SRC'"
hyperfine --warmup 3 \
"$cmd_bat" \
"$cmd_bat_simple" \
"$cmd_pygmentize" \
"$cmd_highlight" \
"$cmd_ccat" \
+4
View File
@@ -0,0 +1,4 @@
line 1
line 2
line 3
line 4
+1
View File
@@ -0,0 +1 @@
hello world
+152
View File
@@ -0,0 +1,152 @@
extern crate assert_cmd;
use assert_cmd::prelude::*;
use std::process::Command;
fn bat() -> Command {
let mut cmd = Command::main_binary().unwrap();
cmd.current_dir("tests/examples");
cmd.arg("--no-config");
cmd.env_remove("PAGER");
cmd.env_remove("BAT_PAGER");
cmd
}
#[test]
fn basic() {
bat()
.arg("test.txt")
.assert()
.success()
.stdout("hello world\n")
.stderr("");
}
#[test]
fn stdin() {
bat()
.with_stdin()
.buffer("foo\nbar\n")
.assert()
.success()
.stdout("foo\nbar\n");
}
#[test]
fn concatenate() {
bat()
.arg("test.txt")
.arg("test.txt")
.assert()
.success()
.stdout("hello world\nhello world\n");
}
#[test]
fn concatenate_stdin() {
bat()
.arg("test.txt")
.arg("-")
.arg("test.txt")
.with_stdin()
.buffer("stdin\n")
.assert()
.success()
.stdout("hello world\nstdin\nhello world\n");
}
#[test]
fn line_numbers() {
bat()
.arg("multiline.txt")
.arg("--style=numbers")
.arg("--decorations=always")
.assert()
.success()
.stdout(" 1 line 1\n 2 line 2\n 3 line 3\n 4 line 4\n");
}
#[test]
fn line_range_2_3() {
bat()
.arg("multiline.txt")
.arg("--line-range=2:3")
.assert()
.success()
.stdout("line 2\nline 3\n");
}
#[test]
fn line_range_first_two() {
bat()
.arg("multiline.txt")
.arg("--line-range=:2")
.assert()
.success()
.stdout("line 1\nline 2\n");
}
#[test]
fn line_range_last_3() {
bat()
.arg("multiline.txt")
.arg("--line-range=2:")
.assert()
.success()
.stdout("line 2\nline 3\nline 4\n");
}
#[test]
fn fail_non_existing() {
bat().arg("non-existing-file").assert().failure();
}
#[test]
fn fail_directory() {
bat().arg("sub_directory").assert().failure();
}
#[test]
fn do_not_exit_directory() {
bat()
.arg("sub_directory")
.arg("test.txt")
.assert()
.stdout("hello world\n")
.failure();
}
#[test]
fn pager_basic() {
bat()
.env("PAGER", "echo pager-output")
.arg("--paging=always")
.arg("test.txt")
.assert()
.success()
.stdout("pager-output\n");
}
#[test]
fn pager_overwrite() {
bat()
.env("PAGER", "echo other-pager")
.env("BAT_PAGER", "echo pager-output")
.arg("--paging=always")
.arg("test.txt")
.assert()
.success()
.stdout("pager-output\n");
}
#[test]
fn pager_disable() {
bat()
.env("PAGER", "echo other-pager")
.env("BAT_PAGER", "")
.arg("--paging=always")
.arg("test.txt")
.assert()
.success()
.stdout("hello world\n");
}
+3 -1
View File
@@ -43,6 +43,7 @@ impl BatTester {
.current_dir(self.temp_dir.path())
.args(&[
"sample.rs",
"--no-config",
"--paging=never",
"--color=never",
"--decorations=always",
@@ -50,7 +51,8 @@ impl BatTester {
&format!("--wrap={}", if wrap { "character" } else { "never" }),
&format!("--tabs={}", tab_width),
&format!("--style={}", style),
]).output()
])
.output()
.expect("bat failed");
// have to do the replace because the filename in the header changes based on the current working directory