Merge branch 'master' into fix_654_stdin_filename

This commit is contained in:
Kyle Criddle 2020-03-24 19:08:43 -06:00
commit 38178fedf4
118 changed files with 1836 additions and 1762 deletions

3
.github/FUNDING.yml vendored
View File

@ -1,3 +0,0 @@
# These are supported funding model platforms
github: sharkdp

94
.gitmodules vendored
View File

@ -1,32 +1,32 @@
[submodule "assets/syntaxes/Elixir"] [submodule "assets/syntaxes/Elixir"]
path = assets/syntaxes/Elixir path = assets/syntaxes/02_Extra/Elixir
url = https://github.com/princemaple/elixir-sublime-syntax/ url = https://github.com/princemaple/elixir-sublime-syntax/
[submodule "assets/syntaxes/Packages"] [submodule "assets/syntaxes/Packages"]
path = assets/syntaxes/Packages path = assets/syntaxes/01_Packages
url = https://github.com/sublimehq/Packages/ url = https://github.com/sublimehq/Packages/
[submodule "assets/syntaxes/TOML"] [submodule "assets/syntaxes/TOML"]
path = assets/syntaxes/TOML path = assets/syntaxes/02_Extra/TOML
url = https://github.com/jasonwilliams/sublime_toml_highlighting url = https://github.com/jasonwilliams/sublime_toml_highlighting
[submodule "assets/syntaxes/Julia"] [submodule "assets/syntaxes/Julia"]
path = assets/syntaxes/Julia path = assets/syntaxes/02_Extra/Julia
url = https://github.com/JuliaEditorSupport/Julia-sublime url = https://github.com/JuliaEditorSupport/Julia-sublime
[submodule "assets/themes/sublime-monokai-extended"] [submodule "assets/themes/sublime-monokai-extended"]
path = assets/themes/sublime-monokai-extended path = assets/themes/sublime-monokai-extended
url = https://github.com/jonschlinkert/sublime-monokai-extended url = https://github.com/jonschlinkert/sublime-monokai-extended
[submodule "assets/syntaxes/Docker"] [submodule "assets/syntaxes/Docker"]
path = assets/syntaxes/Docker path = assets/syntaxes/02_Extra/Docker
url = https://github.com/asbjornenge/Docker.tmbundle url = https://github.com/asbjornenge/Docker.tmbundle
[submodule "assets/syntaxes/VimL"] [submodule "assets/syntaxes/VimL"]
path = assets/syntaxes/VimL path = assets/syntaxes/02_Extra/VimL
url = https://github.com/SalGnt/Sublime-VimL url = https://github.com/SalGnt/Sublime-VimL
[submodule "assets/syntaxes/INI"] [submodule "assets/syntaxes/INI"]
path = assets/syntaxes/INI path = assets/syntaxes/02_Extra/INI
url = https://github.com/clintberry/sublime-text-2-ini url = https://github.com/clintberry/sublime-text-2-ini
[submodule "assets/syntaxes/CMake"] [submodule "assets/syntaxes/CMake"]
path = assets/syntaxes/CMake path = assets/syntaxes/02_Extra/CMake
url = https://github.com/zyxar/Sublime-CMakeLists url = https://github.com/zyxar/Sublime-CMakeLists
[submodule "assets/syntaxes/LESS"] [submodule "assets/syntaxes/LESS"]
path = assets/syntaxes/LESS path = assets/syntaxes/02_Extra/LESS
url = https://github.com/danro/LESS-sublime url = https://github.com/danro/LESS-sublime
[submodule "assets/themes/DarkNeon"] [submodule "assets/themes/DarkNeon"]
path = assets/themes/DarkNeon path = assets/themes/DarkNeon
@ -41,127 +41,127 @@
path = assets/themes/TwoDark path = assets/themes/TwoDark
url = https://github.com/erremauro/TwoDark url = https://github.com/erremauro/TwoDark
[submodule "assets/syntaxes/AWK"] [submodule "assets/syntaxes/AWK"]
path = assets/syntaxes/AWK path = assets/syntaxes/02_Extra/AWK
url = https://github.com/JohnNilsson/awk-sublime url = https://github.com/JohnNilsson/awk-sublime
[submodule "assets/syntaxes/Nix"] [submodule "assets/syntaxes/Nix"]
path = assets/syntaxes/Nix path = assets/syntaxes/02_Extra/Nix
url = https://github.com/wmertens/sublime-nix url = https://github.com/wmertens/sublime-nix
[submodule "assets/themes/zenburn"] [submodule "assets/themes/zenburn"]
path = assets/themes/zenburn path = assets/themes/zenburn
url = https://github.com/colinta/zenburn.git url = https://github.com/colinta/zenburn.git
[submodule "assets/syntaxes/Kotlin"] [submodule "assets/syntaxes/Kotlin"]
path = assets/syntaxes/Kotlin path = assets/syntaxes/02_Extra/Kotlin
url = https://github.com/vkostyukov/kotlin-sublime-package url = https://github.com/vkostyukov/kotlin-sublime-package
[submodule "assets/syntaxes/Elm"] [submodule "assets/syntaxes/Elm"]
path = assets/syntaxes/Elm path = assets/syntaxes/02_Extra/Elm
url = https://github.com/elm-community/SublimeElmLanguageSupport url = https://github.com/elm-community/SublimeElmLanguageSupport
[submodule "assets/syntaxes/TypeScript"] [submodule "assets/syntaxes/TypeScript"]
path = assets/syntaxes/TypeScript path = assets/syntaxes/02_Extra/TypeScript
url = https://github.com/Microsoft/TypeScript-Sublime-Plugin url = https://github.com/Microsoft/TypeScript-Sublime-Plugin
[submodule "assets/syntaxes/Puppet"] [submodule "assets/syntaxes/Puppet"]
path = assets/syntaxes/Puppet path = assets/syntaxes/02_Extra/Puppet
url = https://github.com/russCloak/SublimePuppet url = https://github.com/russCloak/SublimePuppet
[submodule "assets/syntaxes/CSV"] [submodule "assets/syntaxes/CSV"]
path = assets/syntaxes/CSV path = assets/syntaxes/02_Extra/CSV
url = https://github.com/wadetb/Sublime-Text-Advanced-CSV url = https://github.com/wadetb/Sublime-Text-Advanced-CSV
[submodule "assets/themes/onehalf"] [submodule "assets/themes/onehalf"]
path = assets/themes/onehalf path = assets/themes/onehalf
url = https://github.com/sonph/onehalf url = https://github.com/sonph/onehalf
[submodule "assets/syntaxes/JavaScript (Babel)"] [submodule "assets/syntaxes/JavaScript (Babel)"]
path = assets/syntaxes/JavaScript (Babel) path = assets/syntaxes/02_Extra/JavaScript (Babel)
url = https://github.com/babel/babel-sublime url = https://github.com/babel/babel-sublime
[submodule "assets/syntaxes/Cabal"] [submodule "assets/syntaxes/Cabal"]
path = assets/syntaxes/Cabal path = assets/syntaxes/02_Extra/Cabal
url = https://github.com/SublimeHaskell/SublimeHaskell url = https://github.com/SublimeHaskell/SublimeHaskell
[submodule "assets/syntaxes/Dart"] [submodule "assets/syntaxes/Dart"]
path = assets/syntaxes/Dart path = assets/syntaxes/02_Extra/Dart
url = https://github.com/guillermooo/dart-sublime-bundle url = https://github.com/guillermooo/dart-sublime-bundle
[submodule "assets/syntaxes/FSharp"] [submodule "assets/syntaxes/FSharp"]
path = assets/syntaxes/FSharp path = assets/syntaxes/02_Extra/FSharp
url = https://github.com/hoest/sublimetext-fsharp url = https://github.com/hoest/sublimetext-fsharp
[submodule "assets/syntaxes/PureScript"] [submodule "assets/syntaxes/PureScript"]
path = assets/syntaxes/PureScript path = assets/syntaxes/02_Extra/PureScript
url = https://github.com/tellnobody1/sublime-purescript-syntax url = https://github.com/tellnobody1/sublime-purescript-syntax
[submodule "assets/syntaxes/Swift"] [submodule "assets/syntaxes/Swift"]
path = assets/syntaxes/Swift path = assets/syntaxes/02_Extra/Swift
url = https://github.com/quiqueg/Swift-Sublime-Package url = https://github.com/quiqueg/Swift-Sublime-Package
[submodule "assets/syntaxes/Crystal"] [submodule "assets/syntaxes/Crystal"]
path = assets/syntaxes/Crystal path = assets/syntaxes/02_Extra/Crystal
url = https://github.com/crystal-lang-tools/sublime-crystal.git url = https://github.com/crystal-lang-tools/sublime-crystal.git
[submodule "assets/syntaxes/PowerShell"] [submodule "assets/syntaxes/PowerShell"]
path = assets/syntaxes/PowerShell path = assets/syntaxes/02_Extra/PowerShell
url = https://github.com/PowerShell/EditorSyntax url = https://github.com/PowerShell/EditorSyntax
[submodule "assets/syntaxes/Robot"] [submodule "assets/syntaxes/Robot"]
path = assets/syntaxes/Robot path = assets/syntaxes/02_Extra/Robot
url = https://github.com/andriyko/sublime-robot-framework-assistant.git url = https://github.com/andriyko/sublime-robot-framework-assistant.git
[submodule "assets/themes/sublime-snazzy"] [submodule "assets/themes/sublime-snazzy"]
path = assets/themes/sublime-snazzy path = assets/themes/sublime-snazzy
url = https://github.com/greggb/sublime-snazzy url = https://github.com/greggb/sublime-snazzy
[submodule "assets/syntaxes/AsciiDoc"] [submodule "assets/syntaxes/AsciiDoc"]
path = assets/syntaxes/AsciiDoc path = assets/syntaxes/02_Extra/AsciiDoc
url = https://github.com/SublimeText/AsciiDoc.git url = https://github.com/SublimeText/AsciiDoc.git
[submodule "assets/syntaxes/Assembly (ARM)"] [submodule "assets/syntaxes/Assembly (ARM)"]
path = assets/syntaxes/Assembly (ARM) path = assets/syntaxes/02_Extra/Assembly (ARM)
url = https://github.com/tvi/Sublime-ARM-Assembly url = https://github.com/tvi/Sublime-ARM-Assembly
[submodule "assets/syntaxes/syslog-syntax"] [submodule "assets/syntaxes/syslog-syntax"]
path = assets/syntaxes/Syslog path = assets/syntaxes/02_Extra/Syslog
url = https://github.com/caos21/syslog-syntax.git url = https://github.com/caos21/syslog-syntax.git
branch = master branch = master
[submodule "assets/syntaxes/protobuf-syntax-highlighting"] [submodule "assets/syntaxes/protobuf-syntax-highlighting"]
path = assets/syntaxes/Protobuf path = assets/syntaxes/02_Extra/Protobuf
url = https://github.com/VcamX/protobuf-syntax-highlighting.git url = https://github.com/VcamX/protobuf-syntax-highlighting.git
branch = master branch = master
[submodule "assets/syntaxes/Terraform"] [submodule "assets/syntaxes/Terraform"]
path = assets/syntaxes/Terraform path = assets/syntaxes/02_Extra/Terraform
url = https://github.com/alexlouden/Terraform.tmLanguage.git url = https://github.com/alexlouden/Terraform.tmLanguage.git
[submodule "assets/syntaxes/Jsonnet"] [submodule "assets/syntaxes/Jsonnet"]
path = assets/syntaxes/Jsonnet path = assets/syntaxes/02_Extra/Jsonnet
url = https://github.com/gburiola/sublime-jsonnet-syntax.git url = https://github.com/gburiola/sublime-jsonnet-syntax.git
[submodule "assets/syntaxes/varlink"] [submodule "assets/syntaxes/varlink"]
path = assets/syntaxes/varlink path = assets/syntaxes/02_Extra/varlink
url = https://github.com/varlink/syntax-highlight-varlink.git url = https://github.com/varlink/syntax-highlight-varlink.git
[submodule "assets/syntaxes/sublime-fish"] [submodule "assets/syntaxes/sublime-fish"]
path = assets/syntaxes/Fish path = assets/syntaxes/02_Extra/Fish
url = https://github.com/Phidica/sublime-fish.git url = https://github.com/Phidica/sublime-fish.git
[submodule "assets/syntaxes/Org mode"] [submodule "assets/syntaxes/Org mode"]
path = assets/syntaxes/Org mode path = assets/syntaxes/02_Extra/Org mode
url = https://github.com/jezcope/Org.tmbundle.git url = https://github.com/jezcope/Org.tmbundle.git
[submodule "assets/syntaxes/requirementstxt"] [submodule "assets/syntaxes/requirementstxt"]
path = assets/syntaxes/requirementstxt path = assets/syntaxes/02_Extra/requirementstxt
url = https://github.com/wuub/requirementstxt url = https://github.com/wuub/requirementstxt
[submodule "assets/syntaxes/DotENV"] [submodule "assets/syntaxes/DotENV"]
path = assets/syntaxes/DotENV path = assets/syntaxes/02_Extra/DotENV
url = https://github.com/zaynali53/DotENV url = https://github.com/zaynali53/DotENV
[submodule "assets/syntaxes/hosts"] [submodule "assets/syntaxes/hosts"]
path = assets/syntaxes/hosts path = assets/syntaxes/02_Extra/hosts
url = https://github.com/brandonwamboldt/sublime-hosts url = https://github.com/brandonwamboldt/sublime-hosts
[submodule "assets/syntaxes/ssh-config"] [submodule "assets/syntaxes/ssh-config"]
path = assets/syntaxes/ssh-config path = assets/syntaxes/02_Extra/ssh-config
url = https://github.com/robballou/sublimetext-sshconfig.git url = https://github.com/robballou/sublimetext-sshconfig.git
[submodule "assets/syntaxes/GraphQL"] [submodule "assets/syntaxes/GraphQL"]
path = assets/syntaxes/GraphQL path = assets/syntaxes/02_Extra/GraphQL
url = https://github.com/dncrews/GraphQL-SublimeText3.git url = https://github.com/dncrews/GraphQL-SublimeText3.git
[submodule "assets/syntaxes/Verilog"] [submodule "assets/syntaxes/Verilog"]
path = assets/syntaxes/Verilog path = assets/syntaxes/02_Extra/Verilog
url = https://github.com/pro711/sublime-verilog url = https://github.com/pro711/sublime-verilog
[submodule "assets/syntaxes/SCSS_Sass"] [submodule "assets/syntaxes/SCSS_Sass"]
path = assets/syntaxes/SCSS_Sass path = assets/syntaxes/02_Extra/SCSS_Sass
url = https://github.com/braver/SublimeSass url = https://github.com/braver/SublimeSass
[submodule "assets/syntaxes/Strace"] [submodule "assets/syntaxes/Strace"]
path = assets/syntaxes/Strace path = assets/syntaxes/02_Extra/Strace
url = https://github.com/djuretic/SublimeStrace url = https://github.com/djuretic/SublimeStrace
[submodule "assets/syntaxes/Jinja2"] [submodule "assets/syntaxes/Jinja2"]
path = assets/syntaxes/Jinja2 path = assets/syntaxes/02_Extra/Jinja2
url = https://github.com/Martin819/sublime-jinja2 url = https://github.com/Martin819/sublime-jinja2
[submodule "assets/syntaxes/SLS"] [submodule "assets/syntaxes/SLS"]
path = assets/syntaxes/SLS path = assets/syntaxes/02_Extra/SLS
url = https://github.com/saltstack/sublime-text url = https://github.com/saltstack/sublime-text
branch = master branch = master
[submodule "assets/themes/dracula-sublime"] [submodule "assets/themes/dracula-sublime"]
path = assets/themes/dracula-sublime path = assets/themes/dracula-sublime
url = https://github.com/dracula/sublime.git url = https://github.com/dracula/sublime.git
[submodule "assets/syntaxes/HTML (Twig)"] [submodule "assets/syntaxes/HTML (Twig)"]
path = assets/syntaxes/HTML (Twig) path = assets/syntaxes/02_Extra/HTML (Twig)
url = https://github.com/Anomareh/PHP-Twig.tmbundle.git url = https://github.com/Anomareh/PHP-Twig.tmbundle.git
[submodule "assets/themes/Nord-sublime"] [submodule "assets/themes/Nord-sublime"]
path = assets/themes/Nord-sublime path = assets/themes/Nord-sublime
@ -170,9 +170,9 @@
path = assets/themes/solarized-sublime path = assets/themes/solarized-sublime
url = https://github.com/paulcpederson/solarized-sublime.git url = https://github.com/paulcpederson/solarized-sublime.git
[submodule "assets/syntaxes/Vue"] [submodule "assets/syntaxes/Vue"]
path = assets/syntaxes/Vue path = assets/syntaxes/02_Extra/Vue
url = https://github.com/vuejs/vue-syntax-highlight.git url = https://github.com/vuejs/vue-syntax-highlight.git
branch = new branch = new
[submodule "assets/syntaxes/CoffeeScript"] [submodule "assets/syntaxes/CoffeeScript"]
path = assets/syntaxes/CoffeeScript path = assets/syntaxes/02_Extra/CoffeeScript
url = https://github.com/sustained/CoffeeScript-Sublime-Plugin url = https://github.com/sustained/CoffeeScript-Sublime-Plugin

