mirror of
https://github.com/sharkdp/bat
synced 2026-08-03 18:51:44 +00:00
Compare commits
177 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf5883f06f | |||
| e27bdfc7d6 | |||
| a7f4f202cb | |||
| 397223374a | |||
| 0c2da90fa4 | |||
| fe29da6e76 | |||
| 0eccfb50d9 | |||
| f74263e71d | |||
| 54f4896ced | |||
| 9d92350cbb | |||
| 26d409db65 | |||
| 06cd4b2ce8 | |||
| a348a9f68e | |||
| 39e2971e96 | |||
| a13eb60df3 | |||
| 9342d0bb24 | |||
| 36d7250af2 | |||
| 2ce8655167 | |||
| a452467e06 | |||
| 2ea3758c4b | |||
| 65bb4c7ee6 | |||
| 556149ad3a | |||
| 33bbf25468 | |||
| 5ee8913538 | |||
| 9b1c1c0271 | |||
| 2712d63a4b | |||
| b21fb6bca8 | |||
| ee43377a9c | |||
| 120b33a9db | |||
| 17b37fedcb | |||
| 1013cdd80a | |||
| be0a2d6048 | |||
| d1a1943998 | |||
| 2a9f5a24ed | |||
| a0ae089c4a | |||
| 96cc391f2d | |||
| a1e1170319 | |||
| 54a331d162 | |||
| 5e3b17e6f7 | |||
| 486e6a19cd | |||
| 247dfbee83 | |||
| 882931a77b | |||
| 12cb438aa4 | |||
| d0782ef954 | |||
| c826c2a438 | |||
| 9aa97b6c22 | |||
| f7890870ea | |||
| 145b99f01c | |||
| 9af1d2b891 | |||
| 2eee68599d | |||
| d569693dab | |||
| 900f61032d | |||
| d0ca566979 | |||
| a5a7dc14e4 | |||
| 54b33c8c21 | |||
| a5de77af4d | |||
| 870ff7b538 | |||
| 15b9acd12f | |||
| b327127f37 | |||
| 9214a4a4f0 | |||
| fcecd97224 | |||
| 870b3c0daf | |||
| b9c780c8c8 | |||
| ca865f9d26 | |||
| 3ee0e56315 | |||
| 091b0b6437 | |||
| 9f005d115d | |||
| b4cfc9633c | |||
| f7e055b6b7 | |||
| d4b438b9d3 | |||
| cd26d403a3 | |||
| f95a23f948 | |||
| 0886a24685 | |||
| 53eb9c57d6 | |||
| 026a9ebae3 | |||
| bdd10b8bec | |||
| fc160b0dcd | |||
| cb7b158172 | |||
| fcc36b1f79 | |||
| 4e4110bf50 | |||
| 22c8978fca | |||
| f711fb5006 | |||
| 64a9341b73 | |||
| ccf88fd5d8 | |||
| 6343535eb2 | |||
| e2ac6de783 | |||
| 25cee002f9 | |||
| 13a53d230b | |||
| ea27053a63 | |||
| b2b932f3ed | |||
| 747d074be1 | |||
| 61109ece15 | |||
| 389edd7239 | |||
| 23813cc08b | |||
| fdeb98e859 | |||
| 6a417886aa | |||
| 8b9991d780 | |||
| f59ddd1e36 | |||
| f90b9d1acc | |||
| f7af537018 | |||
| fd68af8031 | |||
| ebdef04c8f | |||
| a4150600af | |||
| 49223eed06 | |||
| 7dc7133b3c | |||
| e5e47716b0 | |||
| b4f8cd3bae | |||
| ee3a37f3fc | |||
| 4c60ab12cc | |||
| ac32dd17c9 | |||
| 4e3c57cc7c | |||
| 438a9a99ed | |||
| 9b0877102c | |||
| 67bed73e15 | |||
| ef7c39b159 | |||
| 8a399c8d7d | |||
| 9a0e444e09 | |||
| 438f3df345 | |||
| 7e2e0c82ac | |||
| da92154163 | |||
| 179bd4f525 | |||
| 53d67e2b6e | |||
| b625d07c34 | |||
| ec606e5dcc | |||
| c253821a5e | |||
| ccb1d78b22 | |||
| 9eb64b97fe | |||
| 15f0268bdc | |||
| 3fa70deaa7 | |||
| d4553c6b38 | |||
| 23d92d7641 | |||
| 92729430fc | |||
| 3eb79d63ce | |||
| 0483407775 | |||
| cbdf5c50c4 | |||
| 418b3c5ea1 | |||
| 9dca3126b3 | |||
| 7df9a5fe82 | |||
| 4bba08062c | |||
| 4e8ea815af | |||
| b7bc2d54ba | |||
| 21f9e2b0f7 | |||
| 92aa2b547e | |||
| 65f66d0bee | |||
| f5a9236a47 | |||
| edbe8f3e1a | |||
| ed09a80a73 | |||
| 802540ea08 | |||
| dbf84e77e0 | |||
| 8f18567f2d | |||
| e4d7e004ee | |||
| 51b57ccdb7 | |||
| 25f83610f9 | |||
| 7f070c9dcb | |||
| 64ef61b409 | |||
| 95a2079bcd | |||
| cc60ed6563 | |||
| 50be143c62 | |||
| 59fabd8ca5 | |||
| ced6801740 | |||
| f81e38618c | |||
| 1ff46aaaf8 | |||
| 74d023a7b1 | |||
| 36bbc770eb | |||
| f43409f473 | |||
| 203e4f9249 | |||
| 22e785ca49 | |||
| 57072597d6 | |||
| fb8ef40f3e | |||
| 0e8e39a59d | |||
| 64de2a44d5 | |||
| 716b261efd | |||
| 58ca1f66d6 | |||
| 86dcb3c165 | |||
| 7b7a5a32d6 | |||
| a7232a6ecc | |||
| 38762c34d9 |
+42
@@ -0,0 +1,42 @@
|
||||
[submodule "assets/syntaxes/Elixir"]
|
||||
path = assets/syntaxes/Elixir
|
||||
url = https://github.com/princemaple/elixir-sublime-syntax/
|
||||
[submodule "assets/syntaxes/Packages"]
|
||||
path = assets/syntaxes/Packages
|
||||
url = https://github.com/sublimehq/Packages/
|
||||
[submodule "assets/syntaxes/TOML"]
|
||||
path = assets/syntaxes/TOML
|
||||
url = https://github.com/sharkdp/sublime_toml_highlighting
|
||||
[submodule "assets/syntaxes/Julia"]
|
||||
path = assets/syntaxes/Julia
|
||||
url = https://github.com/JuliaEditorSupport/Julia-sublime
|
||||
[submodule "assets/themes/sublime-monokai-extended"]
|
||||
path = assets/themes/sublime-monokai-extended
|
||||
url = https://github.com/jonschlinkert/sublime-monokai-extended
|
||||
[submodule "assets/syntaxes/Docker"]
|
||||
path = assets/syntaxes/Docker
|
||||
url = https://github.com/asbjornenge/Docker.tmbundle
|
||||
[submodule "assets/syntaxes/VimL"]
|
||||
path = assets/syntaxes/VimL
|
||||
url = https://github.com/SalGnt/Sublime-VimL
|
||||
[submodule "assets/syntaxes/INI"]
|
||||
path = assets/syntaxes/INI
|
||||
url = https://github.com/clintberry/sublime-text-2-ini
|
||||
[submodule "assets/syntaxes/CMake"]
|
||||
path = assets/syntaxes/CMake
|
||||
url = https://github.com/sharkdp/Sublime-CMakeLists
|
||||
[submodule "assets/syntaxes/LESS"]
|
||||
path = assets/syntaxes/LESS
|
||||
url = https://github.com/danro/LESS-sublime
|
||||
[submodule "assets/themes/DarkNeon"]
|
||||
path = assets/themes/DarkNeon
|
||||
url = https://github.com/RainyDayMedia/DarkNeon
|
||||
[submodule "assets/themes/github-sublime-theme"]
|
||||
path = assets/themes/github-sublime-theme
|
||||
url = https://github.com/AlexanderEkdahl/github-sublime-theme
|
||||
[submodule "assets/themes/1337-Scheme"]
|
||||
path = assets/themes/1337-Scheme
|
||||
url = https://github.com/MarkMichos/1337-Scheme
|
||||
[submodule "assets/themes/TwoDark"]
|
||||
path = assets/themes/TwoDark
|
||||
url = https://github.com/erremauro/TwoDark
|
||||
+27
-2
@@ -6,23 +6,46 @@ matrix:
|
||||
- os: linux
|
||||
rust: stable
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: linux
|
||||
rust: stable
|
||||
env:
|
||||
- TARGET=x86_64-unknown-linux-musl
|
||||
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
|
||||
- os: linux
|
||||
rust: stable
|
||||
env: TARGET=i686-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: stable
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
|
||||
# Minimum Rust supported channel.
|
||||
- os: linux
|
||||
rust: 1.25.0
|
||||
rust: 1.24.0
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: linux
|
||||
rust: 1.24.0
|
||||
env:
|
||||
- TARGET=x86_64-unknown-linux-musl
|
||||
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
|
||||
- os: osx
|
||||
rust: 1.25.0
|
||||
rust: 1.24.0
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
|
||||
# Code formatting check
|
||||
- os: linux
|
||||
rust: nightly
|
||||
# skip the global install step
|
||||
install:
|
||||
- cargo install --debug --force rustfmt-nightly
|
||||
script: cargo fmt -- --check
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# needed for i686-unknown-linux-gnu target
|
||||
- gcc-multilib
|
||||
# needed for musl targets
|
||||
- musl-tools
|
||||
# needed to build deb packages
|
||||
- fakeroot
|
||||
|
||||
@@ -42,6 +65,8 @@ script:
|
||||
# Incorporate TARGET env var to the build and test process
|
||||
- cargo build --target $TARGET --verbose
|
||||
- cargo test --target $TARGET --verbose
|
||||
# Run 'bat' on its own source code and the README
|
||||
- cargo run --target $TARGET -- src/main.rs README.md --paging=never
|
||||
|
||||
before_deploy:
|
||||
- bash ci/before_deploy.bash
|
||||
|
||||
Generated
+152
-166
@@ -8,7 +8,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -21,7 +21,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.8"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -40,33 +40,31 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bat"
|
||||
version = "0.1.0"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"directories 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "0.9.2"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -74,19 +72,28 @@ name = "byteorder"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.9"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -100,8 +107,8 @@ version = "2.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -121,10 +128,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.29"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -135,24 +142,18 @@ dependencies = [
|
||||
"clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.2"
|
||||
name = "directories"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -168,10 +169,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"os_pipe 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"os_pipe 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shared_child 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.1"
|
||||
@@ -191,7 +197,7 @@ name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -200,16 +206,20 @@ name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.6.11"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -220,7 +230,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -259,29 +278,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.6.19"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -289,9 +293,9 @@ name = "libz-sys"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -300,6 +304,14 @@ name = "linked-hash-map"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.6"
|
||||
@@ -318,17 +330,19 @@ name = "miniz-sys"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -348,10 +362,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "3.2.1"
|
||||
version = "3.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"onig_sys 68.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -362,36 +376,19 @@ name = "onig_sys"
|
||||
version = "68.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"duct 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_pipe"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -404,21 +401,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
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)",
|
||||
"parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.2.13"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -429,7 +426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.9"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -439,14 +436,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.51 (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 = "proc-macro2"
|
||||
version = "0.3.1"
|
||||
version = "0.3.8"
|
||||
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)",
|
||||
@@ -454,10 +451,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -485,12 +482,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.10"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -502,7 +499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -523,38 +520,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.37"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.37"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.13"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -569,7 +555,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -584,30 +570,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.13.1"
|
||||
version = "0.13.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.2 (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.0.0"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.1 (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.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"onig 3.2.1 (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)",
|
||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -683,7 +669,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -772,7 +758,7 @@ name = "xml-rs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -785,77 +771,77 @@ dependencies = [
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
|
||||
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
||||
"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d"
|
||||
"checksum bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6301db0b49fb63551bc15b5ae348147101cdf323242b93ec7546d5002ff1af"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
|
||||
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||
"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
|
||||
"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873"
|
||||
"checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59"
|
||||
"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba"
|
||||
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
||||
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
|
||||
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
|
||||
"checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1"
|
||||
"checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
|
||||
"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
|
||||
"checksum console 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7649ca90478264b9686aac8d269fcb014f14c2bed7c79a7e51b9f6afd4d783eb"
|
||||
"checksum curl-sys 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f7738d877ec81040305d5bb91976ac594f564f5e455dc02a29a23c1d00fe6f"
|
||||
"checksum directories 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc2561db021b6f1321d0f16b67ed28ce843ef4610dfaa432e3ffa2e8a3050ebf"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum duct 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "166298c17c5b4fe5997b962c2f22e887c7c5adc44308eb9103ce5b66af45a423"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
|
||||
"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.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5b4bb7cd2a44e6e5ee3a26ba6a9ca10d4ce2771cdc3839bbc54b47b7d1be84"
|
||||
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||
"checksum git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f41c0035c37ec11ed3f1e1946a76070b0c740393687e9a9c7612f6a709036b3"
|
||||
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
||||
"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.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
|
||||
"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
|
||||
"checksum libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6eeae66e7b1c995de45cb4e65c5ab438a96a7b4077e448645d4048dc753ad357"
|
||||
"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
|
||||
"checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63"
|
||||
"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
|
||||
"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
|
||||
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
||||
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
|
||||
"checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32"
|
||||
"checksum nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fd5681d13fda646462cfbd4e5f2051279a89a544d50eb98c365b507246839f"
|
||||
"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
|
||||
"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
|
||||
"checksum onig 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be6b3b3411efa38b2cff84a1925df1bb8b048d4c1d60656617ed7aca9a966dd9"
|
||||
"checksum onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f5eeb268a4620c74ea5768c6d2ccd492d60a47a8754666b91a46bfc35cd4d1ba"
|
||||
"checksum onig_sys 68.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c6be7c4f985508684e54f18dd37f71e66f3e1ad9318336a520d7e42f0d3ea8e"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.28 (registry+https://github.com/rust-lang/crates.io-index)" = "0bbd90640b148b46305c1691eed6039b5c8509bed16991e3562a01eeb76902a3"
|
||||
"checksum os_pipe 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f547689aea1f11fac90333d573854a8e3e52a9160df1c42aefa8cd16734a3c0"
|
||||
"checksum os_pipe 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934868c3f86ed7a39ef63d88edeac5bd49a0c843192651900e9ce1178cbbf157"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd"
|
||||
"checksum parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "538ef00b7317875071d5e00f603f24d16f0b474c1a5fc0ccb8b454ca72eafa79"
|
||||
"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
|
||||
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
|
||||
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||
"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
|
||||
"checksum plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503"
|
||||
"checksum proc-macro2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "388d7ea47318c5ccdeb9ba6312cee7d3f65dd2804be8580a170fce410d50b786"
|
||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
||||
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
|
||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
|
||||
"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
|
||||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
|
||||
"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
|
||||
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
|
||||
"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
|
||||
"checksum serde 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "21924cc18e5281f232a17c040355fac97732b42cf019c24996a1642bcb169cdb"
|
||||
"checksum serde_derive 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c624a90bec6fe9bc60d275d7af71c72c26b24cd6c6776d8e344dc4044caa3e2"
|
||||
"checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
|
||||
"checksum shared_child 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd5e483b3475af9bc2a35311c2f3bbf0bd98fde91410ab15a0d4ba3c3127b4e"
|
||||
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
|
||||
"checksum smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03dab98ab5ded3a8b43b2c80751194608d0b2aa0f1d46cf95d1c35e192844aa7"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
||||
"checksum syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9fffcb25a761118df53811bd1cfcd54cf57fcbc51e1ea3167ae263477129ad"
|
||||
"checksum syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "61b8f1b737f929c6516ba46a3133fd6d5215ad8a62f66760f851f7048aebedfb"
|
||||
"checksum syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc8a6f0db88d4afc340522c20d260411e746b2225b257c6b238a75de9d7cec78"
|
||||
"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.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
|
||||
@@ -864,7 +850,7 @@ dependencies = [
|
||||
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
|
||||
"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.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
|
||||
"checksum unicode-normalization 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90d662d111b0dbb08a180f2761026cba648c258023c355954a7c00e00e354636"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
|
||||
+19
-4
@@ -7,16 +7,31 @@ license = "MIT/Apache-2.0"
|
||||
name = "bat"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/sharkdp/bat"
|
||||
version = "0.1.0"
|
||||
version = "0.4.0"
|
||||
|
||||
[dependencies]
|
||||
atty = "0.2.2"
|
||||
syntect = "2"
|
||||
ansi_term = "0.9"
|
||||
ansi_term = "0.10"
|
||||
console = "0.6"
|
||||
git2 = "0.6"
|
||||
directories = "0.10"
|
||||
lazy_static = "1.0"
|
||||
|
||||
[dependencies.git2]
|
||||
version = "0.7"
|
||||
default-features = false
|
||||
features = []
|
||||
|
||||
[dependencies.syntect]
|
||||
version = "2.1"
|
||||
default-features = false
|
||||
features = ["parsing", "yaml-load", "dump-load", "dump-create"]
|
||||
|
||||
[dependencies.clap]
|
||||
version = "2"
|
||||
default-features = false
|
||||
features = ["suggestions", "color", "wrap_help"]
|
||||
|
||||
[dependencies.error-chain]
|
||||
version = "0.11"
|
||||
default-features = false
|
||||
features = []
|
||||
|
||||
@@ -1,28 +1,206 @@
|
||||
# bat
|
||||
<p align="center">
|
||||
<img src="doc/logo-header.svg" alt="bat - a cat clone with wings"><br>
|
||||
<a href="Version info"><img src="https://travis-ci.org/sharkdp/bat.svg?branch=master" alt="Build Status"></a>
|
||||
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
|
||||
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
|
||||
A <i>cat(1)</i> clone with syntax highlighting and Git integration.
|
||||
</p>
|
||||
|
||||
[](https://travis-ci.org/sharkdp/bat)
|
||||
[](https://crates.io/crates/bat)
|
||||
|
||||
*A cat(1) clone with wings.*
|
||||
|
||||
## Features
|
||||
<p align="center">
|
||||
<a href="#syntax-highlighting">Key Features</a> •
|
||||
<a href="#how-to-use">How To Use</a> •
|
||||
<a href="#installation">Installation</a> •
|
||||
<a href="#customization">Customization</a> •
|
||||
<a href="#project-goals-and-alternatives">Project goals, alternatives</a>
|
||||
</p>
|
||||
|
||||
### Syntax highlighting
|
||||
|
||||

|
||||
`bat` supports syntax highlighting for a large number of programming and markup
|
||||
languages:
|
||||
|
||||

|
||||

|
||||
|
||||
### Git integration
|
||||
|
||||

|
||||
`bat` communicates with `git` to show modifications with respect to the index
|
||||
(see left side bar):
|
||||
|
||||

|
||||
|
||||
### Automatic paging
|
||||
|
||||
`bat` can pipe its own output to `less` if the output is too large for one screen.
|
||||
|
||||
### File concatenation
|
||||
|
||||
Oh.. you can also use it to concatenate files :wink:. Whenever
|
||||
`bat` detects a non-interactive terminal, it will fall back to printing
|
||||
the plain file contents.
|
||||
|
||||
## How to use
|
||||
|
||||
Display a single file on the terminal
|
||||
|
||||
```bash
|
||||
> bat README.md
|
||||
```
|
||||
|
||||
Display multiple files at once
|
||||
|
||||
```bash
|
||||
> bat src/*.rs
|
||||
```
|
||||
|
||||
Read from stdin, explicitly specify the language
|
||||
|
||||
```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`:
|
||||
|
||||
```bash
|
||||
bat > note.md # quickly create a new file
|
||||
|
||||
bat header.md content.md footer.md > document.md
|
||||
|
||||
bat -n main.rs # show line numbers (only)
|
||||
|
||||
cat f - g # output 'f', then stdin, then 'g'.
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
cargo install bat
|
||||
### From binaries
|
||||
|
||||
mkdir -p ~/.config/bat/themes
|
||||
cd ~/.config/bat/themes
|
||||
wget https://raw.githubusercontent.com/cj/sublime/master/Color%20Scheme%20-%20Default/Monokai.tmTheme
|
||||
Check out the [Release page](https://github.com/sharkdp/bat/releases) for
|
||||
binary builds and Debian packages.
|
||||
|
||||
#### On Arch Linux
|
||||
|
||||
You can install [the AUR package](https://aur.archlinux.org/packages/bat/)
|
||||
via yaourt, or manually:
|
||||
|
||||
```bash
|
||||
git clone https://aur.archlinux.org/bat.git
|
||||
cd bat
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
#### On FreeBSD
|
||||
|
||||
You can install a precompiled [`bat` package](https://www.freshports.org/textproc/bat) with pkg:
|
||||
|
||||
```bash
|
||||
pkg install bat
|
||||
```
|
||||
|
||||
or build it on your own from the FreeBSD ports:
|
||||
|
||||
```bash
|
||||
cd /usr/ports/textproc/bat
|
||||
make install
|
||||
```
|
||||
|
||||
#### On macOS
|
||||
|
||||
You can install `bat` with [Homebrew](http://braumeister.org/formula/bat):
|
||||
|
||||
```bash
|
||||
brew install bat
|
||||
```
|
||||
|
||||
### From source
|
||||
|
||||
If you want to build to compile `bat` from source, you need Rust 1.24 or
|
||||
higher. You can then use `cargo` to build everything:
|
||||
|
||||
```bash
|
||||
cargo install bat
|
||||
```
|
||||
|
||||
On macOS, you might have to install `cmake` (`brew install cmake`) in order for
|
||||
some dependencies to be built.
|
||||
|
||||
## Customization
|
||||
|
||||
### Highlighting theme
|
||||
|
||||
Use `bat --list-themes` to get a list of all available themes for syntax
|
||||
highlighting. To select the `TwoDark` theme, for example, call `bat` with
|
||||
the `--theme=TwoDark` option. Use `alias bat="bat --theme=TwoDark"` in your
|
||||
shells startup file to make the change permanent.
|
||||
|
||||
### Output style
|
||||
|
||||
You can use the `--style` option to control the appearance of `bat`s output.
|
||||
You can use `--style=numbers,changes`, for example, to show only Git changes
|
||||
and line numbers but no grid and no file header.
|
||||
|
||||
### Add new syntaxes and highlighting themes
|
||||
|
||||
`bat` uses the excellent [`syntect`](https://github.com/trishume/syntect/)
|
||||
library for syntax highlighting. `syntect` can read any
|
||||
[Sublime Text `.sublime-syntax` file](https://www.sublimetext.com/docs/3/syntax.html)
|
||||
and theme.
|
||||
|
||||
To build your own language-set and theme, follow these steps:
|
||||
|
||||
Create a folder with a syntax highlighting theme:
|
||||
|
||||
```bash
|
||||
BAT_CONFIG_DIR="$(bat cache --config-dir)"
|
||||
|
||||
mkdir -p "$BAT_CONFIG_DIR/themes"
|
||||
cd "$BAT_CONFIG_DIR/themes"
|
||||
|
||||
# Download a theme, for example:
|
||||
git clone https://github.com/greggb/sublime-snazzy
|
||||
|
||||
# Create a link for the default theme
|
||||
ln -sf "sublime-snazzy/Sublime Snazzy.tmTheme" Default.tmTheme
|
||||
```
|
||||
|
||||
Create a folder with language definition files:
|
||||
|
||||
```bash
|
||||
mkdir -p "$BAT_CONFIG_DIR/syntaxes"
|
||||
cd "$BAT_CONFIG_DIR/syntaxes"
|
||||
|
||||
# Download some language definition files, for example:
|
||||
git clone https://github.com/sublimehq/Packages
|
||||
git clone https://github.com/danro/LESS-sublime
|
||||
```
|
||||
|
||||
Finally, use the following command to parse all these files into a binary
|
||||
cache:
|
||||
|
||||
```bash
|
||||
bat cache --init
|
||||
```
|
||||
|
||||
Use `bat --list-languages` and `bat --list-themes` to check if all languages and themes are
|
||||
available.
|
||||
|
||||
If you ever want to go back to the default settings, call:
|
||||
|
||||
```bash
|
||||
bat cache --clear
|
||||
```
|
||||
|
||||
## Project goals and alternatives
|
||||
|
||||
`bat` tries to achieve the following goals:
|
||||
|
||||
- Provide beautiful, advanced syntax highlighting
|
||||
- Integrate with Git to show file modifications
|
||||
- Be a drop-in replacement for (POSIX) `cat`
|
||||
- Offer a user-friendly command-line interface
|
||||
|
||||
There are a lot of alternatives, if you are looking for similar programs. See
|
||||
[this document](doc/alternatives.md) for a comparison.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
syntaxes/*
|
||||
themes/*
|
||||
@@ -0,0 +1,31 @@
|
||||
## Syntax Highlighting in bat
|
||||
|
||||
`bat` uses the [syntect](https://github.com/trishume/syntect) library to highlight source
|
||||
code. As a basis, syntect uses [Sublime Text](https://www.sublimetext.com/) syntax definitions
|
||||
in the `.sublime-syntax` format.
|
||||
|
||||
In order to add new syntaxes to `bat`, follow these steps:
|
||||
|
||||
1. Find a Sublime Text syntax for the given language, preferably in a separate Git repository
|
||||
which can be included as a submodule (under `assets/syntaxes`).
|
||||
|
||||
2. If the Sublime Text syntax is only available as a `.tmLanguage` file, open the file in
|
||||
Sublime Text and convert it to a `.sublime-syntax` file via *Tools* -> *Developer* ->
|
||||
*New Syntax from XXX.tmLanguage...*. Save the new file in the `assets/syntaxes` folder.
|
||||
|
||||
3. Run the `create.sh` script. It calls `bat cache --init` to parse all available
|
||||
`.sublime-syntax` files and serialize them to a `syntaxes.bin` file (in this folder).
|
||||
|
||||
4. Re-compile `bat`. At compilation time, the `syntaxes.bin` file will be stored inside the
|
||||
`bat` binary.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
Make sure that the local cache does not interfere with the internally stored syntaxes and
|
||||
themes (`bat cache --clear`).
|
||||
|
||||
### Manual modifications
|
||||
|
||||
The following files have been manually modified after converting from a `.tmLanguage` file:
|
||||
|
||||
* `VimL.sublime-syntax` => added `.vimrc` file type.
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
ASSET_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
bat cache --init --source="$ASSET_DIR" --target="$ASSET_DIR"
|
||||
Binary file not shown.
Submodule
+1
Submodule assets/syntaxes/CMake added at a71f52a390
Submodule
+1
Submodule assets/syntaxes/Docker added at 6e521ead6c
Submodule
+1
Submodule assets/syntaxes/Elixir added at 044d9af8a1
Submodule
+1
Submodule assets/syntaxes/INI added at 8dd3e316ad
@@ -0,0 +1,43 @@
|
||||
%YAML 1.2
|
||||
---
|
||||
# http://www.sublimetext.com/docs/3/syntax.html
|
||||
name: INI
|
||||
file_extensions:
|
||||
- ini
|
||||
- INI
|
||||
- inf
|
||||
- INF
|
||||
- reg
|
||||
- REG
|
||||
- lng
|
||||
- cfg
|
||||
- CFG
|
||||
- url
|
||||
- URL
|
||||
- .editorconfig
|
||||
scope: source.ini
|
||||
contexts:
|
||||
main:
|
||||
- match: ^\s*(;|#).*$\n?
|
||||
scope: comment.line.semicolon.ini
|
||||
captures:
|
||||
1: punctuation.definition.comment.ini
|
||||
- match: '^\s*(\[)(.*?)(\])'
|
||||
scope: meta.tag.section.ini
|
||||
captures:
|
||||
1: punctuation.definition.section.ini
|
||||
2: entity.section.ini
|
||||
3: punctuation.definition.section.ini
|
||||
- match: '^(\s*(["'']?)(.+?)(\2)\s*(=))?\s*((["'']?)(.*?)(\7))\s*(;.*)?$\n?'
|
||||
scope: meta.declaration.ini
|
||||
captures:
|
||||
1: meta.property.ini
|
||||
2: punctuation.definition.quote.ini
|
||||
3: keyword.name.ini
|
||||
4: punctuation.definition.quote.ini
|
||||
5: punctuation.definition.equals.ini
|
||||
6: meta.value.ini
|
||||
7: punctuation.definition.quote.ini
|
||||
8: string.name.value.ini
|
||||
9: punctuation.definition.quote.ini
|
||||
10: comment.declarationline.semicolon.ini
|
||||
Submodule
+1
Submodule assets/syntaxes/Julia added at 581805e47c
Submodule
+1
Submodule assets/syntaxes/LESS added at 46694c86b9
Submodule
+1
Submodule assets/syntaxes/Packages added at 1cb4c3ec36
Submodule
+1
Submodule assets/syntaxes/TOML added at b5e3064e99
Submodule
+1
Submodule assets/syntaxes/VimL added at b453aff6f7
@@ -0,0 +1,91 @@
|
||||
%YAML 1.2
|
||||
---
|
||||
# http://www.sublimetext.com/docs/3/syntax.html
|
||||
name: VimL
|
||||
file_extensions:
|
||||
- vim
|
||||
- .vimrc
|
||||
scope: source.viml
|
||||
contexts:
|
||||
main:
|
||||
- include: comment
|
||||
- include: string_quoted_double
|
||||
- include: string_quoted_single
|
||||
- include: string_regex
|
||||
- include: inline_comment
|
||||
- include: number_int
|
||||
- include: number_hex
|
||||
- include: keyword
|
||||
- include: support_function
|
||||
- include: support_variable
|
||||
- include: support_type
|
||||
- include: function_params
|
||||
- include: function_definition
|
||||
- include: function_call
|
||||
- include: function
|
||||
- include: variable
|
||||
- include: expr
|
||||
comment:
|
||||
- match: ^\s*".*$
|
||||
scope: comment.line.quotes.viml
|
||||
captures:
|
||||
1: punctuation.definition.comment.vim
|
||||
expr:
|
||||
- match: (\|\||&&|==(\?|#)?|(!|>|<)=(#|\?)?|(=|!)~(#|\?)?|(>|<)(#|\?)is|isnot|\.|\*|\\|%)
|
||||
scope: storage.function.viml
|
||||
function:
|
||||
- match: \b(fu(n|nction)?|end(f|fu|fun|function)?)\b
|
||||
scope: storage.function.viml
|
||||
function_call:
|
||||
- match: '(([sgbwtl]|)?:?[0-9a-zA-Z_#]+)(?=\()'
|
||||
scope: support.function.any-method
|
||||
function_definition:
|
||||
- match: '^\s*(function)\s*!?\s+(?=(s:)?[0-9a-zA-Z_#]+\s*\()'
|
||||
captures:
|
||||
1: storage.function.viml
|
||||
push:
|
||||
- meta_scope: meta.function.viml
|
||||
- match: (\()
|
||||
captures:
|
||||
1: punctuation.definition.parameters.begin.viml
|
||||
pop: true
|
||||
- match: "(s:)?[0-9a-zA-Z_#]+"
|
||||
scope: entity.name.function.viml
|
||||
function_params:
|
||||
- match: '-\w+='
|
||||
scope: support.type.viml
|
||||
inline_comment:
|
||||
- match: '(?!\$)(")(?!\{).*$\n?'
|
||||
scope: comment.line.quotes.viml
|
||||
captures:
|
||||
1: punctuation.definition.comment.vim
|
||||
keyword:
|
||||
- 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}"
|
||||
scope: constant.numeric.hex
|
||||
number_int:
|
||||
- match: '-?\d+'
|
||||
scope: constant.numeric.integer
|
||||
string_quoted_double:
|
||||
- match: '"(\\\\|\\"|\n[^\S\n]*\\|[^\n"])*"'
|
||||
scope: string.quoted.double.viml
|
||||
string_quoted_single:
|
||||
- match: '''(''''|\n[^\S\n]*\\|[^\n''])*'''
|
||||
scope: string.quoted.single.viml
|
||||
string_regex:
|
||||
- match: '/(\\\\|\\/|\n[^\S\n]*\\|[^\n/])*/'
|
||||
scope: string.regexp.viml
|
||||
support_function:
|
||||
- match: \b(set(local|global)?|let|command|filetype|colorscheme|\w*map|\w*a(b|brev)?|syn|exe(c|cute)?|ec(ho|)?|au(tocmd|)?)\b
|
||||
scope: support.function.viml
|
||||
support_type:
|
||||
- match: <.*?>
|
||||
scope: support.type.viml
|
||||
support_variable:
|
||||
- match: '\b(am(enu|)?|(hl|inc)?search|[Bb]uf([Nn]ew[Ff]ile|[Rr]ead)?|[Ff]ile[Tt]ype)\b'
|
||||
scope: support.variable.viml
|
||||
variable:
|
||||
- match: '([sSgGbBwWlLaAvV]:|@|$|&(?!&))\w*'
|
||||
scope: variable.other.viml
|
||||
Binary file not shown.
Submodule
+1
Submodule assets/themes/1337-Scheme added at 82db0222c3
Submodule
+1
Submodule assets/themes/DarkNeon added at 174bd535da
Symlink
+1
@@ -0,0 +1 @@
|
||||
sublime-monokai-extended/Monokai Extended.tmTheme
|
||||
Submodule
+1
Submodule assets/themes/TwoDark added at 8e0f6fa5b5
Submodule
+1
Submodule assets/themes/github-sublime-theme added at 508740b243
Submodule
+1
Submodule assets/themes/sublime-monokai-extended added at 1658f51c15
@@ -0,0 +1,20 @@
|
||||
# Alternatives
|
||||
|
||||
The following table tries to give an overview *from `bat`s perspective*, i.e. we only compare
|
||||
categories which are relevant for `bat`. Some of these projects have completely different goals and
|
||||
if you are not looking for a program like `bat`, this comparison might not be for you.
|
||||
|
||||
| | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) |
|
||||
|----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|
|
||||
| Drop-in `cat` replacement | (:heavy_check_mark:) [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: |
|
||||
| Git integration | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
|
||||
| Automatic paging | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: | :x: | :x: |
|
||||
| Languages (circa) | 60 | 300 | 200 | 7 | 80 | 130 | 30 | 130 |
|
||||
| Extensible (languages, themes) | :heavy_check_mark: | (:heavy_check_mark:) | (:heavy_check_mark:) | :x: | (:heavy_check_mark:) | :x: | :x: | :x: |
|
||||
| Advanced highlighting (e.g. nested syntaxes) | :heavy_check_mark: | :heavy_check_mark: | (:heavy_check_mark:) ? | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| Execution time [ms] (`jquery-3.3.1.js`) | 624 | 789 | 400 | 80 | 300 | 316 | 157 | 695 |
|
||||
| Execution time [ms] (`miniz.c`) | 66 | 656 | 26 | 8 | 53 | 141 | 75 | 254 |
|
||||
| Execution time [ms] (370 kB XML file) | 238 | 487 | 129 | 111 | 110 | 339 | 147 | 359 |
|
||||
|
||||
If you think that some entries in this table are outdated or wrong, please open a ticket or pull
|
||||
request.
|
||||
@@ -0,0 +1,326 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1000"
|
||||
height="286.64285"
|
||||
viewBox="0 0 1000 286.64285"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996"
|
||||
id="svg1285"
|
||||
sodipodi:docname="logo-header.svg"
|
||||
inkscape:version="0.92.2 2405546, 2018-03-11"><metadata
|
||||
id="metadata1289"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1175"
|
||||
id="namedview1287"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="0.82573726"
|
||||
inkscape:cx="438.92362"
|
||||
inkscape:cy="320.87266"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg1285"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true" />
|
||||
<rect
|
||||
style="opacity:1;fill:#f2f2f2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.14294769px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"
|
||||
id="rect1929"
|
||||
width="1000"
|
||||
height="286.64285"
|
||||
x="0"
|
||||
y="0" /><g
|
||||
id="g929"
|
||||
transform="translate(0,13.321425)"><g
|
||||
transform="matrix(5.1207879,0,0,4.741146,45.483811,-7057.152)"
|
||||
id="g1168">
|
||||
<path
|
||||
d="m 77.792,1533.05 c 0,0.32 -0.064,0.61 -0.192,0.88 -0.128,0.27 -0.3,0.5 -0.516,0.7 -0.216,0.19 -0.468,0.34 -0.756,0.45 -0.288,0.11 -0.596,0.16 -0.924,0.16 h -4.02 v -8.52 h 4.104 c 0.296,0 0.564,0.07 0.804,0.19 0.24,0.13 0.444,0.3 0.612,0.5 0.168,0.21 0.298,0.44 0.39,0.7 0.092,0.26 0.138,0.52 0.138,0.78 0,0.44 -0.108,0.83 -0.324,1.19 -0.216,0.35 -0.516,0.62 -0.9,0.8 0.488,0.14 0.874,0.41 1.158,0.8 0.284,0.39 0.426,0.85 0.426,1.37 z m -0.84,-0.15 c 0,-0.21 -0.036,-0.41 -0.108,-0.6 -0.072,-0.2 -0.174,-0.37 -0.306,-0.52 -0.132,-0.15 -0.288,-0.27 -0.468,-0.36 -0.18,-0.09 -0.374,-0.14 -0.582,-0.14 h -3.264 v 3.23 h 3.18 c 0.216,0 0.418,-0.04 0.606,-0.13 0.188,-0.09 0.352,-0.21 0.492,-0.35 0.14,-0.15 0.25,-0.33 0.33,-0.52 0.08,-0.2 0.12,-0.4 0.12,-0.61 z m -4.728,-5.45 v 3.15 h 2.928 c 0.208,0 0.402,-0.04 0.582,-0.13 0.18,-0.09 0.334,-0.21 0.462,-0.35 0.128,-0.14 0.228,-0.31 0.3,-0.5 0.072,-0.19 0.108,-0.38 0.108,-0.59 0,-0.22 -0.034,-0.42 -0.102,-0.62 -0.068,-0.19 -0.164,-0.35 -0.288,-0.49 -0.124,-0.14 -0.27,-0.26 -0.438,-0.34 -0.168,-0.08 -0.352,-0.13 -0.552,-0.13 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1162"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 88.436,1526.72 h 0.708 l 3.54,8.52 h -0.888 l -1.104,-2.66 h -3.828 l -1.092,2.66 h -0.9 z m 2.064,5.2 -1.716,-4.21 -1.74,4.21 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1164"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 105.716,1527.47 h -3.036 v 7.77 h -0.84 v -7.77 h -3.036 v -0.75 h 6.912 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1166"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g><g
|
||||
transform="translate(1.9578e-5)"
|
||||
id="g6103"><g
|
||||
id="g1172"
|
||||
transform="matrix(0.31374232,0,0,0.31374232,-949.56013,-170.6326)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1170"
|
||||
style="fill:url(#_Linear1)"
|
||||
d="m 4399.57,773.907 c 0,0 35.33,20.718 42.25,24.779 13.1,7.683 47.96,27.832 64.24,37.232 1.77,1.027 2.87,2.923 2.87,4.975 0.01,2.053 -1.08,3.952 -2.85,4.986 -27.1,15.803 -110.2,64.254 -128.26,74.788 -2.16,1.254 -4.82,1.237 -6.95,-0.046 -13.57,-8.147 -62.93,-37.791 -75.02,-44.875 -16.93,-9.911 -37.27,-21.84 -37.27,-21.84 z" />
|
||||
</g><g
|
||||
id="g1176"
|
||||
transform="matrix(0.31374232,0,0,0.31374232,-949.56013,-170.6326)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1174"
|
||||
style="fill:#31369e"
|
||||
d="m 4269.48,860.305 c -54.5,-31.918 -88.34,-51.732 -117.18,-68.621 -3.98,-2.335 -6.43,-6.608 -6.44,-11.228 0,-4.619 2.45,-8.893 6.44,-11.229 l 319.41,-187.171 c 2.02,-1.186 4.52,-1.198 6.56,-0.032 2.03,1.166 3.29,3.333 3.29,5.678 0,29.472 0,107.932 0,138.732 0,7.842 -4.16,15.094 -10.94,19.049 -13.32,7.783 -54.43,31.465 -67.73,39.233 0,0 -133.3,75.654 -133.41,75.589 z" />
|
||||
</g><g
|
||||
id="g1180"
|
||||
transform="matrix(0.31374232,0,0,0.31374232,-949.56013,-170.6326)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1178"
|
||||
style="fill:#1d2167"
|
||||
d="m 4604.42,705.593 85.54,34.367 v -63.802 c 0,-2.628 -1.37,-5.066 -3.62,-6.431 -2.24,-1.365 -5.04,-1.459 -7.37,-0.247 -5.93,3.078 -74.55,36.113 -74.55,36.113 z" />
|
||||
</g><g
|
||||
id="g1184"
|
||||
transform="matrix(0.31374232,0,0,0.31374232,-949.56013,-170.6326)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1182"
|
||||
style="fill:url(#_Linear2)"
|
||||
d="m 4976.91,704.019 c 0,0 -8.53,-4.983 -8.56,-5 -79.92,-46.83 -170.16,-99.71 -199.6,-116.963 -2.02,-1.186 -4.52,-1.198 -6.56,-0.032 -2.04,1.166 -3.29,3.333 -3.29,5.678 0,29.472 0,107.932 0,138.732 0,7.842 4.16,15.094 10.93,19.049 13.33,7.783 68.33,39.913 68.33,39.913 z" />
|
||||
</g><g
|
||||
id="g1188"
|
||||
transform="matrix(0.31374232,0,0,0.31374232,-949.56013,-170.6326)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1186"
|
||||
style="fill:url(#_Linear3)"
|
||||
d="m 4968.44,699.073 c 0,0 -235.66,138.235 -263.83,154.762 -3.01,1.764 -6.73,1.783 -9.76,0.05 -3.02,-1.733 -4.89,-4.953 -4.89,-8.44 V 731.796 c 0,0 -111.16,-50.383 -128.47,-59.371 -2.33,-1.212 -4.9781,-0.84921 -7.37,0.247 -1.9592,0.89788 -3.62,3.803 -3.62,6.431 v 166.342 c 0,3.487 0.43,15.045 -12.02,22.226 -2.41,1.392 -130.21,75.278 -130.21,75.278 l 211.99,122.751 c 0,0 377.71,-221.201 467.9,-274.016 3.98,-2.335 6.43,-6.608 6.43,-11.228 0,-4.619 -2.45,-8.893 -6.43,-11.229 -24.64,-14.438 -119.72,-70.154 -119.72,-70.154"
|
||||
sodipodi:nodetypes="cccsccsssccccscc" />
|
||||
</g></g><g
|
||||
transform="matrix(0.18627124,0,0,0.22786575,340.43532,-286.36087)"
|
||||
id="g1262">
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1192">
|
||||
<path
|
||||
d="m 374.487,2270.67 h 4.788 l 23.94,57.61 h -6.006 l -7.465,-18.01 h -25.887 l -7.385,18.01 h -6.086 z m 13.958,35.14 -11.604,-28.49 -11.767,28.49 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1190"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1196">
|
||||
<path
|
||||
d="m 421.293,2307.02 c 0,-2.97 0.514,-5.78 1.542,-8.44 1.028,-2.65 2.475,-4.96 4.342,-6.94 1.866,-1.97 4.098,-3.52 6.695,-4.66 2.596,-1.14 5.464,-1.7 8.602,-1.7 4.003,0 7.492,0.9 10.468,2.71 2.975,1.82 5.221,4.26 6.735,7.35 l -5.356,1.7 c -1.19,-2.16 -2.853,-3.85 -4.99,-5.07 -2.137,-1.22 -4.504,-1.83 -7.101,-1.83 -2.164,0 -4.179,0.44 -6.046,1.3 -1.866,0.87 -3.489,2.05 -4.869,3.53 -1.379,1.49 -2.461,3.26 -3.246,5.32 -0.784,2.05 -1.176,4.3 -1.176,6.73 0,2.38 0.405,4.63 1.217,6.74 0.811,2.11 1.92,3.94 3.327,5.48 1.407,1.54 3.043,2.76 4.91,3.65 1.866,0.89 3.854,1.34 5.964,1.34 1.353,0 2.692,-0.19 4.017,-0.57 1.326,-0.38 2.556,-0.91 3.692,-1.58 1.137,-0.68 2.11,-1.45 2.922,-2.32 0.811,-0.86 1.379,-1.78 1.704,-2.75 l 5.437,1.62 c -0.595,1.51 -1.461,2.91 -2.597,4.18 -1.136,1.27 -2.475,2.38 -4.017,3.32 -1.541,0.95 -3.246,1.68 -5.112,2.2 -1.867,0.51 -3.801,0.77 -5.802,0.77 -3.084,0 -5.924,-0.59 -8.521,-1.75 -2.597,-1.16 -4.842,-2.76 -6.736,-4.79 -1.893,-2.03 -3.367,-4.36 -4.422,-7.02 -1.055,-2.65 -1.583,-5.49 -1.583,-8.52 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1194"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1200">
|
||||
<path
|
||||
d="m 476.962,2329.1 c -2.001,0 -3.854,-0.34 -5.558,-1.02 -1.705,-0.67 -3.192,-1.61 -4.464,-2.8 -1.271,-1.19 -2.258,-2.58 -2.962,-4.18 -0.703,-1.59 -1.055,-3.31 -1.055,-5.15 0,-1.84 0.433,-3.54 1.299,-5.11 0.865,-1.57 2.083,-2.92 3.652,-4.06 1.568,-1.14 3.435,-2.02 5.599,-2.64 2.164,-0.62 4.544,-0.93 7.141,-0.93 2.164,0 4.355,0.19 6.573,0.57 2.218,0.38 4.193,0.92 5.924,1.62 v -3.81 c 0,-3.74 -1.055,-6.7 -3.165,-8.89 -2.11,-2.19 -5.031,-3.29 -8.764,-3.29 -2.164,0 -4.382,0.44 -6.654,1.3 -2.272,0.87 -4.572,2.11 -6.898,3.74 l -1.948,-3.66 c 5.465,-3.67 10.766,-5.51 15.906,-5.51 5.302,0 9.467,1.48 12.497,4.46 3.03,2.97 4.544,7.09 4.544,12.33 v 19.07 c 0,1.52 0.677,2.28 2.029,2.28 v 4.86 c -0.919,0.17 -1.623,0.25 -2.11,0.25 -1.406,0 -2.502,-0.35 -3.286,-1.06 -0.785,-0.7 -1.204,-1.67 -1.258,-2.92 l -0.162,-3.33 c -1.948,2.55 -4.396,4.5 -7.345,5.85 -2.948,1.35 -6.126,2.03 -9.535,2.03 z m 1.299,-4.22 c 2.867,0 5.504,-0.54 7.912,-1.63 2.407,-1.08 4.233,-2.51 5.478,-4.3 0.486,-0.48 0.852,-1.01 1.095,-1.58 0.244,-0.57 0.365,-1.09 0.365,-1.58 v -6.9 c -1.839,-0.7 -3.746,-1.24 -5.721,-1.62 -1.975,-0.38 -3.99,-0.57 -6.046,-0.57 -3.895,0 -7.06,0.81 -9.494,2.43 -2.435,1.63 -3.652,3.76 -3.652,6.41 0,1.3 0.257,2.52 0.771,3.66 0.514,1.13 1.217,2.12 2.11,2.96 0.893,0.84 1.961,1.5 3.205,1.99 1.245,0.48 2.57,0.73 3.977,0.73 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1198"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1204">
|
||||
<path
|
||||
d="m 528.158,2326.26 c -0.325,0.16 -0.798,0.38 -1.42,0.65 -0.622,0.27 -1.339,0.54 -2.151,0.81 -0.811,0.27 -1.731,0.51 -2.759,0.73 -1.028,0.21 -2.11,0.32 -3.246,0.32 -1.19,0 -2.326,-0.16 -3.408,-0.49 -1.082,-0.32 -2.029,-0.82 -2.84,-1.5 -0.812,-0.67 -1.461,-1.52 -1.948,-2.55 -0.487,-1.03 -0.73,-2.22 -0.73,-3.57 v -30.27 h -5.843 v -4.38 h 5.843 v -14.29 h 5.518 v 14.29 h 9.738 v 4.38 h -9.738 v 28.73 c 0.108,1.56 0.663,2.71 1.664,3.44 1,0.73 2.15,1.1 3.448,1.1 1.569,0 2.949,-0.26 4.139,-0.77 1.19,-0.52 1.948,-0.88 2.272,-1.1 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1202"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1208">
|
||||
<path
|
||||
d="m 547.959,2307.02 c 0,-2.97 0.514,-5.78 1.542,-8.44 1.027,-2.65 2.475,-4.96 4.341,-6.94 1.866,-1.97 4.098,-3.52 6.695,-4.66 2.597,-1.14 5.464,-1.7 8.602,-1.7 4.003,0 7.493,0.9 10.468,2.71 2.976,1.82 5.221,4.26 6.736,7.35 l -5.356,1.7 c -1.19,-2.16 -2.854,-3.85 -4.991,-5.07 -2.137,-1.22 -4.504,-1.83 -7.101,-1.83 -2.164,0 -4.179,0.44 -6.045,1.3 -1.867,0.87 -3.49,2.05 -4.869,3.53 -1.38,1.49 -2.462,3.26 -3.246,5.32 -0.785,2.05 -1.177,4.3 -1.177,6.73 0,2.38 0.406,4.63 1.217,6.74 0.812,2.11 1.921,3.94 3.327,5.48 1.407,1.54 3.044,2.76 4.91,3.65 1.866,0.89 3.855,1.34 5.965,1.34 1.352,0 2.691,-0.19 4.016,-0.57 1.326,-0.38 2.557,-0.91 3.693,-1.58 1.136,-0.68 2.11,-1.45 2.921,-2.32 0.812,-0.86 1.38,-1.78 1.704,-2.75 l 5.437,1.62 c -0.595,1.51 -1.46,2.91 -2.596,4.18 -1.136,1.27 -2.475,2.38 -4.017,3.32 -1.542,0.95 -3.246,1.68 -5.113,2.2 -1.866,0.51 -3.8,0.77 -5.802,0.77 -3.084,0 -5.924,-0.59 -8.521,-1.75 -2.597,-1.16 -4.842,-2.76 -6.735,-4.79 -1.894,-2.03 -3.368,-4.36 -4.423,-7.02 -1.055,-2.65 -1.582,-5.49 -1.582,-8.52 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1206"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1212">
|
||||
<path
|
||||
d="m 593.24,2269.05 h 5.519 v 49.66 c 0,1.57 0.432,2.8 1.298,3.69 0.866,0.89 2.083,1.34 3.652,1.34 0.595,0 1.298,-0.08 2.11,-0.24 0.811,-0.16 1.569,-0.38 2.272,-0.65 l 0.974,4.46 c -1.028,0.43 -2.286,0.79 -3.774,1.06 -1.487,0.27 -2.772,0.4 -3.854,0.4 -2.543,0 -4.545,-0.72 -6.005,-2.15 -1.461,-1.43 -2.192,-3.45 -2.192,-6.04 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1210"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1216">
|
||||
<path
|
||||
d="m 630.651,2329.1 c -3.084,0 -5.897,-0.59 -8.44,-1.75 -2.543,-1.16 -4.747,-2.74 -6.614,-4.75 -1.866,-2 -3.313,-4.32 -4.341,-6.97 -1.028,-2.66 -1.542,-5.44 -1.542,-8.36 0,-2.98 0.527,-5.79 1.582,-8.44 1.055,-2.65 2.516,-4.98 4.383,-6.98 1.866,-2 4.071,-3.6 6.613,-4.79 2.543,-1.19 5.329,-1.78 8.359,-1.78 3.029,0 5.829,0.59 8.399,1.78 2.57,1.19 4.788,2.79 6.654,4.79 1.867,2 3.327,4.33 4.382,6.98 1.055,2.65 1.583,5.46 1.583,8.44 0,2.92 -0.514,5.7 -1.542,8.36 -1.028,2.65 -2.475,4.97 -4.342,6.97 -1.866,2.01 -4.084,3.59 -6.654,4.75 -2.57,1.16 -5.397,1.75 -8.48,1.75 z m -15.338,-21.75 c 0,2.38 0.406,4.58 1.218,6.61 0.811,2.03 1.907,3.82 3.286,5.36 1.38,1.54 3.003,2.74 4.869,3.61 1.867,0.86 3.855,1.3 5.965,1.3 2.11,0 4.098,-0.45 5.964,-1.34 1.867,-0.89 3.503,-2.11 4.91,-3.65 1.406,-1.54 2.516,-3.34 3.327,-5.4 0.812,-2.06 1.217,-4.27 1.217,-6.65 0,-2.33 -0.405,-4.53 -1.217,-6.62 -0.811,-2.08 -1.921,-3.89 -3.327,-5.43 -1.407,-1.55 -3.043,-2.76 -4.91,-3.66 -1.866,-0.89 -3.854,-1.34 -5.964,-1.34 -2.11,0 -4.085,0.45 -5.924,1.34 -1.84,0.9 -3.463,2.13 -4.869,3.7 -1.407,1.56 -2.516,3.39 -3.327,5.47 -0.812,2.09 -1.218,4.32 -1.218,6.7 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1214"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1220">
|
||||
<path
|
||||
d="m 694.029,2328.28 h -5.518 v -23.61 c 0,-5.03 -0.744,-8.68 -2.232,-10.95 -1.488,-2.28 -3.773,-3.41 -6.857,-3.41 -1.623,0 -3.246,0.29 -4.869,0.89 -1.623,0.59 -3.124,1.43 -4.504,2.52 -1.379,1.08 -2.61,2.36 -3.692,3.85 -1.082,1.49 -1.867,3.1 -2.354,4.83 v 25.88 h -5.518 v -42.27 h 5.032 v 9.57 c 1.731,-3.08 4.206,-5.57 7.425,-7.46 3.219,-1.9 6.722,-2.84 10.509,-2.84 2.326,0 4.301,0.43 5.924,1.29 1.623,0.87 2.921,2.09 3.895,3.65 0.974,1.57 1.677,3.5 2.11,5.77 0.433,2.27 0.649,4.79 0.649,7.54 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1218"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1224">
|
||||
<path
|
||||
d="m 721.62,2329.1 c -3.084,0 -5.91,-0.59 -8.48,-1.75 -2.57,-1.16 -4.801,-2.76 -6.695,-4.79 -1.893,-2.03 -3.368,-4.36 -4.423,-7.02 -1.055,-2.65 -1.582,-5.49 -1.582,-8.52 0,-2.97 0.527,-5.77 1.582,-8.4 1.055,-2.62 2.516,-4.92 4.382,-6.89 1.867,-1.98 4.099,-3.55 6.695,-4.71 2.597,-1.16 5.41,-1.74 8.44,-1.74 3.084,0 5.91,0.58 8.48,1.74 2.57,1.16 4.775,2.74 6.614,4.75 1.839,2 3.273,4.3 4.301,6.89 1.028,2.6 1.542,5.36 1.542,8.28 0,0.44 0,0.87 0,1.3 0,0.43 -0.027,0.73 -0.081,0.89 h -36.193 c 0.162,2.28 0.689,4.37 1.582,6.29 0.893,1.92 2.042,3.59 3.449,4.99 1.407,1.41 3.016,2.5 4.828,3.29 1.813,0.78 3.747,1.18 5.803,1.18 1.352,0 2.705,-0.19 4.057,-0.57 1.353,-0.38 2.597,-0.89 3.733,-1.54 1.136,-0.65 2.164,-1.45 3.084,-2.4 0.919,-0.94 1.623,-1.99 2.11,-3.12 l 4.787,1.3 c -0.649,1.57 -1.568,2.99 -2.759,4.26 -1.19,1.27 -2.569,2.38 -4.138,3.32 -1.569,0.95 -3.3,1.68 -5.194,2.2 -1.893,0.51 -3.868,0.77 -5.924,0.77 z m 15.581,-24.19 c -0.162,-2.27 -0.69,-4.34 -1.582,-6.21 -0.893,-1.86 -2.029,-3.47 -3.409,-4.82 -1.379,-1.35 -2.975,-2.41 -4.788,-3.17 -1.812,-0.76 -3.746,-1.13 -5.802,-1.13 -2.056,0 -4.003,0.37 -5.843,1.13 -1.839,0.76 -3.449,1.82 -4.828,3.17 -1.38,1.35 -2.489,2.97 -3.327,4.87 -0.839,1.89 -1.339,3.95 -1.502,6.16 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1222"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1228">
|
||||
<path
|
||||
d="m 818.344,2286.01 h 5.437 l -18.178,42.27 h -4.544 l -9.089,-21.58 -9.008,21.58 h -4.544 l -18.178,-42.27 h 5.356 l 15.418,36.59 8.034,-19.31 -7.222,-17.2 h 4.626 l 5.518,13.79 5.518,-13.79 h 4.707 l -7.223,17.2 8.034,19.31 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1226"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1232">
|
||||
<path
|
||||
d="m 828.65,2328.28 v -42.27 h 5.518 v 42.27 z m 0,-51.12 v -8.11 h 5.518 v 8.11 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1230"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1236">
|
||||
<path
|
||||
d="m 864.193,2326.26 c -0.324,0.16 -0.798,0.38 -1.42,0.65 -0.622,0.27 -1.339,0.54 -2.15,0.81 -0.812,0.27 -1.731,0.51 -2.759,0.73 -1.028,0.21 -2.11,0.32 -3.246,0.32 -1.19,0 -2.327,-0.16 -3.409,-0.49 -1.082,-0.32 -2.028,-0.82 -2.84,-1.5 -0.811,-0.67 -1.461,-1.52 -1.947,-2.55 -0.487,-1.03 -0.731,-2.22 -0.731,-3.57 v -30.27 h -5.843 v -4.38 h 5.843 v -14.29 h 5.518 v 14.29 h 9.738 v 4.38 h -9.738 v 28.73 c 0.109,1.56 0.663,2.71 1.664,3.44 1.001,0.73 2.15,1.1 3.449,1.1 1.569,0 2.948,-0.26 4.139,-0.77 1.19,-0.52 1.947,-0.88 2.272,-1.1 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1234"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1240">
|
||||
<path
|
||||
d="m 904.201,2328.28 h -5.519 v -23.61 c 0,-4.81 -0.825,-8.41 -2.475,-10.79 -1.65,-2.38 -4.071,-3.57 -7.263,-3.57 -1.569,0 -3.124,0.31 -4.666,0.93 -1.542,0.62 -2.989,1.47 -4.341,2.56 -1.353,1.08 -2.53,2.35 -3.53,3.81 -1.001,1.46 -1.745,3.06 -2.232,4.79 v 25.88 h -5.518 v -59.23 h 5.518 v 26.53 c 1.677,-3.19 4.003,-5.71 6.979,-7.55 2.975,-1.83 6.194,-2.75 9.657,-2.75 2.434,0 4.49,0.44 6.167,1.33 1.677,0.9 3.057,2.14 4.139,3.74 1.082,1.59 1.866,3.51 2.353,5.76 0.487,2.24 0.731,4.72 0.731,7.42 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1238"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1244">
|
||||
<path
|
||||
d="m 983.314,2286.01 h 5.437 l -18.177,42.27 h -4.545 l -9.088,-21.58 -9.008,21.58 h -4.545 l -18.177,-42.27 h 5.356 l 15.418,36.59 8.034,-19.31 -7.222,-17.2 h 4.625 l 5.519,13.79 5.518,-13.79 h 4.707 l -7.223,17.2 8.034,19.31 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1242"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1248">
|
||||
<path
|
||||
d="m 993.62,2328.28 v -42.27 h 5.519 v 42.27 z m 0,-51.12 v -8.11 h 5.519 v 8.11 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1246"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1252">
|
||||
<path
|
||||
d="m 1044.42,2328.28 h -5.52 v -23.61 c 0,-5.03 -0.74,-8.68 -2.23,-10.95 -1.49,-2.28 -3.77,-3.41 -6.86,-3.41 -1.62,0 -3.24,0.29 -4.87,0.89 -1.62,0.59 -3.12,1.43 -4.5,2.52 -1.38,1.08 -2.61,2.36 -3.69,3.85 -1.08,1.49 -1.87,3.1 -2.36,4.83 v 25.88 h -5.51 v -42.27 h 5.03 v 9.57 c 1.73,-3.08 4.2,-5.57 7.42,-7.46 3.22,-1.9 6.73,-2.84 10.51,-2.84 2.33,0 4.3,0.43 5.93,1.29 1.62,0.87 2.92,2.09 3.89,3.65 0.97,1.57 1.68,3.5 2.11,5.77 0.43,2.27 0.65,4.79 0.65,7.54 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1250"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1256">
|
||||
<path
|
||||
d="m 1070.71,2328.85 c -2.92,0 -5.58,-0.61 -7.99,-1.82 -2.41,-1.22 -4.49,-2.83 -6.25,-4.83 -1.76,-2 -3.12,-4.3 -4.1,-6.9 -0.97,-2.6 -1.46,-5.27 -1.46,-8.03 0,-2.92 0.48,-5.72 1.42,-8.4 0.95,-2.68 2.29,-5.02 4.02,-7.02 1.73,-2 3.8,-3.6 6.21,-4.79 2.4,-1.19 5.07,-1.78 7.99,-1.78 3.63,0 6.76,0.9 9.41,2.71 2.66,1.82 4.93,4.1 6.82,6.86 v -8.84 h 4.95 v 42.44 c 0,2.92 -0.55,5.5 -1.66,7.75 -1.11,2.24 -2.6,4.12 -4.47,5.64 -1.86,1.51 -4.05,2.65 -6.57,3.4 -2.51,0.76 -5.18,1.14 -7.99,1.14 -4.87,0 -8.79,-0.86 -11.77,-2.6 -2.97,-1.73 -5.38,-4.05 -7.22,-6.97 l 3.41,-2.68 c 1.67,2.7 3.89,4.69 6.65,5.96 2.76,1.27 5.74,1.91 8.93,1.91 2.05,0 4,-0.28 5.84,-0.85 1.84,-0.57 3.45,-1.41 4.83,-2.52 1.38,-1.11 2.47,-2.51 3.29,-4.22 0.81,-1.7 1.21,-3.69 1.21,-5.96 v -8.36 c -1.62,2.7 -3.84,4.84 -6.65,6.41 -2.81,1.57 -5.76,2.35 -8.85,2.35 z m 1.55,-4.62 c 1.62,0 3.21,-0.3 4.78,-0.89 1.57,-0.6 2.99,-1.4 4.26,-2.4 1.28,-1 2.34,-2.12 3.21,-3.37 0.86,-1.24 1.43,-2.51 1.7,-3.81 v -13.07 c -0.59,-1.51 -1.4,-2.92 -2.43,-4.22 -1.03,-1.29 -2.19,-2.4 -3.49,-3.32 -1.3,-0.92 -2.69,-1.65 -4.18,-2.19 -1.49,-0.55 -2.99,-0.82 -4.5,-0.82 -2.39,0 -4.51,0.5 -6.37,1.5 -1.87,1.01 -3.45,2.32 -4.75,3.94 -1.3,1.62 -2.29,3.46 -2.96,5.52 -0.68,2.06 -1.02,4.14 -1.02,6.25 0,2.27 0.41,4.43 1.22,6.49 0.81,2.06 1.93,3.86 3.37,5.4 1.43,1.54 3.09,2.76 4.99,3.65 1.89,0.89 3.95,1.34 6.17,1.34 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1254"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.28,0,0,1,-97.8353,0)"
|
||||
id="g1260">
|
||||
<path
|
||||
d="m 1115.51,2329.1 c -3.3,0 -6.52,-0.55 -9.66,-1.63 -3.14,-1.08 -5.84,-2.65 -8.11,-4.7 l 2.51,-3.74 c 2.38,1.95 4.8,3.41 7.27,4.39 2.46,0.97 5.09,1.46 7.91,1.46 3.41,0 6.12,-0.69 8.15,-2.07 2.03,-1.38 3.05,-3.34 3.05,-5.89 0,-1.19 -0.27,-2.17 -0.82,-2.96 -0.54,-0.78 -1.33,-1.47 -2.39,-2.07 -1.05,-0.59 -2.38,-1.12 -3.98,-1.58 -1.59,-0.46 -3.44,-0.93 -5.56,-1.42 -2.43,-0.59 -4.54,-1.19 -6.32,-1.78 -1.79,-0.6 -3.26,-1.28 -4.43,-2.03 -1.16,-0.76 -2.03,-1.69 -2.59,-2.8 -0.57,-1.11 -0.86,-2.51 -0.86,-4.18 0,-2.11 0.42,-3.98 1.26,-5.6 0.84,-1.63 1.98,-2.96 3.41,-4.02 1.43,-1.05 3.11,-1.85 5.03,-2.39 1.92,-0.54 3.96,-0.81 6.13,-0.81 3.24,0 6.19,0.52 8.84,1.58 2.65,1.05 4.79,2.45 6.41,4.18 l -2.67,3.24 c -1.57,-1.62 -3.48,-2.84 -5.72,-3.65 -2.25,-0.81 -4.59,-1.22 -7.02,-1.22 -1.47,0 -2.82,0.15 -4.06,0.45 -1.25,0.3 -2.34,0.77 -3.29,1.42 -0.94,0.65 -1.69,1.47 -2.23,2.48 -0.54,1 -0.81,2.17 -0.81,3.52 0,1.14 0.19,2.06 0.57,2.76 0.37,0.71 1,1.32 1.86,1.83 0.87,0.51 1.96,0.97 3.29,1.38 1.33,0.41 2.94,0.83 4.83,1.26 2.7,0.65 5.08,1.3 7.14,1.94 2.05,0.66 3.77,1.41 5.15,2.28 1.38,0.86 2.42,1.92 3.13,3.16 0.7,1.25 1.05,2.76 1.05,4.55 0,3.89 -1.49,6.98 -4.46,9.25 -2.98,2.27 -6.98,3.41 -12.01,3.41 z"
|
||||
style="fill:#1d2167;fill-rule:nonzero"
|
||||
id="path1258"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g></g>
|
||||
<defs
|
||||
id="defs1283"><linearGradient
|
||||
id="_Linear1"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-158.501,-265.604,265.604,-158.501,4436.06,964.047)"><stop
|
||||
offset="0"
|
||||
style="stop-color:rgb(49,54,158);stop-opacity:1"
|
||||
id="stop1266" /><stop
|
||||
offset="0.52"
|
||||
style="stop-color:rgb(38,42,122);stop-opacity:1"
|
||||
id="stop1268" /><stop
|
||||
offset="1"
|
||||
style="stop-color:black;stop-opacity:1"
|
||||
id="stop1270" /></linearGradient><linearGradient
|
||||
id="_Linear2"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(160.563,96.0376,-96.0376,160.563,4771.78,656.669)"><stop
|
||||
offset="0"
|
||||
style="stop-color:rgb(49,54,158);stop-opacity:1"
|
||||
id="stop1273" /><stop
|
||||
offset="1"
|
||||
style="stop-color:rgb(29,33,103);stop-opacity:1"
|
||||
id="stop1275" /></linearGradient><linearGradient
|
||||
id="_Linear3"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(76.53,136.554,-136.554,76.53,4737.26,847.244)"><stop
|
||||
offset="0"
|
||||
style="stop-color:rgb(49,54,158);stop-opacity:1"
|
||||
id="stop1278" /><stop
|
||||
offset="1"
|
||||
style="stop-color:rgb(29,33,103);stop-opacity:1"
|
||||
id="stop1280" /></linearGradient></defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
+331
@@ -0,0 +1,331 @@
|
||||
use atty::{self, Stream};
|
||||
use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, ArgMatches, SubCommand};
|
||||
use console::Term;
|
||||
use errors::*;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use style::{OutputComponent, OutputComponents, OutputWrap};
|
||||
|
||||
#[cfg(windows)]
|
||||
use ansi_term;
|
||||
|
||||
pub struct App {
|
||||
pub matches: ArgMatches<'static>,
|
||||
interactive_output: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new() -> Self {
|
||||
let interactive_output = atty::is(Stream::Stdout);
|
||||
|
||||
#[cfg(windows)]
|
||||
let interactive_output = interactive_output && ansi_term::enable_ansi_support().is_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
|
||||
} else {
|
||||
AppSettings::ColorNever
|
||||
};
|
||||
|
||||
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("language")
|
||||
.short("l")
|
||||
.long("language")
|
||||
.overrides_with("language")
|
||||
.help("Set the language for highlighting")
|
||||
.long_help(
|
||||
"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("FILE")
|
||||
.help("File(s) to print / concatenate. Use '-' for standard input.")
|
||||
.long_help(
|
||||
"File(s) to print. Use no argument or '-' to read from standard \
|
||||
input",
|
||||
)
|
||||
.multiple(true)
|
||||
.empty_values(false),
|
||||
)
|
||||
.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",
|
||||
])
|
||||
.default_value("auto")
|
||||
.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')",
|
||||
),
|
||||
)
|
||||
.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"),
|
||||
)
|
||||
.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("When to use the pager")
|
||||
.long_help("Specify when to use the pager (less)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("wrap")
|
||||
.long("wrap")
|
||||
.overrides_with("wrap")
|
||||
.takes_value(true)
|
||||
.value_name("mode")
|
||||
.possible_values(&["character", "never"])
|
||||
.default_value("character")
|
||||
.help("When to wrap text"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("list-languages")
|
||||
.long("list-languages")
|
||||
.help("Displays supported languages")
|
||||
.long_help("Display a list of supported languages"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("theme")
|
||||
.long("theme")
|
||||
.overrides_with("theme")
|
||||
.takes_value(true)
|
||||
.help("Set the theme for highlighting")
|
||||
.long_help(
|
||||
"Set the theme for syntax highlighting. Use '--list-themes' to \
|
||||
see all available themes",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("list-themes")
|
||||
.long("list-themes")
|
||||
.help("Displays supported themes")
|
||||
.help("Display a list of supported themes for syntax highlighting"),
|
||||
)
|
||||
.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(
|
||||
"Show line numbers (no other decorations). This is an alias for \
|
||||
'--style=numbers'",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("unbuffered")
|
||||
.short("u")
|
||||
.help("(ignored)")
|
||||
// TODO: use '.hidden_short_help(true)' when the next clap version is released
|
||||
.long_help(
|
||||
"This option exists for POSIX-compliance reasons ('u' is for \
|
||||
'unbuffered'). The output is always unbuffered - this option \
|
||||
it simply ignored.",
|
||||
),
|
||||
)
|
||||
.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("Reset the cache"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config-dir")
|
||||
.long("config-dir")
|
||||
.short("d")
|
||||
.help("Show the configuration directory"),
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("cache-actions")
|
||||
.args(&["init", "clear", "config-dir"])
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("source")
|
||||
.long("source")
|
||||
.requires("init")
|
||||
.takes_value(true)
|
||||
.value_name("dir")
|
||||
.help("Use a different source for loading syntaxes and themes from"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("target")
|
||||
.long("target")
|
||||
.requires("init")
|
||||
.takes_value(true)
|
||||
.value_name("dir")
|
||||
.help(
|
||||
"Use a different source to store the cached syntax and theme set",
|
||||
),
|
||||
),
|
||||
)
|
||||
.help_message("Print this help message.")
|
||||
.version_message("Show version information.")
|
||||
.get_matches()
|
||||
}
|
||||
|
||||
pub fn config(&self) -> Result<Config> {
|
||||
let files = self.files();
|
||||
|
||||
Ok(Config {
|
||||
true_color: is_truecolor_terminal(),
|
||||
output_components: self.output_components()?,
|
||||
language: self.matches.value_of("language"),
|
||||
output_wrap: if !self.interactive_output {
|
||||
// We don't have the tty width when piping to another program.
|
||||
// There's no point in wrapping when this is the case.
|
||||
OutputWrap::None
|
||||
} else {
|
||||
match self.matches.value_of("wrap") {
|
||||
Some("character") => OutputWrap::Character,
|
||||
Some("never") | _ => OutputWrap::None,
|
||||
}
|
||||
},
|
||||
colored_output: match self.matches.value_of("color") {
|
||||
Some("always") => true,
|
||||
Some("never") => false,
|
||||
Some("auto") | _ => self.interactive_output,
|
||||
},
|
||||
paging_mode: match self.matches.value_of("paging") {
|
||||
Some("always") => PagingMode::Always,
|
||||
Some("never") => PagingMode::Never,
|
||||
Some("auto") | _ => if files.contains(&None) {
|
||||
// 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 {
|
||||
if self.interactive_output {
|
||||
PagingMode::QuitIfOneScreen
|
||||
} else {
|
||||
PagingMode::Never
|
||||
}
|
||||
},
|
||||
},
|
||||
term_width: Term::stdout().size().1 as usize,
|
||||
files,
|
||||
theme: self.matches.value_of("theme"),
|
||||
})
|
||||
}
|
||||
|
||||
fn files(&self) -> Vec<Option<&str>> {
|
||||
self.matches
|
||||
.values_of("FILE")
|
||||
.map(|values| {
|
||||
values
|
||||
.map(|filename| {
|
||||
if filename == "-" {
|
||||
None
|
||||
} else {
|
||||
Some(filename)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_else(|| vec![None]) // read from stdin (None) if no args are given
|
||||
}
|
||||
|
||||
fn output_components(&self) -> Result<OutputComponents> {
|
||||
let matches = &self.matches;
|
||||
Ok(OutputComponents(if matches.is_present("number") {
|
||||
[OutputComponent::Numbers].iter().cloned().collect()
|
||||
} else {
|
||||
values_t!(matches.values_of("style"), OutputComponent)?
|
||||
.into_iter()
|
||||
.map(|style| style.components(self.interactive_output))
|
||||
.fold(HashSet::new(), |mut acc, components| {
|
||||
acc.extend(components.iter().cloned());
|
||||
acc
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum PagingMode {
|
||||
Always,
|
||||
QuitIfOneScreen,
|
||||
Never,
|
||||
}
|
||||
|
||||
pub struct Config<'a> {
|
||||
pub true_color: bool,
|
||||
pub output_wrap: OutputWrap,
|
||||
pub output_components: OutputComponents,
|
||||
pub language: Option<&'a str>,
|
||||
pub colored_output: bool,
|
||||
pub paging_mode: PagingMode,
|
||||
pub term_width: usize,
|
||||
pub files: Vec<Option<&'a str>>,
|
||||
pub theme: Option<&'a str>,
|
||||
}
|
||||
|
||||
fn is_truecolor_terminal() -> bool {
|
||||
env::var("COLORTERM")
|
||||
.map(|colorterm| colorterm == "truecolor" || colorterm == "24bit")
|
||||
.unwrap_or(false)
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
use directories::ProjectDirs;
|
||||
use errors::*;
|
||||
use std::borrow::Cow;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
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};
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
|
||||
lazy_static! {
|
||||
static ref PROJECT_DIRS: ProjectDirs = ProjectDirs::from("", "", crate_name!());
|
||||
}
|
||||
|
||||
pub struct HighlightingAssets {
|
||||
pub syntax_set: SyntaxSet,
|
||||
pub theme_set: ThemeSet,
|
||||
}
|
||||
|
||||
impl HighlightingAssets {
|
||||
pub fn new() -> Self {
|
||||
Self::from_cache().unwrap_or_else(|_| Self::from_binary())
|
||||
}
|
||||
|
||||
pub fn from_files(dir: Option<&Path>) -> Result<Self> {
|
||||
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir());
|
||||
|
||||
let theme_dir = source_dir.join("themes");
|
||||
let theme_set = ThemeSet::load_from_folder(&theme_dir).chain_err(|| {
|
||||
format!(
|
||||
"Could not load themes from '{}'",
|
||||
theme_dir.to_string_lossy()
|
||||
)
|
||||
})?;
|
||||
let mut syntax_set = SyntaxSet::new();
|
||||
let syntax_dir = source_dir.join("syntaxes");
|
||||
if !syntax_dir.exists() {
|
||||
return Err(format!(
|
||||
"Could not load syntaxes from '{}'",
|
||||
syntax_dir.to_string_lossy()
|
||||
).into());
|
||||
}
|
||||
syntax_set.load_syntaxes(syntax_dir, true)?;
|
||||
syntax_set.load_plain_text_syntax();
|
||||
|
||||
Ok(HighlightingAssets {
|
||||
syntax_set,
|
||||
theme_set,
|
||||
})
|
||||
}
|
||||
|
||||
fn from_cache() -> Result<Self> {
|
||||
let theme_set_path = theme_set_path();
|
||||
let syntax_set_file = File::open(&syntax_set_path()).chain_err(|| {
|
||||
format!(
|
||||
"Could not load cached syntax set '{}'",
|
||||
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 theme_set_file = File::open(&theme_set_path).chain_err(|| {
|
||||
format!(
|
||||
"Could not load cached theme set '{}'",
|
||||
theme_set_path.to_string_lossy()
|
||||
)
|
||||
})?;
|
||||
let theme_set: ThemeSet =
|
||||
from_reader(theme_set_file).chain_err(|| "Could not parse cached theme set")?;
|
||||
|
||||
Ok(HighlightingAssets {
|
||||
syntax_set,
|
||||
theme_set,
|
||||
})
|
||||
}
|
||||
|
||||
fn from_binary() -> Self {
|
||||
let mut syntax_set: SyntaxSet = from_binary(include_bytes!("../assets/syntaxes.bin"));
|
||||
syntax_set.link_syntaxes();
|
||||
let theme_set: ThemeSet = from_binary(include_bytes!("../assets/themes.bin"));
|
||||
|
||||
HighlightingAssets {
|
||||
syntax_set,
|
||||
theme_set,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
let theme_set_path = target_dir.join("themes.bin");
|
||||
let syntax_set_path = target_dir.join("syntaxes.bin");
|
||||
|
||||
print!(
|
||||
"Writing theme set to {} ... ",
|
||||
theme_set_path.to_string_lossy()
|
||||
);
|
||||
dump_to_file(&self.theme_set, &theme_set_path).chain_err(|| {
|
||||
format!(
|
||||
"Could not save theme set to {}",
|
||||
theme_set_path.to_string_lossy()
|
||||
)
|
||||
})?;
|
||||
println!("okay");
|
||||
|
||||
print!(
|
||||
"Writing syntax set to {} ... ",
|
||||
syntax_set_path.to_string_lossy()
|
||||
);
|
||||
dump_to_file(&self.syntax_set, &syntax_set_path).chain_err(|| {
|
||||
format!(
|
||||
"Could not save syntax set to {}",
|
||||
syntax_set_path.to_string_lossy()
|
||||
)
|
||||
})?;
|
||||
println!("okay");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_theme(&self, theme: &str) -> Result<&Theme> {
|
||||
Ok(self.theme_set.themes.get(theme).ok_or_else(|| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Could not find '{}' theme", theme),
|
||||
)
|
||||
})?)
|
||||
}
|
||||
|
||||
pub fn get_syntax(&self, language: Option<&str>, filename: Option<&str>) -> &SyntaxDefinition {
|
||||
let syntax = match (language, filename) {
|
||||
(Some(language), _) => self.syntax_set.find_syntax_by_token(language),
|
||||
(None, Some(filename)) => {
|
||||
#[cfg(not(unix))]
|
||||
let may_read_from_file = true;
|
||||
|
||||
// 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);
|
||||
|
||||
if may_read_from_file {
|
||||
self.syntax_set
|
||||
.find_syntax_for_file(filename)
|
||||
.unwrap_or(None)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
(None, None) => None,
|
||||
};
|
||||
|
||||
syntax.unwrap_or_else(|| self.syntax_set.find_syntax_plain_text())
|
||||
}
|
||||
}
|
||||
|
||||
fn theme_set_path() -> PathBuf {
|
||||
PROJECT_DIRS.cache_dir().join("themes.bin")
|
||||
}
|
||||
|
||||
fn syntax_set_path() -> PathBuf {
|
||||
PROJECT_DIRS.cache_dir().join("syntaxes.bin")
|
||||
}
|
||||
|
||||
pub fn config_dir() -> Cow<'static, str> {
|
||||
PROJECT_DIRS.config_dir().to_string_lossy()
|
||||
}
|
||||
|
||||
pub fn clear_assets() {
|
||||
print!("Clearing theme set cache ... ");
|
||||
fs::remove_file(theme_set_path()).ok();
|
||||
println!("okay");
|
||||
|
||||
print!("Clearing syntax set cache ... ");
|
||||
fs::remove_file(syntax_set_path()).ok();
|
||||
println!("okay");
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
use ansi_term::Style;
|
||||
use diff::LineChange;
|
||||
use printer::{Colors, Printer};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DecorationText {
|
||||
pub width: usize,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
pub trait Decoration {
|
||||
fn generate(&self, line_number: usize, continuation: bool, printer: &Printer)
|
||||
-> DecorationText;
|
||||
fn width(&self) -> usize;
|
||||
}
|
||||
|
||||
// Line number decoration.
|
||||
pub struct LineNumberDecoration {
|
||||
color: Style,
|
||||
cached_wrap: DecorationText,
|
||||
cached_wrap_invalid_at: usize,
|
||||
}
|
||||
|
||||
impl LineNumberDecoration {
|
||||
pub fn new(colors: &Colors) -> Self {
|
||||
LineNumberDecoration {
|
||||
color: colors.line_number,
|
||||
cached_wrap_invalid_at: 10000,
|
||||
cached_wrap: DecorationText {
|
||||
text: colors.line_number.paint(" ".repeat(4)).to_string(),
|
||||
width: 4,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoration for LineNumberDecoration {
|
||||
fn generate(
|
||||
&self,
|
||||
line_number: usize,
|
||||
continuation: bool,
|
||||
_printer: &Printer,
|
||||
) -> DecorationText {
|
||||
if continuation {
|
||||
if line_number > self.cached_wrap_invalid_at {
|
||||
let new_width = self.cached_wrap.width + 1;
|
||||
return DecorationText {
|
||||
text: self.color.paint(" ".repeat(new_width)).to_string(),
|
||||
width: new_width,
|
||||
};
|
||||
}
|
||||
|
||||
self.cached_wrap.clone()
|
||||
} else {
|
||||
let plain: String = format!("{:4}", line_number);
|
||||
DecorationText {
|
||||
width: plain.len(),
|
||||
text: self.color.paint(plain).to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
4
|
||||
}
|
||||
}
|
||||
|
||||
// Line changes decoration.
|
||||
pub struct LineChangesDecoration {
|
||||
cached_none: DecorationText,
|
||||
cached_added: DecorationText,
|
||||
cached_removed_above: DecorationText,
|
||||
cached_removed_below: DecorationText,
|
||||
cached_modified: DecorationText,
|
||||
}
|
||||
|
||||
impl LineChangesDecoration {
|
||||
#[inline]
|
||||
fn generate_cached(style: Style, text: &str) -> DecorationText {
|
||||
DecorationText {
|
||||
text: style.paint(text).to_string(),
|
||||
width: text.chars().count(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(colors: &Colors) -> Self {
|
||||
LineChangesDecoration {
|
||||
cached_none: Self::generate_cached(Style::default(), " "),
|
||||
cached_added: Self::generate_cached(colors.git_added, "+"),
|
||||
cached_removed_above: Self::generate_cached(colors.git_removed, "‾"),
|
||||
cached_removed_below: Self::generate_cached(colors.git_removed, "_"),
|
||||
cached_modified: Self::generate_cached(colors.git_modified, "~"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoration for LineChangesDecoration {
|
||||
fn generate(
|
||||
&self,
|
||||
line_number: usize,
|
||||
continuation: bool,
|
||||
printer: &Printer,
|
||||
) -> DecorationText {
|
||||
if !continuation {
|
||||
if let Some(ref changes) = printer.line_changes {
|
||||
return match changes.get(&(line_number as u32)) {
|
||||
Some(&LineChange::Added) => self.cached_added.clone(),
|
||||
Some(&LineChange::RemovedAbove) => self.cached_removed_above.clone(),
|
||||
Some(&LineChange::RemovedBelow) => self.cached_removed_below.clone(),
|
||||
Some(&LineChange::Modified) => self.cached_modified.clone(),
|
||||
_ => self.cached_none.clone(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
self.cached_none.clone()
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.cached_none.width
|
||||
}
|
||||
}
|
||||
|
||||
// Grid border decoration.
|
||||
pub struct GridBorderDecoration {
|
||||
cached: DecorationText,
|
||||
}
|
||||
|
||||
impl GridBorderDecoration {
|
||||
pub fn new(colors: &Colors) -> Self {
|
||||
GridBorderDecoration {
|
||||
cached: DecorationText {
|
||||
text: colors.grid.paint("│").to_string(),
|
||||
width: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoration for GridBorderDecoration {
|
||||
fn generate(
|
||||
&self,
|
||||
_line_number: usize,
|
||||
_continuation: bool,
|
||||
_printer: &Printer,
|
||||
) -> DecorationText {
|
||||
self.cached.clone()
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.cached.width
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
use git2::{DiffOptions, IntoCString, Repository};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LineChange {
|
||||
Added,
|
||||
RemovedAbove,
|
||||
RemovedBelow,
|
||||
Modified,
|
||||
}
|
||||
|
||||
pub type LineChanges = HashMap<u32, LineChange>;
|
||||
|
||||
pub fn get_git_diff(filename: &str) -> Option<LineChanges> {
|
||||
let repo = Repository::discover(&filename).ok()?;
|
||||
let path_absolute = fs::canonicalize(&filename).ok()?;
|
||||
let path_relative_to_repo = path_absolute.strip_prefix(repo.workdir()?).ok()?;
|
||||
|
||||
let mut diff_options = DiffOptions::new();
|
||||
let pathspec = path_relative_to_repo.into_c_string().ok()?;
|
||||
diff_options.pathspec(pathspec);
|
||||
diff_options.context_lines(0);
|
||||
|
||||
let diff = repo
|
||||
.diff_index_to_workdir(None, Some(&mut diff_options))
|
||||
.ok()?;
|
||||
|
||||
let mut line_changes: LineChanges = HashMap::new();
|
||||
|
||||
let mark_section =
|
||||
|line_changes: &mut LineChanges, start: u32, end: i32, change: LineChange| {
|
||||
for line in start..(end + 1) as u32 {
|
||||
line_changes.insert(line, change);
|
||||
}
|
||||
};
|
||||
|
||||
let _ = diff.foreach(
|
||||
&mut |_, _| true,
|
||||
None,
|
||||
Some(&mut |delta, hunk| {
|
||||
let path = delta.new_file().path().unwrap_or_else(|| Path::new(""));
|
||||
|
||||
if path_relative_to_repo != path {
|
||||
return false;
|
||||
}
|
||||
|
||||
let old_lines = hunk.old_lines();
|
||||
let new_start = hunk.new_start();
|
||||
let new_lines = hunk.new_lines();
|
||||
let new_end = (new_start + new_lines) as i32 - 1;
|
||||
|
||||
if old_lines == 0 && new_lines > 0 {
|
||||
mark_section(&mut line_changes, new_start, new_end, LineChange::Added);
|
||||
} else if new_lines == 0 && old_lines > 0 {
|
||||
if new_start == 0 {
|
||||
mark_section(&mut line_changes, 1, 1, LineChange::RemovedAbove);
|
||||
} else {
|
||||
mark_section(
|
||||
&mut line_changes,
|
||||
new_start,
|
||||
new_start as i32,
|
||||
LineChange::RemovedBelow,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
mark_section(&mut line_changes, new_start, new_end, LineChange::Modified);
|
||||
}
|
||||
|
||||
true
|
||||
}),
|
||||
None,
|
||||
);
|
||||
|
||||
Some(line_changes)
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
use ansi_term::Colour::Green;
|
||||
use app::Config;
|
||||
use assets::HighlightingAssets;
|
||||
use diff::get_git_diff;
|
||||
use errors::*;
|
||||
use output::OutputType;
|
||||
use printer::Printer;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead, BufReader};
|
||||
use syntect::easy::HighlightLines;
|
||||
use syntect::highlighting::Theme;
|
||||
use syntect::parsing::SyntaxDefinition;
|
||||
|
||||
pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
|
||||
let mut languages = assets
|
||||
.syntax_set
|
||||
.syntaxes()
|
||||
.iter()
|
||||
.filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty())
|
||||
.collect::<Vec<_>>();
|
||||
languages.sort_by_key(|lang| lang.name.to_uppercase());
|
||||
|
||||
let longest = languages
|
||||
.iter()
|
||||
.map(|syntax| syntax.name.len())
|
||||
.max()
|
||||
.unwrap_or(32); // Fallback width if they have no language definitions.
|
||||
|
||||
let comma_separator = ", ";
|
||||
let separator = " ";
|
||||
// Line-wrapping for the possible file extension overflow.
|
||||
let desired_width = term_width - longest - separator.len();
|
||||
|
||||
for lang in languages {
|
||||
print!("{:width$}{}", lang.name, separator, width = longest);
|
||||
|
||||
// Number of characters on this line so far, wrap before `desired_width`
|
||||
let mut num_chars = 0;
|
||||
|
||||
let mut extension = lang.file_extensions.iter().peekable();
|
||||
while let Some(word) = extension.next() {
|
||||
// If we can't fit this word in, then create a line break and align it in.
|
||||
let new_chars = word.len() + comma_separator.len();
|
||||
if num_chars + new_chars >= desired_width {
|
||||
num_chars = 0;
|
||||
print!("\n{:width$}{}", "", separator, width = longest);
|
||||
}
|
||||
|
||||
num_chars += new_chars;
|
||||
print!("{}", Green.paint(&word[..]));
|
||||
if extension.peek().is_some() {
|
||||
print!("{}", comma_separator);
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_files(assets: &HighlightingAssets, config: &Config) -> Result<bool> {
|
||||
let theme = assets.get_theme(config.theme.unwrap_or("Default"))?;
|
||||
let mut output_type = OutputType::from_mode(config.paging_mode);
|
||||
let handle = output_type.handle()?;
|
||||
let mut printer = Printer::new(handle, &config);
|
||||
let mut no_errors: bool = true;
|
||||
|
||||
for file in &config.files {
|
||||
printer.line_changes = file.and_then(|filename| get_git_diff(filename));
|
||||
let syntax = assets.get_syntax(config.language, *file);
|
||||
|
||||
let result = print_file(theme, &syntax, &mut printer, *file);
|
||||
|
||||
if let Err(error) = result {
|
||||
handle_error(&error);
|
||||
no_errors = false;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(no_errors)
|
||||
}
|
||||
|
||||
fn print_file(
|
||||
theme: &Theme,
|
||||
syntax: &SyntaxDefinition,
|
||||
printer: &mut Printer,
|
||||
filename: Option<&str>,
|
||||
) -> Result<()> {
|
||||
let stdin = io::stdin(); // TODO: this is not always needed
|
||||
|
||||
let mut reader: Box<BufRead> = match filename {
|
||||
None => Box::new(stdin.lock()),
|
||||
Some(filename) => Box::new(BufReader::new(File::open(filename)?)),
|
||||
};
|
||||
|
||||
let mut highlighter = HighlightLines::new(syntax, theme);
|
||||
|
||||
printer.print_header(filename)?;
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
while reader.read_until(b'\n', &mut buffer)? > 0 {
|
||||
{
|
||||
let line = String::from_utf8_lossy(&buffer);
|
||||
let regions = highlighter.highlight(line.as_ref());
|
||||
|
||||
printer.print_line(®ions)?;
|
||||
}
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
printer.print_footer()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+103
-204
@@ -1,223 +1,122 @@
|
||||
extern crate ansi_term;
|
||||
extern crate atty;
|
||||
extern crate console;
|
||||
extern crate git2;
|
||||
extern crate syntect;
|
||||
// `error_chain!` can recurse deeply
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::io::{self, BufRead, ErrorKind, Result, StdoutLock, Write};
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
extern crate ansi_term;
|
||||
extern crate atty;
|
||||
extern crate console;
|
||||
extern crate directories;
|
||||
extern crate git2;
|
||||
extern crate syntect;
|
||||
|
||||
mod app;
|
||||
mod assets;
|
||||
mod decorations;
|
||||
mod diff;
|
||||
mod features;
|
||||
mod output;
|
||||
mod printer;
|
||||
mod style;
|
||||
mod terminal;
|
||||
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
|
||||
use ansi_term::Colour::{Fixed, Green, Red, White, Yellow};
|
||||
use ansi_term::Style;
|
||||
use atty::Stream;
|
||||
use clap::{App, AppSettings, Arg, ArgMatches};
|
||||
use console::Term;
|
||||
use git2::{DiffOptions, IntoCString, Repository};
|
||||
use app::App;
|
||||
use assets::{clear_assets, config_dir, HighlightingAssets};
|
||||
use features::{list_languages, print_files};
|
||||
|
||||
use syntect::easy::HighlightFile;
|
||||
use syntect::highlighting::{Theme, ThemeSet};
|
||||
use syntect::parsing::SyntaxSet;
|
||||
use syntect::util::as_24_bit_terminal_escaped;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum LineChange {
|
||||
Added,
|
||||
RemovedAbove,
|
||||
RemovedBelow,
|
||||
Modified,
|
||||
}
|
||||
|
||||
type LineChanges = HashMap<u32, LineChange>;
|
||||
|
||||
const PANEL_WIDTH: usize = 7;
|
||||
const GRID_COLOR: u8 = 238;
|
||||
|
||||
fn print_horizontal_line(
|
||||
handle: &mut StdoutLock,
|
||||
grid_char: char,
|
||||
term_width: usize,
|
||||
) -> io::Result<()> {
|
||||
let bar = "─".repeat(term_width - (PANEL_WIDTH + 1));
|
||||
let line = format!("{}{}{}", "─".repeat(PANEL_WIDTH), grid_char, bar);
|
||||
|
||||
write!(handle, "{}\n", Fixed(GRID_COLOR).paint(line))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_file<P: AsRef<Path>>(
|
||||
theme: &Theme,
|
||||
syntax_set: &SyntaxSet,
|
||||
filename: P,
|
||||
line_changes: Option<LineChanges>,
|
||||
) -> io::Result<()> {
|
||||
let mut highlighter = HighlightFile::new(filename.as_ref().clone(), syntax_set, theme)?;
|
||||
|
||||
let stdout = io::stdout();
|
||||
let mut handle = stdout.lock();
|
||||
|
||||
let term = Term::stdout();
|
||||
let (_, term_width) = term.size();
|
||||
let term_width = term_width as usize;
|
||||
|
||||
print_horizontal_line(&mut handle, '┬', term_width)?;
|
||||
|
||||
write!(
|
||||
handle,
|
||||
"{}{} {}\n",
|
||||
" ".repeat(PANEL_WIDTH),
|
||||
Fixed(GRID_COLOR).paint("│"),
|
||||
White.bold().paint(filename.as_ref().to_string_lossy())
|
||||
)?;
|
||||
|
||||
print_horizontal_line(&mut handle, '┼', term_width)?;
|
||||
|
||||
for (idx, maybe_line) in highlighter.reader.lines().enumerate() {
|
||||
let line_nr = idx + 1;
|
||||
let line = maybe_line.unwrap_or("<INVALID UTF-8>".into());
|
||||
let regions = highlighter.highlight_lines.highlight(&line);
|
||||
|
||||
let line_change = if let Some(ref changes) = line_changes {
|
||||
match changes.get(&(line_nr as u32)) {
|
||||
Some(&LineChange::Added) => Green.paint("+"),
|
||||
Some(&LineChange::RemovedAbove) => Red.paint("‾"),
|
||||
Some(&LineChange::RemovedBelow) => Red.paint("_"),
|
||||
Some(&LineChange::Modified) => Yellow.paint("~"),
|
||||
_ => Style::default().paint(" "),
|
||||
}
|
||||
} else {
|
||||
Style::default().paint(" ")
|
||||
};
|
||||
|
||||
write!(
|
||||
handle,
|
||||
"{} {} {} {}\n",
|
||||
Fixed(244).paint(format!("{:4}", line_nr)),
|
||||
line_change,
|
||||
Fixed(GRID_COLOR).paint("│"),
|
||||
as_24_bit_terminal_escaped(®ions, false)
|
||||
)?;
|
||||
}
|
||||
|
||||
print_horizontal_line(&mut handle, '┴', term_width)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_git_diff(filename: String) -> Option<LineChanges> {
|
||||
let repo = Repository::open_from_env().ok()?;
|
||||
|
||||
let mut diff_options = DiffOptions::new();
|
||||
diff_options.pathspec(filename.into_c_string().ok()?);
|
||||
diff_options.context_lines(0);
|
||||
|
||||
let diff = repo.diff_index_to_workdir(None, Some(&mut diff_options))
|
||||
.ok()?;
|
||||
|
||||
let mut line_changes: LineChanges = HashMap::new();
|
||||
|
||||
let mark_section =
|
||||
|line_changes: &mut LineChanges, start: u32, end: i32, change: LineChange| {
|
||||
for line in start..(end + 1) as u32 {
|
||||
line_changes.insert(line, change);
|
||||
}
|
||||
};
|
||||
|
||||
let _ = diff.foreach(
|
||||
&mut |_, _| true,
|
||||
None,
|
||||
Some(&mut |_, hunk| {
|
||||
let old_lines = hunk.old_lines();
|
||||
let new_start = hunk.new_start();
|
||||
let new_lines = hunk.new_lines();
|
||||
let new_end = (new_start + new_lines) as i32 - 1;
|
||||
|
||||
if old_lines == 0 && new_lines > 0 {
|
||||
mark_section(&mut line_changes, new_start, new_end, LineChange::Added);
|
||||
} else if new_lines == 0 && old_lines > 0 {
|
||||
if new_start <= 0 {
|
||||
mark_section(&mut line_changes, 1, 1, LineChange::RemovedAbove);
|
||||
} else {
|
||||
mark_section(
|
||||
&mut line_changes,
|
||||
new_start,
|
||||
new_start as i32,
|
||||
LineChange::RemovedBelow,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
mark_section(&mut line_changes, new_start, new_end, LineChange::Modified);
|
||||
}
|
||||
|
||||
true
|
||||
}),
|
||||
None,
|
||||
);
|
||||
|
||||
Some(line_changes)
|
||||
}
|
||||
|
||||
fn run(matches: &ArgMatches) -> Result<()> {
|
||||
let home_dir = env::home_dir().ok_or(io::Error::new(
|
||||
ErrorKind::Other,
|
||||
"Could not get home directory",
|
||||
))?;
|
||||
|
||||
let theme_dir = home_dir.join(".config").join("bat").join("themes");
|
||||
let theme_set = ThemeSet::load_from_folder(theme_dir)
|
||||
.map_err(|_| io::Error::new(ErrorKind::Other, "Could not load themes"))?;
|
||||
let theme = &theme_set.themes["Monokai"];
|
||||
|
||||
let syntax_set = SyntaxSet::load_defaults_nonewlines();
|
||||
|
||||
if let Some(files) = matches.values_of("FILE") {
|
||||
for file in files {
|
||||
let line_changes = get_git_diff(file.to_string());
|
||||
print_file(theme, &syntax_set, file, line_changes)?;
|
||||
mod errors {
|
||||
error_chain! {
|
||||
foreign_links {
|
||||
Clap(::clap::Error);
|
||||
Io(::std::io::Error);
|
||||
SyntectError(::syntect::LoadingError);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
pub fn handle_error(error: &Error) {
|
||||
match error {
|
||||
&Error(ErrorKind::Io(ref io_error), _)
|
||||
if io_error.kind() == super::io::ErrorKind::BrokenPipe =>
|
||||
{
|
||||
super::process::exit(0);
|
||||
}
|
||||
_ => {
|
||||
use ansi_term::Colour::Red;
|
||||
eprintln!("{}: {}", Red.paint("[bat error]"), error);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
use errors::*;
|
||||
|
||||
/// 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();
|
||||
|
||||
match app.matches.subcommand() {
|
||||
("cache", Some(cache_matches)) => {
|
||||
if cache_matches.is_present("init") {
|
||||
let source_dir = cache_matches.value_of("source").map(Path::new);
|
||||
let target_dir = cache_matches.value_of("target").map(Path::new);
|
||||
|
||||
let assets = HighlightingAssets::from_files(source_dir)?;
|
||||
assets.save(target_dir)?;
|
||||
} else if cache_matches.is_present("clear") {
|
||||
clear_assets();
|
||||
} else if cache_matches.is_present("config-dir") {
|
||||
println!("{}", config_dir());
|
||||
}
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
_ => {
|
||||
let config = app.config()?;
|
||||
let assets = HighlightingAssets::new();
|
||||
|
||||
if app.matches.is_present("list-languages") {
|
||||
list_languages(&assets, config.term_width);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if app.matches.is_present("list-themes") {
|
||||
let themes = &assets.theme_set.themes;
|
||||
for (theme, _) in themes.iter() {
|
||||
println!("{}", theme);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
print_files(&assets, &config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let clap_color_setting = if atty::is(Stream::Stdout) {
|
||||
AppSettings::ColoredHelp
|
||||
} else {
|
||||
AppSettings::ColorNever
|
||||
};
|
||||
let result = run();
|
||||
|
||||
let matches = App::new(crate_name!())
|
||||
.version(crate_version!())
|
||||
.setting(clap_color_setting)
|
||||
.setting(AppSettings::DeriveDisplayOrder)
|
||||
.setting(AppSettings::UnifiedHelpMessage)
|
||||
.setting(AppSettings::NextLineHelp)
|
||||
.setting(AppSettings::DisableVersion)
|
||||
.max_term_width(90)
|
||||
.about(crate_description!())
|
||||
.arg(
|
||||
Arg::with_name("FILE")
|
||||
.help("File(s) to print")
|
||||
.multiple(true)
|
||||
.empty_values(false),
|
||||
)
|
||||
.help_message("Print this help message.")
|
||||
.version_message("Show version information.")
|
||||
.get_matches();
|
||||
|
||||
let result = run(&matches);
|
||||
|
||||
if let Err(e) = result {
|
||||
if e.kind() != ErrorKind::BrokenPipe {
|
||||
eprintln!("{}: {}", Red.paint("[bat error]"), e);
|
||||
match result {
|
||||
Err(error) => {
|
||||
handle_error(&error);
|
||||
process::exit(1);
|
||||
}
|
||||
Ok(false) => {
|
||||
process::exit(1);
|
||||
}
|
||||
Ok(true) => {
|
||||
process::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
use app::PagingMode;
|
||||
use errors::*;
|
||||
use std::io::{self, Write};
|
||||
use std::process::{Child, Command, Stdio};
|
||||
|
||||
pub enum OutputType {
|
||||
Pager(Child),
|
||||
Stdout(io::Stdout),
|
||||
}
|
||||
|
||||
impl OutputType {
|
||||
pub fn from_mode(mode: PagingMode) -> Self {
|
||||
use self::PagingMode::*;
|
||||
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 {
|
||||
let mut args = vec!["--RAW-CONTROL-CHARS", "--no-init"];
|
||||
if quit_if_one_screen {
|
||||
args.push("--quit-if-one-screen");
|
||||
}
|
||||
Command::new("less")
|
||||
.args(&args)
|
||||
.env("LESSCHARSET", "UTF-8")
|
||||
.stdin(Stdio::piped())
|
||||
.spawn()
|
||||
.map(OutputType::Pager)
|
||||
.unwrap_or_else(|_| OutputType::stdout())
|
||||
}
|
||||
|
||||
fn stdout() -> Self {
|
||||
OutputType::Stdout(io::stdout())
|
||||
}
|
||||
|
||||
pub fn handle(&mut self) -> Result<&mut Write> {
|
||||
Ok(match *self {
|
||||
OutputType::Pager(ref mut command) => command
|
||||
.stdin
|
||||
.as_mut()
|
||||
.chain_err(|| "Could not open stdin for pager")?,
|
||||
OutputType::Stdout(ref mut handle) => handle,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for OutputType {
|
||||
fn drop(&mut self) {
|
||||
if let OutputType::Pager(ref mut command) = *self {
|
||||
let _ = command.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
use ansi_term::Colour::{Fixed, Green, Red, White, Yellow};
|
||||
use ansi_term::Style;
|
||||
use app::Config;
|
||||
use console::AnsiCodeIterator;
|
||||
use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration};
|
||||
use diff::LineChanges;
|
||||
use errors::*;
|
||||
use std::boxed::Box;
|
||||
use std::io::Write;
|
||||
use std::vec::Vec;
|
||||
use style::OutputWrap;
|
||||
use syntect::highlighting;
|
||||
use terminal::as_terminal_escaped;
|
||||
|
||||
pub struct Printer<'a> {
|
||||
handle: &'a mut Write,
|
||||
colors: Colors,
|
||||
config: &'a Config<'a>,
|
||||
decorations: Vec<Box<Decoration>>,
|
||||
panel_width: usize,
|
||||
line_number: usize,
|
||||
pub line_changes: Option<LineChanges>,
|
||||
}
|
||||
|
||||
impl<'a> Printer<'a> {
|
||||
pub fn new(handle: &'a mut Write, config: &'a Config) -> Self {
|
||||
let colors = if config.colored_output {
|
||||
Colors::colored()
|
||||
} else {
|
||||
Colors::plain()
|
||||
};
|
||||
|
||||
// Create decorations.
|
||||
let mut decorations: Vec<Box<Decoration>> = Vec::new();
|
||||
|
||||
if config.output_components.numbers() {
|
||||
decorations.push(Box::new(LineNumberDecoration::new(&colors)));
|
||||
}
|
||||
|
||||
if config.output_components.changes() {
|
||||
decorations.push(Box::new(LineChangesDecoration::new(&colors)));
|
||||
}
|
||||
|
||||
let mut panel_width: usize =
|
||||
decorations.len() + decorations.iter().fold(0, |a, x| a + x.width());
|
||||
|
||||
// The grid border decoration isn't added until after the panel_width calculation, since the
|
||||
// print_horizontal_line, print_header, and print_footer functions all assume the panel
|
||||
// width is without the grid border.
|
||||
if config.output_components.grid() && !decorations.is_empty() {
|
||||
decorations.push(Box::new(GridBorderDecoration::new(&colors)));
|
||||
}
|
||||
|
||||
// Disable the panel if the terminal is too small (i.e. can't fit 5 characters with the
|
||||
// panel showing).
|
||||
if config.term_width
|
||||
< (decorations.len() + decorations.iter().fold(0, |a, x| a + x.width())) + 5
|
||||
{
|
||||
decorations.clear();
|
||||
panel_width = 0;
|
||||
}
|
||||
|
||||
// Create printer.
|
||||
Printer {
|
||||
panel_width,
|
||||
handle,
|
||||
colors,
|
||||
config,
|
||||
decorations,
|
||||
line_number: 0,
|
||||
line_changes: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_header(&mut self, filename: Option<&str>) -> Result<()> {
|
||||
self.line_number = 0;
|
||||
|
||||
if !self.config.output_components.header() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if self.config.output_components.grid() {
|
||||
self.print_horizontal_line('┬')?;
|
||||
|
||||
write!(
|
||||
self.handle,
|
||||
"{}{}",
|
||||
" ".repeat(self.panel_width),
|
||||
self.colors
|
||||
.grid
|
||||
.paint(if self.panel_width > 0 { "│ " } else { "" }),
|
||||
)?;
|
||||
} else {
|
||||
write!(self.handle, "{}", " ".repeat(self.panel_width))?;
|
||||
}
|
||||
|
||||
writeln!(
|
||||
self.handle,
|
||||
"{}{}",
|
||||
filename.map_or("", |_| "File: "),
|
||||
self.colors.filename.paint(filename.unwrap_or("STDIN"))
|
||||
)?;
|
||||
|
||||
if self.config.output_components.grid() {
|
||||
self.print_horizontal_line('┼')?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_footer(&mut self) -> Result<()> {
|
||||
if self.config.output_components.grid() {
|
||||
self.print_horizontal_line('┴')
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_line(&mut self, regions: &[(highlighting::Style, &str)]) -> Result<()> {
|
||||
self.line_number += 1;
|
||||
let mut cursor: usize = 0;
|
||||
let mut cursor_max: usize = self.config.term_width;
|
||||
let mut panel_wrap: Option<String> = None;
|
||||
|
||||
// Line decorations.
|
||||
if self.panel_width > 0 {
|
||||
let decorations = self
|
||||
.decorations
|
||||
.iter()
|
||||
.map(|ref d| d.generate(self.line_number, false, self))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for deco in decorations {
|
||||
write!(self.handle, "{} ", deco.text)?;
|
||||
cursor_max -= deco.width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Line contents.
|
||||
if self.config.output_wrap == OutputWrap::None {
|
||||
let true_color = self.config.true_color;
|
||||
let colored_output = self.config.colored_output;
|
||||
|
||||
write!(
|
||||
self.handle,
|
||||
"{}",
|
||||
regions
|
||||
.iter()
|
||||
.map(|&(style, text)| as_terminal_escaped(
|
||||
style,
|
||||
text,
|
||||
true_color,
|
||||
colored_output,
|
||||
))
|
||||
.collect::<Vec<_>>()
|
||||
.join("")
|
||||
)?;
|
||||
} else {
|
||||
for &(style, region) in regions.iter() {
|
||||
let mut ansi_iterator = AnsiCodeIterator::new(region);
|
||||
let mut ansi_prefix = "";
|
||||
for chunk in ansi_iterator {
|
||||
match chunk {
|
||||
// ANSI escape passthrough.
|
||||
(text, true) => {
|
||||
ansi_prefix = text;
|
||||
}
|
||||
|
||||
// Regular text.
|
||||
(text, false) => {
|
||||
let text = text.trim_right_matches(|c| c == '\r' || c == '\n');
|
||||
let mut chars = text.chars();
|
||||
let mut remaining = text.chars().count();
|
||||
|
||||
while remaining > 0 {
|
||||
let available = cursor_max - cursor;
|
||||
|
||||
// It fits.
|
||||
if remaining <= available {
|
||||
let text = chars.by_ref().take(remaining).collect::<String>();
|
||||
cursor += remaining;
|
||||
|
||||
write!(
|
||||
self.handle,
|
||||
"{}",
|
||||
as_terminal_escaped(
|
||||
style,
|
||||
&*format!("{}{}", ansi_prefix, text),
|
||||
self.config.true_color,
|
||||
self.config.colored_output,
|
||||
)
|
||||
)?;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate wrap padding if not already generated.
|
||||
if panel_wrap.is_none() {
|
||||
panel_wrap = if self.panel_width > 0 {
|
||||
Some(format!(
|
||||
"{} ",
|
||||
self.decorations
|
||||
.iter()
|
||||
.map(|ref d| d
|
||||
.generate(self.line_number, true, self)
|
||||
.text)
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
))
|
||||
} else {
|
||||
Some("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
// It wraps.
|
||||
let text = chars.by_ref().take(available).collect::<String>();
|
||||
cursor = 0;
|
||||
remaining -= available;
|
||||
|
||||
write!(
|
||||
self.handle,
|
||||
"{}\n{}",
|
||||
as_terminal_escaped(
|
||||
style,
|
||||
&*format!("{}{}", ansi_prefix, text),
|
||||
self.config.true_color,
|
||||
self.config.colored_output,
|
||||
),
|
||||
panel_wrap.clone().unwrap()
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write!(self.handle, "\n")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_horizontal_line(&mut self, grid_char: char) -> Result<()> {
|
||||
if self.panel_width == 0 {
|
||||
writeln!(
|
||||
self.handle,
|
||||
"{}",
|
||||
self.colors.grid.paint("─".repeat(self.config.term_width))
|
||||
)?;
|
||||
} else {
|
||||
let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
|
||||
let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
|
||||
writeln!(self.handle, "{}", self.colors.grid.paint(hline))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const GRID_COLOR: u8 = 238;
|
||||
const LINE_NUMBER_COLOR: u8 = 244;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Colors {
|
||||
pub grid: Style,
|
||||
pub filename: Style,
|
||||
pub git_added: Style,
|
||||
pub git_removed: Style,
|
||||
pub git_modified: Style,
|
||||
pub line_number: Style,
|
||||
}
|
||||
|
||||
impl Colors {
|
||||
fn plain() -> Self {
|
||||
Colors::default()
|
||||
}
|
||||
|
||||
fn colored() -> Self {
|
||||
Colors {
|
||||
grid: Fixed(GRID_COLOR).normal(),
|
||||
filename: White.bold(),
|
||||
git_added: Green.normal(),
|
||||
git_removed: Red.normal(),
|
||||
git_modified: Yellow.normal(),
|
||||
line_number: Fixed(LINE_NUMBER_COLOR).normal(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use errors::*;
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
|
||||
pub enum OutputComponent {
|
||||
Auto,
|
||||
Changes,
|
||||
Grid,
|
||||
Header,
|
||||
Numbers,
|
||||
Full,
|
||||
Plain,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
|
||||
pub enum OutputWrap {
|
||||
Character,
|
||||
None,
|
||||
}
|
||||
|
||||
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::Changes => &[OutputComponent::Changes],
|
||||
OutputComponent::Grid => &[OutputComponent::Grid],
|
||||
OutputComponent::Header => &[OutputComponent::Header],
|
||||
OutputComponent::Numbers => &[OutputComponent::Numbers],
|
||||
OutputComponent::Full => &[
|
||||
OutputComponent::Changes,
|
||||
OutputComponent::Grid,
|
||||
OutputComponent::Header,
|
||||
OutputComponent::Numbers,
|
||||
],
|
||||
OutputComponent::Plain => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OutputComponent {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
match s {
|
||||
"auto" => Ok(OutputComponent::Auto),
|
||||
"changes" => Ok(OutputComponent::Changes),
|
||||
"grid" => Ok(OutputComponent::Grid),
|
||||
"header" => Ok(OutputComponent::Header),
|
||||
"numbers" => Ok(OutputComponent::Numbers),
|
||||
"full" => Ok(OutputComponent::Full),
|
||||
"plain" | _ => Ok(OutputComponent::Plain),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OutputComponents(pub HashSet<OutputComponent>);
|
||||
|
||||
impl OutputComponents {
|
||||
pub fn changes(&self) -> bool {
|
||||
self.0.contains(&OutputComponent::Changes)
|
||||
}
|
||||
|
||||
pub fn grid(&self) -> bool {
|
||||
self.0.contains(&OutputComponent::Grid)
|
||||
}
|
||||
|
||||
pub fn header(&self) -> bool {
|
||||
self.0.contains(&OutputComponent::Header)
|
||||
}
|
||||
|
||||
pub fn numbers(&self) -> bool {
|
||||
self.0.contains(&OutputComponent::Numbers)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use ansi_term::Colour::{Fixed, RGB};
|
||||
use ansi_term::Style;
|
||||
use syntect::highlighting::{self, FontStyle};
|
||||
|
||||
/// Approximate a 24 bit color value by a 8 bit ANSI code
|
||||
fn rgb2ansi(r: u8, g: u8, b: u8) -> u8 {
|
||||
const BLACK: u8 = 16;
|
||||
const WHITE: u8 = 231;
|
||||
|
||||
if r == g && g == b {
|
||||
if r < 8 {
|
||||
BLACK
|
||||
} else if r > 248 {
|
||||
WHITE
|
||||
} else {
|
||||
let fr = f32::from(r);
|
||||
(((fr - 8.) / 247.) * 24.) as u8 + 232
|
||||
}
|
||||
} else {
|
||||
let fr = f32::from(r);
|
||||
let fg = f32::from(g);
|
||||
let fb = f32::from(b);
|
||||
16 + (36 * (fr / 255. * 5.) as u8) + (6 * (fg / 255. * 5.) as u8) + (fb / 255. * 5.) as u8
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_terminal_escaped(
|
||||
style: highlighting::Style,
|
||||
text: &str,
|
||||
true_color: bool,
|
||||
colored: bool,
|
||||
) -> String {
|
||||
let style = if !colored {
|
||||
Style::default()
|
||||
} else {
|
||||
let color = if true_color {
|
||||
RGB(style.foreground.r, style.foreground.g, style.foreground.b)
|
||||
} else {
|
||||
let ansi = rgb2ansi(style.foreground.r, style.foreground.g, style.foreground.b);
|
||||
Fixed(ansi)
|
||||
};
|
||||
|
||||
if style.font_style.contains(FontStyle::BOLD) {
|
||||
color.bold()
|
||||
} else if style.font_style.contains(FontStyle::UNDERLINE) {
|
||||
color.underline()
|
||||
} else if style.font_style.contains(FontStyle::ITALIC) {
|
||||
color.italic()
|
||||
} else {
|
||||
color.normal()
|
||||
}
|
||||
};
|
||||
|
||||
style.paint(text).to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rgb2ansi_black_white() {
|
||||
assert_eq!(16, rgb2ansi(0x00, 0x00, 0x00));
|
||||
assert_eq!(231, rgb2ansi(0xff, 0xff, 0xff));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rgb2ansi_gray() {
|
||||
assert_eq!(241, rgb2ansi(0x6c, 0x6c, 0x6c));
|
||||
assert_eq!(233, rgb2ansi(0x1c, 0x1c, 0x1c));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rgb2ansi_color() {
|
||||
assert_eq!(96, rgb2ansi(0x87, 0x5f, 0x87));
|
||||
assert_eq!(141, rgb2ansi(0xaf, 0x87, 0xff));
|
||||
assert_eq!(193, rgb2ansi(0xd7, 0xff, 0xaf));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rgb2ansi_approx() {
|
||||
assert_eq!(231, rgb2ansi(0xfe, 0xfe, 0xfe));
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
test-src/* linguist-vendored
|
||||
@@ -0,0 +1 @@
|
||||
test-src/*
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! which hyperfine > /dev/null 2>&1; then
|
||||
echo "'hyperfine' does not seem to be installed."
|
||||
echo "You can get it here: https://github.com/sharkdp/hyperfine"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SRC="test-src/jquery-3.3.1.js"
|
||||
|
||||
|
||||
cmd_bat="bat --style=full --color=always --paging=never '$SRC'"
|
||||
cmd_pygmentize="pygmentize -g '$SRC'"
|
||||
cmd_highlight="highlight -O truecolor '$SRC'"
|
||||
cmd_ccat="ccat --color=always '$SRC'"
|
||||
cmd_source_highlight="source-highlight --failsafe --infer-lang -f esc -i '$SRC'"
|
||||
cmd_hicat="hicat '$SRC'"
|
||||
cmd_coderay="coderay '$SRC'"
|
||||
cmd_rouge="rougify '$SRC'"
|
||||
|
||||
hyperfine --warmup 3 \
|
||||
"$cmd_bat" \
|
||||
"$cmd_pygmentize" \
|
||||
"$cmd_highlight" \
|
||||
"$cmd_ccat" \
|
||||
"$cmd_source_highlight" \
|
||||
"$cmd_hicat" \
|
||||
"$cmd_coderay" \
|
||||
"$cmd_rouge" \
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! which hyperfine > /dev/null 2>&1; then
|
||||
echo "'hyperfine' does not seem to be installed."
|
||||
echo "You can get it here: https://github.com/sharkdp/hyperfine"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "### Startup time"
|
||||
echo
|
||||
|
||||
hyperfine --warmup 3 bat
|
||||
|
||||
echo
|
||||
echo "### Plain text"
|
||||
echo
|
||||
|
||||
hyperfine --warmup 3 "bat --language txt --paging=never 'test-src/jquery-3.3.1.js'"
|
||||
|
||||
echo
|
||||
echo "### Time to syntax-highlight large files"
|
||||
echo
|
||||
|
||||
for SRC in test-src/*; do
|
||||
hyperfine --warmup 3 "bat --style=full --color=always --paging=never '$SRC'"
|
||||
done
|
||||
+10364
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Vendored
+602
@@ -0,0 +1,602 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||
* Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
|
||||
typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
|
||||
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------- zlib-style API's */
|
||||
|
||||
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
|
||||
{
|
||||
mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
|
||||
size_t block_len = buf_len % 5552;
|
||||
if (!ptr)
|
||||
return MZ_ADLER32_INIT;
|
||||
while (buf_len)
|
||||
{
|
||||
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
|
||||
{
|
||||
s1 += ptr[0], s2 += s1;
|
||||
s1 += ptr[1], s2 += s1;
|
||||
s1 += ptr[2], s2 += s1;
|
||||
s1 += ptr[3], s2 += s1;
|
||||
s1 += ptr[4], s2 += s1;
|
||||
s1 += ptr[5], s2 += s1;
|
||||
s1 += ptr[6], s2 += s1;
|
||||
s1 += ptr[7], s2 += s1;
|
||||
}
|
||||
for (; i < block_len; ++i)
|
||||
s1 += *ptr++, s2 += s1;
|
||||
s1 %= 65521U, s2 %= 65521U;
|
||||
buf_len -= block_len;
|
||||
block_len = 5552;
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
||||
|
||||
/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */
|
||||
#if 0
|
||||
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
|
||||
{
|
||||
static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
|
||||
mz_uint32 crcu32 = (mz_uint32)crc;
|
||||
if (!ptr)
|
||||
return MZ_CRC32_INIT;
|
||||
crcu32 = ~crcu32;
|
||||
while (buf_len--)
|
||||
{
|
||||
mz_uint8 b = *ptr++;
|
||||
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
|
||||
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
|
||||
}
|
||||
return ~crcu32;
|
||||
}
|
||||
#else
|
||||
/* Faster, but larger CPU cache footprint.
|
||||
*/
|
||||
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
|
||||
{
|
||||
static const mz_uint32 s_crc_table[256] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
|
||||
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
|
||||
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
|
||||
0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
|
||||
0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
|
||||
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
|
||||
0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
|
||||
0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
|
||||
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
|
||||
0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
|
||||
0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
|
||||
0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
|
||||
0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
|
||||
0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
|
||||
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
|
||||
0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
|
||||
0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
|
||||
0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
|
||||
0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
|
||||
0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
|
||||
0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
|
||||
0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
|
||||
0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
|
||||
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
|
||||
0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
|
||||
0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
|
||||
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
|
||||
0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
|
||||
const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
|
||||
|
||||
while (buf_len >= 4)
|
||||
{
|
||||
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
|
||||
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
|
||||
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
|
||||
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
|
||||
pByte_buf += 4;
|
||||
buf_len -= 4;
|
||||
}
|
||||
|
||||
while (buf_len)
|
||||
{
|
||||
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
|
||||
++pByte_buf;
|
||||
--buf_len;
|
||||
}
|
||||
|
||||
return ~crc32;
|
||||
}
|
||||
#endif
|
||||
|
||||
void mz_free(void *p)
|
||||
{
|
||||
MZ_FREE(p);
|
||||
}
|
||||
|
||||
void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
|
||||
{
|
||||
(void)opaque, (void)items, (void)size;
|
||||
return MZ_MALLOC(items * size);
|
||||
}
|
||||
void miniz_def_free_func(void *opaque, void *address)
|
||||
{
|
||||
(void)opaque, (void)address;
|
||||
MZ_FREE(address);
|
||||
}
|
||||
void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
|
||||
{
|
||||
(void)opaque, (void)address, (void)items, (void)size;
|
||||
return MZ_REALLOC(address, items * size);
|
||||
}
|
||||
|
||||
const char *mz_version(void)
|
||||
{
|
||||
return MZ_VERSION;
|
||||
}
|
||||
|
||||
#ifndef MINIZ_NO_ZLIB_APIS
|
||||
|
||||
int mz_deflateInit(mz_streamp pStream, int level)
|
||||
{
|
||||
return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
|
||||
}
|
||||
|
||||
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
|
||||
{
|
||||
tdefl_compressor *pComp;
|
||||
mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
|
||||
|
||||
if (!pStream)
|
||||
return MZ_STREAM_ERROR;
|
||||
if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
pStream->data_type = 0;
|
||||
pStream->adler = MZ_ADLER32_INIT;
|
||||
pStream->msg = NULL;
|
||||
pStream->reserved = 0;
|
||||
pStream->total_in = 0;
|
||||
pStream->total_out = 0;
|
||||
if (!pStream->zalloc)
|
||||
pStream->zalloc = miniz_def_alloc_func;
|
||||
if (!pStream->zfree)
|
||||
pStream->zfree = miniz_def_free_func;
|
||||
|
||||
pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
|
||||
if (!pComp)
|
||||
return MZ_MEM_ERROR;
|
||||
|
||||
pStream->state = (struct mz_internal_state *)pComp;
|
||||
|
||||
if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
|
||||
{
|
||||
mz_deflateEnd(pStream);
|
||||
return MZ_PARAM_ERROR;
|
||||
}
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_deflateReset(mz_streamp pStream)
|
||||
{
|
||||
if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
|
||||
return MZ_STREAM_ERROR;
|
||||
pStream->total_in = pStream->total_out = 0;
|
||||
tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_deflate(mz_streamp pStream, int flush)
|
||||
{
|
||||
size_t in_bytes, out_bytes;
|
||||
mz_ulong orig_total_in, orig_total_out;
|
||||
int mz_status = MZ_OK;
|
||||
|
||||
if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
|
||||
return MZ_STREAM_ERROR;
|
||||
if (!pStream->avail_out)
|
||||
return MZ_BUF_ERROR;
|
||||
|
||||
if (flush == MZ_PARTIAL_FLUSH)
|
||||
flush = MZ_SYNC_FLUSH;
|
||||
|
||||
if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
|
||||
return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
|
||||
|
||||
orig_total_in = pStream->total_in;
|
||||
orig_total_out = pStream->total_out;
|
||||
for (;;)
|
||||
{
|
||||
tdefl_status defl_status;
|
||||
in_bytes = pStream->avail_in;
|
||||
out_bytes = pStream->avail_out;
|
||||
|
||||
defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
|
||||
pStream->next_in += (mz_uint)in_bytes;
|
||||
pStream->avail_in -= (mz_uint)in_bytes;
|
||||
pStream->total_in += (mz_uint)in_bytes;
|
||||
pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
|
||||
|
||||
pStream->next_out += (mz_uint)out_bytes;
|
||||
pStream->avail_out -= (mz_uint)out_bytes;
|
||||
pStream->total_out += (mz_uint)out_bytes;
|
||||
|
||||
if (defl_status < 0)
|
||||
{
|
||||
mz_status = MZ_STREAM_ERROR;
|
||||
break;
|
||||
}
|
||||
else if (defl_status == TDEFL_STATUS_DONE)
|
||||
{
|
||||
mz_status = MZ_STREAM_END;
|
||||
break;
|
||||
}
|
||||
else if (!pStream->avail_out)
|
||||
break;
|
||||
else if ((!pStream->avail_in) && (flush != MZ_FINISH))
|
||||
{
|
||||
if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
|
||||
break;
|
||||
return MZ_BUF_ERROR; /* Can't make forward progress without some input.
|
||||
*/
|
||||
}
|
||||
}
|
||||
return mz_status;
|
||||
}
|
||||
|
||||
int mz_deflateEnd(mz_streamp pStream)
|
||||
{
|
||||
if (!pStream)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (pStream->state)
|
||||
{
|
||||
pStream->zfree(pStream->opaque, pStream->state);
|
||||
pStream->state = NULL;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
|
||||
{
|
||||
(void)pStream;
|
||||
/* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */
|
||||
return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
|
||||
}
|
||||
|
||||
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
|
||||
{
|
||||
int status;
|
||||
mz_stream stream;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
|
||||
/* In case mz_ulong is 64-bits (argh I hate longs). */
|
||||
if ((source_len | *pDest_len) > 0xFFFFFFFFU)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
stream.next_in = pSource;
|
||||
stream.avail_in = (mz_uint32)source_len;
|
||||
stream.next_out = pDest;
|
||||
stream.avail_out = (mz_uint32)*pDest_len;
|
||||
|
||||
status = mz_deflateInit(&stream, level);
|
||||
if (status != MZ_OK)
|
||||
return status;
|
||||
|
||||
status = mz_deflate(&stream, MZ_FINISH);
|
||||
if (status != MZ_STREAM_END)
|
||||
{
|
||||
mz_deflateEnd(&stream);
|
||||
return (status == MZ_OK) ? MZ_BUF_ERROR : status;
|
||||
}
|
||||
|
||||
*pDest_len = stream.total_out;
|
||||
return mz_deflateEnd(&stream);
|
||||
}
|
||||
|
||||
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||
{
|
||||
return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
mz_ulong mz_compressBound(mz_ulong source_len)
|
||||
{
|
||||
return mz_deflateBound(NULL, source_len);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
tinfl_decompressor m_decomp;
|
||||
mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
|
||||
int m_window_bits;
|
||||
mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
|
||||
tinfl_status m_last_status;
|
||||
} inflate_state;
|
||||
|
||||
int mz_inflateInit2(mz_streamp pStream, int window_bits)
|
||||
{
|
||||
inflate_state *pDecomp;
|
||||
if (!pStream)
|
||||
return MZ_STREAM_ERROR;
|
||||
if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
pStream->data_type = 0;
|
||||
pStream->adler = 0;
|
||||
pStream->msg = NULL;
|
||||
pStream->total_in = 0;
|
||||
pStream->total_out = 0;
|
||||
pStream->reserved = 0;
|
||||
if (!pStream->zalloc)
|
||||
pStream->zalloc = miniz_def_alloc_func;
|
||||
if (!pStream->zfree)
|
||||
pStream->zfree = miniz_def_free_func;
|
||||
|
||||
pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
|
||||
if (!pDecomp)
|
||||
return MZ_MEM_ERROR;
|
||||
|
||||
pStream->state = (struct mz_internal_state *)pDecomp;
|
||||
|
||||
tinfl_init(&pDecomp->m_decomp);
|
||||
pDecomp->m_dict_ofs = 0;
|
||||
pDecomp->m_dict_avail = 0;
|
||||
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
|
||||
pDecomp->m_first_call = 1;
|
||||
pDecomp->m_has_flushed = 0;
|
||||
pDecomp->m_window_bits = window_bits;
|
||||
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_inflateInit(mz_streamp pStream)
|
||||
{
|
||||
return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
|
||||
}
|
||||
|
||||
int mz_inflate(mz_streamp pStream, int flush)
|
||||
{
|
||||
inflate_state *pState;
|
||||
mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
|
||||
size_t in_bytes, out_bytes, orig_avail_in;
|
||||
tinfl_status status;
|
||||
|
||||
if ((!pStream) || (!pStream->state))
|
||||
return MZ_STREAM_ERROR;
|
||||
if (flush == MZ_PARTIAL_FLUSH)
|
||||
flush = MZ_SYNC_FLUSH;
|
||||
if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
|
||||
return MZ_STREAM_ERROR;
|
||||
|
||||
pState = (inflate_state *)pStream->state;
|
||||
if (pState->m_window_bits > 0)
|
||||
decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
|
||||
orig_avail_in = pStream->avail_in;
|
||||
|
||||
first_call = pState->m_first_call;
|
||||
pState->m_first_call = 0;
|
||||
if (pState->m_last_status < 0)
|
||||
return MZ_DATA_ERROR;
|
||||
|
||||
if (pState->m_has_flushed && (flush != MZ_FINISH))
|
||||
return MZ_STREAM_ERROR;
|
||||
pState->m_has_flushed |= (flush == MZ_FINISH);
|
||||
|
||||
if ((flush == MZ_FINISH) && (first_call))
|
||||
{
|
||||
/* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
|
||||
decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
|
||||
in_bytes = pStream->avail_in;
|
||||
out_bytes = pStream->avail_out;
|
||||
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
|
||||
pState->m_last_status = status;
|
||||
pStream->next_in += (mz_uint)in_bytes;
|
||||
pStream->avail_in -= (mz_uint)in_bytes;
|
||||
pStream->total_in += (mz_uint)in_bytes;
|
||||
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||
pStream->next_out += (mz_uint)out_bytes;
|
||||
pStream->avail_out -= (mz_uint)out_bytes;
|
||||
pStream->total_out += (mz_uint)out_bytes;
|
||||
|
||||
if (status < 0)
|
||||
return MZ_DATA_ERROR;
|
||||
else if (status != TINFL_STATUS_DONE)
|
||||
{
|
||||
pState->m_last_status = TINFL_STATUS_FAILED;
|
||||
return MZ_BUF_ERROR;
|
||||
}
|
||||
return MZ_STREAM_END;
|
||||
}
|
||||
/* flush != MZ_FINISH then we must assume there's more input. */
|
||||
if (flush != MZ_FINISH)
|
||||
decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
|
||||
|
||||
if (pState->m_dict_avail)
|
||||
{
|
||||
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||
pStream->next_out += n;
|
||||
pStream->avail_out -= n;
|
||||
pStream->total_out += n;
|
||||
pState->m_dict_avail -= n;
|
||||
pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||
return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
in_bytes = pStream->avail_in;
|
||||
out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
|
||||
|
||||
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
|
||||
pState->m_last_status = status;
|
||||
|
||||
pStream->next_in += (mz_uint)in_bytes;
|
||||
pStream->avail_in -= (mz_uint)in_bytes;
|
||||
pStream->total_in += (mz_uint)in_bytes;
|
||||
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||
|
||||
pState->m_dict_avail = (mz_uint)out_bytes;
|
||||
|
||||
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||
pStream->next_out += n;
|
||||
pStream->avail_out -= n;
|
||||
pStream->total_out += n;
|
||||
pState->m_dict_avail -= n;
|
||||
pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||
|
||||
if (status < 0)
|
||||
return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
|
||||
else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
|
||||
return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
|
||||
else if (flush == MZ_FINISH)
|
||||
{
|
||||
/* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
|
||||
if (status == TINFL_STATUS_DONE)
|
||||
return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
|
||||
/* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
|
||||
else if (!pStream->avail_out)
|
||||
return MZ_BUF_ERROR;
|
||||
}
|
||||
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
|
||||
break;
|
||||
}
|
||||
|
||||
return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||
}
|
||||
|
||||
int mz_inflateEnd(mz_streamp pStream)
|
||||
{
|
||||
if (!pStream)
|
||||
return MZ_STREAM_ERROR;
|
||||
if (pStream->state)
|
||||
{
|
||||
pStream->zfree(pStream->opaque, pStream->state);
|
||||
pStream->state = NULL;
|
||||
}
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||
{
|
||||
mz_stream stream;
|
||||
int status;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
|
||||
/* In case mz_ulong is 64-bits (argh I hate longs). */
|
||||
if ((source_len | *pDest_len) > 0xFFFFFFFFU)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
stream.next_in = pSource;
|
||||
stream.avail_in = (mz_uint32)source_len;
|
||||
stream.next_out = pDest;
|
||||
stream.avail_out = (mz_uint32)*pDest_len;
|
||||
|
||||
status = mz_inflateInit(&stream);
|
||||
if (status != MZ_OK)
|
||||
return status;
|
||||
|
||||
status = mz_inflate(&stream, MZ_FINISH);
|
||||
if (status != MZ_STREAM_END)
|
||||
{
|
||||
mz_inflateEnd(&stream);
|
||||
return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
|
||||
}
|
||||
*pDest_len = stream.total_out;
|
||||
|
||||
return mz_inflateEnd(&stream);
|
||||
}
|
||||
|
||||
const char *mz_error(int err)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
int m_err;
|
||||
const char *m_pDesc;
|
||||
} s_error_descs[] =
|
||||
{
|
||||
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
|
||||
};
|
||||
mz_uint i;
|
||||
for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
|
||||
if (s_error_descs[i].m_err == err)
|
||||
return s_error_descs[i].m_pDesc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /*MINIZ_NO_ZLIB_APIS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
import itertools
|
||||
import subprocess
|
||||
import pathlib
|
||||
import shutil
|
||||
|
||||
def generate_snapshots():
|
||||
single_styles = ["changes", "grid", "header", "numbers"]
|
||||
collective_styles = ["full", "plain"]
|
||||
|
||||
for num in range(len(single_styles)):
|
||||
for grouped in itertools.combinations(single_styles, num + 1):
|
||||
generate_snapshot(",".join(grouped))
|
||||
|
||||
for style in collective_styles:
|
||||
generate_snapshot(style)
|
||||
|
||||
def generate_snapshot(option):
|
||||
command = "../../target/debug/bat --style={0} sample.rs > output/{0}.snapshot.txt".format(
|
||||
option
|
||||
)
|
||||
print("generating snapshot for {}".format(option))
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
def build_bat():
|
||||
print("building bat")
|
||||
subprocess.call("cargo build", cwd="../..", shell=True)
|
||||
|
||||
def prepare_output_dir():
|
||||
shutil.rmtree("output", ignore_errors=True)
|
||||
pathlib.Path("output").mkdir()
|
||||
|
||||
def modify_sample_file():
|
||||
print("modifying sample.rs to show changes")
|
||||
shutil.copyfile("sample.modified.rs", "sample.rs")
|
||||
|
||||
def undo_sample_file_modification():
|
||||
print("undoing sample.rs modifications")
|
||||
subprocess.call("git checkout -- sample.rs", shell=True)
|
||||
|
||||
build_bat()
|
||||
prepare_output_dir()
|
||||
modify_sample_file()
|
||||
generate_snapshots()
|
||||
undo_sample_file_modification()
|
||||
@@ -0,0 +1,26 @@
|
||||
───────┬────────────────────────────────────────────────────────────────────────
|
||||
│ File: sample.rs
|
||||
───────┼────────────────────────────────────────────────────────────────────────
|
||||
1 │ struct Rectangle {
|
||||
2 │ width: u32,
|
||||
3 │ height: u32,
|
||||
4 │ }
|
||||
5 │
|
||||
6 _ │ fn main() {
|
||||
7 │ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8 │
|
||||
9 │ println!(
|
||||
10 ~ │ "The perimeter of the rectangle is {} pixels.",
|
||||
11 ~ │ perimeter(&rect1)
|
||||
12 │ );
|
||||
13 + │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 │ }
|
||||
15 │
|
||||
16 │ fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 │ rectangle.width * rectangle.height
|
||||
18 │ }
|
||||
19 + │
|
||||
20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 + │ (rectangle.width + rectangle.height) * 2
|
||||
22 + │ }
|
||||
───────┴────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,26 @@
|
||||
──┬─────────────────────────────────────────────────────────────────────────────
|
||||
│ File: sample.rs
|
||||
──┼─────────────────────────────────────────────────────────────────────────────
|
||||
│ struct Rectangle {
|
||||
│ width: u32,
|
||||
│ height: u32,
|
||||
│ }
|
||||
│
|
||||
_ │ fn main() {
|
||||
│ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
│
|
||||
│ println!(
|
||||
~ │ "The perimeter of the rectangle is {} pixels.",
|
||||
~ │ perimeter(&rect1)
|
||||
│ );
|
||||
+ │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
│ }
|
||||
│
|
||||
│ fn area(rectangle: &Rectangle) -> u32 {
|
||||
│ rectangle.width * rectangle.height
|
||||
│ }
|
||||
+ │
|
||||
+ │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
+ │ (rectangle.width + rectangle.height) * 2
|
||||
+ │ }
|
||||
──┴─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
1 │ struct Rectangle {
|
||||
2 │ width: u32,
|
||||
3 │ height: u32,
|
||||
4 │ }
|
||||
5 │
|
||||
6 _ │ fn main() {
|
||||
7 │ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8 │
|
||||
9 │ println!(
|
||||
10 ~ │ "The perimeter of the rectangle is {} pixels.",
|
||||
11 ~ │ perimeter(&rect1)
|
||||
12 │ );
|
||||
13 + │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 │ }
|
||||
15 │
|
||||
16 │ fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 │ rectangle.width * rectangle.height
|
||||
18 │ }
|
||||
19 + │
|
||||
20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 + │ (rectangle.width + rectangle.height) * 2
|
||||
22 + │ }
|
||||
───────┴────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
│ struct Rectangle {
|
||||
│ width: u32,
|
||||
│ height: u32,
|
||||
│ }
|
||||
│
|
||||
_ │ fn main() {
|
||||
│ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
│
|
||||
│ println!(
|
||||
~ │ "The perimeter of the rectangle is {} pixels.",
|
||||
~ │ perimeter(&rect1)
|
||||
│ );
|
||||
+ │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
│ }
|
||||
│
|
||||
│ fn area(rectangle: &Rectangle) -> u32 {
|
||||
│ rectangle.width * rectangle.height
|
||||
│ }
|
||||
+ │
|
||||
+ │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
+ │ (rectangle.width + rectangle.height) * 2
|
||||
+ │ }
|
||||
──┴─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
File: sample.rs
|
||||
1 struct Rectangle {
|
||||
2 width: u32,
|
||||
3 height: u32,
|
||||
4 }
|
||||
5
|
||||
6 _ fn main() {
|
||||
7 let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8
|
||||
9 println!(
|
||||
10 ~ "The perimeter of the rectangle is {} pixels.",
|
||||
11 ~ perimeter(&rect1)
|
||||
12 );
|
||||
13 + println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 }
|
||||
15
|
||||
16 fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 rectangle.width * rectangle.height
|
||||
18 }
|
||||
19 +
|
||||
20 + fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 + (rectangle.width + rectangle.height) * 2
|
||||
22 + }
|
||||
@@ -0,0 +1,23 @@
|
||||
File: sample.rs
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
_ fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
~ "The perimeter of the rectangle is {} pixels.",
|
||||
~ perimeter(&rect1)
|
||||
);
|
||||
+ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
+
|
||||
+ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
+ (rectangle.width + rectangle.height) * 2
|
||||
+ }
|
||||
@@ -0,0 +1,22 @@
|
||||
1 struct Rectangle {
|
||||
2 width: u32,
|
||||
3 height: u32,
|
||||
4 }
|
||||
5
|
||||
6 _ fn main() {
|
||||
7 let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8
|
||||
9 println!(
|
||||
10 ~ "The perimeter of the rectangle is {} pixels.",
|
||||
11 ~ perimeter(&rect1)
|
||||
12 );
|
||||
13 + println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 }
|
||||
15
|
||||
16 fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 rectangle.width * rectangle.height
|
||||
18 }
|
||||
19 +
|
||||
20 + fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 + (rectangle.width + rectangle.height) * 2
|
||||
22 + }
|
||||
@@ -0,0 +1,22 @@
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
_ fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
~ "The perimeter of the rectangle is {} pixels.",
|
||||
~ perimeter(&rect1)
|
||||
);
|
||||
+ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
+
|
||||
+ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
+ (rectangle.width + rectangle.height) * 2
|
||||
+ }
|
||||
@@ -0,0 +1,26 @@
|
||||
───────┬────────────────────────────────────────────────────────────────────────
|
||||
│ File: sample.rs
|
||||
───────┼────────────────────────────────────────────────────────────────────────
|
||||
1 │ struct Rectangle {
|
||||
2 │ width: u32,
|
||||
3 │ height: u32,
|
||||
4 │ }
|
||||
5 │
|
||||
6 _ │ fn main() {
|
||||
7 │ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8 │
|
||||
9 │ println!(
|
||||
10 ~ │ "The perimeter of the rectangle is {} pixels.",
|
||||
11 ~ │ perimeter(&rect1)
|
||||
12 │ );
|
||||
13 + │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 │ }
|
||||
15 │
|
||||
16 │ fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 │ rectangle.width * rectangle.height
|
||||
18 │ }
|
||||
19 + │
|
||||
20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 + │ (rectangle.width + rectangle.height) * 2
|
||||
22 + │ }
|
||||
───────┴────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,26 @@
|
||||
─────┬──────────────────────────────────────────────────────────────────────────
|
||||
│ File: sample.rs
|
||||
─────┼──────────────────────────────────────────────────────────────────────────
|
||||
1 │ struct Rectangle {
|
||||
2 │ width: u32,
|
||||
3 │ height: u32,
|
||||
4 │ }
|
||||
5 │
|
||||
6 │ fn main() {
|
||||
7 │ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8 │
|
||||
9 │ println!(
|
||||
10 │ "The perimeter of the rectangle is {} pixels.",
|
||||
11 │ perimeter(&rect1)
|
||||
12 │ );
|
||||
13 │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 │ }
|
||||
15 │
|
||||
16 │ fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 │ rectangle.width * rectangle.height
|
||||
18 │ }
|
||||
19 │
|
||||
20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 │ (rectangle.width + rectangle.height) * 2
|
||||
22 │ }
|
||||
─────┴──────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,26 @@
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
File: sample.rs
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The perimeter of the rectangle is {} pixels.",
|
||||
perimeter(&rect1)
|
||||
);
|
||||
println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
|
||||
fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
(rectangle.width + rectangle.height) * 2
|
||||
}
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
1 │ struct Rectangle {
|
||||
2 │ width: u32,
|
||||
3 │ height: u32,
|
||||
4 │ }
|
||||
5 │
|
||||
6 │ fn main() {
|
||||
7 │ let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8 │
|
||||
9 │ println!(
|
||||
10 │ "The perimeter of the rectangle is {} pixels.",
|
||||
11 │ perimeter(&rect1)
|
||||
12 │ );
|
||||
13 │ println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 │ }
|
||||
15 │
|
||||
16 │ fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 │ rectangle.width * rectangle.height
|
||||
18 │ }
|
||||
19 │
|
||||
20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 │ (rectangle.width + rectangle.height) * 2
|
||||
22 │ }
|
||||
─────┴──────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The perimeter of the rectangle is {} pixels.",
|
||||
perimeter(&rect1)
|
||||
);
|
||||
println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
|
||||
fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
(rectangle.width + rectangle.height) * 2
|
||||
}
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
@@ -0,0 +1,23 @@
|
||||
File: sample.rs
|
||||
1 struct Rectangle {
|
||||
2 width: u32,
|
||||
3 height: u32,
|
||||
4 }
|
||||
5
|
||||
6 fn main() {
|
||||
7 let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8
|
||||
9 println!(
|
||||
10 "The perimeter of the rectangle is {} pixels.",
|
||||
11 perimeter(&rect1)
|
||||
12 );
|
||||
13 println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 }
|
||||
15
|
||||
16 fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 rectangle.width * rectangle.height
|
||||
18 }
|
||||
19
|
||||
20 fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 (rectangle.width + rectangle.height) * 2
|
||||
22 }
|
||||
@@ -0,0 +1,23 @@
|
||||
File: sample.rs
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The perimeter of the rectangle is {} pixels.",
|
||||
perimeter(&rect1)
|
||||
);
|
||||
println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
|
||||
fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
(rectangle.width + rectangle.height) * 2
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
1 struct Rectangle {
|
||||
2 width: u32,
|
||||
3 height: u32,
|
||||
4 }
|
||||
5
|
||||
6 fn main() {
|
||||
7 let rect1 = Rectangle { width: 30, height: 50 };
|
||||
8
|
||||
9 println!(
|
||||
10 "The perimeter of the rectangle is {} pixels.",
|
||||
11 perimeter(&rect1)
|
||||
12 );
|
||||
13 println!(r#"This line contains invalid utf8: "�����"#;
|
||||
14 }
|
||||
15
|
||||
16 fn area(rectangle: &Rectangle) -> u32 {
|
||||
17 rectangle.width * rectangle.height
|
||||
18 }
|
||||
19
|
||||
20 fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
21 (rectangle.width + rectangle.height) * 2
|
||||
22 }
|
||||
@@ -0,0 +1,22 @@
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The perimeter of the rectangle is {} pixels.",
|
||||
perimeter(&rect1)
|
||||
);
|
||||
println!(r#"This line contains invalid utf8: "�����"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
|
||||
fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
(rectangle.width + rectangle.height) * 2
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The perimeter of the rectangle is {} pixels.",
|
||||
perimeter(&rect1)
|
||||
);
|
||||
println!(r#"This line contains invalid utf8: "øˆ€€€"#;
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
|
||||
fn perimeter(rectangle: &Rectangle) -> u32 {
|
||||
(rectangle.width + rectangle.height) * 2
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
struct Rectangle {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// width and height of a rectangle can be different
|
||||
let rect1 = Rectangle { width: 30, height: 50 };
|
||||
|
||||
println!(
|
||||
"The area of the rectangle is {} square pixels.",
|
||||
area(&rect1)
|
||||
);
|
||||
}
|
||||
|
||||
fn area(rectangle: &Rectangle) -> u32 {
|
||||
rectangle.width * rectangle.height
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
pub struct BatTester {
|
||||
exe: PathBuf,
|
||||
}
|
||||
|
||||
impl BatTester {
|
||||
pub fn new() -> Self {
|
||||
modify_sample_file();
|
||||
// Lifted from fd :)
|
||||
let root = env::current_exe()
|
||||
.expect("tests executable")
|
||||
.parent()
|
||||
.expect("tests executable directory")
|
||||
.parent()
|
||||
.expect("bat executable directory")
|
||||
.to_path_buf();
|
||||
|
||||
let exe_name = if cfg!(windows) { "bat.exe" } else { "bat" };
|
||||
|
||||
BatTester {
|
||||
exe: root.join(exe_name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_snapshot(&self, style: &str) {
|
||||
let output = Command::new(&self.exe)
|
||||
.args(&["tests/snapshots/sample.rs", &format!("--style={}", style)])
|
||||
.output()
|
||||
.expect("bat failed");
|
||||
// have to do the replace because the filename in the header changes based on the current working directory
|
||||
let actual = String::from_utf8_lossy(&output.stdout)
|
||||
.as_ref()
|
||||
.replace("tests/snapshots/", "");
|
||||
|
||||
let mut expected = String::new();
|
||||
let mut file = File::open(format!("tests/snapshots/output/{}.snapshot.txt", style))
|
||||
.expect("snapshot file missing");
|
||||
file.read_to_string(&mut expected)
|
||||
.expect("could not read snapshot file");
|
||||
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BatTester {
|
||||
fn drop(&mut self) {
|
||||
undo_sample_file_modification();
|
||||
}
|
||||
}
|
||||
|
||||
fn modify_sample_file() {
|
||||
fs::copy(
|
||||
"tests/snapshots/sample.modified.rs",
|
||||
"tests/snapshots/sample.rs",
|
||||
).expect("generating modified sample file failed");
|
||||
}
|
||||
|
||||
fn undo_sample_file_modification() {
|
||||
let output = Command::new("git")
|
||||
.args(&["checkout", "--", "tests/snapshots/sample.rs"])
|
||||
.output()
|
||||
.expect("git checkout failed");
|
||||
|
||||
if !output.status.success() {
|
||||
panic!("undoing modified sample changes failed")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
mod tester;
|
||||
|
||||
use tester::BatTester;
|
||||
|
||||
static STYLES: &'static [&'static str] = &[
|
||||
"changes",
|
||||
"grid",
|
||||
"header",
|
||||
"numbers",
|
||||
"changes,grid",
|
||||
"changes,header",
|
||||
"changes,numbers",
|
||||
"grid,header",
|
||||
"grid,numbers",
|
||||
"header,numbers",
|
||||
"changes,grid,header",
|
||||
"changes,grid,numbers",
|
||||
"changes,header,numbers",
|
||||
"grid,header,numbers",
|
||||
"changes,grid,header,numbers",
|
||||
"full",
|
||||
"plain",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_snapshots() {
|
||||
let bat_tester = BatTester::new();
|
||||
|
||||
for style in STYLES {
|
||||
println!("testing {}", style);
|
||||
bat_tester.test_snapshot(&*style);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user