View File

@ -33,15 +33,15 @@ matrix:
# Minimum Rust supported channel. # Minimum Rust supported channel.
- os: linux - os: linux
rust: 1.36.0 rust: 1.37.0
env: TARGET=x86_64-unknown-linux-gnu env: TARGET=x86_64-unknown-linux-gnu
- os: linux - os: linux
rust: 1.36.0 rust: 1.37.0
env: env:
- TARGET=x86_64-unknown-linux-musl - TARGET=x86_64-unknown-linux-musl
- CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc - CC_x86_64_unknown_linux_musl=/usr/bin/musl-gcc
- os: osx - os: osx
rust: 1.36.0 rust: 1.37.0
env: TARGET=x86_64-apple-darwin env: TARGET=x86_64-apple-darwin
# Disable nightly for now # Disable nightly for now

816
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ license = "MIT/Apache-2.0"
name = "bat" name = "bat"
readme = "README.md" readme = "README.md"
repository = "https://github.com/sharkdp/bat" repository = "https://github.com/sharkdp/bat"
version = "0.12.1" version = "0.13.0"
exclude = [ exclude = [
"assets/syntaxes/*", "assets/syntaxes/*",
"assets/themes/*", "assets/themes/*",
@ -27,9 +27,10 @@ content_inspector = "0.2.4"
encoding = "0.2" encoding = "0.2"
shell-words = "0.1.0" shell-words = "0.1.0"
unicode-width = "0.1.7" unicode-width = "0.1.7"
globset = "0.4"
[dependencies.git2] [dependencies.git2]
version = "0.12" version = "0.13"
default-features = false default-features = false
features = [] features = []
@ -54,7 +55,7 @@ assert_cmd = "0.12.0"
[build-dependencies] [build-dependencies]
clap = "2.33" clap = "2.33"
liquid = "0.19" liquid = "0.20"
lazy_static = "1.4" lazy_static = "1.4"
[profile.release] [profile.release]

View File

@ -13,7 +13,7 @@
<a href="#installation">Installation</a> <a href="#installation">Installation</a>
<a href="#customization">Customization</a> <a href="#customization">Customization</a>
<a href="#project-goals-and-alternatives">Project goals, alternatives</a> <a href="#project-goals-and-alternatives">Project goals, alternatives</a>
Translation [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="doc/README-ja.md">日本語</a>] Translation [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="doc/README-ja.md">日本語</a>][<a href="doc/README-ko.md">한국어</a>]
</p> </p>
### Syntax highlighting ### Syntax highlighting
@ -180,7 +180,7 @@ apt install bat
If you want to run the latest release of bat or if you are on older versions of Ubuntu/Debian, download the latest `.deb` package from the [release page](https://github.com/sharkdp/bat/releases) If you want to run the latest release of bat or if you are on older versions of Ubuntu/Debian, download the latest `.deb` package from the [release page](https://github.com/sharkdp/bat/releases)
and install it via: and install it via:
```bash ```bash
sudo dpkg -i bat_0.12.1_amd64.deb # adapt version number and architecture sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
``` ```
### On Alpine Linux ### On Alpine Linux
@ -341,7 +341,7 @@ binaries are also available: look for archives with `musl` in the file name.
### From source ### From source
If you want to build `bat` from source, you need Rust 1.36 or If you want to build `bat` from source, you need Rust 1.37 or
higher. You can then use `cargo` to build everything: higher. You can then use `cargo` to build everything:
```bash ```bash
@ -500,11 +500,11 @@ Example configuration file:
# Use italic text on the terminal (not supported on all terminals) # Use italic text on the terminal (not supported on all terminals)
--italic-text=always --italic-text=always
# Use C++ syntax (instead of C) for .h header files # Use C++ syntax for .ino files
--map-syntax h:cpp --map-syntax "*.ino:C++"
# Use "gitignore" highlighting for ".ignore" files # Use ".gitignore"-style highlighting for ".ignore" files
--map-syntax .ignore:.gitignore --map-syntax ".ignore:Git Ignore"
``` ```
## Using `bat` on Windows ## Using `bat` on Windows

View File

@ -1,7 +1,7 @@
diff --git syntaxes/Packages/Java/JavaDoc.sublime-syntax syntaxes/Packages/Java/JavaDoc.sublime-syntax diff --git syntaxes/01_Packages/Java/JavaDoc.sublime-syntax syntaxes/01_Packages/Java/JavaDoc.sublime-syntax
index 422a6a9..40a741e 100644 index 422a6a9..40a741e 100644
--- syntaxes/Packages/Java/JavaDoc.sublime-syntax --- syntaxes/01_Packages/Java/JavaDoc.sublime-syntax
+++ syntaxes/Packages/Java/JavaDoc.sublime-syntax +++ syntaxes/01_Packages/Java/JavaDoc.sublime-syntax
@@ -13,7 +13,7 @@ variables: @@ -13,7 +13,7 @@ variables:
contexts: contexts:
prototype: prototype:

2
assets/create.sh vendored
View File

@ -44,7 +44,7 @@ bat cache --clear
# TODO: Remove this (and the reverse part below) when # TODO: Remove this (and the reverse part below) when
# https://github.com/trishume/syntect/issues/222 has been fixed # https://github.com/trishume/syntect/issues/222 has been fixed
JAVADOC_FILE="${ASSET_DIR}/syntaxes/Packages/Java/JavaDoc.sublime-syntax" JAVADOC_FILE="${ASSET_DIR}/syntaxes/01_Packages/Java/JavaDoc.sublime-syntax"
JAVADOC_PATCH="${ASSET_DIR}/JavaDoc.sublime-syntax.patch" JAVADOC_PATCH="${ASSET_DIR}/JavaDoc.sublime-syntax.patch"
patch "$JAVADOC_FILE" "$JAVADOC_PATCH" patch "$JAVADOC_FILE" "$JAVADOC_PATCH"

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

@ -1,18 +1,23 @@
.TH {{PROJECT_EXECUTABLE | upcase}} "1" .TH {{PROJECT_EXECUTABLE | upcase}} "1"
.SH NAME .SH NAME
{{PROJECT_EXECUTABLE}} \- manual page for {{PROJECT_NAME}} {{PROJECT_EXECUTABLE}} \- a cat(1) clone with syntax highlighting and Git integration.
.SH DESCRIPTION
{{PROJECT_EXECUTABLE}} - a cat(1) clone with syntax highlighting and Git integration.
.SH "USAGE" .SH "USAGE"
.IP .IP "{{PROJECT_EXECUTABLE}} [OPTIONS] [FILE]..."
{{PROJECT_EXECUTABLE}} [OPTIONS] [FILE]... .IP "{{PROJECT_EXECUTABLE}} cache [CACHE-OPTIONS] [--build|--clear]
.IP .SH DESCRIPTION
{{PROJECT_EXECUTABLE}} <SUBCOMMAND> {{PROJECT_EXECUTABLE}} prints the syntax-highlighted content of a collection of FILEs to the
terminal. If no FILE is specified, or when FILE is '-', it reads from standard input.
{{PROJECT_EXECUTABLE}} supports a large number of programming and markup languages.
It also communicates with git(1) to show modifications with respect to the git index.
{{PROJECT_EXECUTABLE}} automatically pipes its output through a pager (by default: less).
Whenever the output of {{PROJECT_EXECUTABLE}} goes to a non-interactive terminal, i.e. when the
output is piped into another process or into a file, {{PROJECT_EXECUTABLE}} will act as a drop-in
replacement for cat(1) and fall back to printing the plain file contents.
.SH "OPTIONS" .SH "OPTIONS"
.HP General remarks: Command-line options like '-l'/'--language' that take values can be specified as
General remarks
.IP
Command-line options like '-l'/'--language' that take values can be specified as
either '--language value', '--language=value', '-l value' or '-lvalue'. either '--language value', '--language=value', '-l value' or '-lvalue'.
.HP .HP
\fB\-A\fR, \fB\-\-show\-all\fR \fB\-A\fR, \fB\-\-show\-all\fR
@ -33,78 +38,80 @@ specified as a name (like 'C++' or 'LaTeX') or possible file extension
(like 'cpp', 'hpp' or 'md'). Use '\-\-list\-languages' to show all supported (like 'cpp', 'hpp' or 'md'). Use '\-\-list\-languages' to show all supported
language names and file extensions. language names and file extensions.
.HP .HP
\fB\-H\fR, \fB\-\-highlight\-line\fR <N>... \fB\-H\fR, \fB\-\-highlight\-line\fR <N:M>...
.IP .IP
Highlight the N\-th line with a different background color Highlight the specified line ranges with a different background color For example:
.RS
.IP "\-\-highlight\-line 40"
highlights line 40
.IP "\-\-highlight\-line 30:40"
highlights lines 30 to 40
.IP "\-\-highlight\-line :40"
highlights lines 1 to 40
.IP "\-\-highlight\-line 40:"
highlights lines 40 to the end of the file
.RE
.HP .HP
\fB\-\-tabs\fR <T> \fB\-\-tabs\fR <T>
.IP .IP
Set the tab width to T spaces. Use a width of 0 to pass tabs through Set the tab width to T spaces. Use a width of 0 to pass tabs through directly
directly
.HP .HP
\fB\-\-wrap\fR <mode> \fB\-\-wrap\fR <mode>
.IP .IP
Specify the text\-wrapping mode (*auto*, never, character). The Specify the text\-wrapping mode (*auto*, never, character). The '\-\-terminal\-width' option
\&'\-\-terminal\-width' option can be used in addition to control the output can be used in addition to control the output width.
width.
.HP .HP
\fB\-\-terminal\-width\fR <width> \fB\-\-terminal\-width\fR <width>
.IP .IP
Explicitly set the width of the terminal instead of determining it Explicitly set the width of the terminal instead of determining it automatically. If
automatically. If prefixed with '+' or '\-', the value will be treated as prefixed with '+' or '\-', the value will be treated as an offset to the actual terminal
an offset to the actual terminal width. See also: '\-\-wrap'. width. See also: '\-\-wrap'.
.HP .HP
\fB\-n\fR, \fB\-\-number\fR \fB\-n\fR, \fB\-\-number\fR
.IP .IP
Only show line numbers, no other decorations. This is an alias for Only show line numbers, no other decorations. This is an alias for '\-\-style=numbers'
\&'\-\-style=numbers'
.HP .HP
\fB\-\-color\fR <when> \fB\-\-color\fR <when>
.IP .IP
Specify when to use colored output. The automatic mode only enables colors Specify when to use colored output. The automatic mode only enables colors if an
if an interactive terminal is detected. Possible values: *auto*, never, interactive terminal is detected. Possible values: *auto*, never, always.
always.
.HP .HP
\fB\-\-italic\-text\fR <when> \fB\-\-italic\-text\fR <when>
.IP .IP
Specify when to use ANSI sequences for italic text in the output. Possible Specify when to use ANSI sequences for italic text in the output. Possible values:
values: always, *never*. always, *never*.
.HP .HP
\fB\-\-decorations\fR <when> \fB\-\-decorations\fR <when>
.IP .IP
Specify when to use the decorations that have been specified via Specify when to use the decorations that have been specified via '\-\-style'. The
\&'\-\-style'. The automatic mode only enables decorations if an interactive automatic mode only enables decorations if an interactive terminal is detected. Possible
terminal is detected. Possible values: *auto*, never, always. values: *auto*, never, always.
.HP .HP
\fB\-\-paging\fR <when> \fB\-\-paging\fR <when>
.IP .IP
Specify when to use the pager. To control which pager is used, set the Specify when to use the pager. To control which pager is used, set the PAGER or
PAGER or BAT_PAGER environment variables (the latter takes precedence) or BAT_PAGER environment variables (the latter takes precedence) or use the '\-\-pager'
use the '\-\-pager' option. To disable the pager permanently, set BAT_PAGER option. To disable the pager permanently, set BAT_PAGER to an empty string or set
to an empty string or set '\-\-paging=never' in the configuration file. \&'\-\-paging=never' in the configuration file. Possible values: *auto*, never, always.
Possible values: *auto*, never, always.
.HP .HP
\fB\-\-pager\fR <command> \fB\-\-pager\fR <command>
.IP .IP
Determine which pager is used. This option will overwrite the PAGER and Determine which pager is used. This option will overwrite the PAGER and BAT_PAGER
BAT_PAGER environment variables. The default pager is 'less'. To disable environment variables. The default pager is 'less'. To disable the pager completely, use
the pager completely, use the '\-\-paging' option. Example: '\-\-pager "less the '\-\-paging' option. Example: '\-\-pager "less \fB\-RF\fR"'.
\fB\-RF\fR"'.
.HP .HP
\fB\-m\fR, \fB\-\-map\-syntax\fR <from:to>... \fB\-m\fR, \fB\-\-map\-syntax\fR <glob-pattern:syntax-name>...
.IP .IP
Map a file extension or file name to an existing syntax (specified by a Map a glob pattern to an existing syntax name. The glob pattern is matched on the full
file extension or file name). For example, to path and the filename. For example, to highlight *.build files with the Python syntax,
highlight *.build files with the Python syntax, use '\-m build:py'. To use -m '*.build:Python'. To highlight files named '.myignore' with the Git Ignore
highlight files named '.myignore' with the Git Ignore syntax, use '\-m syntax, use -m '.myignore:Git Ignore'.
\&.myignore:gitignore'.
.HP .HP
\fB\-\-theme\fR <theme> \fB\-\-theme\fR <theme>
.IP .IP
Set the theme for syntax highlighting. Use '\-\-list\-themes' to see all Set the theme for syntax highlighting. Use '\-\-list\-themes' to see all available themes.
available themes. To set a default theme, add the '\-\-theme="..."' option To set a default theme, add the '\-\-theme="..."' option to the configuration file or
to the configuration file or export the BAT_THEME environment variable export the BAT_THEME environment variable (e.g.: export BAT_THEME="...").
(e.g.: export BAT_THEME="...").
.HP .HP
\fB\-\-list\-themes\fR \fB\-\-list\-themes\fR
.IP .IP
@ -112,12 +119,11 @@ Display a list of supported themes for syntax highlighting.
.HP .HP
\fB\-\-style\fR <style\-components> \fB\-\-style\fR <style\-components>
.IP .IP
Configure which elements (line numbers, file headers, grid borders, Git Configure which elements (line numbers, file headers, grid borders, Git modifications,
modifications, ..) to display in addition to the file contents. The \&..) to display in addition to the file contents. The argument is a comma\-separated list
argument is a comma\-separated list of components to display (e.g. of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full').
\&'numbers,changes,grid') or a pre\-defined style ('full'). To set a default To set a default style, add the '\-\-style=".."' option to the configuration file or
style, add the '\-\-style=".."' option to the configuration file or export export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
values: *auto*, full, plain, changes, header, grid, numbers, snip. values: *auto*, full, plain, changes, header, grid, numbers, snip.
.HP .HP
\fB\-r\fR, \fB\-\-line\-range\fR <N:M>... \fB\-r\fR, \fB\-\-line\-range\fR <N:M>...
@ -138,8 +144,8 @@ Display a list of supported languages for syntax highlighting.
.HP .HP
\fB\-u\fR, \fB\-\-unbuffered\fR \fB\-u\fR, \fB\-\-unbuffered\fR
.IP .IP
This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). This option exists for POSIX\-compliance reasons ('u' is for 'unbuffered'). The output is
The output is always unbuffered \- this option is simply ignored. always unbuffered \- this option is simply ignored.
.HP .HP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
.IP .IP
@ -148,13 +154,20 @@ Print this help message.
\fB\-V\fR, \fB\-\-version\fR \fB\-V\fR, \fB\-\-version\fR
.IP .IP
Show version information. Show version information.
.SH "ARGS" .SH "POSITIONAL ARGUMENTS"
.HP
\fB<FILE>...\fR
.IP .IP
<FILE>... Files to print and concatenate. Use a dash ('\-') or no argument at all to read from
.IP standard input.
File(s) to print / concatenate. Use a dash ('\-') or no argument at all to read
from standard input.
.SH "SUBCOMMANDS" .SH "SUBCOMMANDS"
.IP .HP
cache \fBcache\fR - Modify the syntax\-definition and theme cache.
Modify the syntax\-definition and theme cache .SH "FILES"
{{PROJECT_EXECUTABLE}} can also be customized with a configuration file. The location of the file
is dependent on your operating system. To get the default path for your system, call:
\fB{{PROJECT_EXECUTABLE}} --config-file\fR
Alternatively, you can use the BAT_CONFIG_PATH environment variable to point bat to a non-default
location of the configuration file.

BIN
assets/syntaxes.bin vendored

Binary file not shown.

View File

@ -1,672 +0,0 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: "F#"
file_extensions:
- fs
- fsi
- fsx
scope: source.fsharp
contexts:
main:
- include: compiler_directives
- include: comments
- include: constants
- include: strings
- include: chars
- include: double_tick
- include: definition
- include: abstract_definition
- include: attributes
- include: modules
- include: anonymous_functions
- include: du_declaration
- include: record_declaration
- include: records
- include: strp_inlined
- include: keywords
- include: cexprs
- include: text
abstract_definition:
- match: '\b(abstract)\s+(member)?(\s+\[\<.*\>\])?\s*([_[:alpha:]0-9,\._`\s]+)(:)'
captures:
1: keyword.fsharp
2: keyword.fsharp
3: support.function.attribute.fsharp
5: keyword.fsharp
push:
- meta_scope: abstract.definition.fsharp
- match: \s*(with)\b|=|$
captures:
1: keyword.fsharp
pop: true
- include: comments
- include: common_declaration
- match: '(\?{0,1})([[:alpha:]0-9''`^._ ]+)\s*(:)(\s*([[:alpha:]0-9''`^._ ]+)){0,1}'
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp
3: keyword.symbol.fsharp
4: entity.name.type.fsharp
- match: '(?!with|get|set\b)\b([\w0-9''`^._]+)'
captures:
1: entity.name.type.fsharp
- include: keywords
anonymous_functions:
- match: \b(fun)\b
captures:
1: keyword.fsharp
push:
- meta_scope: function.anonymous
- match: (->)
captures:
1: keyword.fsharp
pop: true
- include: comments
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: \s*(?=(->))
captures:
1: keyword.symbol.fsharp
pop: true
- include: member_declaration
- include: variables
attributes:
- match: '\[\<'
push:
- meta_scope: support.function.attribute.fsharp
- match: '\>\]|\]'
pop: true
- include: main
cexprs:
- match: '\b(async|seq|promise|task|maybe|asyncMaybe|controller|scope|application|pipeline)\s*\{'
scope: cexpr.fsharp
captures:
0: keyword.fsharp
chars:
- match: ('\\?.')
scope: char.fsharp
captures:
1: string.quoted.single.fsharp
comments:
- match: (\(\*(?!\)))
captures:
1: comment.block.fsharp
push:
- meta_scope: comment.block.fsharp
- match: (\*\))
captures:
1: comment.block.fsharp
pop: true
- match: //.*$
scope: comment.line.double-slash.fsharp
common_binding_definition:
- include: comments
- include: attributes
- match: (:)\s*(\()\s*(static member|member)
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
3: keyword.fsharp
push:
- match: (\))\s*((?=,)|(?=\=))
captures:
1: keyword.symbol.fsharp
pop: true
- match: '(\^[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- include: variables
- include: keywords
- match: (:)\s*(\()
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
push:
- match: '(\)\s*(([?[:alpha:]0-9''`^._ ]*)))'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
pop: true
- include: tuple_signature
- match: '(:)\s*(\^[[:alpha:]0-9''._]+)\s*(when)'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
3: keyword.fsharp
push:
- match: (?=:)
captures:
1: keyword.symbol.fsharp
pop: true
- match: \b(and|when|or)\b
scope: keyword.fsharp
- match: "([[:alpha:]0-9'^._]+)"
comment: Because we first capture the keywords, we can capture what looks like a word and assume it's an entity definition
captures:
1: entity.name.type.fsharp
- match: (\(|\))
scope: keyword.symbol.fsharp
- match: '(:)\s*([?[:alpha:]0-9''`^._ ]+)'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
- match: '(->)\s*(\()?\s*([?[:alpha:]0-9''`^._ ]+)*'
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
3: entity.name.type.fsharp
- match: (\*)\s*(\()
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
push:
- match: '(\)\s*(([?[:alpha:]0-9''`^._ ]+))+)'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
pop: true
- include: tuple_signature
- match: '(\*)(\s*([?[:alpha:]0-9''`^._ ]+))*'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
- match: '(<(?![[:space:]]*\)))'
captures:
1: keyword.symbol.fsharp
push:
- match: ((?<!:)>)
captures:
1: keyword.symbol.fsharp
pop: true
- include: generic_declaration
- match: "({)"
captures:
1: keyword.symbol.fsharp
push:
- match: "(})"
captures:
1: keyword.symbol.fsharp
pop: true
- include: record_signature
- include: definition
- include: variables
- include: keywords
common_declaration:
- match: '\s*(->)\s*([[:alpha:]0-9''`^._ ]+)(<)'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
3: keyword.symbol.fsharp
push:
- match: (>)
captures:
1: keyword.symbol.fsharp
pop: true
- match: "([[:alpha:]0-9'`^._ ]+)"
captures:
1: entity.name.type.fsharp
- include: keywords
- match: '\s*(->)\s*(?!with|get|set\b)\b([\w0-9''`^._]+)'
captures:
1: keyword.symbol.fsharp
2: entity.name.type.fsharp
- match: '(\?{0,1})([[:alpha:]0-9''`^._ ]+)\s*(:)(\s*([?[:alpha:]0-9''`^._ ]+)(<))'
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp
3: keyword.symbol.fsharp
4: keyword.symbol.fsharp
5: entity.name.type.fsharp
push:
- match: (>)
captures:
1: keyword.symbol.fsharp
pop: true
- match: "([[:alpha:]0-9'`^._ ]+)"
captures:
1: entity.name.type.fsharp
- include: keywords
compiler_directives:
- match: \s?(#if|#elif|#else|#elseif|#endif|#light|#nowarn)
scope: compiler_directive.fsharp
captures:
constants:
- match: \(\)
scope: constant.language.unit.fsharp
- match: '\b-?[0-9][0-9_]*((\.([0-9][0-9_]*([eE][+-]??[0-9][0-9_]*)?)?)|([eE][+-]??[0-9][0-9_]*))'
scope: constant.numeric.floating-point.fsharp
- match: '\b(-?((0(x|X)[0-9a-fA-F][0-9a-fA-F_]*)|(0(o|O)[0-7][0-7_]*)|(0(b|B)[01][01_]*)|([0-9][0-9_]*)))'
scope: constant.numeric.integer.nativeint.fsharp
- match: \b(true|false|null|unit)\b
scope: constant.others.fsharp
definition:
- match: '\b(let mutable|static let mutable|let inline|let|member val|static member inline|static member|default|member|override|let!)(\s+rec|mutable)?(\s+\[\<.*\>\])?\s*(private|internal|public)?\s+(\[[^-=]*\]|[_[:alpha:]]([_[:alpha:]0-9,\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\._`\s]+|(?<=,)\s)*)?'
captures:
1: keyword.fsharp
2: keyword.fsharp
3: support.function.attribute.fsharp
4: keyword.fsharp
5: variable.fsharp
push:
- meta_scope: binding.fsharp
- match: \s*(with\b|=|\n+=|(?<=\=))
captures:
1: keyword.fsharp
pop: true
- include: common_binding_definition
- match: '\b(static val mutable|val mutable|val)(\s+rec|mutable)?(\s+\[\<.*\>\])?\s*(private|internal|public)?\s+(\[[^-=]*\]|[_[:alpha:]]([_[:alpha:]0-9,\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\._`\s]+|(?<=,)\s)*)?'
captures:
1: keyword.fsharp
2: keyword.fsharp
3: support.function.attribute.fsharp
4: keyword.fsharp
5: variable.fsharp
push:
- meta_scope: binding.fsharp
- match: \n$
pop: true
- include: common_binding_definition
double_tick:
- match: (``)(.*)(``)
scope: variable.other.binding.fsharp
captures:
1: string.quoted.single.fsharp
2: variable.other.binding.fsharp
3: string.quoted.single.fsharp
du_declaration:
- match: \b(of)\b
captures:
1: keyword.fsharp
push:
- meta_scope: du_declaration.fsharp
- match: $|(\|)
captures:
1: keyword.symbol.fsharp
pop: true
- include: comments
- match: '([[:alpha:]0-9''`<>^._]+|``[[:alpha:]0-9'' <>^._]+``)\s*(:)\s*([[:alpha:]0-9''`<>^._]+|``[[:alpha:]0-9'' <>^._]+``)'
captures:
1: variable.parameter.fsharp
2: keyword.symbol.fsharp
3: entity.name.type.fsharp
- match: "([[:alpha:]0-9'`^._]+)|``([[:alpha:]0-9'^._ ]+)``"
captures:
1: entity.name.type.fsharp
- include: keywords
generic_declaration:
- match: (:)\s*(\()\s*(static member|member)
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
3: keyword.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- include: member_declaration
- match: '((''|\^)[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- include: variables
- include: keywords
- match: \b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\!|return\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|use|use\!|struct|while|mutable)(?!')\b
scope: keyword.fsharp
- match: ":"
scope: keyword.fsharp
- include: constants
- match: '((''|\^)[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- match: (<)
captures:
1: keyword.symbol.fsharp
push:
- match: (>)
captures:
1: keyword.symbol.fsharp
pop: true
- match: '((''|\^)[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- include: tuple_signature
- include: generic_declaration
- match: '(?!when|and|or\b)\b([\w0-9''`^._]+)'
captures:
1: entity.name.type.fsharp
- match: (\|)
captures:
1: keyword.symbol.fsharp
- include: keywords
keywords:
- match: \b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\!|return\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|or|use|use\!|struct|while|mutable)(?!')\b
scope: keyword.fsharp
- match: '(&&&|\|\|\||\^\^\^|~~~|<<<|>>>|\|>|\->|\<\-|:>|:\?>|:|\[|\]|\;|<>|=|@|\|\||&&|{|}|\||_|\.\.|\,|\+|\-|\*|\/|\^|\!|\>|\>\=|\>\>|\<|\<\=|\(|\)|\<\<)'
scope: keyword.symbol.fsharp
member_declaration:
- include: comments
- include: common_declaration
- match: (:)\s*(\()\s*(static member|member)
captures:
1: keyword.symbol.fsharp
2: keyword.symbol.fsharp
3: keyword.fsharp
push:
- match: (\))\s*((?=,)|(?=\=))
captures:
1: keyword.symbol.fsharp
pop: true
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- include: member_declaration
- match: '(\^[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- include: variables
- include: keywords
- match: '(\^[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- match: \b(and|when|or)\b
scope: keyword.fsharp
- match: (\(|\))
scope: keyword.symbol.fsharp
- match: '(\?{0,1})([[:alpha:]0-9''`^._]+|``[[:alpha:]0-9''`^:,._ ]+``)\s*(:{0,1})(\s*([?[:alpha:]0-9''`<>._ ]+)){0,1}'
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp
3: keyword.symbol.fsharp
4: entity.name.type.fsharp
- include: keywords
modules:
- match: '\b(namespace|module)\s*(public|internal|private)?\s+([[:alpha:]][[:alpha:]0-9''_. ]*)'
captures:
1: keyword.fsharp
2: keyword.fsharp
3: entity.name.section.fsharp
push:
- meta_scope: entity.name.section.fsharp
- match: (\s?=|\s|$)
captures:
1: keyword.symbol.fsharp
pop: true
- match: '(\.)([A-Z][[:alpha:]0-9''_]*)'
scope: entity.name.section.fsharp
captures:
1: punctuation.separator.namespace-reference.fsharp
2: entity.name.section.fsharp
- match: '\b(open)\s+([[:alpha:]][[:alpha:]0-9''_]*)(?=(\.[A-Z][[:alpha:]0-9_]*)*)'
captures:
1: keyword.fsharp
2: entity.name.section.fsharp
push:
- meta_scope: namespace.open.fsharp
- match: (\s|$)
pop: true
- match: '(\.)([[:alpha:]][[:alpha:]0-9''_]*)'
scope: entity.name.section.fsharp
captures:
1: punctuation.separator.namespace-reference.fsharp
2: entity.name.section.fsharp
- match: '^\s*(module)\s+([A-Z][[:alpha:]0-9''_]*)\s*(=)\s*([A-Z][[:alpha:]0-9''_]*)'
captures:
1: keyword.fsharp
2: entity.name.type.namespace.fsharp
3: punctuation.separator.namespace-definition.fsharp
4: entity.name.section.fsharp
push:
- meta_scope: namespace.alias.fsharp
- match: (\s|$)
pop: true
- match: '(\.)([A-Z][[:alpha:]0-9''_]*)'
scope: entity.name.section.fsharp
captures:
1: punctuation.separator.namespace-reference.fsharp
2: entity.name.section.fsharp
record_declaration:
- match: '(\{)'
captures:
1: keyword.symbol.fsharp
push:
- match: '(?<=\})'
pop: true
- include: comments
- match: '(((mutable)\s[[:alpha:]]+)|[[:alpha:]0-9''`<>^._]*)\s*((?<!:):(?!:))\s*'
captures:
3: keyword.fsharp
4: keyword.symbol.fsharp
push:
- match: '$|(;|\})'
captures:
1: keyword.symbol.fsharp
pop: true
- include: comments
- match: "([[:alpha:]0-9'`^_ ]+)"
captures:
1: entity.name.type.fsharp
- include: keywords
- include: compiler_directives
- include: constants
- include: strings
- include: chars
- include: double_tick
- include: definition
- include: attributes
- include: anonymous_functions
- include: keywords
- include: cexprs
- include: text
record_signature:
- match: "[[:alpha:]0-9'`^_ ]+(=)([[:alpha:]0-9'`^_ ]+)"
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp
- match: "({)"
captures:
1: keyword.symbol.fsharp
push:
- match: "(})"
captures:
1: keyword.symbol.fsharp
pop: true
- match: "[[:alpha:]0-9'`^_ ]+(=)([[:alpha:]0-9'`^_ ]+)"
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp
- include: record_signature
- include: keywords
records:
- match: '\b(type)[\s]+(private|internal|public)?\s*'
captures:
1: keyword.fsharp
2: keyword.fsharp
push:
- meta_scope: record.fsharp
- match: '\s*((with)|((as)\s+([[:alpha:]0-9'']+))|(=)|[\n=]|(\(\)))'
captures:
2: keyword.fsharp
3: keyword.fsharp
4: keyword.fsharp
5: variable.parameter.fsharp
6: keyword.symbol.fsharp
7: constant.language.unit.fsharp
pop: true
- include: comments
- include: attributes
- match: "([[:alpha:]0-9'^._]+|``[[:alpha:]0-9'`^:,._ ]+``)"
captures:
1: entity.name.type.fsharp
- match: (<)
captures:
1: keyword.fsharp
push:
- match: ((?<!:)>)
captures:
1: keyword.fsharp
pop: true
- match: '((''|\^)``[[:alpha:]0-9`^:,._ ]+``|(''|\^)[[:alpha:]0-9`^:._]+)'
captures:
1: entity.name.type.fsharp
- match: \b(interface|with|abstract|and|when|or|not|struct|equality|comparison|unmanaged|delegate|enum)\b
scope: keyword.fsharp
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- match: (static member|member|new)
captures:
1: keyword.fsharp
- include: common_binding_definition
- match: '([\w0-9''`^._]+)'
captures:
1: entity.name.type.fsharp
- include: keywords
- match: \s*(private|internal|public)
captures:
1: keyword.symbol.fsharp
2: keyword.fsharp
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: '\s*(?=(=)|[\n=]|(\(\))|(as))'
captures:
1: keyword.symbol.fsharp
pop: true
- include: member_declaration
- include: keywords
string_formatter:
- match: (%0?-?(\d+)?((a|t)|(\.\d+)?(f|F|e|E|g|G|M)|(b|c|s|d|i|x|X|o|u)|(s|b|O)|(\+?A)))
scope: entity.name.type.format.specifier.fsharp
captures:
1: keyword.format.specifier.fsharp
strings:
- match: '(?=[^\\])(@")'
captures:
1: punctuation.definition.string.begin.fsharp
push:
- meta_scope: string.quoted.literal.fsharp
- match: (")(?!")
captures:
1: punctuation.definition.string.end.fsharp
pop: true
- match: '"(")'
scope: constant.character.string.escape.fsharp
- match: '(?=[^\\])(""")'
captures:
1: punctuation.definition.string.begin.fsharp
push:
- meta_scope: string.quoted.triple.fsharp
- match: (""")
captures:
1: punctuation.definition.string.end.fsharp
pop: true
- include: string_formatter
- match: '(?=[^\\])(")'
captures:
1: punctuation.definition.string.begin.fsharp
push:
- meta_scope: string.quoted.double.fsharp
- match: (")
captures:
1: punctuation.definition.string.end.fsharp
pop: true
- match: '\\$[ \t]*'
scope: punctuation.separator.string.ignore-eol.fsharp
- match: '\\([\\''''ntbr]|u[a-fA-F0-9]{4}|u[a-fA-F0-9]{8})'
scope: constant.character.string.escape.fsharp
- match: '\\(?![\\''''ntbr]|u[a-fA-F0-9]{4}|u[a-fA-F0-9]{8}).'
scope: invalid.illeagal.character.string.fsharp
- include: string_formatter
strp_inlined:
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- include: strp_inlined_body
strp_inlined_body:
- include: comments
- include: anonymous_functions
- match: '(\^[[:alpha:]0-9''._]+)'
captures:
1: entity.name.type.fsharp
- match: \b(and|when|or)\b
scope: keyword.fsharp
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- include: strp_inlined_body
- match: '(static member|member)\s*([[:alpha:]0-9''`<>^._]+|``[[:alpha:]0-9'' <>^._]+``)\s*(:)'
captures:
1: keyword.fsharp
2: variable.fsharp
3: keyword.symbol.fsharp
- include: compiler_directives
- include: constants
- include: strings
- include: chars
- include: double_tick
- include: keywords
- include: text
- include: definition
- include: attributes
- include: keywords
- include: cexprs
- include: text
text:
- match: \\
scope: text.fsharp
tuple_signature:
- match: "(([?[:alpha:]0-9'`^._ ]+))+"
captures:
1: entity.name.type.fsharp
- match: (\()
captures:
1: keyword.symbol.fsharp
push:
- match: (\))
captures:
1: keyword.symbol.fsharp
pop: true
- match: "(([?[:alpha:]0-9'`^._ ]+))+"
captures:
1: entity.name.type.fsharp
- include: tuple_signature
- include: keywords
variables:
- match: \(\)
scope: constant.language.unit.fsharp
- match: '(\?{0,1})(``[[:alpha:]0-9''`^:,._ ]+``|[[:alpha:]0-9''`<>^._ ]\w*)'
captures:
1: keyword.symbol.fsharp
2: variable.parameter.fsharp

BIN
assets/themes.bin vendored

Binary file not shown.

View File

@ -7,6 +7,7 @@ extern crate liquid;
use std::error::Error; use std::error::Error;
use std::fs; use std::fs;
use std::path::Path;
// Read environment variables. // Read environment variables.
lazy_static! { lazy_static! {
@ -17,34 +18,13 @@ lazy_static! {
.unwrap_or("bat"); .unwrap_or("bat");
} }
fn init_template() -> liquid::value::Object {
let mut globals = liquid::value::Object::new();
globals.insert(
"PROJECT_NAME".into(),
liquid::value::Value::scalar(PROJECT_NAME.to_owned()),
);
globals.insert(
"PROJECT_EXECUTABLE".into(),
liquid::value::Value::scalar(EXECUTABLE_NAME.to_owned()),
);
globals.insert(
"PROJECT_VERSION".into(),
liquid::value::Value::scalar(PROJECT_VERSION.to_owned()),
);
globals
}
/// Generates a file from a liquid template. /// Generates a file from a liquid template.
fn template( fn template(
variables: &liquid::value::Object, variables: &liquid::Object,
in_file: &str, in_file: &str,
out_file: &str, out_file: impl AsRef<Path>,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let template = liquid::ParserBuilder::with_liquid() let template = liquid::ParserBuilder::with_stdlib()
.build()? .build()?
.parse(&fs::read_to_string(in_file)?)?; .parse(&fs::read_to_string(in_file)?)?;
@ -53,13 +33,27 @@ fn template(
} }
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let variables = init_template(); let variables = liquid::object!({
"PROJECT_NAME": PROJECT_NAME.to_owned(),
"PROJECT_EXECUTABLE": EXECUTABLE_NAME.to_owned(),
"PROJECT_VERSION": PROJECT_VERSION.to_owned(),
});
template(&variables, "assets/manual/bat.1.in", "assets/manual/bat.1")?; let out_dir_env = std::env::var_os("OUT_DIR").expect("OUT_DIR to be set in build.rs");
let out_dir = Path::new(&out_dir_env);
std::fs::create_dir_all(out_dir.join("assets/manual")).unwrap();
std::fs::create_dir_all(out_dir.join("assets/completions")).unwrap();
template(
&variables,
"assets/manual/bat.1.in",
out_dir.join("assets/manual/bat.1"),
)?;
template( template(
&variables, &variables,
"assets/completions/bat.fish.in", "assets/completions/bat.fish.in",
"assets/completions/bat.fish", out_dir.join("assets/completions/bat.fish"),
)?; )?;
Ok(()) Ok(())

11
ci/before_deploy.bash vendored
View File

@ -38,7 +38,7 @@ pack() {
"${gcc_prefix}"strip "$tempdir/$package_name/$PROJECT_NAME" "${gcc_prefix}"strip "$tempdir/$package_name/$PROJECT_NAME"
# manpage, readme and license # manpage, readme and license
cp "assets/manual/bat.1" "$tempdir/$package_name/$PROJECT_NAME.1" cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/manual/bat.1 "$tempdir/$package_name/$PROJECT_NAME.1"
cp README.md "$tempdir/$package_name" cp README.md "$tempdir/$package_name"
cp LICENSE-MIT "$tempdir/$package_name" cp LICENSE-MIT "$tempdir/$package_name"
cp LICENSE-APACHE "$tempdir/$package_name" cp LICENSE-APACHE "$tempdir/$package_name"
@ -47,7 +47,7 @@ pack() {
# TODO: disabled for now, see issue #372 # TODO: disabled for now, see issue #372
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".bash "$tempdir/$package_name/autocomplete/${PROJECT_NAME}.bash-completion" # cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".bash "$tempdir/$package_name/autocomplete/${PROJECT_NAME}.bash-completion"
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".fish "$tempdir/$package_name/autocomplete" # cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/"$PROJECT_NAME".fish "$tempdir/$package_name/autocomplete"
cp "assets/completions/bat.fish" "$tempdir/$package_name/autocomplete/$PROJECT_NAME.fish" cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/completions/bat.fish "$tempdir/$package_name/autocomplete/$PROJECT_NAME.fish"
# cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/_"$PROJECT_NAME" "$tempdir/$package_name/autocomplete" # cp target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/_"$PROJECT_NAME" "$tempdir/$package_name/autocomplete"
# archiving # archiving
@ -108,11 +108,11 @@ make_deb() {
"${gcc_prefix}"strip "$tempdir/usr/bin/$PROJECT_NAME" "${gcc_prefix}"strip "$tempdir/usr/bin/$PROJECT_NAME"
# manpage # manpage
install -Dm644 "assets/manual/bat.1" "$tempdir/usr/share/man/man1/$PROJECT_NAME.1" install -Dm644 target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/manual/bat.1 "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
gzip --best "$tempdir/usr/share/man/man1/$PROJECT_NAME.1" gzip --best "$tempdir/usr/share/man/man1/$PROJECT_NAME.1"
# completions # completions
install -Dm644 "assets/completions/bat.fish" "$tempdir/usr/share/fish/vendor_completions.d/$PROJECT_NAME.fish" install -Dm644 target/"$TARGET"/release/build/"$PROJECT_NAME"-*/out/assets/completions/bat.fish "$tempdir/usr/share/fish/vendor_completions.d/$PROJECT_NAME.fish"
# readme and license # readme and license
install -Dm644 README.md "$tempdir/usr/share/doc/$PROJECT_NAME/README.md" install -Dm644 README.md "$tempdir/usr/share/doc/$PROJECT_NAME/README.md"
@ -164,7 +164,8 @@ Package: $dpkgname
Version: $version Version: $version
Section: utils Section: utils
Priority: optional Priority: optional
Maintainer: David Peter <mail@david-peter.de> Maintainer: $maintainer
Homepage: $homepage
Architecture: $architecture Architecture: $architecture
Provides: $PROJECT_NAME Provides: $PROJECT_NAME
Conflicts: $conflictname Conflicts: $conflictname

View File

@ -13,7 +13,7 @@
<a href="#インストール">インストール</a> <a href="#インストール">インストール</a>
<a href="#カスタマイズ">カスタマイズ</a> <a href="#カスタマイズ">カスタマイズ</a>
<a href="#プロジェクトの目標と既存の類似したOSS">プロジェクトの目標と既存の類似したOSS</a> <a href="#プロジェクトの目標と既存の類似したOSS">プロジェクトの目標と既存の類似したOSS</a>
翻訳 [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="README-ja.md">日本語</a>] 翻訳 [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="README-ja.md">日本語</a>][<a href="README-ko.md">한국어</a>]
</p> </p>
### シンタックスハイライト ### シンタックスハイライト
@ -180,7 +180,7 @@ apt install bat
batの最新リリースを実行する場合、または Ubuntu/Debian の古いバージョンを使用している場合は、[release page](https://github.com/sharkdp/bat/releases) から最新の `.deb` パッケージをダウンロードし、 batの最新リリースを実行する場合、または Ubuntu/Debian の古いバージョンを使用している場合は、[release page](https://github.com/sharkdp/bat/releases) から最新の `.deb` パッケージをダウンロードし、
次の方法でインストールします: 次の方法でインストールします:
```bash ```bash
sudo dpkg -i bat_0.12.1_amd64.deb # adapt version number and architecture sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
``` ```
### On Alpine Linux ### On Alpine Linux
@ -500,11 +500,11 @@ export BAT_CONFIG_PATH="/path/to/bat.conf"
# Use italic text on the terminal (not supported on all terminals) # Use italic text on the terminal (not supported on all terminals)
--italic-text=always --italic-text=always
# Use C++ syntax (instead of C) for .h header files # Use C++ syntax for .ino files
--map-syntax h:cpp --map-syntax "*.ino:C++"
# Use "gitignore" highlighting for ".ignore" files # Use ".gitignore"-style highlighting for ".ignore" files
--map-syntax .ignore:.gitignore --map-syntax ".ignore:Git Ignore"
``` ```
## Windows での `bat` の利用 ## Windows での `bat` の利用

560
doc/README-ko.md Normal file
View File

@ -0,0 +1,560 @@
<p align="center">
<img src="../doc/logo-header.svg" alt="bat - a cat clone with wings"><br>
<a href="https://travis-ci.org/sharkdp/bat"><img src="https://travis-ci.org/sharkdp/bat.svg?branch=master" alt="Build Status"></a>
<a href="https://ci.appveyor.com/project/sharkdp/bat"><img src="https://ci.appveyor.com/api/projects/status/cptsmtbiwbnr2vhf/branch/master?svg=true"></a>
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
문법 강조와 깃 통합 기능의 <i>cat(1)</i> 클론
</p>
<p align="center">
<a href="#문법-강조">주요 기능들</a>
<a href="#사용법">사용법</a>
<a href="#설치">설치</a>
<a href="#커스터마이즈">커스터마이즈</a>
<a href="#프로젝트-목표와-대안들">프로젝트 목표와 대안들</a>
번역 [<a href="https://github.com/chinanf-boy/bat-zh">中文</a>][<a href="../doc/README-ja.md">日本語</a>]
</p>
### 문법 강조
`bat`은 다양한 프로그래밍 언어와 마크업 언어에 대해 문법 강조(Syntax highlighting)기능을 지원하고 있습니다:
![Syntax highlighting example](https://imgur.com/rGsdnDe.png)
### Git 통합
`bat``git`을 통해 인덱스와 함께 변경분을 표시합니다 (왼쪽 바를 확인하세요):
![Git integration example](https://i.imgur.com/2lSW4RE.png)
### 표시할 수 없는 문자 처리
`-A`/`--show-all` 옵션을 사용하여 표시할수 없는 문자를 시각화 해줍니다:
![Non-printable character example](https://i.imgur.com/WndGp9H.png)
### 자동 페이징
하나의 화면에 비해 출력이 너무 큰 경우, `less` 를 이용해 출력들을 연결할 수 있습니다.
### 파일 연결
이 뿐만 아니라 파일을 연결할 때도 사용 할 수 있습니다. :wink: `bat`가 인터렉티브 하지 않은(non-interactive)가 감지하면 (예를 들어,다른 프로세스 혹은 파일과 파이프라인을 연결 한 경우) `bat``cat`을 대신하여 동작하며 일반 파일 내용을 표기해줍니다.
## 사용법
터미널에서 하나의 파일 표시하기
```bash
> bat README.md
```
여러 파일 한번에 보여주기
```bash
> bat src/*.rs
```
stdin에서 읽고, 자동으로 맞는 문법 강조 적용하기
```bash
> curl -s https://sh.rustup.rs | bat
```
stdin에서 읽고, 명시적으로 언어 지정하여 적용하기
```bash
> yaml2json .travis.yml | json_pp | bat -l json
```
표시할 수 없는 문자 처리하기
```bash
> bat -A /etc/hosts
```
`cat` 대신 사용하기:
```bash
bat > note.md # quickly create a new file
bat header.md content.md footer.md > document.md
bat -n main.rs # show line numbers (only)
bat f - g # output 'f', then stdin, then 'g'.
```
### 다른 툴과의 통합
#### `find``fd`
`find``-exec` 옵션을 사용하여 `bat`의 모든 검색 결과를 미리 볼 수 있습니다:
```bash
find … -exec bat {} +
```
[`fd`](https://github.com/sharkdp/fd)를 사용하고 있는 경우, `-X`/`--exec-batch` 옵션을 이용하여 동일하게 사용할 수 있습니다:
```bash
fd … -X bat
```
#### `ripgrep`
[`batgrep`](https://github.com/eth-p/bat-extras/blob/master/doc/batgrep.md)과 함께, [`ripgrep`](https://github.com/BurntSushi/ripgrep)의 검색 결과를 `bat`을 이용하여 볼 수 있습니다.
```bash
batgrep needle src/
```
#### `tail -f`
`bat``tail -f`를 함께 사용하여, 특정 파일을 문법 강조하며 지속적으로 모니터링 할 수 있습니다.
```bash
tail -f /var/log/pacman.log | bat --paging=never -l log
```
이 작업을 하려면 페이징 기능을 꺼야합니다. 또, 자동 감지가 되지 않기 때문에, 적용되어야할 문법을 명시적(`-l log`)으로 지정해야 합니다.
#### `git`
`bat``git show`를 함께 사용하여 주어진 파일의 이전 기록을 문법 강조와 함께 볼 수 있습니다:
```bash
git show v0.6.0:src/main.rs | bat -l rs
```
diffs 내에서 문법 강조 표시는 현재 지원되지 않습니다. 이 기능은 [`delta`](https://github.com/dandavison/delta)에서 찾아 볼 수 있습니다.
#### `xclip`
`bat` 출력에서 라인 넘버와 Git 수정 내역이 같이 있어 파일 내용을 복사하기가 어려울 수도 있습니다. 이 경우에는 `-p`/`--plain` 옵션을 사용 하거나 출력 시 파이프라인으로 `xclip`을 사용하면 됩니다:
```bash
bat main.cpp | xclip
```
`bat` 에서는 리다이렉트된 것으로 감지하여, 파일 내용만 출력합니다.
#### `man`
`bat``MANPAGER` 환경 변수 설정을 통해 `man`에 대하여 컬러 페이져를 사용할 수 있습니다:
```bash
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
man 2 select
```
포매팅 문제가 발생한다면, `MANROFFOPT="-c"` 설정 해야 할 수도 있습니다 .
새 커맨드에서 이 번들을 사용하려면, [`batman`](https://github.com/eth-p/bat-extras/blob/master/doc/batman.md)을 이용 할 수 있습니다.
참고 : [Manpage syntax](../assets/syntaxes/Manpage.sublime-syntax)는 이 저장소에서 개발되고 있으며, 아직 작업 중 입니다.
#### `prettier` / `shfmt` / `rustfmt`
[`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) 스크립트는 코드를 포맷팅하고 `bat`으로 출력해주는 랩퍼(wrapper) 입니다.
## 설치
[![Packaging status](https://repology.org/badge/vertical-allrepos/bat.svg)](https://repology.org/project/bat/versions)
### On Ubuntu
*... 그리고 기타 Debian 기반의 Linux 배포판들.*
Ubuntu Eoan 19.10 혹은 Debian unstable sid 이후 버전 부터는 [Ubuntu용 `bat` 패키지](https://packages.ubuntu.com/eoan/bat)나 [Debian용 `bat` 패키지](https://packages.debian.org/sid/bat) 를 설치 할 수 있습니다.
```bash
apt install bat
```
만약 최근 릴리즈된 bat을 사용을 원하거나 buntu/Debian 예전 버전을 사용하는 경우, [릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다음과 같이 `.deb` 패키지를 받아 설치 할 수도 있습니다:
```bash
sudo dpkg -i bat_0.13.0_amd64.deb # adapt version number and architecture
```
### On Alpine Linux
공식 소스를 통해 [`bat` 패키지](https://pkgs.alpinelinux.org/packages?name=bat) 를 설치 할 수 있습니다:
```bash
apk add bat
```
### On Arch Linux
공식 소스를 통해 [`bat` 패키지](https://www.archlinux.org/packages/community/x86_64/bat/)를 설치할 수 있습니다:
```bash
pacman -S bat
```
### On Fedora
[공식 Fedora 모듈 저장소](https://docs.fedoraproject.org/en-US/modularity/using-modules/)에서 [`bat` 패키지](https://koji.fedoraproject.org/koji/packageinfo?packageID=27506)을 설치할 수 있습니다:
```bash
dnf install bat
```
### On Gentoo Linux
공식 소스를 통해 [`bat` 패키지](https://packages.gentoo.org/packages/sys-apps/bat)를 설치할 수 있습니다.
```bash
emerge sys-apps/bat
```
### On Void Linux
xbps-install를 이용해 `bat`을 설치할 수 있습니다:
```bash
xbps-install -S bat
```
### On FreeBSD
pkg를 이용하여 미리 컴파일된 [`bat` 패키지](https://www.freshports.org/textproc/bat)를 설치할 수 있습니다:
```bash
pkg install bat
```
또는 FreeBSD 포트에서 직접 빌드할 수도 있습니다:
```bash
cd /usr/ports/textproc/bat
make install
```
### Via nix
[nix package manager](https://nixos.org/nix)를 이용해 `bat`을 설치할 수 있습니다:
```bash
nix-env -i bat
```
### On openSUSE
zypper을 이용해 `bat`을 설치할 수 있습니다:
```bash
zypper install bat
```
### On macOS
[Homebrew](http://braumeister.org/formula/bat)를 이용해 `bat`을 설치할 수 있습니다:
```bash
brew install bat
```
또는 [MacPorts](https://ports.macports.org/port/bat/summary)를 사용할 수도 있습니다:
```bash
port install bat
```
### On Windows
Windows에서 `bat`을 설치할 수 있는 몇 가지 옵션들이 있습니다. 먼저 `bat`을 설치 한 후, ["Windows에서 사용하기"](#Windows에서-사용하기) 참고하시기 바랍니다.
#### With Chocolatey
[Chocolatey](https://chocolatey.org/packages/Bat)를 이용해 `bat`을 설치할 수 있습니다:
```bash
choco install bat
```
#### With Scoop
[scoop](https://scoop.sh/)을 이용해 `bat`을 설치할 수 있습니다:
```bash
scoop install bat
```
[Visual C++ Redistributable 패키지](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)를 같이 설치해 주어야 합니다.
#### From prebuilt binaries:
[릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 빌드된 바이너리를 다운받을 수 있습니다.
[Visual C++ Redistributable 패키지](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)를 같이 설치해 주어야 합니다.
### Via Docker
컨테이너에서 `bat`을 사용할 수 있는 [Docker image](https://hub.docker.com/r/danlynn/bat/)가 있습니다.:
```bash
docker pull danlynn/bat
alias bat='docker run -it --rm -e BAT_THEME -e BAT_STYLE -e BAT_TABS -v "$(pwd):/myapp" danlynn/bat'
```
### Via Ansible
[Ansible](https://www.ansible.com/)을 사용해 `bat`을 설치할 수 있습니다:
```bash
# Install role on local machine
ansible-galaxy install aeimer.install_bat
```
```yaml
---
# Playbook to install bat
- host: all
roles:
- aeimer.install_bat
```
- [Ansible Galaxy](https://galaxy.ansible.com/aeimer/install_bat)
- [GitHub](https://github.com/aeimer/ansible-install-bat)
다음 배포판들에서 동작합니다:
- Debian/Ubuntu
- ARM (eg. Raspberry PI)
- Arch Linux
- Void Linux
- FreeBSD
- MacOS
### From binaries
[릴리즈 페이지](https://github.com/sharkdp/bat/releases)에서 다양한 환경을 위해 빌드된 버전들을 확인 할 수 있습니다. 정적 링크 바이너리들은 아카이브에서 파일 이름에 `musl` 이 포함 파일로 확인 할 수 있습니다.
### From source
`bat`의 소스를 직접 빌드하기 위해서는, Rust 1.36 이상이 필요하며 `cargo`를 이용해 빌드할 수 있습니다.
```bash
cargo install bat
```
일부 플랫폼에서는 `llvm` 그리고/또는 `libclang-dev` 설치가 필요할 수도 있습니다.
## 커스터마이즈
### 문법 강조 테마
`bat --list-themes`을 사용하면, 현재 사용 가능한 문법 강조 테마들을 확인할 수 있습니다. `TwoDark` 테마 선택하는 경우, `--theme=TwoDark` 옵션과 함께 `bat`을 사용하거나 환경변수에서 `BAT_THEME``TwoDark`로 세팅해주면 됩니다. 쉘 시작 파일에 `export BAT_THEME="TwoDark"` 를 정의해 계속 사용도 가능합니다. 이 밖에 `bat`의 [설정 파일](#설정-파일)을 이용할 수도 있습니다.
다른 테마를 미리 보고 싶은경우 다음 명령어와 같이 사용할 수 있습니다.(이 경우 [`fzf`](https://github.com/junegunn/fzf)가 필요합니다.)
```bash
bat --list-themes | fzf --preview="bat --theme={} --color=always /path/to/file"
```
`bat`의 기본 테마는 어두운 배경색 터미널에 적합합니다. 만일 밝은 배경색을 사용할 경우에는 `GitHub` 이나 `OneHalfLight` 과 같은 테마가 더 잘 어울립니다. 아래 [새로운 테마 추가하기](#새로운-테마-추가하기)에 따라 커스텀 테마를 사용할수도 있습니다.
### 출력 스타일
`--style` 옵션을 이용하여 `bat`의 출력 스타일을 변경 할 수 있습니다. 예를 들어, `--style=numbers,changes`는 Git 변경분과 라인 넘버에 대해서만 출력하며 눈금과 파일 헤더가 표시되지 않습니다. `BAT_STYLE` 환경 변수로 정의하여 계속해서 사용하거나`bat`의 [설정 파일](#설정-파일)을 사용할 수도 있습니다.
### 새로운 문법 강조 / 언어 추가하기
`bat`은 문법 강조를 위해 [`syntect`](https://github.com/trishume/syntect/) 라이브러리를 사용하고 있습니다. `syntect`는 [Sublime Text의 `.sublime-syntax` 파일](https://www.sublimetext.com/docs/3/syntax.html)과 테마를 읽을 수 있습니다. 새로운 문법 강조를 추가하는 방법은 다음과 같습니다.
우선 문법 정의 파일을 넣을 폴더를 만듭니다:
```bash
mkdir -p "$(bat --config-dir)/syntaxes"
cd "$(bat --config-dir)/syntaxes"
# Put new '.sublime-syntax' language definition files
# in this folder (or its subdirectories), for example:
git clone https://github.com/tellnobody1/sublime-purescript-syntax
```
다음 명령어를 통해 파일을 바이너리 캐시로 파싱합니다.
```bash
bat cache --build
```
마지막으로 `bat --list-languages`을 통해 새로운 언어가 사용 가능한지 확인합니다.
기본 설정으로 돌아가려면, 다음 명령어를 이용합니다.:
```bash
bat cache --clear
```
### 새로운 테마 추가하기
새로운 문법 정의 추가와 매우 유사합니다.
먼저, 새로운 문법 강조 테마 폴더를 만듭니다.
```bash
mkdir -p "$(bat --config-dir)/themes"
cd "$(bat --config-dir)/themes"
# Download a theme in '.tmTheme' format, for example:
git clone https://github.com/greggb/sublime-snazzy
# Update the binary cache
bat cache --build
```
마지막으로 `bat --list-themes`을 통해 새로운 테마가 사용 가능한지 확인합니다.
### 다른 페이져 사용하기
`bat`은 환경변수 `PAGER`로 사용할 페이져를 명시합니다. 만약 이 변수가 정의되어있지 않다면 `less`가 기본입니다. 만약 다른 페이져를 사용하고 싶다면 `PAGER` 변수를 수정하거나 `BAT_PAGER` 환경 변수로 `PAGER` 대신 정의 할 수도 있습니다.
만약 커맨드라인 인수로 넘기려면, `PAGER`/`BAT_PAGER` 변수를 정의를 통해 사용 할 수 있습니다. :
```bash
export BAT_PAGER="less -RF"
```
환경 변수 대신, `bat`의 [설정 파일](#설정-파일)에서 페이져를 설정 할 수도 있습니다.(`--pager` 옵션)
**참고**: 기본적으로 페이져가 `less`로 설정 되어있다면, `bat`은 다음 옵션들을 받을 수 있습니다: `-R`/`--RAW-CONTROL-CHARS`,
`-F`/`--quit-if-one-screen` 그리고 `-X`/`--no-init`. 마지막 옵션(`-X`)은 530 이전 버전에서만 사용됩니다.
`-R` 옵션은 ANSI 컬러를 올바르게 해석하기 위해 필요합니다. 두번째 옵션 (`-F`)은 출력 크기가 터미널의 세로 크기보다 작을 경우 즉시 종료되도록 합니다.
페이져를 종료하기 위해 `q`를 누를 필요 없기 때문에 작은 파일을 다룰 때 용이합니다. 세번째 옵션(`-X`)는 `less` 이전 버전의 `--quit-if-one-screen` 기능과 함께 버그를 잡을 때 필요합니다. 안타깝게도, `less`의 마우스 휠 지원은 종료합니다.
`less` 예전 버전에서 마우스 휠 기능을 활성화 시키려면, `-R` 옵션을 사용하면 됩니다. (위의 예제처럼, 이 옵션은 quit-if-one-screen 기능을 비활성화 시킵니다.)
530 이하 버전에서는 그대로 사용할 수 있습니다.
### 다크 모드
macOS에서 다크 모드를 사용하고 있다면, OS 테마에 따라 다른 테마를 사용하도록 `bat`의 구성할 수 있습니다. 아래 코드는 라이트 모드에서는 `default` 테마를 다크모드에서는 `Github` 테마를 사용하는 방법입니다.
```bash
alias cat="bat --theme=\$(defaults read -globalDomain AppleInterfaceStyle &> /dev/null && echo default || echo GitHub)"
```
## 설정 파일
`bat` 설정 파일로 커스터마이즈 할 수 있습니다. 파일의 위치는 운영 체제에 따라 다릅니다. 아래 커맨드를 통해 시스템의 기본 경로를 알 수 있습니다.
```
bat --config-file
```
또는, `BAT_CONFIG_PATH` 환경 변수를 사용하여 `bat`의 설정 파일 위치를 지정할 수 있습니다.
```bash
export BAT_CONFIG_PATH="/path/to/bat.conf"
```
### 포맷
설정 파일은 명령어 인수들의 리스트 입니다. `bat --help`를 이용하여 가능한 옵션들과 값들을 확인해 볼 수 있습니다. 또, `#` 으로 주석을 추가할수도 있습니다.
설정 파일의 예:
```bash
# Set the theme to "TwoDark"
--theme="TwoDark"
# Show line numbers, Git modifications and file header (but no grid)
--style="numbers,changes,header"
# Use italic text on the terminal (not supported on all terminals)
--italic-text=always
# Use C++ syntax for .ino files
--map-syntax "*.ino:C++"
# Use ".gitignore"-style highlighting for ".ignore" files
--map-syntax ".ignore:Git Ignore"
```
## Windows에서 사용하기
`bat` 대부분의 경우 Windows에서 기본적으로 잘 작동하지만, 일부 기능에는 추가 적인 구성이 필요할 수 있습니다.
### 페이징
Windows는 `more` 형식의 매우 제한된 페이저만이 포함되어있습니다. `less`용 Windows 바이너리는 [이 홈페이지](http://www.greenwoodsoftware.com/less/download.html)나 [Chocolatey](https://chocolatey.org/packages/Less)에서 다운로드 받을 수 있습니다. 이를 사용하려면 바이너리를 `PATH` 디렉토리에 배치하거나 [환경 변수로 정의](#using-a-different-pager) 하세요. [Chocolatey 패키지](#on-windows)로 `less`를 자동으로 설치할 수 있습니다.
### 색상
Windows 10은 기본 내장기능으로 [v1511](https://en.wikipedia.org/wiki/Windows_10_version_history#Version_1511_(November_Update)) 이후의 `conhost.exe`(Command Prompt) 와 PowerShell, 그리고 최신 버전의 bash에서 색상을 지원합니다. 이전 버전의 Windows에서는, [ConEmu](https://conemu.github.io/)가 포함 된 [Cmder](http://cmder.net/)를 사용할 수 있습니다 .
**참고:** `less`의 Git과 MSYS 버전은 Windows에서 색상을 올바르게 해석하지 않습니다. 다른 페이져가 설치되어 있지 않은 경우, `--paging=never` 하거나 `BAT_PAGER`를 빈 문자열로 설정하여 페이징을 완전히 비활성화 할 수 있습니다 .
### Cygwin
Windows에서의 `bat`은 기본적으로 Cygwin의 unix 스타일의 경로(`/cygdrive/*`)를 지원하지 않습니다. cygwin 절대경로를 인자로 받았을 때, `bat`은 다음과 같이 오류를 반환합니다. `:The system cannot find the path specified. (os error 3)`
이 경우, wrapper를 만들거나 다음 함수를 `.bash_profile`추가하여 문제를 해결하실 수 있습니다 :
```bash
bat() {
local index
local args=("$@")
for index in $(seq 0 ${#args[@]}) ; do
case "${args[index]}" in
-*) continue;;
*) [ -e "${args[index]}" ] && args[index]="$(cygpath --windows "${args[index]}")";;
esac
done
command bat "${args[@]}"
}
```
## 트러블슈팅
### 터미널과 색상
`bat`은 터미널 트루컬러 지원 여부와 상관없이 동작합니다. 하지만, 문법 강조 테마의 색상이 8-bit 컬러에는 최적화 되어 있지 않고 있으며, 24-bit 트루컬러 지원하는 터미널 사용하는 것을 적극 권장합니다.(`terminator`, `konsole`, `iTerm2`, ...). [이 글](https://gist.github.com/XVilka/8346728)에서 24-bit 트루컬러 지원하는 터미널들을 찾아보실 수 있습니다.
사용하고 있는 터미널에서 `COLORTERM``truecolor` 혹은
`24bit`으로 설정 되어있는지 확인하세요. 만약 아니라면, `bat`은 24-bit escape sequence를 지원되는지 여부를 판단 할 수 없습니다. (그리고 8-bit 색상으로 돌아갑니다.)
### 라인 숫자와 눈금이 잘 보이지 않는 경우
다른 테마를 사용해 보세요. (`bat --list-themes`에서 테마들을 확인해 볼 수 있습니다.) `OneHalfDark``OneHalfLight` 테마는 눈금과 선의 색을 밝게 합니다.
### 파일 인코딩
`bat`은 기본적으로 UTF-8과 UTF-8을 제공합니다. 다른 파일 인코딩의 경우, 자동 감지 되지 않으므로 UTF-8로 먼저 변환해 주어야 합니다. 이렇게 할 때, `iconv`를 사용 할 수 있습니다. 예를 들어, Latin-1 (ISO-8859-1)로 인코딩된 PHP파일이라면 다음과 같이 사용할 수 있습니다.:
``` bash
iconv -f ISO-8859-1 -t UTF-8 my-file.php | bat
```
참고: `bat`으로 자동 감지가 되지 않는 경우에는 `-l`/`--language` 옵션을 사용할 수도 있습니다.
## 배포
```bash
# Recursive clone to retrieve all submodules
git clone --recursive https://github.com/sharkdp/bat
# Build (debug version)
cd bat
cargo build --bins
# Run unit tests and integration tests
cargo test
# Install (release version)
cargo install
# Build a bat binary with modified syntaxes and themes
bash assets/create.sh
cargo install -f
```
## 메인테이너들
- [sharkdp](https://github.com/sharkdp)
- [eth-p](https://github.com/eth-p)
## 프로젝트 목표와 대안들
`bat`은 아래와 같은 목표를 달성하려고 합니다:
- 아름답고 발전된 문법 강조 기능
- Git 연동을 통한 파일 수정 내역 확인
- (POSIX)`cat`의 대체제
- 사용자 친화적인 CLI 제공
비슷한 프로그램들을 찾고 있다면, 많은 대안들이 있습니다. 비교는 [이 문서]((doc/alternatives.md))를 참조해주세요.
## 라이센스
Copyright (c) 2018-2020 [bat-developers](https://github.com/sharkdp/bat).
`bat`는 MIT 라이센스 및 Apache 라이센스 2.0의 조건에 따라 배포됩니다.
라이센스 세부사항은 [LICENSE-APACHE](LICENSE-APACHE)와 [LICENSE-MIT](LICENSE-MIT)를 참조하세요.

33
examples/cat.rs Normal file
View File

@ -0,0 +1,33 @@
/// A very simple colorized `cat` clone, using `bat` as a library.
/// See `src/bin/bat` for the full `bat` application.
use bat::{
config::{Config, InputFile, StyleComponent, StyleComponents},
Controller, HighlightingAssets,
};
use console::Term;
use std::process;
fn main() {
let files = std::env::args_os().skip(1).collect::<Vec<_>>();
if files.is_empty() {
eprintln!("No input files specified");
process::exit(1);
}
let config = Config {
term_width: Term::stdout().size().1 as usize,
colored_output: true,
true_color: true,
style_components: StyleComponents::new(&[
StyleComponent::Header,
StyleComponent::Grid,
StyleComponent::Numbers,
]),
files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
..Default::default()
};
let assets = HighlightingAssets::from_binary();
Controller::new(&config, &assets).run().expect("no errors");
}

View File

@ -1,35 +1,20 @@
/// A simple program that prints its own source code using the bat library
use bat::{ use bat::{
assets::HighlightingAssets, config::{Config, InputFile},
controller::Controller, Controller, HighlightingAssets,
inputfile::InputFile,
style::{OutputComponent, OutputComponents},
Config,
}; };
use console::Term; use std::ffi::OsStr;
use std::process;
fn main() { fn main() {
let files = std::env::args_os().skip(1).collect::<Vec<_>>(); let path_to_this_file = OsStr::new(file!());
if files.is_empty() {
eprintln!("No input files specified");
process::exit(1);
}
let config = Config { let config = Config {
term_width: Term::stdout().size().1 as usize, files: vec![InputFile::Ordinary(path_to_this_file)],
colored_output: true, colored_output: true,
true_color: true, true_color: true,
output_components: OutputComponents::new(&[
OutputComponent::Header,
OutputComponent::Grid,
OutputComponent::Numbers,
]),
files: files.iter().map(|file| InputFile::Ordinary(file)).collect(),
theme: "1337".into(),
..Default::default() ..Default::default()
}; };
let assets = HighlightingAssets::new(); let assets = HighlightingAssets::from_binary();
Controller::new(&config, &assets).run().expect("no errors"); Controller::new(&config, &assets).run().expect("no errors");
} }

View File

@ -1,41 +1,35 @@
use std::borrow::Cow;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::BufReader; use std::io::BufReader;
use std::path::{Path, PathBuf}; use std::path::Path;
use syntect::dumps::{dump_to_file, from_binary, from_reader}; use syntect::dumps::{dump_to_file, from_binary, from_reader};
use syntect::highlighting::{Theme, ThemeSet}; use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder}; use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
use crate::dirs::PROJECT_DIRS;
use crate::errors::*; use crate::errors::*;
use crate::inputfile::{InputFile, InputFileReader}; use crate::inputfile::{InputFile, InputFileReader};
use crate::syntax_mapping::SyntaxMapping; use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
pub const BAT_THEME_DEFAULT: &str = "Monokai Extended";
#[derive(Debug)] #[derive(Debug)]
pub struct HighlightingAssets { pub struct HighlightingAssets {
pub syntax_set: SyntaxSet, pub(crate) syntax_set: SyntaxSet,
pub theme_set: ThemeSet, pub(crate) theme_set: ThemeSet,
fallback_theme: Option<&'static str>,
} }
impl HighlightingAssets { impl HighlightingAssets {
pub fn new() -> Self { pub fn default_theme() -> &'static str {
Self::from_cache().unwrap_or_else(|_| Self::from_binary()) "Monokai Extended"
} }
pub fn from_files(dir: Option<&Path>, start_empty: bool) -> Result<Self> { pub fn from_files(source_dir: &Path, include_integrated_assets: bool) -> Result<Self> {
let source_dir = dir.unwrap_or_else(|| PROJECT_DIRS.config_dir()); let mut theme_set = if include_integrated_assets {
Self::get_integrated_themeset()
let mut theme_set = if start_empty { } else {
ThemeSet { ThemeSet {
themes: BTreeMap::new(), themes: BTreeMap::new(),
} }
} else {
Self::get_integrated_themeset()
}; };
let theme_dir = source_dir.join("themes"); let theme_dir = source_dir.join("themes");
@ -48,7 +42,7 @@ impl HighlightingAssets {
); );
} }
let mut syntax_set_builder = if start_empty { let mut syntax_set_builder = if !include_integrated_assets {
let mut builder = SyntaxSetBuilder::new(); let mut builder = SyntaxSetBuilder::new();
builder.add_plain_text_syntax(); builder.add_plain_text_syntax();
builder builder
@ -69,15 +63,15 @@ impl HighlightingAssets {
Ok(HighlightingAssets { Ok(HighlightingAssets {
syntax_set: syntax_set_builder.build(), syntax_set: syntax_set_builder.build(),
theme_set, theme_set,
fallback_theme: None,
}) })
} }
fn from_cache() -> Result<Self> { pub fn from_cache(theme_set_path: &Path, syntax_set_path: &Path) -> Result<Self> {
let theme_set_path = theme_set_path(); let syntax_set_file = File::open(syntax_set_path).chain_err(|| {
let syntax_set_file = File::open(&syntax_set_path()).chain_err(|| {
format!( format!(
"Could not load cached syntax set '{}'", "Could not load cached syntax set '{}'",
syntax_set_path().to_string_lossy() syntax_set_path.to_string_lossy()
) )
})?; })?;
let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file)) let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file))
@ -95,6 +89,7 @@ impl HighlightingAssets {
Ok(HighlightingAssets { Ok(HighlightingAssets {
syntax_set, syntax_set,
theme_set, theme_set,
fallback_theme: None,
}) })
} }
@ -106,18 +101,18 @@ impl HighlightingAssets {
from_binary(include_bytes!("../assets/themes.bin")) from_binary(include_bytes!("../assets/themes.bin"))
} }
fn from_binary() -> Self { pub fn from_binary() -> Self {
let syntax_set = Self::get_integrated_syntaxset(); let syntax_set = Self::get_integrated_syntaxset();
let theme_set = Self::get_integrated_themeset(); let theme_set = Self::get_integrated_themeset();
HighlightingAssets { HighlightingAssets {
syntax_set, syntax_set,
theme_set, theme_set,
fallback_theme: None,
} }
} }
pub fn save(&self, dir: Option<&Path>) -> Result<()> { pub fn save_to_cache(&self, target_dir: &Path) -> Result<()> {
let target_dir = dir.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
let _ = fs::create_dir_all(target_dir); let _ = fs::create_dir_all(target_dir);
let theme_set_path = target_dir.join("themes.bin"); let theme_set_path = target_dir.join("themes.bin");
let syntax_set_path = target_dir.join("syntaxes.bin"); let syntax_set_path = target_dir.join("syntaxes.bin");
@ -149,22 +144,36 @@ impl HighlightingAssets {
Ok(()) Ok(())
} }
pub fn get_theme(&self, theme: &str) -> &Theme { pub fn set_fallback_theme(&mut self, theme: &'static str) {
self.fallback_theme = Some(theme);
}
pub fn syntaxes(&self) -> &[SyntaxReference] {
self.syntax_set.syntaxes()
}
pub fn themes(&self) -> impl Iterator<Item = &String> {
self.theme_set.themes.keys()
}
pub(crate) fn get_theme(&self, theme: &str) -> &Theme {
match self.theme_set.themes.get(theme) { match self.theme_set.themes.get(theme) {
Some(theme) => theme, Some(theme) => theme,
None => { None => {
use ansi_term::Colour::Yellow; if theme != "" {
eprintln!( use ansi_term::Colour::Yellow;
"{}: Unknown theme '{}', using default.", eprintln!(
Yellow.paint("[bat warning]"), "{}: Unknown theme '{}', using default.",
theme Yellow.paint("[bat warning]"),
); theme
&self.theme_set.themes[BAT_THEME_DEFAULT] );
}
&self.theme_set.themes[self.fallback_theme.unwrap_or(Self::default_theme())]
} }
} }
} }
pub fn get_syntax( pub(crate) fn get_syntax(
&self, &self,
language: Option<&str>, language: Option<&str>,
filename: InputFile, filename: InputFile,
@ -175,25 +184,28 @@ impl HighlightingAssets {
(Some(language), _) => self.syntax_set.find_syntax_by_token(language), (Some(language), _) => self.syntax_set.find_syntax_by_token(language),
(None, InputFile::Ordinary(filename)) => { (None, InputFile::Ordinary(filename)) => {
let path = Path::new(filename); let path = Path::new(filename);
let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
let extension = path.extension().and_then(|x| x.to_str()).unwrap_or(""); let extension = path.extension().and_then(|x| x.to_str()).unwrap_or("");
let file_name = mapping.replace(file_name);
let extension = mapping.replace(extension);
let ext_syntax = self let ext_syntax = self
.syntax_set .syntax_set
.find_syntax_by_extension(&file_name) .find_syntax_by_extension(&file_name)
.or_else(|| self.syntax_set.find_syntax_by_extension(&extension)); .or_else(|| self.syntax_set.find_syntax_by_extension(&extension));
let line_syntax = if ext_syntax.is_none() { let line_syntax = String::from_utf8(reader.first_line.clone())
String::from_utf8(reader.first_line.clone()) .ok()
.ok() .and_then(|l| self.syntax_set.find_syntax_by_first_line(&l));
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))
} else {
None
};
ext_syntax.or(line_syntax) let absolute_path = path.canonicalize().ok().unwrap_or(path.to_owned());
match mapping.get_syntax_for(absolute_path) {
Some(MappingTarget::MapTo(syntax_name)) => {
// TODO: we should probably return an error here if this syntax can not be
// found. Currently, we just fall back to 'plain'.
self.syntax_set.find_syntax_by_name(syntax_name)
}
Some(MappingTarget::MapToUnknown) => line_syntax,
None => ext_syntax.or(line_syntax),
}
} }
(None, InputFile::StdIn) => String::from_utf8(reader.first_line.clone()) (None, InputFile::StdIn) => String::from_utf8(reader.first_line.clone())
.ok() .ok()
@ -205,28 +217,120 @@ impl HighlightingAssets {
} }
} }
fn theme_set_path() -> PathBuf { #[cfg(test)]
PROJECT_DIRS.cache_dir().join("themes.bin") mod tests {
} use std::ffi::OsStr;
use std::fs::File;
use std::io;
use std::io::Write;
fn syntax_set_path() -> PathBuf { use tempdir::TempDir;
PROJECT_DIRS.cache_dir().join("syntaxes.bin")
}
pub fn config_dir() -> Cow<'static, str> { use crate::assets::HighlightingAssets;
PROJECT_DIRS.config_dir().to_string_lossy() use crate::inputfile::InputFile;
} use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
pub fn cache_dir() -> Cow<'static, str> { struct SyntaxDetectionTest<'a> {
PROJECT_DIRS.cache_dir().to_string_lossy() assets: HighlightingAssets,
} pub syntax_mapping: SyntaxMapping<'a>,
temp_dir: TempDir,
}
pub fn clear_assets() { impl<'a> SyntaxDetectionTest<'a> {
print!("Clearing theme set cache ... "); fn new() -> Self {
fs::remove_file(theme_set_path()).ok(); SyntaxDetectionTest {
println!("okay"); assets: HighlightingAssets::from_binary(),
syntax_mapping: SyntaxMapping::builtin(),
temp_dir: TempDir::new("bat_syntax_detection_tests")
.expect("creation of temporary directory"),
}
}
print!("Clearing syntax set cache ... "); fn synax_for_file_with_content(&self, file_name: &str, first_line: &str) -> String {
fs::remove_file(syntax_set_path()).ok(); let file_path = self.temp_dir.path().join(file_name);
println!("okay"); {
let mut temp_file = File::create(&file_path).unwrap();
writeln!(temp_file, "{}", first_line).unwrap();
}
let input_file = InputFile::Ordinary(OsStr::new(&file_path));
let syntax = self.assets.get_syntax(
None,
input_file,
&mut input_file.get_reader(&io::stdin()).unwrap(),
&self.syntax_mapping,
);
syntax.name.clone()
}
fn syntax_for_file(&self, file_name: &str) -> String {
self.synax_for_file_with_content(file_name, "")
}
}
#[test]
fn syntax_detection_basic() {
let test = SyntaxDetectionTest::new();
assert_eq!(test.syntax_for_file("test.rs"), "Rust");
assert_eq!(test.syntax_for_file("test.cpp"), "C++");
assert_eq!(test.syntax_for_file("test.build"), "NAnt Build File");
assert_eq!(
test.syntax_for_file("PKGBUILD"),
"Bourne Again Shell (bash)"
);
assert_eq!(test.syntax_for_file(".bashrc"), "Bourne Again Shell (bash)");
assert_eq!(test.syntax_for_file("Makefile"), "Makefile");
}
#[test]
fn syntax_detection_well_defined_mapping_for_duplicate_extensions() {
let test = SyntaxDetectionTest::new();
assert_eq!(test.syntax_for_file("test.h"), "C++");
assert_eq!(test.syntax_for_file("test.sass"), "Sass");
assert_eq!(test.syntax_for_file("test.hs"), "Haskell (improved)");
assert_eq!(test.syntax_for_file("test.js"), "JavaScript (Babel)");
}
#[test]
fn syntax_detection_first_line() {
let test = SyntaxDetectionTest::new();
assert_eq!(
test.synax_for_file_with_content("my_script", "#!/bin/bash"),
"Bourne Again Shell (bash)"
);
assert_eq!(
test.synax_for_file_with_content("build", "#!/bin/bash"),
"Bourne Again Shell (bash)"
);
assert_eq!(
test.synax_for_file_with_content("my_script", "<?php"),
"PHP"
);
}
#[test]
fn syntax_detection_with_custom_mapping() {
let mut test = SyntaxDetectionTest::new();
assert_eq!(test.syntax_for_file("test.h"), "C++");
test.syntax_mapping
.insert("*.h", MappingTarget::MapTo("C"))
.ok();
assert_eq!(test.syntax_for_file("test.h"), "C");
}
#[test]
fn syntax_detection_is_case_sensitive() {
let mut test = SyntaxDetectionTest::new();
assert_ne!(test.syntax_for_file("README.MD"), "Markdown");
test.syntax_mapping
.insert("*.MD", MappingTarget::MapTo("Markdown"))
.ok();
assert_eq!(test.syntax_for_file("README.MD"), "Markdown");
}
} }

View File

@ -17,13 +17,12 @@ use console::Term;
use ansi_term; use ansi_term;
use bat::{ use bat::{
assets::BAT_THEME_DEFAULT, config::{
Config, HighlightedLineRanges, InputFile, LineRange, LineRanges, MappingTarget, OutputWrap,
PagingMode, StyleComponent, StyleComponents, SyntaxMapping,
},
errors::*, errors::*,
inputfile::InputFile, HighlightingAssets,
line_range::{LineRange, LineRanges},
style::{OutputComponent, OutputComponents, OutputWrap},
syntax_mapping::SyntaxMapping,
Config, PagingMode,
}; };
fn is_truecolor_terminal() -> bool { fn is_truecolor_terminal() -> bool {
@ -79,7 +78,7 @@ impl App {
pub fn config(&self) -> Result<Config> { pub fn config(&self) -> Result<Config> {
let files = self.files(); let files = self.files();
let output_components = self.output_components()?; let style_components = self.style_components()?;
let paging_mode = match self.matches.value_of("paging") { let paging_mode = match self.matches.value_of("paging") {
Some("always") => PagingMode::Always, Some("always") => PagingMode::Always,
@ -105,17 +104,17 @@ impl App {
} }
}; };
let mut syntax_mapping = SyntaxMapping::new(); let mut syntax_mapping = SyntaxMapping::builtin();
if let Some(values) = self.matches.values_of("map-syntax") { if let Some(values) = self.matches.values_of("map-syntax") {
for from_to in values { for from_to in values {
let parts: Vec<_> = from_to.split(':').collect(); let parts: Vec<_> = from_to.split(':').collect();
if parts.len() != 2 { if parts.len() != 2 {
return Err("Invalid syntax mapping. The format of the -m/--map-syntax option is 'from:to'.".into()); return Err("Invalid syntax mapping. The format of the -m/--map-syntax option is '<glob-pattern>:<syntax-name>'. For example: '*.cpp:C++'.".into());
} }
syntax_mapping.insert(parts[0], parts[1]); syntax_mapping.insert(parts[0], MappingTarget::MapTo(parts[1]))?;
} }
} }
@ -158,7 +157,7 @@ impl App {
Some("character") => OutputWrap::Character, Some("character") => OutputWrap::Character,
Some("never") => OutputWrap::None, Some("never") => OutputWrap::None,
Some("auto") | _ => { Some("auto") | _ => {
if output_components.plain() { if style_components.plain() {
OutputWrap::None OutputWrap::None
} else { } else {
OutputWrap::Character OutputWrap::Character
@ -188,7 +187,7 @@ impl App {
.or_else(|| env::var("BAT_TABS").ok()) .or_else(|| env::var("BAT_TABS").ok())
.and_then(|t| t.parse().ok()) .and_then(|t| t.parse().ok())
.unwrap_or( .unwrap_or(
if output_components.plain() && paging_mode == PagingMode::Never { if style_components.plain() && paging_mode == PagingMode::Never {
0 0
} else { } else {
4 4
@ -201,33 +200,34 @@ impl App {
.or_else(|| env::var("BAT_THEME").ok()) .or_else(|| env::var("BAT_THEME").ok())
.map(|s| { .map(|s| {
if s == "default" { if s == "default" {
String::from(BAT_THEME_DEFAULT) String::from(HighlightingAssets::default_theme())
} else { } else {
s s
} }
}) })
.unwrap_or_else(|| String::from(BAT_THEME_DEFAULT)), .unwrap_or_else(|| String::from(HighlightingAssets::default_theme())),
line_ranges: LineRanges::from( line_ranges: self
self.matches .matches
.values_of("line-range") .values_of("line-range")
.map(|vs| vs.map(LineRange::from).collect()) .map(|vs| vs.map(LineRange::from).collect())
.transpose()? .transpose()?
.unwrap_or_else(|| vec![]), .map(LineRanges::from)
), .unwrap_or_default(),
output_components, style_components,
syntax_mapping, syntax_mapping,
pager: self.matches.value_of("pager"), pager: self.matches.value_of("pager"),
use_italic_text: match self.matches.value_of("italic-text") { use_italic_text: match self.matches.value_of("italic-text") {
Some("always") => true, Some("always") => true,
_ => false, _ => false,
}, },
highlight_lines: LineRanges::from( highlighted_lines: self
self.matches .matches
.values_of("highlight-line") .values_of("highlight-line")
.map(|ws| ws.map(LineRange::from).collect()) .map(|ws| ws.map(LineRange::from).collect())
.transpose()? .transpose()?
.unwrap_or_else(|| vec![LineRange { lower: 0, upper: 0 }]), .map(LineRanges::from)
), .map(|lr| HighlightedLineRanges(lr))
.unwrap_or_default(),
filenames: self filenames: self
.matches .matches
.values_of("file-name") .values_of("file-name")
@ -252,23 +252,23 @@ impl App {
.unwrap_or_else(|| vec![InputFile::StdIn]) .unwrap_or_else(|| vec![InputFile::StdIn])
} }
fn output_components(&self) -> Result<OutputComponents> { fn style_components(&self) -> Result<StyleComponents> {
let matches = &self.matches; let matches = &self.matches;
Ok(OutputComponents( Ok(StyleComponents(
if matches.value_of("decorations") == Some("never") { if matches.value_of("decorations") == Some("never") {
HashSet::new() HashSet::new()
} else if matches.is_present("number") { } else if matches.is_present("number") {
[OutputComponent::Numbers].iter().cloned().collect() [StyleComponent::Numbers].iter().cloned().collect()
} else if matches.is_present("plain") { } else if matches.is_present("plain") {
[OutputComponent::Plain].iter().cloned().collect() [StyleComponent::Plain].iter().cloned().collect()
} else { } else {
let env_style_components: Option<Vec<OutputComponent>> = env::var("BAT_STYLE") let env_style_components: Option<Vec<StyleComponent>> = env::var("BAT_STYLE")
.ok() .ok()
.map(|style_str| { .map(|style_str| {
style_str style_str
.split(',') .split(',')
.map(|x| OutputComponent::from_str(&x)) .map(|x| StyleComponent::from_str(&x))
.collect::<Result<Vec<OutputComponent>>>() .collect::<Result<Vec<StyleComponent>>>()
}) })
.transpose()?; .transpose()?;
@ -277,12 +277,12 @@ impl App {
.map(|styles| { .map(|styles| {
styles styles
.split(',') .split(',')
.map(|style| style.parse::<OutputComponent>()) .map(|style| style.parse::<StyleComponent>())
.filter_map(|style| style.ok()) .filter_map(|style| style.ok())
.collect::<Vec<_>>() .collect::<Vec<_>>()
}) })
.or(env_style_components) .or(env_style_components)
.unwrap_or_else(|| vec![OutputComponent::Full]) .unwrap_or_else(|| vec![StyleComponent::Full])
.into_iter() .into_iter()
.map(|style| style.components(self.interactive_output)) .map(|style| style.components(self.interactive_output))
.fold(HashSet::new(), |mut acc, components| { .fold(HashSet::new(), |mut acc, components| {

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