1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-09-01 10:52:24 +01:00

Compare commits

..

75 Commits

Author SHA1 Message Date
David Peter
8244eb8ef8 Experiment: remove CARGO_TEST_OPTIONS
In principle, this *could* work. `cargo cross` runs the tests via QEMU.
For integration tests, the only difficulty is that we run `bat` from
within the tests. But maybe this is handled by assert_cmd.
2021-08-22 16:31:41 +02:00
David Peter
ff70a80741 Add statically linked binaries for ARM 2021-08-22 15:52:23 +02:00
David Peter
ecdb17148d Use Ubuntu 20.04 instead of 18.04 2021-08-22 15:52:23 +02:00
David Peter
11bd523f7e Remove post-release section 2021-08-22 09:38:35 +02:00
David Peter
01fbedc246 Formatting 2021-08-22 09:38:35 +02:00
David Peter
05e4e1f2f2 Add refined version of release checklist 2021-08-22 09:38:35 +02:00
David Peter
20223ad77c Add old release checklist 2021-08-22 09:38:35 +02:00
a1346054
51edacb5eb style: trim excess whitespace 2021-08-21 23:07:37 +02:00
a1346054
5197ef9048 fix: spelling 2021-08-21 23:07:37 +02:00
a1346054
19678527e5 chore(find-slow-to-highlight-files.py): be explicit about using python3
In many distros, `python` no longer leads to anything, and instead
`python2` or `python3` need to be explicitly run.
2021-08-21 23:07:37 +02:00
a1346054
5d319dee94 style(create.sh): remove non-POSIX keyword 2021-08-21 23:07:37 +02:00
Ville Skyttä
43e1a11ad8 Make Package Control reference a link 2021-08-19 07:21:32 +02:00
Martin Nordholts
ed09f90e5e Fix all lints that are new with Rust 1.54
They are all of the following type:
https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
2021-08-19 07:19:12 +02:00
Martin Nordholts
cbd96237fd CICD: Add 'cargo fmt' check 2021-08-19 07:18:05 +02:00
Martin Nordholts
f5c1cb2dff Run 'cargo fmt' 2021-08-19 07:18:05 +02:00
Keith Hall
5eb93a6eae Merge pull request #1800 from sharkdp/syslog_no_colon_after_process
Fix syslog syntax highlighting when no colon after "process"
2021-08-17 21:22:52 +03:00
Martin Nordholts
25fa577cd0 Make 'build-assets' an optional capability for application
Also structure features a bit more clever to avoid duplication of
feature dependency declarations.
2021-08-17 10:58:21 +02:00
Martin Nordholts
deddc81426 src/assets.rs: Use ThemeSet::new() instead of BTreeMap::new() 2021-08-17 10:58:21 +02:00
Keith Hall
133b06e945 Fix syslog syntax highlighting when no colon after "process" 2021-08-16 22:15:39 +03:00
Mario Finelli
699f1e65cc Add slim syntax test 2021-08-16 06:16:53 +02:00
Mario Finelli
9ef87dab27 Convert tmLanguage into sublime-syntax 2021-08-16 06:16:53 +02:00
Mario Finelli
5125e9c941 Add support for ruby-slim syntax 2021-08-16 06:16:53 +02:00
Bill Risher
6c62ed5608 revamped integration test, made CHANGELOG changes 2021-08-14 22:02:58 +02:00
Bill Risher
bf78288e9e feat(config): added recognition of $BAT_CONFIG_DIR 2021-08-14 22:02:58 +02:00
Keith Hall
f8498b260b Merge pull request #1793 from scop/syslog-improvements
Syslog highlight improvements
2021-08-12 09:49:33 +03:00
Ville Skyttä
79f08588c6 Mention syslog highlight improvements in change log 2021-08-11 23:03:33 +03:00
Ville Skyttä
2d92a4dbb3 Allow colon in syslog loghost
Makes it work with IPv6 addresses.
2021-08-11 21:36:43 +03:00
Ville Skyttä
f508ddf66d Allow period in syslog loghost
Makes it work with FQDN's and IPv4 addresses.
2021-08-11 16:43:04 +03:00
Ville Skyttä
02218c916c Allow period in syslog process name 2021-08-11 16:41:56 +03:00
Martin Nordholts
89217e0d58 Make --no-paging and --no-pager work again 2021-08-09 13:37:56 +02:00
Martin Nordholts
cb4973987b Cargo.toml: Introduce 'quick-build-application' feature
Use it like this:

  cargo build --no-default-features --features quick-build-application

It reduces dependencies to build from 154 to 125, allowing quicker iteration
when developing the app.
2021-08-08 11:18:26 +02:00
Martin Nordholts
905902d811 bin: Allow to build without bugreport 2021-08-08 11:18:26 +02:00
Martin Nordholts
c83e382eac Cargo.toml: Only build bugreport with the app 2021-08-08 11:18:26 +02:00
Martin Nordholts
f6975e2acd Bump bugreport to 0.4.1 2021-08-08 11:18:26 +02:00
Martin Nordholts
d8b813c0bf When returning a SyntaxReference, also return the SyntaxSet that contains it (#1776)
To improve startup performance, we will later load smaller `SyntaxSet`s instead
of one giant one. However, the current API assumes only one `SyntaxSet` is ever used,
and that that implicitly is the `SyntaxSet` from which returned `SyntaxReference`s
comes.

This change changes the API to reflect that `SyntaxSet` and `SyntaxReference`
are tightly coupled, and enables the use of several `SyntaxSet`.
2021-08-08 08:26:17 +02:00
Martin Nordholts
5236ed135e Fix typo in unreachable!(..) message for --wrap 2021-08-08 06:40:18 +02:00
Martin Nordholts
47d955a2ab Add code for analyzing dependencies between syntaxes
And also to generate independent SyntaxSets. This will later be used
to improve bat startup time.
2021-08-07 22:38:39 +02:00
Martin Nordholts
bd797c75a4 integration_tests: Add diagnostic_sanity_check() 2021-08-07 20:07:46 +02:00
Keith Hall
05c11964fc add patch for Python syntax to help improve performance 2021-08-07 17:54:08 +02:00
Martin Nordholts
8ecd23eab4 Make --style docs reflect that 'full' is default
Closes #1742
2021-08-07 09:51:36 +02:00
Martin Nordholts
1ef0206f24 CHANGELOG.md: Highlight for vimrc and gvimrc files 2021-08-06 09:26:56 +02:00
dependabot[bot]
6694aa369e Bump assets/syntaxes/02_Extra/VimL from 7ebcaa1 to c91fe3a
Bumps [assets/syntaxes/02_Extra/VimL](https://github.com/SalGnt/Sublime-VimL) from `7ebcaa1` to `c91fe3a`.
- [Release notes](https://github.com/SalGnt/Sublime-VimL/releases)
- [Commits](7ebcaa1d98...c91fe3ab02)

---
updated-dependencies:
- dependency-name: assets/syntaxes/02_Extra/VimL
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-06 09:26:56 +02:00
Martin Nordholts
0331d28ee4 cargo fmt 2021-08-05 20:21:18 +02:00
Layle | Luca
51c7eb7ac1 Included LLVM syntax highlighting submodule and added regression tests 2021-08-05 20:20:33 +02:00
Keith Hall
5516bcb839 Merge pull request #1779 from sharkdp/http-request-response-syntax-update
Bump assets/syntaxes/02_Extra/http-request-response from f58bffe to 93b9326
2021-08-04 09:47:34 +03:00
Keith Hall
056b966501 Bump assets/syntaxes/02_Extra/http-request-response from f58bffe to 93b9326 2021-08-03 23:07:55 +03:00
Martin Nordholts
28eca6a2be Use assert!(..) instead of assert_eq!(true, ..)
This fixes all of these lint warnings:
https://rust-lang.github.io/rust-clippy/master/index.html#bool_assert_comparison

They only appear in recent versions of clippy. Not on our MSRV.
2021-08-02 22:35:50 +02:00
dependabot[bot]
b7fd55242e Bump assert_cmd from 1.0.5 to 1.0.8
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 1.0.5 to 1.0.8.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v1.0.5...v1.0.8)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 22:19:55 +02:00
dependabot[bot]
8161955cc7 Bump nix from 0.21.0 to 0.22.0
Bumps [nix](https://github.com/nix-rust/nix) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/nix-rust/nix/releases)
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/commits)

---
updated-dependencies:
- dependency-name: nix
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 22:17:45 +02:00
Keith Hall
3b020fd95a Merge pull request #1771 from sharkdp/warn_when_missing_contexts
Warn when building assets from files if some referenced contexts are missing
2021-08-02 22:55:37 +03:00
Martin Nordholts
697d106bd4 CICD: Pass --locked to all cargo commands
To avoid that earlier cargo commands "fixes" Cargo.lock before cargo commands
with --locked has a chance to check if it is up to date.
2021-08-02 21:49:51 +02:00
Keith Hall
50e1c6074f Warn when building assets from files if some referenced contexts are missing 2021-08-02 21:22:01 +03:00
Martin Nordholts
a610987ef7 assets::tests: Add get_syntax_name() helper
And instead of taking a get_syntax_set() detour to return a
name that represents "no syntax", return such a string directly.
2021-08-02 19:23:14 +02:00
dependabot[bot]
a7fd9f4b1b Bump predicates from 1.0.8 to 2.0.1
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 1.0.8 to 2.0.1.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v1.0.8...v2.0.1)

---
updated-dependencies:
- dependency-name: predicates
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 23:18:16 +02:00
dependabot[bot]
5f5b77cdda Bump semver from 0.11.0 to 1.0.4
Bumps [semver](https://github.com/dtolnay/semver) from 0.11.0 to 1.0.4.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/0.11.0...1.0.4)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 13:58:34 +02:00
dependabot[bot]
83808a63be Bump serde from 1.0.126 to 1.0.127
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.126 to 1.0.127.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.126...v1.0.127)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-01 13:56:19 +02:00
Keith Hall
6d5ff671e7 Add HTTP Request/Response syntax as a git submodule 2021-07-29 21:36:16 +02:00
Martin Nordholts
ffdf349a96 HighlightingAssets: Encapsulate theme_set behind a getter
Mainly to prepare for potential lazy-loading in the future to
improve startup performance. Like we did for syntax_set.
2021-07-29 21:30:03 +02:00
David Peter
f3d53b79a2 Update git2 dependency to fix incompatibility with Rust 1.54 2021-07-29 20:59:37 +02:00
Martin Nordholts
6acec2c074 Reduce startup time in loop-through mode with 80%-90%
Instead of 100 ms - 50 ms, startup takes 10 ms - 5 ms.

HighlightingAssets::get_syntax_set() is never called when e.g. piping the bat
output to a file (see Config::loop_through), so by loading the SyntaxSet only
when needed, we radically improve startup time when it is not needed.
2021-07-29 20:36:05 +02:00
Martin Nordholts
1bac3750df HighlightingAssets: Move out fn get_integrated_*set() to module scope
They are just a way to get access to data embedded in the binary, so they don't
conceptually belong inside HighlightingAssets.

This has the nice side effect of getting HighlightingAssets::from_cache() and
::from_binary(), that are highly related, next to each other.
2021-07-29 20:36:05 +02:00
Martin Nordholts
b040efff79 Support a hidden arg --no-custom-assets that skips loading assets from the cache 2021-07-29 08:27:02 +02:00
Martin Nordholts
a81009607a HighlightingAssets: Make .syntaxes() and syntax_for_file_name() failable
Or rather, introduce new versions of these methods and deprecate the old ones.

This is preparation to enable robust and user-friendly support for lazy-loading.
With lazy-loading, we don't know if the SyntaxSet is valid until after we try to
use it, so wherever we try to use it, we need to return a Result. See discussion
about panics in #1747.
2021-07-29 08:26:18 +02:00
Martin Nordholts
c0e09662b4 HighlightingAssets::get_extension_syntax(): Split up into smaller methods
To make the code easier to understand and change.
2021-07-28 08:42:18 +02:00
Martin Nordholts
ccf4563573 Make loading of cached assets closer in performance to integrated assets
Using BufReader makes sense for large files, but assets are never large enough
to require buffering. It is significantly faster to load the file contents in
one go, so let's do that instead.

Closes #1753
2021-07-27 14:53:59 +02:00
David Peter
fb1ab09e3e Add Enselic in FUNDING.yml 2021-07-26 20:11:34 +02:00
Sarvesh MD
f464b1ba39 Update battest.py
Add decorator test `@classmethod` and fixed spellings.
2021-07-26 08:44:05 +02:00
Frank Steffahn
2ea6348b85 Add rs identifier for Rust code blocks in Markdown 2021-07-25 15:11:23 +02:00
David Peter
6e536ab06d Update CHANGELOG 2021-07-25 13:28:43 +02:00
Ville Skyttä
7537e309d8 Add groff syntax
The syntax is named "Man Page" upstream, but our man page syntax is
different, it's for rendered man pages. Rename to Groff and remove
`.man` from extensions.
2021-07-25 13:27:30 +02:00
David Peter
84e2a2e5d1 Add custom FUNDING.yml 2021-07-25 12:30:40 +02:00
Martin Nordholts
f6fc826dc6 HighlightingAssets: Introduce private fn new() helper
It already now reduces code duplication slightly, but will become even more
useful in the future when we add more complicated logic such as lazy-loading.
2021-07-20 06:34:32 +02:00
Martin Nordholts
375d55aa5d HighlightingAssets: Encapsulate syntax_set behind a getter
Since we only modify `pub(crate)` items, the stable bat-as-a-library API is not
affected.

This takes us one step closer to making SyntaxSet lazy-loaded, which in turn
takes us one step closer to solving #951.
2021-07-19 05:27:12 +02:00
Martin Nordholts
6ef2bb3283 De-duplicate some themes.bin and syntaxes.bin related code 2021-07-15 16:22:35 +02:00
bl-ue
fc0794a83d Fix typo in README 2021-07-13 15:54:18 +02:00
59 changed files with 1973 additions and 419 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: [sharkdp, keith-hall, Enselic]

View File

@@ -1,2 +1 @@
blank_issues_enabled: true

View File

@@ -7,4 +7,3 @@ assignees: ''
---

View File

@@ -7,4 +7,3 @@ assignees: ''
---

View File

@@ -16,7 +16,7 @@ on:
jobs:
min_version:
name: Minimum supported rust version
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- name: Checkout source code
uses: actions/checkout@v2
@@ -27,20 +27,26 @@ jobs:
toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
default: true
profile: minimal # minimal component installation (ie, no documentation)
components: clippy
components: clippy, rustfmt
- name: Ensure `cargo fmt` has been run
uses: actions-rs/cargo@v1
with:
command: fmt
args: -- --check
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-targets --all-features
args: --locked --all-targets --all-features
- name: Run tests
uses: actions-rs/cargo@v1
with:
command: test
args: --locked
test_with_new_syntaxes_and_themes:
name: Run tests with updated syntaxes and themes
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- name: Git checkout
uses: actions/checkout@v2
@@ -68,12 +74,12 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --release
args: --locked --release
- name: Run ignored-by-default unit tests with new syntaxes and themes
uses: actions-rs/cargo@v1
with:
command: test
args: --release -- --ignored
args: --locked --release -- --ignored
- name: Syntax highlighting regression test
run: tests/syntax-tests/regression_test.sh
- name: List of languages
@@ -86,7 +92,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: doc
args: --no-deps --document-private-items --all-features
args: --locked --no-deps --document-private-items --all-features
build:
name: ${{ matrix.job.os }} (${{ matrix.job.target }})
@@ -95,12 +101,13 @@ jobs:
fail-fast: false
matrix:
job:
- { os: ubuntu-18.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
- { os: ubuntu-18.04, target: aarch64-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-18.04, target: i686-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-18.04, target: i686-unknown-linux-musl , use-cross: true }
- { os: ubuntu-18.04, target: x86_64-unknown-linux-gnu }
- { os: ubuntu-18.04, target: x86_64-unknown-linux-musl , use-cross: true }
- { os: ubuntu-20.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
- { os: ubuntu-20.04, target: arm-unknown-linux-musleabihf, use-cross: true }
- { os: ubuntu-20.04, target: aarch64-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-20.04, target: i686-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-20.04, target: i686-unknown-linux-musl , use-cross: true }
- { os: ubuntu-20.04, target: x86_64-unknown-linux-gnu }
- { os: ubuntu-20.04, target: x86_64-unknown-linux-musl , use-cross: true }
- { os: macos-10.15 , target: x86_64-apple-darwin }
# - { os: windows-2019, target: i686-pc-windows-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
- { os: windows-2019, target: i686-pc-windows-msvc }
@@ -114,7 +121,7 @@ jobs:
shell: bash
run: |
case ${{ matrix.job.target }} in
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
@@ -149,7 +156,7 @@ jobs:
with:
use-cross: ${{ matrix.job.use-cross }}
command: build
args: --release --target=${{ matrix.job.target }}
args: --locked --release --target=${{ matrix.job.target }}
- name: Strip debug information from executable
id: strip
@@ -164,7 +171,7 @@ jobs:
# Figure out what strip tool to use if any
STRIP="strip"
case ${{ matrix.job.target }} in
arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;;
arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;;
*-pc-windows-msvc) STRIP="" ;;
esac;
@@ -187,63 +194,61 @@ jobs:
echo ::set-output name=BIN_PATH::${BIN_PATH}
echo ::set-output name=BIN_NAME::${BIN_NAME}
- name: Set testing options
id: test-options
shell: bash
run: |
# test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac;
echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
- name: Run tests
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: test
args: --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
args: --locked --target=${{ matrix.job.target }}
- name: Run bat
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: run
args: --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs
args: --locked --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs
- name: Show diagnostics (bat --diagnostic)
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: run
args: --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs --diagnostic
args: --locked --target=${{ matrix.job.target }} -- --paging=never --color=always --theme=ansi Cargo.toml src/config.rs --diagnostic
- name: "Feature check: regex-onig"
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig
args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig
- name: "Feature check: regex-onig,git"
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git
args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git
- name: "Feature check: regex-onig,paging"
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,paging
args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,paging
- name: "Feature check: regex-onig,git,paging"
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: check
args: --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git,paging
args: --locked --target=${{ matrix.job.target }} --verbose --lib --no-default-features --features regex-onig,git,paging
- name: "Feature check: minimal-application"
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: check
args: --locked --target=${{ matrix.job.target }} --verbose --no-default-features --features minimal-application
- name: Create tarball
id: package

14
.gitmodules vendored
View File

@@ -217,4 +217,16 @@
url = https://github.com/vidann1/visual-studio-dark-plus.git
[submodule "assets/syntaxes/02_Extra/SublimeEthereum"]
path = assets/syntaxes/02_Extra/SublimeEthereum
url = https://github.com/davidhq/SublimeEthereum.git
url = https://github.com/davidhq/SublimeEthereum.git
[submodule "assets/syntaxes/02_Extra/Groff"]
path = assets/syntaxes/02_Extra/Groff
url = https://github.com/carsonoid/sublime_man_page_support
[submodule "assets/syntaxes/02_Extra/http-request-response"]
path = assets/syntaxes/02_Extra/http-request-response
url = https://github.com/keith-hall/http-request-response-syntax.git
[submodule "assets/syntaxes/02_Extra/LLVM"]
path = assets/syntaxes/02_Extra/LLVM
url = https://github.com/ioncodes/LLVM.tmBundle
[submodule "assets/syntaxes/02_Extra/Slim"]
path = assets/syntaxes/02_Extra/Slim
url = https://github.com/slim-template/ruby-slim.tmbundle.git

View File

@@ -2,21 +2,33 @@
## Features
- `$BAT_CONFIG_DIR` is now a recognized environment variable. It has precedence over `$XDG_CONFIG_HOME`, see #1727 (@billrisher)
## Bugfixes
- Python syntax highlighting no longer suffers from abysmal performance in specific scenarios. See #1688 (@keith-hall)
## Other
- Load cached assets as fast as integrated assets, see #1753 (@Enselic)
- Greatly reduce startup time in loop-through mode, e.g. when redirecting output. Instead of *50 ms* - *100 ms*, startup takes *5 ms* - *10 ms*. See #1747 (@Enselic)
## Syntaxes
- Groff, see #1685 (@scop)
- HTTP Requests and Responses, see #1748 (@keith-hall)
- LLVM, see #1777 (@ioncodes)
- Highlight for `vimrc` and `gvimrc` files, see #1763 (@SuperSandro2000)
- Syslog highlighting improvements, see #1793 (@scop)
- Added support for `slim` syntax, see #1693 (@mfinelli)
## New themes
## `bat` as a library
- Deprecate `HighlightingAssets::syntaxes()` and `HighlightingAssets::syntax_for_file_name()`. Use `HighlightingAssets::get_syntaxes()` and `HighlightingAssets::get_syntax_for_file_name()` instead. They return a `Result` which is needed for upcoming lazy-loading work to improve startup performance. They also return what `SyntaxSet` the returned `SyntaxReference` belongs to. See #1747, #1755 and #1776 (@Enselic)

104
Cargo.lock generated
View File

@@ -46,9 +46,9 @@ dependencies = [
[[package]]
name = "assert_cmd"
version = "1.0.5"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a88b6bd5df287567ffdf4ddf4d33060048e1068308e5f62d81c6f9824a045a48"
checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe"
dependencies = [
"bstr",
"doc-comment",
@@ -101,6 +101,7 @@ dependencies = [
"globset",
"grep-cli",
"lazy_static",
"lazycell",
"nix",
"path_abs",
"predicates",
@@ -159,9 +160,9 @@ dependencies = [
[[package]]
name = "bugreport"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0e97e538864a7c95d33accbf64c8d354018ba3b6e032502fd0fe7259cf1aa3d"
checksum = "0014b4b2b4f63bfe69c3838470121290cc437fdc79785d408a761a21e8b2404c"
dependencies = [
"git-version",
"shell-escape",
@@ -261,10 +262,10 @@ dependencies = [
]
[[package]]
name = "difference"
version = "2.0.0"
name = "difflib"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "dirs-next"
@@ -299,6 +300,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "encode_unicode"
version = "0.3.6"
@@ -380,9 +387,9 @@ dependencies = [
[[package]]
name = "fancy-regex"
version = "0.3.5"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae91abf6555234338687bb47913978d275539235fcb77ba9863b779090b42b14"
checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf"
dependencies = [
"bit-set",
"regex",
@@ -402,9 +409,9 @@ dependencies = [
[[package]]
name = "float-cmp"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
@@ -460,9 +467,9 @@ dependencies = [
[[package]]
name = "git2"
version = "0.13.19"
version = "0.13.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17929de7239dea9f68aa14f94b2ab4974e7b24c1314275ffcc12a7758172fa18"
checksum = "d9831e983241f8c5591ed53f17d874833e2fa82cac2625f3888c50cbfe136cba"
dependencies = [
"bitflags",
"libc",
@@ -552,6 +559,15 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.7"
@@ -581,15 +597,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.95"
version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "libgit2-sys"
version = "0.12.20+1.1.0"
version = "0.12.21+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e2f09917e00b9ad194ae72072bb5ada2cca16d8171a43e91ddba2afbb02664b"
checksum = "86271bacd72b2b9e854c3dcfb82efd538f15f870e4c11af66900effb462f6825"
dependencies = [
"cc",
"libc",
@@ -675,9 +691,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.21.0"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7"
checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187"
dependencies = [
"bitflags",
"cc",
@@ -773,15 +789,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
@@ -810,12 +817,13 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "predicates"
version = "1.0.8"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df"
checksum = "bc3d91237f5de3bcd9d927e24d03b495adb6135097b001cea7403e2d573d00a9"
dependencies = [
"difference",
"difflib",
"float-cmp",
"itertools",
"normalize-line-endings",
"predicates-core",
"regex",
@@ -984,36 +992,24 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "0.11.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]]
name = "serde"
version = "1.0.126"
version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.126"
version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
dependencies = [
"proc-macro2",
"quote",
@@ -1108,9 +1104,9 @@ dependencies = [
[[package]]
name = "syntect"
version = "4.5.0"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bfac2b23b4d049dc9a89353b4e06bbc85a8f42020cccbe5409a115cf19031e5"
checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
dependencies = [
"bincode",
"bitflags",
@@ -1213,12 +1209,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unicode-bidi"
version = "0.3.5"

View File

@@ -16,17 +16,26 @@ default = ["application"]
# Feature required for bat the application. Should be disabled when depending on
# bat as a library.
application = [
"bugreport",
"build-assets",
"git",
"minimal-application",
]
# Mainly for developers that want to iterate quickly
# Be aware that the included features might change in the future
minimal-application = [
"atty",
"clap",
"dirs-next",
"git",
"lazy_static",
"paging",
"wild",
"regex-onig",
"wild",
]
git = ["git2"] # Support indicating git modifications
paging = ["shell-words"] # Support applying a pager on the output
# Add "syntect/plist-load" when https://github.com/trishume/syntect/pull/345 reaches us
build-assets = ["syntect/yaml-load", "syntect/dump-create"]
# You need to use one of these if you depend on bat as a library:
regex-onig = ["syntect/regex-onig"] # Use the "oniguruma" regex engine
@@ -38,6 +47,7 @@ ansi_term = "^0.12.1"
ansi_colours = "^1.0"
console = "0.14.1"
lazy_static = { version = "1.4", optional = true }
lazycell = "1.0"
wild = { version = "2.0", optional = true }
content_inspector = "0.2.4"
encoding = "0.2"
@@ -46,10 +56,10 @@ unicode-width = "0.1.8"
globset = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
semver = "0.11"
semver = "1.0"
path_abs = { version = "0.5", default-features = false }
clircle = "0.3"
bugreport = "0.4"
bugreport = { version = "0.4", optional = true }
dirs-next = { version = "2.0.0", optional = true }
grep-cli = "0.1.6"
@@ -59,9 +69,9 @@ optional = true
default-features = false
[dependencies.syntect]
version = "4.5.0"
version = "4.6.0"
default-features = false
features = ["parsing", "yaml-load", "dump-load", "dump-create"]
features = ["parsing", "dump-load"]
[dependencies.clap]
version = "2.33"
@@ -74,14 +84,14 @@ version = "0.12"
default-features = false
[dev-dependencies]
assert_cmd = "1.0.5"
assert_cmd = "1.0.8"
serial_test = "0.5.1"
predicates = "1.0.7"
predicates = "2.0.1"
wait-timeout = "0.2.0"
tempfile = "3.2.0"
[target.'cfg(unix)'.dev-dependencies]
nix = "0.21.0"
nix = "0.22.0"
[build-dependencies]
clap = { version = "2.33", optional = true }

View File

@@ -719,7 +719,7 @@ Take a look at the [`CONTRIBUTING.md`](CONTRIBUTING.md) guide.
## Security vulnerabilities
Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnarability in `bat`.
Please contact [David Peter](https://david-peter.de/) via email if you want to report a vulnerability in `bat`.
## Project goals and alternatives

View File

@@ -34,7 +34,7 @@ complete -c {{PROJECT_EXECUTABLE}} -s H -l highlight-line -x -d "<N> Highlight t
complete -c {{PROJECT_EXECUTABLE}} -l italic-text -xka "always never" -d "Specify when to use ANSI sequences for italic text (default: never)" -n "not __fish_seen_subcommand_from cache"
complete -c {{PROJECT_EXECUTABLE}} -s l -l language -d "Set the language for syntax highlighting" -n "not __fish_seen_subcommand_from cache" -xa "(__{{PROJECT_EXECUTABLE}}_autocomplete_languages)"
complete -c {{PROJECT_EXECUTABLE}} -s l -l language -d "Set the language for syntax highlighting" -n "not __fish_seen_subcommand_from cache" -xa "(__{{PROJECT_EXECUTABLE}}_autocomplete_languages)"
complete -c {{PROJECT_EXECUTABLE}} -s r -l line-range -x -d "<N:M> Only print the specified range of lines for each file" -n "not __fish_seen_subcommand_from cache"

View File

@@ -45,6 +45,7 @@ _{{PROJECT_EXECUTABLE}}_main() {
'(-r --line-range)'{-r+,--line-range=}'[Only print the lines from N to M]:<N\:M>...'
'(: --list-themes --list-languages -L)'{-L,--list-languages}'[Display all supported languages]'
'(: --no-config)'--no-config'[Do not use the configuration file]'
'(: --no-custom-assets)'--no-custom-assets'[Do not load custom assets]'
'(: --config-dir)'--config-dir'[Show bat'"'"'s configuration directory]'
'(: --config-file)'--config-file'[Show path to the configuration file]'
'(: --generate-config-file)'--generate-config-file'[Generates a default configuration file]'

2
assets/create.sh vendored
View File

@@ -5,7 +5,7 @@ ASSET_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
REPO_DIR="$ASSET_DIR/.."
# Ensure submodules are initialized.
function update_submodules() {
update_submodules() {
local submodule
local submodule_prompt=unspecified
local submodule_path

View File

@@ -142,7 +142,7 @@ Configure which elements (line numbers, file headers, grid borders, Git modifica
of components to display (e.g. 'numbers,changes,grid') or a pre\-defined style ('full').
To set a default style, add the '\-\-style=".."' option to the configuration file or
export the BAT_STYLE environment variable (e.g.: export BAT_STYLE=".."). Possible
values: *auto*, full, plain, changes, header, grid, rule, numbers, snip.
values: *full*, auto, plain, changes, header, grid, rule, numbers, snip.
.HP
\fB\-r\fR, \fB\-\-line\-range\fR <N:M>...
.IP
@@ -218,7 +218,7 @@ git clone https://github.com/tellnobody1/sublime-purescript-syntax
Once the cache is built, the new language will be visible in `\fB{{PROJECT_EXECUTABLE}} --list-languages\fR`.
.br
If you ever want to remove the custom languages, you can clear the cache with `\fB{{PROJECT_EXECUTABLE}} cache --clear\fR`.
If you ever want to remove the custom languages, you can clear the cache with `\fB{{PROJECT_EXECUTABLE}} cache --clear\fR`.
.SH "ADDING CUSTOM THEMES"
Similarly to custom languages, {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.tmTheme\fR themes.

View File

@@ -0,0 +1,16 @@
diff --git syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax
index 57834af..6648664 100644
--- syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax
+++ syntaxes/02_Extra/Groff/Man Page/Man Page.sublime-syntax
@@ -4,9 +4,9 @@
# - man-pages(7)
# - groff(7)
---
-name: Man Page (groff/troff)
+name: Groff/troff
scope: text.groff
-file_extensions: [man, groff, troff, '1', '2', '3', '4', '5', '6', '7']
+file_extensions: [groff, troff, '1', '2', '3', '4', '5', '6', '7', '8', '9']
contexts:
main:

View File

@@ -1,5 +1,5 @@
diff --git syntaxes/01_Packages/Markdown/Markdown.sublime-syntax syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
index 19dc685d..6afd87ae 100644
index 19dc685d..44440c7f 100644
--- syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
+++ syntaxes/01_Packages/Markdown/Markdown.sublime-syntax
@@ -24,7 +24,6 @@ variables:
@@ -166,3 +166,12 @@ index 19dc685d..6afd87ae 100644
- match: ^\s*$\n?
scope: invalid.illegal.non-terminated.bold-italic.markdown
pop: true
@@ -1152,7 +1110,7 @@ contexts:
- match: |-
(?x)
{{fenced_code_block_start}}
- ((?i:rust))
+ ((?i:rust|rs))
{{fenced_code_block_trailing_infostring_characters}}
captures:
0: meta.code-fence.definition.begin.rust.markdown-gfm

View File

@@ -0,0 +1,15 @@
diff --git syntaxes/01_Packages/Python/Python.sublime-syntax syntaxes/01_Packages/Python/Python.sublime-syntax
index 2acd86d8..86257f7b 100644
--- syntaxes/01_Packages/Python/Python.sublime-syntax
+++ syntaxes/01_Packages/Python/Python.sublime-syntax
@@ -988,10 +988,6 @@ contexts:
- match: \}
scope: punctuation.section.mapping-or-set.end.python
set: after-expression
- - match: (?={{simple_expression}}:|\s*\*\*)
- set: inside-dictionary
- - match: (?={{simple_expression}}[,}]|\s*\*)
- set: inside-set
- match: ','
scope: punctuation.separator.set.python
set: inside-set

View File

@@ -0,0 +1,306 @@
%YAML 1.2
---
# http://www.sublimetext.com/docs/syntax.html
name: Ruby Slim
file_extensions:
- slim
- skim
scope: text.slim
contexts:
main:
- match: ^(\s*)(ruby):$
captures:
2: constant.language.name.ruby.filter.slim
push:
- meta_scope: text.ruby.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.ruby
- match: ^(\s*)(javascript):$
captures:
2: constant.language.name.javascript.filter.slim
push:
- meta_scope: source.js.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.js
- match: ^(---)\s*\n
captures:
1: storage.frontmatter.slim
push:
- meta_scope: source.yaml.meta.slim
- match: ^(---)\s*\n
captures:
1: storage.frontmatter.slim
pop: true
- include: scope:source.yaml
- match: ^(\s*)(coffee):$
captures:
2: constant.language.name.coffeescript.filter.slim
push:
- meta_scope: text.coffeescript.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.coffee
- match: ^(\s*)(markdown):$
captures:
2: constant.language.name.markdown.filter.slim
push:
- meta_scope: text.markdown.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:text.html.markdown
- match: ^(\s*)(css):$
captures:
2: constant.language.name.css.filter.slim
push:
- meta_scope: text.css.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.css
- match: ^(\s*)(sass):$
captures:
2: constant.language.name.sass.filter.slim
push:
- meta_scope: text.sass.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.sass
- match: ^(\s*)(scss):$
captures:
2: constant.language.name.scss.filter.slim
push:
- meta_scope: text.scss.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.scss
- match: ^(\s*)(less):$
captures:
2: constant.language.name.less.filter.slim
push:
- meta_scope: text.less.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.less
- match: ^(\s*)(erb):$
captures:
2: constant.language.name.erb.filter.slim
push:
- meta_scope: text.erb.filter.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:source.erb
- match: ^(! )($|\s.*)
scope: meta.prolog.slim
captures:
1: punctuation.definition.prolog.slim
- match: ^(\s*)(/)\s*.*$
captures:
2: comment.line.slash.slim
push:
- meta_scope: comment.block.slim
- match: ^(?!(\1\s)|\s*$)
pop: true
- match: ^\s*(?=-)
push:
- match: $
pop: true
- include: rubyline
- match: (?==+|~)
push:
- match: $
pop: true
- include: rubyline
- include: tag-attribute
- include: embedded-ruby
- match: ^(\s*)(\||')\s*
comment: Verbatim text (can include HTML tags and copied lines)
push:
- match: ^(?!(\1\s)|\s*$)
pop: true
- include: scope:text.html.basic
- include: embedded-ruby
- match: '^\s*(\.|#|[-a-zA-Z0-9]+)([\w-]+)?'
comment: '1 - dot OR hash OR any combination of word, number; 2 - OPTIONAL any combination of word, number, dash or underscore (following a . or'
captures:
1: entity.name.tag.slim
2: entity.other.attribute-name.event.slim
push:
- meta_scope: meta.tag
- match: '$|(?!\.|#|:|-|~|/|\}|\]|\*|\s?[\*\{])'
captures:
1: entity.name.tag.slim
2: entity.other.attribute-name.event.slim
pop: true
- match: '(:[\w\d]+)+'
comment: XML
push:
- meta_scope: entity.name.tag.slim
- match: $|\s
pop: true
- match: '(:\s)(\.|#|[a-zA-Z0-9]+)([\w-]+)?'
comment: Inline HTML / 1 - colon; 2 - dot OR hash OR any combination of word, number; 3 - OPTIONAL any combination of word, number, dash or underscore (following a . or
captures:
1: punctuation.definition.tag.end.slim
2: entity.name.tag.slim
3: entity.other.attribute-name.event.slim
push:
- match: '$|(?!\.|#|=|-|~|/|\}|\]|\*|\s?[\*\{])'
captures:
1: punctuation.definition.tag.end.slim
2: entity.name.tag.slim
3: entity.other.attribute-name.event.slim
pop: true
- include: root-class-id-tag
- include: tag-attribute
- match: '(\*\{)(?=.*\}|.*\|\s*$)'
comment: Splat attributes
captures:
1: punctuation.section.embedded.ruby
push:
- meta_scope: source.ruby.embedded.slim
- match: '(\})|$|^(?!.*\|\s*$)'
captures:
1: punctuation.section.embedded.ruby
pop: true
- include: embedded-ruby
- include: root-class-id-tag
- include: rubyline
- match: /
scope: punctuation.terminator.tag.slim
- match: ^\s*(\\.)
captures:
1: meta.escape.slim
- match: ^\s*(?=\||')
push:
- match: $
pop: true
- include: embedded-ruby
- include: scope:text.html.basic
- match: '(?=<[\w\d\:]+)'
comment: Inline and root-level HTML tags
push:
- match: $|\/\>
pop: true
- include: scope:text.html.basic
continuation:
- match: '([\\,])\s*\n'
captures:
1: punctuation.separator.continuation.slim
delimited-ruby-a:
- match: '=\('
push:
- meta_scope: source.ruby.embedded.slim
- match: \)(?=( \w|$))
pop: true
- include: scope:source.ruby.rails
delimited-ruby-b:
- match: '=\['
push:
- meta_scope: source.ruby.embedded.slim
- match: '\](?=( \w|$))'
pop: true
- include: scope:source.ruby.rails
delimited-ruby-c:
- match: '=\{'
push:
- meta_scope: source.ruby.embedded.slim
- match: '\}(?=( \w|$))'
pop: true
- include: scope:source.ruby.rails
embedded-ruby:
- match: '(?<!\\)#\{{1,2}'
captures:
0: punctuation.section.embedded.ruby
push:
- meta_scope: source.ruby.embedded.html
- match: '\}{1,2}'
captures:
0: punctuation.section.embedded.ruby
pop: true
- include: scope:source.ruby.rails
entities:
- match: '(&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)'
scope: constant.character.entity.html
captures:
1: punctuation.definition.entity.html
3: punctuation.definition.entity.html
- match: '&'
scope: invalid.illegal.bad-ampersand.html
interpolated-ruby:
- match: '=(?=\b)'
push:
- meta_scope: source.ruby.embedded.html
- match: \s|\w$
pop: true
root-class-id-tag:
- match: '(\.|#)([\w\d\-]+)'
captures:
1: punctuation.separator.key-value.html
2: entity.other.attribute-name.html
rubyline:
- match: (==|=)(<>|><|<'|'<|<|>)?|-
comment: Hack to thwart Sublime's Ruby highlighter. It thinks do without a variable continues the next line (this can be muted with a / at the end of the line). For things like yields, do is unnecessary without an argument, so this hack will suffice
push:
- meta_scope: meta.line.ruby.slim
- meta_content_scope: source.ruby.embedded.slim
- match: (do\s*\n$)|(?<!\\|,|,\n|\\\n)$
captures:
1: keyword.control.start-block.ruby
pop: true
- match: '#.*$'
comment: Hack to let ruby comments work in this context properly
scope: comment.line.number-sign.ruby
- include: continuation
- include: scope:source.ruby.rails
string-double-quoted:
- match: (")(?=.*")
captures:
0: punctuation.definition.string.begin.html
push:
- meta_scope: string.quoted.double.html
- meta_content_scope: meta.toc-list.id.html
- match: '"'
captures:
0: punctuation.definition.string.end.html
pop: true
- include: embedded-ruby
- include: entities
string-single-quoted:
- match: (')(?=.*')
captures:
0: punctuation.definition.string.begin.html
push:
- meta_scope: string.quoted.single.html
- meta_content_scope: meta.toc-list.id.html
- match: "'"
captures:
0: punctuation.definition.string.end.html
pop: true
- include: embedded-ruby
- include: entities
tag-attribute:
- match: '([\w.#_-]+)(=)(?!\s)(true|false|nil)?(\s*\(|\{)?'
captures:
1: entity.other.attribute-name.event.slim
2: punctuation.separator.key-value.html
3: constant.language.slim
push:
- meta_scope: meta.attribute-with-value.slim
- match: '\}|\)|$'
captures:
1: entity.other.attribute-name.event.slim
2: punctuation.separator.key-value.html
3: constant.language.slim
pop: true
- include: tag-stuff
- include: string-double-quoted
- include: string-single-quoted
tag-stuff:
- include: tag-attribute
- include: interpolated-ruby
- include: delimited-ruby-a
- include: delimited-ruby-b
- include: delimited-ruby-c
- include: rubyline
- include: embedded-ruby

View File

@@ -16,11 +16,11 @@ contexts:
- match: ^
push: text
loghost:
- match: '[\w-]+'
- match: '[\w:.-]+'
scope: entity.other.attribute-name.loghost.syslog
set: process
process:
- match: ([\w-]+)(?:(\[)(\d+)(\]))?(:)
- match: ([\w.-]+)(?:(\[)(\d+)(\]))?([ :])
captures:
1: support.function.process.syslog
2: punctuation.separator.pid.begin.syslog

View File

@@ -434,11 +434,11 @@ export BAT_PAGER="less -RF"
`-R`/`--RAW-CONTROL-CHARS`,
`-F`/`--quit-if-one-screen` и `-X`/`--no-init`. Последний флаг(`-X`) используется только для `less`, чья версия раньше 530.
Флаг `-R` нужен чтобы корректно воспроизвести ANSI цвета. Второй флаг (`-F`) говорит
Флаг `-R` нужен чтобы корректно воспроизвести ANSI цвета. Второй флаг (`-F`) говорит
`less` чтобы тот сразу же завершился, если размер вывода меньше чем вертикальный размер терминала.
Это удобно для небольших файлов, так как вам не надо каждый раз нажимать `q`, чтобы выйти из пейджера. Третий флаг (`-X`) нужен для того, чтобы исправить баг с `--quit-if-one-screen` в старых версиях `less`. К сожалению, это блокирует возможность использования колеса мышки.
Если вы хотите все же его включить, вы можете добавить флаг `-R`.
Если вы хотите все же его включить, вы можете добавить флаг `-R`.
Для `less` новее чем 530 оно должно работать из коробки.
### Темная тема
@@ -499,7 +499,7 @@ Windows поддерживает только очень простой пейд
### Цвета
Windows 10 поддерживает цвета и в `conhost.exe` (Command Prompt), и в PowerShell начиная с версии Windows
[v1511](https://ru.wikipedia.org/wiki/Windows_10#Обновления и поддержка), так же как и в bash. На ранних версиях Windows вы можете использовать
[v1511](https://ru.wikipedia.org/wiki/Windows_10#Обновления и поддержка), так же как и в bash. На ранних версиях Windows вы можете использовать
[Cmder](http://cmder.net/), в котором есть [ConEmu](https://conemu.github.io/).
**Внимание:** Версия `less` в Git и MSYS2 воспроизводит цвета некорректно. Если у вас нет других пейджеров, мы можете отключить использование пейджеров с помощью флага `--paging=never`

View File

@@ -9,7 +9,9 @@ in the `.sublime-syntax` format.
**Important:** Before proceeding, verify that the syntax you wish to add meets the [criteria for inclusion](#Criteria-for-inclusion-of-new-syntaxes).
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`).
which can be included as a submodule (under `assets/syntaxes`) using
`git submodule add <https github link> ./assets/syntaxes/02_Extra/<repo name>`, replacing
the contents of the angle brackets as appropriate.
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* ->
@@ -26,7 +28,8 @@ in the `.sublime-syntax` format.
6. Add a syntax test for the new language. See [below](#Syntax-tests) for details.
7. If you send a pull request with your changes, please do *not* include the changed `syntaxes.bin`
file. A new binary cache file will be created once before every new release of `bat`.
file. A new binary cache file will be created once before every new release of `bat`. This
avoids bloating the repository size unnecessarily.
### Syntax tests
@@ -68,7 +71,7 @@ themes (`bat cache --clear`).
## Criteria for inclusion of new syntaxes
* More than 10,000 downloads on packagecontrol.io/
* More than 10,000 downloads at [Package Control](https://packagecontrol.io)
### Manual modifications

58
doc/release-checklist.md Normal file
View File

@@ -0,0 +1,58 @@
# Release checklist
## Dependencies
See this page for a good overview: https://deps.rs/repo/github/sharkdp/bat
- [ ] Optional: update dependencies with `cargo update`. This is also done by
dependabot, so it is not strictly necessary.
- [ ] Check for outdated dependencies (`cargo outdated`) and decide for each of
them whether we want to (manually) upgrade. This will require changes to
`Cargo.toml`.
## Version bump
- [ ] Update version in `Cargo.toml`. Run `cargo build` to update `Cargo.lock`.
Make sure to `git add` the `Cargo.lock` changes as well.
- [ ] Find the current min. supported Rust version by running
`grep '^\s*MIN_SUPPORTED_RUST_VERSION' .github/workflows/CICD.yml`.
- [ ] Update the version and the min. supported Rust version in `README.md` and
`doc/README-*.md`.
- [ ] Update `CHANGELOG.md`. Introduce a section for the new release and
prepare a new (empty) "unreleased" section at the top.
## Update syntaxes and themes (build assets)
- [ ] Install the latest master version (`cargo install -f --path .`) and make
sure that it is available on the `PATH` (`bat --version` should show the
new version).
- [ ] Run `assets/create.sh` and check in the binary asset files.
## Documentation
- [ ] Review the `-h` and `--help` texts
- [ ] Review the `man` page
## Pre-release checks
- [ ] Push all changes and wait for CI to succeed (before continuing with the
next section).
- [ ] Optional: manually test the new features and command-line options. To do
this, install the latest `bat` version again (to include the new synaxes
and themes).
- [ ] Run `cargo publish --dry-run --allow-dirty` to make sure that it will
succeed later (after creating the GitHub release).
## Release
- [ ] Create a tag and push it to the remote `git tag vX.Y.Z; git push --tags`.
This will trigger the deployment via GitHub Actions.
- [ ] Go to https://github.com/sharkdp/bat/releases/new to create the new
release. Select the new tag and also use it as the release title. For the
release notes, copy the corresponding section from `CHANGELOG.md` and
possibly add additional remarks for package maintainers.
Publish the release.
- [ ] Check if the binary deployment works (archives and Debian packages should
appear when the CI run for the Git tag has finished).
- [ ] Publish to crates.io by running `cargo publish` in a *clean* repository.
The safest way to do this is to clone a fresh copy.

View File

@@ -1,16 +1,15 @@
use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::BufReader;
use std::path::Path;
use std::fs;
use std::path::{Path, PathBuf};
use syntect::dumps::{dump_to_file, from_binary, from_reader};
use lazycell::LazyCell;
use syntect::dumps::{from_binary, from_reader};
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet, SyntaxSetBuilder};
use syntect::parsing::{SyntaxReference, SyntaxSet};
use path_abs::PathAbs;
use crate::assets_metadata::AssetsMetadata;
use crate::bat_warning;
use crate::error::*;
use crate::input::{InputReader, OpenedInput, OpenedInputKind};
@@ -18,11 +17,18 @@ use crate::syntax_mapping::{MappingTarget, SyntaxMapping};
#[derive(Debug)]
pub struct HighlightingAssets {
pub(crate) syntax_set: SyntaxSet,
pub(crate) theme_set: ThemeSet,
syntax_set_cell: LazyCell<SyntaxSet>,
serialized_syntax_set: Option<SerializedSyntaxSet>,
theme_set: ThemeSet,
fallback_theme: Option<&'static str>,
}
#[derive(Debug)]
pub struct SyntaxReferenceInSet<'a> {
pub syntax: &'a SyntaxReference,
pub syntax_set: &'a SyntaxSet,
}
const IGNORED_SUFFIXES: [&str; 10] = [
// Editor etc backups
"~",
@@ -41,17 +47,36 @@ const IGNORED_SUFFIXES: [&str; 10] = [
];
impl HighlightingAssets {
fn new(
syntax_set: Option<SyntaxSet>,
serialized_syntax_set: Option<SerializedSyntaxSet>,
theme_set: ThemeSet,
) -> Self {
assert!(syntax_set.is_some() || serialized_syntax_set.is_some());
let syntax_set_cell = LazyCell::new();
if let Some(syntax_set) = syntax_set {
syntax_set_cell.fill(syntax_set).expect("can never fail");
}
HighlightingAssets {
syntax_set_cell,
serialized_syntax_set,
theme_set,
fallback_theme: None,
}
}
pub fn default_theme() -> &'static str {
"Monokai Extended"
}
#[cfg(feature = "build-assets")]
pub fn from_files(source_dir: &Path, include_integrated_assets: bool) -> Result<Self> {
let mut theme_set = if include_integrated_assets {
Self::get_integrated_themeset()
get_integrated_themeset()
} else {
ThemeSet {
themes: BTreeMap::new(),
}
ThemeSet::new()
};
let theme_dir = source_dir.join("themes");
@@ -72,11 +97,11 @@ impl HighlightingAssets {
}
let mut syntax_set_builder = if !include_integrated_assets {
let mut builder = SyntaxSetBuilder::new();
let mut builder = syntect::parsing::SyntaxSetBuilder::new();
builder.add_plain_text_syntax();
builder
} else {
Self::get_integrated_syntaxset().into_builder()
from_binary::<SyntaxSet>(get_serialized_integrated_syntaxset()).into_builder()
};
let syntax_dir = source_dir.join("syntaxes");
@@ -89,95 +114,63 @@ impl HighlightingAssets {
);
}
Ok(HighlightingAssets {
syntax_set: syntax_set_builder.build(),
theme_set,
fallback_theme: None,
})
if std::env::var("BAT_PRINT_SYNTAX_DEPENDENCIES").is_ok() {
// To trigger this code, run:
// BAT_PRINT_SYNTAX_DEPENDENCIES=1 cargo run -- cache --build --source assets --blank --target /tmp
crate::syntax_dependencies::print_syntax_dependencies(&syntax_set_builder);
}
let syntax_set = syntax_set_builder.build();
let missing_contexts = syntax_set.find_unlinked_contexts();
if !missing_contexts.is_empty() {
println!("Some referenced contexts could not be found!");
for context in missing_contexts {
println!("- {}", context);
}
}
Ok(HighlightingAssets::new(Some(syntax_set), None, theme_set))
}
pub fn from_cache(cache_path: &Path) -> Result<Self> {
let syntax_set_path = cache_path.join("syntaxes.bin");
let theme_set_path = cache_path.join("themes.bin");
let syntax_set_file = File::open(&syntax_set_path).chain_err(|| {
format!(
"Could not load cached syntax set '{}'",
syntax_set_path.to_string_lossy()
)
})?;
let syntax_set: SyntaxSet = from_reader(BufReader::new(syntax_set_file))
.chain_err(|| "Could not parse cached syntax set")?;
let theme_set_file = File::open(&theme_set_path).chain_err(|| {
format!(
"Could not load cached theme set '{}'",
theme_set_path.to_string_lossy()
)
})?;
let theme_set: ThemeSet = from_reader(BufReader::new(theme_set_file))
.chain_err(|| "Could not parse cached theme set")?;
Ok(HighlightingAssets {
syntax_set,
theme_set,
fallback_theme: None,
})
}
fn get_integrated_syntaxset() -> SyntaxSet {
from_binary(include_bytes!("../assets/syntaxes.bin"))
}
fn get_integrated_themeset() -> ThemeSet {
from_binary(include_bytes!("../assets/themes.bin"))
Ok(HighlightingAssets::new(
None,
Some(SerializedSyntaxSet::FromFile(
cache_path.join("syntaxes.bin"),
)),
asset_from_cache(&cache_path.join("themes.bin"), "theme set")?,
))
}
pub fn from_binary() -> Self {
let syntax_set = Self::get_integrated_syntaxset();
let theme_set = Self::get_integrated_themeset();
HighlightingAssets {
syntax_set,
theme_set,
fallback_theme: None,
}
HighlightingAssets::new(
None,
Some(SerializedSyntaxSet::FromBinary(
get_serialized_integrated_syntaxset(),
)),
get_integrated_themeset(),
)
}
#[cfg(feature = "build-assets")]
pub fn save_to_cache(&self, target_dir: &Path, current_version: &str) -> Result<()> {
let _ = fs::create_dir_all(target_dir);
let theme_set_path = target_dir.join("themes.bin");
let syntax_set_path = target_dir.join("syntaxes.bin");
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");
asset_to_cache(
self.get_theme_set(),
&target_dir.join("themes.bin"),
"theme set",
)?;
asset_to_cache(
self.get_syntax_set()?,
&target_dir.join("syntaxes.bin"),
"syntax set",
)?;
print!(
"Writing metadata to folder {} ... ",
target_dir.to_string_lossy()
);
AssetsMetadata::new(current_version).save_to_folder(target_dir)?;
crate::assets_metadata::AssetsMetadata::new(current_version).save_to_folder(target_dir)?;
println!("okay");
Ok(())
@@ -187,31 +180,74 @@ impl HighlightingAssets {
self.fallback_theme = Some(theme);
}
pub(crate) fn get_syntax_set(&self) -> Result<&SyntaxSet> {
if !self.syntax_set_cell.filled() {
self.syntax_set_cell.fill(
self.serialized_syntax_set
.as_ref()
.expect("a dev forgot to setup serialized_syntax_set, please report to https://github.com/sharkdp/bat/issues")
.deserialize()?
).unwrap();
}
// It is safe to .unwrap() because we just made sure it was .filled()
Ok(self.syntax_set_cell.borrow().unwrap())
}
/// Use [Self::get_syntaxes] instead
#[deprecated]
pub fn syntaxes(&self) -> &[SyntaxReference] {
self.syntax_set.syntaxes()
self.get_syntax_set()
.expect(".syntaxes() is deprecated, use .get_syntaxes() instead")
.syntaxes()
}
pub fn get_syntaxes(&self) -> Result<&[SyntaxReference]> {
Ok(self.get_syntax_set()?.syntaxes())
}
fn get_theme_set(&self) -> &ThemeSet {
&self.theme_set
}
pub fn themes(&self) -> impl Iterator<Item = &str> {
self.theme_set.themes.keys().map(|s| s.as_ref())
self.get_theme_set().themes.keys().map(|s| s.as_ref())
}
/// Use [Self::get_syntax_for_file_name] instead
#[deprecated]
pub fn syntax_for_file_name(
&self,
file_name: impl AsRef<Path>,
mapping: &SyntaxMapping,
) -> Option<&SyntaxReference> {
self.get_syntax_for_file_name(file_name, mapping)
.expect(
".syntax_for_file_name() is deprecated, use .get_syntax_for_file_name() instead",
)
.map(|syntax_in_set| syntax_in_set.syntax)
}
pub fn get_syntax_for_file_name(
&self,
file_name: impl AsRef<Path>,
mapping: &SyntaxMapping,
) -> Result<Option<SyntaxReferenceInSet>> {
let file_name = file_name.as_ref();
match mapping.get_syntax_for(file_name) {
Ok(match mapping.get_syntax_for(file_name) {
Some(MappingTarget::MapToUnknown) => None,
Some(MappingTarget::MapTo(syntax_name)) => {
self.syntax_set.find_syntax_by_name(syntax_name)
let syntax_set = self.get_syntax_set()?;
syntax_set
.find_syntax_by_name(syntax_name)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })
}
None => self.get_extension_syntax(file_name.as_os_str()),
}
None => self.get_extension_syntax(file_name.as_os_str())?,
})
}
pub(crate) fn get_theme(&self, theme: &str) -> &Theme {
match self.theme_set.themes.get(theme) {
match self.get_theme_set().themes.get(theme) {
Some(theme) => theme,
None => {
if theme == "ansi-light" || theme == "ansi-dark" {
@@ -221,7 +257,8 @@ impl HighlightingAssets {
if !theme.is_empty() {
bat_warning!("Unknown theme '{}', using default.", theme)
}
&self.theme_set.themes[self.fallback_theme.unwrap_or_else(|| Self::default_theme())]
&self.get_theme_set().themes
[self.fallback_theme.unwrap_or_else(|| Self::default_theme())]
}
}
}
@@ -231,13 +268,15 @@ impl HighlightingAssets {
language: Option<&str>,
input: &mut OpenedInput,
mapping: &SyntaxMapping,
) -> Result<&SyntaxReference> {
) -> Result<SyntaxReferenceInSet> {
if let Some(language) = language {
self.syntax_set
let syntax_set = self.get_syntax_set()?;
syntax_set
.find_syntax_by_token(language)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })
.ok_or_else(|| ErrorKind::UnknownSyntax(language.to_owned()).into())
} else {
let line_syntax = self.get_first_line_syntax(&mut input.reader);
let line_syntax = self.get_first_line_syntax(&mut input.reader)?;
// Get the path of the file:
// If this was set by the metadata, that will take priority.
@@ -265,14 +304,17 @@ impl HighlightingAssets {
ErrorKind::UndetectedSyntax(path.to_string_lossy().into()).into()
}),
Some(MappingTarget::MapTo(syntax_name)) => self
.syntax_set
.find_syntax_by_name(syntax_name)
.ok_or_else(|| ErrorKind::UnknownSyntax(syntax_name.to_owned()).into()),
Some(MappingTarget::MapTo(syntax_name)) => {
let syntax_set = self.get_syntax_set()?;
syntax_set
.find_syntax_by_name(syntax_name)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set })
.ok_or_else(|| ErrorKind::UnknownSyntax(syntax_name.to_owned()).into())
}
None => {
let file_name = path.file_name().unwrap_or_default();
self.get_extension_syntax(file_name)
self.get_extension_syntax(file_name)?
.or(line_syntax)
.ok_or_else(|| {
ErrorKind::UndetectedSyntax(path.to_string_lossy().into()).into()
@@ -286,37 +328,122 @@ impl HighlightingAssets {
}
}
fn get_extension_syntax(&self, file_name: &OsStr) -> Option<&SyntaxReference> {
self.syntax_set
.find_syntax_by_extension(file_name.to_str().unwrap_or_default())
.or_else(|| {
let file_path = Path::new(file_name);
self.syntax_set
.find_syntax_by_extension(
file_path
.extension()
.and_then(|x| x.to_str())
.unwrap_or_default(),
)
.or_else(|| {
if let Some(file_str) = file_path.to_str() {
for suffix in IGNORED_SUFFIXES.iter() {
if let Some(stripped_filename) = file_str.strip_suffix(suffix) {
return self
.get_extension_syntax(OsStr::new(stripped_filename));
}
}
}
None
})
})
fn get_extension_syntax(&self, file_name: &OsStr) -> Result<Option<SyntaxReferenceInSet>> {
let mut syntax = self.find_syntax_by_file_name(file_name)?;
if syntax.is_none() {
syntax = self.find_syntax_by_file_name_extension(file_name)?;
}
if syntax.is_none() {
syntax = self.get_extension_syntax_with_stripped_suffix(file_name)?;
}
Ok(syntax)
}
fn get_first_line_syntax(&self, reader: &mut InputReader) -> Option<&SyntaxReference> {
String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| self.syntax_set.find_syntax_by_first_line(&l))
fn find_syntax_by_file_name(&self, file_name: &OsStr) -> Result<Option<SyntaxReferenceInSet>> {
let syntax_set = self.get_syntax_set()?;
Ok(syntax_set
.find_syntax_by_extension(file_name.to_str().unwrap_or_default())
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
fn find_syntax_by_file_name_extension(
&self,
file_name: &OsStr,
) -> Result<Option<SyntaxReferenceInSet>> {
let file_path = Path::new(file_name);
let syntax_set = self.get_syntax_set()?;
Ok(syntax_set
.find_syntax_by_extension(
file_path
.extension()
.and_then(|x| x.to_str())
.unwrap_or_default(),
)
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
/// If we find an ignored suffix on the file name, e.g. '~', we strip it and
/// then try again to find a syntax without it. Note that we do this recursively.
fn get_extension_syntax_with_stripped_suffix(
&self,
file_name: &OsStr,
) -> Result<Option<SyntaxReferenceInSet>> {
let file_path = Path::new(file_name);
let mut syntax = None;
if let Some(file_str) = file_path.to_str() {
for suffix in IGNORED_SUFFIXES.iter() {
if let Some(stripped_filename) = file_str.strip_suffix(suffix) {
syntax = self.get_extension_syntax(OsStr::new(stripped_filename))?;
break;
}
}
}
Ok(syntax)
}
fn get_first_line_syntax(
&self,
reader: &mut InputReader,
) -> Result<Option<SyntaxReferenceInSet>> {
let syntax_set = self.get_syntax_set()?;
Ok(String::from_utf8(reader.first_line.clone())
.ok()
.and_then(|l| syntax_set.find_syntax_by_first_line(&l))
.map(|syntax| SyntaxReferenceInSet { syntax, syntax_set }))
}
}
/// A SyntaxSet in serialized form, i.e. bincoded and flate2 compressed.
/// We keep it in this format since we want to load it lazily.
#[derive(Debug)]
enum SerializedSyntaxSet {
/// The data comes from a user-generated cache file.
FromFile(PathBuf),
/// The data to use is embedded into the bat binary.
FromBinary(&'static [u8]),
}
impl SerializedSyntaxSet {
fn deserialize(&self) -> Result<SyntaxSet> {
match self {
SerializedSyntaxSet::FromBinary(data) => Ok(from_binary(data)),
SerializedSyntaxSet::FromFile(ref path) => asset_from_cache(path, "syntax set"),
}
}
}
fn get_serialized_integrated_syntaxset() -> &'static [u8] {
include_bytes!("../assets/syntaxes.bin")
}
fn get_integrated_themeset() -> ThemeSet {
from_binary(include_bytes!("../assets/themes.bin"))
}
#[cfg(feature = "build-assets")]
fn asset_to_cache<T: serde::Serialize>(asset: &T, path: &Path, description: &str) -> Result<()> {
print!("Writing {} to {} ... ", description, path.to_string_lossy());
syntect::dumps::dump_to_file(asset, &path).chain_err(|| {
format!(
"Could not save {} to {}",
description,
path.to_string_lossy()
)
})?;
println!("okay");
Ok(())
}
fn asset_from_cache<T: serde::de::DeserializeOwned>(path: &Path, description: &str) -> Result<T> {
let contents = fs::read(path).chain_err(|| {
format!(
"Could not load cached {} '{}'",
description,
path.to_string_lossy()
)
})?;
from_reader(&contents[..]).chain_err(|| format!("Could not parse cached {}", description))
}
#[cfg(test)]
@@ -326,7 +453,7 @@ mod tests {
use std::ffi::OsStr;
use std::fs::File;
use std::io::Write;
use std::io::{BufReader, Write};
use tempfile::TempDir;
use crate::input::Input;
@@ -346,6 +473,18 @@ mod tests {
}
}
fn get_syntax_name(
&self,
language: Option<&str>,
input: &mut OpenedInput,
mapping: &SyntaxMapping,
) -> String {
self.assets
.get_syntax(language, input, mapping)
.map(|syntax_in_set| syntax_in_set.syntax.name.clone())
.unwrap_or_else(|_| "!no syntax!".to_owned())
}
fn syntax_for_real_file_with_content_os(
&self,
file_name: &OsStr,
@@ -361,11 +500,7 @@ mod tests {
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap();
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
}
fn syntax_for_file_with_content_os(&self, file_name: &OsStr, first_line: &str) -> String {
@@ -375,11 +510,7 @@ mod tests {
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap();
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
}
#[cfg(unix)]
@@ -399,11 +530,7 @@ mod tests {
let input = Input::stdin().with_name(Some(file_name));
let mut opened_input = input.open(content, None).unwrap();
self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
.unwrap_or_else(|_| self.assets.syntax_set.find_syntax_plain_text())
.name
.clone()
self.get_syntax_name(None, &mut opened_input, &self.syntax_mapping)
}
fn syntax_is_same_for_inputkinds(&self, file_name: &str, content: &str) -> bool {
@@ -557,10 +684,7 @@ mod tests {
let mut opened_input = input.open(dummy_stdin, None).unwrap();
assert_eq!(
test.assets
.get_syntax(None, &mut opened_input, &test.syntax_mapping)
.unwrap_or_else(|_| test.assets.syntax_set.find_syntax_plain_text())
.name,
test.get_syntax_name(None, &mut opened_input, &test.syntax_mapping),
"SSH Config"
);
}

View File

@@ -16,6 +16,7 @@ pub struct AssetsMetadata {
const FILENAME: &str = "metadata.yaml";
impl AssetsMetadata {
#[cfg(feature = "build-assets")]
pub(crate) fn new(current_version: &str) -> AssetsMetadata {
AssetsMetadata {
bat_version: Some(current_version.to_owned()),
@@ -23,6 +24,7 @@ impl AssetsMetadata {
}
}
#[cfg(feature = "build-assets")]
pub(crate) fn save_to_folder(&self, path: &Path) -> Result<()> {
let file = File::create(path.join(FILENAME))?;
serde_yaml::to_writer(file, self)?;

View File

@@ -158,7 +158,7 @@ impl App {
WrappingMode::Character
}
}
_ => unreachable!("other values for --paging are not allowed"),
_ => unreachable!("other values for --wrap are not allowed"),
}
} else {
// We don't have the tty width when piping to another program.
@@ -234,6 +234,7 @@ impl App {
.map(LineRanges::from)
.map(HighlightedLineRanges)
.unwrap_or_default(),
use_custom_assets: !self.matches.is_present("no-custom-assets"),
})
}
@@ -300,7 +301,7 @@ impl App {
.map(|style_str| {
style_str
.split(',')
.map(|x| StyleComponent::from_str(&x))
.map(|x| StyleComponent::from_str(x))
.collect::<Result<Vec<StyleComponent>>>()
})
.transpose()?;

View File

@@ -18,26 +18,14 @@ pub fn cache_dir() -> Cow<'static, str> {
}
pub fn clear_assets() {
let theme_set_path = PROJECT_DIRS.cache_dir().join("themes.bin");
let syntax_set_path = PROJECT_DIRS.cache_dir().join("syntaxes.bin");
let metadata_file = PROJECT_DIRS.cache_dir().join("metadata.yaml");
print!("Clearing theme set cache ... ");
fs::remove_file(theme_set_path).ok();
println!("okay");
print!("Clearing syntax set cache ... ");
fs::remove_file(syntax_set_path).ok();
println!("okay");
print!("Clearing metadata file ... ");
fs::remove_file(metadata_file).ok();
println!("okay");
clear_asset("themes.bin", "theme set cache");
clear_asset("syntaxes.bin", "syntax set cache");
clear_asset("metadata.yaml", "metadata file");
}
pub fn assets_from_cache_or_binary() -> Result<HighlightingAssets> {
pub fn assets_from_cache_or_binary(use_custom_assets: bool) -> Result<HighlightingAssets> {
let cache_dir = PROJECT_DIRS.cache_dir();
if let Some(metadata) = AssetsMetadata::load_from_folder(&cache_dir)? {
if let Some(metadata) = AssetsMetadata::load_from_folder(cache_dir)? {
if !metadata.is_compatible_with(crate_version!()) {
return Err(format!(
"The binary caches for the user-customized syntaxes and themes \
@@ -53,6 +41,16 @@ pub fn assets_from_cache_or_binary() -> Result<HighlightingAssets> {
}
}
Ok(HighlightingAssets::from_cache(&cache_dir)
.unwrap_or_else(|_| HighlightingAssets::from_binary()))
let custom_assets = if use_custom_assets {
HighlightingAssets::from_cache(cache_dir).ok()
} else {
None
};
Ok(custom_assets.unwrap_or_else(HighlightingAssets::from_binary))
}
fn clear_asset(filename: &str, description: &str) {
print!("Clearing {} ... ", description);
fs::remove_file(PROJECT_DIRS.cache_dir().join(filename)).ok();
println!("okay");
}

View File

@@ -294,6 +294,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.arg(
Arg::with_name("no-paging")
.short("P")
.long("no-paging")
.alias("no-pager")
.overrides_with("no-paging")
.hidden(true)
@@ -394,8 +395,8 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
'--style=\"..\"' option to the configuration file or export the \
BAT_STYLE environment variable (e.g.: export BAT_STYLE=\"..\").\n\n\
Possible values:\n\n \
* full: enables all available components.\n \
* auto: same as 'full', unless the output is piped (default).\n \
* full: enables all available components (default).\n \
* auto: same as 'full', unless the output is piped.\n \
* plain: disables all available components.\n \
* changes: show Git modification markers.\n \
* header: show filenames before the content.\n \
@@ -450,6 +451,12 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
.hidden(true)
.help("Do not use the configuration file"),
)
.arg(
Arg::with_name("no-custom-assets")
.long("no-custom-assets")
.hidden(true)
.help("Do not load custom assets"),
)
.arg(
Arg::with_name("config-file")
.long("config-file")

View File

@@ -4,8 +4,9 @@ use std::path::{Path, PathBuf};
use lazy_static::lazy_static;
/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
/// This means that the `XDG_CACHE_HOME` and `XDG_CONFIG_HOME` environment variables are
/// checked first. The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively.
/// The `XDG_CACHE_HOME` environment variable is checked first. `BAT_CONFIG_DIR`
/// is then checked before the `XDG_CONFIG_HOME` environment variable.
/// The fallback directories are `~/.cache/bat` and `~/.config/bat`, respectively.
pub struct BatProjectDirs {
cache_dir: PathBuf,
config_dir: PathBuf,
@@ -15,16 +16,23 @@ impl BatProjectDirs {
fn new() -> Option<BatProjectDirs> {
let cache_dir = BatProjectDirs::get_cache_dir()?;
#[cfg(target_os = "macos")]
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs_next::home_dir().map(|d| d.join(".config")));
// Checks whether or not $BAT_CONFIG_DIR exists. If it doesn't, set our config dir
// to our system's default configuration home.
let config_dir =
if let Some(config_dir_op) = env::var_os("BAT_CONFIG_DIR").map(PathBuf::from) {
config_dir_op
} else {
#[cfg(target_os = "macos")]
let config_dir_op = env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs_next::home_dir().map(|d| d.join(".config")));
#[cfg(not(target_os = "macos"))]
let config_dir_op = dirs_next::config_dir();
#[cfg(not(target_os = "macos"))]
let config_dir_op = dirs_next::config_dir();
let config_dir = config_dir_op.map(|d| d.join("bat"))?;
config_dir_op.map(|d| d.join("bat"))?
};
Some(BatProjectDirs {
cache_dir,

View File

@@ -23,12 +23,10 @@ use crate::{
};
use assets::{assets_from_cache_or_binary, cache_dir, clear_assets, config_dir};
use clap::crate_version;
use directories::PROJECT_DIRS;
use globset::GlobMatcher;
use bat::{
assets::HighlightingAssets,
config::Config,
controller::Controller,
error::*,
@@ -39,21 +37,29 @@ use bat::{
const THEME_PREVIEW_DATA: &[u8] = include_bytes!("../../../assets/theme_preview.rs");
#[cfg(feature = "build-assets")]
fn build_assets(matches: &clap::ArgMatches) -> Result<()> {
let source_dir = matches
.value_of("source")
.map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.config_dir());
let target_dir = matches
.value_of("target")
.map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
let blank = matches.is_present("blank");
let assets = bat::assets::HighlightingAssets::from_files(source_dir, !blank)?;
assets.save_to_cache(target_dir, clap::crate_version!())
}
fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
if matches.is_present("build") {
let source_dir = matches
.value_of("source")
.map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.config_dir());
let target_dir = matches
.value_of("target")
.map(Path::new)
.unwrap_or_else(|| PROJECT_DIRS.cache_dir());
let blank = matches.is_present("blank");
let assets = HighlightingAssets::from_files(source_dir, !blank)?;
assets.save_to_cache(target_dir, crate_version!())?;
#[cfg(feature = "build-assets")]
build_assets(matches)?;
#[cfg(not(feature = "build-assets"))]
println!("bat has been built without the 'build-assets' feature. The 'cache --build' option is not available.");
} else if matches.is_present("clear") {
clear_assets();
}
@@ -80,9 +86,9 @@ fn get_syntax_mapping_to_paths<'a>(
pub fn get_languages(config: &Config) -> Result<String> {
let mut result: String = String::new();
let assets = assets_from_cache_or_binary()?;
let assets = assets_from_cache_or_binary(config.use_custom_assets)?;
let mut languages = assets
.syntaxes()
.get_syntaxes()?
.iter()
.filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty())
.cloned()
@@ -101,8 +107,11 @@ pub fn get_languages(config: &Config) -> Result<String> {
true
} else {
let test_file = Path::new("test").with_extension(extension);
match assets.syntax_for_file_name(test_file, &config.syntax_mapping) {
Some(syntax) => syntax.name == lang_name,
let syntax_in_set = assets
.get_syntax_for_file_name(test_file, &config.syntax_mapping)
.unwrap(); // safe since .get_syntaxes() above worked
match syntax_in_set {
Some(syntax_in_set) => syntax_in_set.syntax.name == lang_name,
None => false,
}
}
@@ -175,7 +184,7 @@ fn theme_preview_file<'a>() -> Input<'a> {
}
pub fn list_themes(cfg: &Config) -> Result<()> {
let assets = assets_from_cache_or_binary()?;
let assets = assets_from_cache_or_binary(cfg.use_custom_assets)?;
let mut config = cfg.clone();
let mut style = HashSet::new();
style.insert(StyleComponent::Plain);
@@ -216,57 +225,64 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
}
fn run_controller(inputs: Vec<Input>, config: &Config) -> Result<bool> {
let assets = assets_from_cache_or_binary()?;
let controller = Controller::new(&config, &assets);
let assets = assets_from_cache_or_binary(config.use_custom_assets)?;
let controller = Controller::new(config, &assets);
controller.run(inputs)
}
#[cfg(feature = "bugreport")]
fn invoke_bugreport(app: &App) {
use bugreport::{bugreport, collector::*, format::Markdown};
let pager = bat::config::get_pager_executable(app.matches.value_of("pager"))
.unwrap_or_else(|| "less".to_owned()); // FIXME: Avoid non-canonical path to "less".
let report = bugreport!()
.info(SoftwareVersion::default())
.info(OperatingSystem::default())
.info(CommandLine::default())
.info(EnvironmentVariables::list(&[
"SHELL",
"PAGER",
"LESS",
"BAT_PAGER",
"BAT_CACHE_PATH",
"BAT_CONFIG_PATH",
"BAT_OPTS",
"BAT_STYLE",
"BAT_TABS",
"BAT_THEME",
"XDG_CONFIG_HOME",
"XDG_CACHE_HOME",
"COLORTERM",
"NO_COLOR",
"MANPAGER",
]))
.info(FileContent::new("Config file", config_file()))
.info(CompileTimeInformation::default());
let mut report = if let Ok(resolved_path) = grep_cli::resolve_binary(pager) {
report.info(CommandOutput::new(
"Less version",
resolved_path,
&["--version"],
))
} else {
report
};
report.print::<Markdown>();
}
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Ok(true)` on full success and
/// `Ok(false)` if any intermediate errors occurred (were printed).
fn run() -> Result<bool> {
let app = App::new()?;
if app.matches.is_present("diagnostic") {
use bugreport::{bugreport, collector::*, format::Markdown};
let pager = bat::config::get_pager_executable(app.matches.value_of("pager"))
.unwrap_or_else(|| "less".to_owned()); // FIXME: Avoid non-canonical path to "less".
let report = bugreport!()
.info(SoftwareVersion::default())
.info(OperatingSystem::default())
.info(CommandLine::default())
.info(EnvironmentVariables::list(&[
"SHELL",
"PAGER",
"LESS",
"BAT_PAGER",
"BAT_CACHE_PATH",
"BAT_CONFIG_PATH",
"BAT_OPTS",
"BAT_STYLE",
"BAT_TABS",
"BAT_THEME",
"XDG_CONFIG_HOME",
"XDG_CACHE_HOME",
"COLORTERM",
"NO_COLOR",
"MANPAGER",
]))
.info(FileContent::new("Config file", config_file()))
.info(CompileTimeInformation::default());
let mut report = if let Ok(resolved_path) = grep_cli::resolve_binary(pager) {
report.info(CommandOutput::new(
"Less version",
resolved_path,
&["--version"],
))
} else {
report
};
report.print::<Markdown>();
#[cfg(feature = "bugreport")]
invoke_bugreport(&app);
#[cfg(not(feature = "bugreport"))]
println!("bat has been built without the 'bugreport' feature. The '--diagnostic' option is not available.");
return Ok(true);
}

View File

@@ -82,9 +82,13 @@ pub struct Config<'a> {
/// Ranges of lines which should be highlighted with a special background color
pub highlighted_lines: HighlightedLineRanges,
/// Whether or not to allow custom assets. If this is false or if custom assets (a.k.a.
/// cached assets) are not available, assets from the binary will be used instead.
pub use_custom_assets: bool,
}
#[cfg(all(feature = "application", feature = "paging"))]
#[cfg(all(feature = "minimal-application", feature = "paging"))]
pub fn get_pager_executable(config_pager: Option<&str>) -> Option<String> {
if let Ok(Some(pager)) = crate::pager::get_pager(config_pager) {
Some(pager.bin)

View File

@@ -45,7 +45,7 @@ impl<'b> Controller<'b> {
// Do not launch the pager if NONE of the input files exist
let mut paging_mode = self.config.paging_mode;
if self.config.paging_mode != PagingMode::Never {
let call_pager = inputs.iter().any(|ref input| {
let call_pager = inputs.iter().any(|input| {
if let InputKind::OrdinaryFile(ref path) = input.kind {
Path::new(path).exists()
} else {
@@ -124,11 +124,11 @@ impl<'b> Controller<'b> {
};
let mut printer: Box<dyn Printer> = if self.config.loop_through {
Box::new(SimplePrinter::new(&self.config))
Box::new(SimplePrinter::new(self.config))
} else {
Box::new(InteractivePrinter::new(
&self.config,
&self.assets,
self.config,
self.assets,
&mut opened_input,
#[cfg(feature = "git")]
&line_changes,

View File

@@ -3,7 +3,7 @@ use std::io::Write;
error_chain! {
foreign_links {
Clap(::clap::Error) #[cfg(feature = "application")];
Clap(::clap::Error) #[cfg(feature = "minimal-application")];
Io(::std::io::Error);
SyntectError(::syntect::LoadingError);
ParseIntError(::std::num::ParseIntError);

View File

@@ -51,7 +51,7 @@ impl InputDescription {
pub fn title(&self) -> &String {
match self.title.as_ref() {
Some(ref title) => title,
Some(title) => title,
None => &self.name,
}
}
@@ -282,21 +282,21 @@ fn basic() {
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert!(res.unwrap());
assert_eq!(b"#!/bin/bash\n", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert!(res.unwrap());
assert_eq!(b"echo hello", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(!res.unwrap());
assert!(buffer.is_empty());
}
@@ -311,20 +311,20 @@ fn utf16le() {
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert!(res.unwrap());
assert_eq!(b"\xFF\xFE\x73\x00\x0A\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(true, res.unwrap());
assert!(res.unwrap());
assert_eq!(b"\x64\x00", &buffer[..]);
buffer.clear();
let res = reader.read_line(&mut buffer);
assert!(res.is_ok());
assert_eq!(false, res.unwrap());
assert!(!res.unwrap());
assert!(buffer.is_empty());
}

View File

@@ -40,6 +40,8 @@ mod preprocessor;
mod pretty_printer;
pub(crate) mod printer;
pub mod style;
#[cfg(feature = "build-assets")]
mod syntax_dependencies;
pub(crate) mod syntax_mapping;
mod terminal;
pub(crate) mod wrapping;

View File

@@ -235,7 +235,9 @@ impl<'a> PrettyPrinter<'a> {
}
pub fn syntaxes(&self) -> impl Iterator<Item = &SyntaxReference> {
self.assets.syntaxes().iter()
// We always use assets from the binary, which are guaranteed to always
// be valid, so get_syntaxes() can never fail here
self.assets.get_syntaxes().unwrap().iter()
}
/// Pretty-print all specified inputs. This method will "use" all stored inputs.

View File

@@ -18,7 +18,7 @@ use encoding::{DecoderTrap, Encoding};
use unicode_width::UnicodeWidthChar;
use crate::assets::HighlightingAssets;
use crate::assets::{HighlightingAssets, SyntaxReferenceInSet};
use crate::config::Config;
#[cfg(feature = "git")]
use crate::decorations::LineChangesDecoration;
@@ -163,23 +163,29 @@ impl<'a> InteractivePrinter<'a> {
panel_width = 0;
}
let highlighter = if input
let (highlighter, syntax_set) = if input
.reader
.content_type
.map_or(false, |c| c.is_binary() && !config.show_nonprintable)
{
None
(None, assets.get_syntax_set()?)
} else {
// Determine the type of syntax for highlighting
let syntax = match assets.get_syntax(config.language, input, &config.syntax_mapping) {
Ok(syntax) => syntax,
Err(Error(ErrorKind::UndetectedSyntax(_), _)) => {
assets.syntax_set.find_syntax_plain_text()
}
Err(e) => return Err(e),
};
let syntax_in_set =
match assets.get_syntax(config.language, input, &config.syntax_mapping) {
Ok(syntax_in_set) => syntax_in_set,
Err(Error(ErrorKind::UndetectedSyntax(_), _)) => {
let syntax_set = assets.get_syntax_set()?;
let syntax = syntax_set.find_syntax_plain_text();
SyntaxReferenceInSet { syntax, syntax_set }
}
Err(e) => return Err(e),
};
Some(HighlightLines::new(syntax, theme))
(
Some(HighlightLines::new(syntax_in_set.syntax, theme)),
syntax_in_set.syntax_set,
)
};
Ok(InteractivePrinter {
@@ -192,7 +198,7 @@ impl<'a> InteractivePrinter<'a> {
#[cfg(feature = "git")]
line_changes,
highlighter,
syntax_set: &assets.syntax_set,
syntax_set,
background_color_highlight,
})
}
@@ -366,19 +372,19 @@ impl<'a> Printer for InteractivePrinter<'a> {
line_buffer: &[u8],
) -> Result<()> {
let line = if self.config.show_nonprintable {
replace_nonprintable(&line_buffer, self.config.tab_width)
replace_nonprintable(line_buffer, self.config.tab_width)
} else {
match self.content_type {
Some(ContentType::BINARY) | None => {
return Ok(());
}
Some(ContentType::UTF_16LE) => UTF_16LE
.decode(&line_buffer, DecoderTrap::Replace)
.decode(line_buffer, DecoderTrap::Replace)
.map_err(|_| "Invalid UTF-16LE")?,
Some(ContentType::UTF_16BE) => UTF_16BE
.decode(&line_buffer, DecoderTrap::Replace)
.decode(line_buffer, DecoderTrap::Replace)
.map_err(|_| "Invalid UTF-16BE")?,
_ => String::from_utf8_lossy(&line_buffer).to_string(),
_ => String::from_utf8_lossy(line_buffer).to_string(),
}
};
@@ -414,7 +420,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
let decorations = self
.decorations
.iter()
.map(|ref d| d.generate(line_number, false, self))
.map(|d| d.generate(line_number, false, self))
.collect::<Vec<_>>();
for deco in decorations {
@@ -525,7 +531,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
"{} ",
self.decorations
.iter()
.map(|ref d| d
.map(|d| d
.generate(line_number, true, self)
.text)
.collect::<Vec<String>>()

184
src/syntax_dependencies.rs Normal file
View File

@@ -0,0 +1,184 @@
use std::collections::HashMap;
use syntect::parsing::syntax_definition::{
ContextReference, MatchOperation, MatchPattern, Pattern, SyntaxDefinition,
};
use syntect::parsing::{Scope, SyntaxSet, SyntaxSetBuilder};
type SyntaxName = String;
/// Used to look up what dependencies a given [SyntaxDefinition] has
type SyntaxToDependencies = HashMap<SyntaxName, Vec<Dependency>>;
/// Used to look up which [SyntaxDefinition] corresponds to a given [Dependency]
type DependencyToSyntax<'a> = HashMap<Dependency, &'a SyntaxDefinition>;
/// Represents a dependency on an external `.sublime-syntax` file.
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
enum Dependency {
/// By name. Example YAML: `include: C.sublime-syntax`
ByName(String),
/// By scope. Example YAML: `embed: scope:source.c`
ByScope(Scope),
}
/// Generates independent [SyntaxSet]s after analyzing dependencies between syntaxes
/// in a [SyntaxSetBuilder], and then prints the reults.
pub(crate) fn print_syntax_dependencies(syntax_set_builder: &SyntaxSetBuilder) {
println!("Constructing independent SyntaxSets...");
let independent_syntax_sets = build_independent_syntax_sets(syntax_set_builder);
println!("Independent SyntaxSets:");
for syntax_set in independent_syntax_sets {
let names = syntax_set
.syntaxes()
.iter()
.map(|syntax| &syntax.name)
.collect::<Vec<_>>();
println!("{:?}", names);
}
}
/// Analyzes dependencies between syntaxes in a [SyntaxSetBuilder].
/// From that, it builds independent [SyntaxSet]s.
fn build_independent_syntax_sets(
syntax_set_builder: &'_ SyntaxSetBuilder,
) -> impl Iterator<Item = SyntaxSet> + '_ {
let syntaxes = syntax_set_builder.syntaxes();
// Build the data structures we need for dependency resolution
let (syntax_to_dependencies, dependency_to_syntax) = generate_maps(syntaxes);
// Create one independent SyntaxSet from each (non-hidden) SyntaxDefinition
syntaxes.iter().filter_map(move |syntax| {
if syntax.hidden {
return None;
}
let mut builder = SyntaxSetDependencyBuilder::new();
builder.add_with_dependencies(syntax, &syntax_to_dependencies, &dependency_to_syntax);
Some(builder.build())
})
}
/// In order to analyze dependencies, we need two key pieces of data.
/// First, when we have a [Dependency], we need to know what [SyntaxDefinition] that
/// corresponds to. Second, when we have a [SyntaxDefinition], we need to know
/// what dependencies it has. This functions generates that data for each syntax.
fn generate_maps(syntaxes: &[SyntaxDefinition]) -> (SyntaxToDependencies, DependencyToSyntax) {
let mut syntax_to_dependencies = HashMap::new();
let mut dependency_to_syntax = HashMap::new();
for syntax in syntaxes {
syntax_to_dependencies.insert(syntax.name.clone(), dependencies_for_syntax(syntax));
dependency_to_syntax.insert(Dependency::ByName(syntax.name.clone()), syntax);
dependency_to_syntax.insert(Dependency::ByScope(syntax.scope), syntax);
}
(syntax_to_dependencies, dependency_to_syntax)
}
/// Gets what external dependencies a given [SyntaxDefinition] has.
/// An external dependency is another `.sublime-syntax` file.
/// It does that by looking for variants of the following YAML patterns:
/// - `include: C.sublime-syntax`
/// - `embed: scope:source.c`
fn dependencies_for_syntax(syntax: &SyntaxDefinition) -> Vec<Dependency> {
let mut dependencies: Vec<Dependency> = syntax
.contexts
.values()
.flat_map(|context| &context.patterns)
.flat_map(dependencies_from_pattern)
.collect();
// No need to track a dependency more than once
dependencies.dedup();
dependencies
}
fn dependencies_from_pattern(pattern: &Pattern) -> Vec<Dependency> {
match *pattern {
Pattern::Match(MatchPattern {
operation: MatchOperation::Push(ref context_references),
..
}) => context_references
.iter()
.map(dependency_from_context_reference)
.collect(),
Pattern::Include(ref context_reference) => {
vec![dependency_from_context_reference(context_reference)]
}
_ => vec![],
}
.into_iter()
.flatten()
.collect()
}
fn dependency_from_context_reference(context_reference: &ContextReference) -> Option<Dependency> {
match &context_reference {
ContextReference::File { ref name, .. } => Some(Dependency::ByName(name.clone())),
ContextReference::ByScope { ref scope, .. } => Some(Dependency::ByScope(*scope)),
_ => None,
}
}
/// Helper to construct a [SyntaxSetBuilder] that contains only [SyntaxDefinition]s
/// that have dependencies among them.
struct SyntaxSetDependencyBuilder {
syntax_set_builder: SyntaxSetBuilder,
}
impl SyntaxSetDependencyBuilder {
fn new() -> Self {
SyntaxSetDependencyBuilder {
syntax_set_builder: SyntaxSetBuilder::new(),
}
}
/// Add a [SyntaxDefinition] to the underlying [SyntaxSetBuilder].
/// Also resolve any dependencies it has and add those [SyntaxDefinition]s too.
/// This is a recursive process.
fn add_with_dependencies(
&mut self,
syntax: &SyntaxDefinition,
syntax_to_dependencies: &SyntaxToDependencies,
dependency_to_syntax: &DependencyToSyntax,
) {
let name = &syntax.name;
if self.is_syntax_already_added(name) {
return;
}
self.syntax_set_builder.add(syntax.clone());
let dependencies = syntax_to_dependencies.get(name);
if dependencies.is_none() {
eprintln!("ERROR: Unknown dependencies for {}", name);
return;
}
for dependency in dependencies.unwrap() {
if let Some(syntax_definition_dependency) = dependency_to_syntax.get(dependency) {
self.add_with_dependencies(
syntax_definition_dependency,
syntax_to_dependencies,
dependency_to_syntax,
)
}
}
}
fn is_syntax_already_added(&self, name: &str) -> bool {
self.syntax_set_builder
.syntaxes()
.iter()
.any(|syntax| syntax.name == name)
}
fn build(self) -> SyntaxSet {
self.syntax_set_builder.build()
}
}

View File

@@ -3,9 +3,9 @@ cd "$(dirname "${BASH_SOURCE[0]}")" || exit
# Check that Hyperfine is installed.
if ! command -v 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
echo "'hyperfine' does not seem to be installed."
echo "You can get it here: https://github.com/sharkdp/hyperfine"
exit 1
fi
# Determine the target directories.
@@ -15,7 +15,7 @@ get_target_dir() {
| sed 's/^[[:space:]]*target-dir[[:space:]]*=//; s/^[[:space:]]*"//; s/"[[:space:]]*$//' \
&& return 0
fi
echo "../../target"
}
@@ -68,5 +68,5 @@ echo "### Time to syntax-highlight large files"
echo
for SRC in test-src/*; do
hyperfine --warmup 3 "$(printf "%q" "$BAT") --style=full --color=always --paging=never $(printf "%q" "$SRC")"
hyperfine --warmup 3 "$(printf "%q" "$BAT") --style=full --color=always --paging=never $(printf "%q" "$SRC")"
done

View File

@@ -40,6 +40,7 @@ fn bat_raw_command_with_config() -> Command {
cmd.env_remove("BAT_STYLE");
cmd.env_remove("BAT_THEME");
cmd.env_remove("BAT_TABS");
cmd.env_remove("BAT_CONFIG_DIR");
cmd
}
@@ -700,6 +701,16 @@ fn pager_failed_to_parse() {
.stderr(predicate::str::contains("Could not parse pager command"));
}
#[test]
fn diagnostic_sanity_check() {
bat()
.arg("--diagnostic")
.assert()
.success()
.stdout(predicate::str::contains("BAT_PAGER="))
.stderr("");
}
#[test]
fn config_location_test() {
bat_with_config()
@@ -737,6 +748,16 @@ fn config_location_when_generating() {
assert!(tmp_config_path.exists());
}
#[test]
fn config_location_from_bat_config_dir_variable() {
bat_with_config()
.env("BAT_CONFIG_DIR", "conf/")
.arg("--config-file")
.assert()
.success()
.stdout(predicate::str::is_match("conf/config\n").unwrap());
}
#[test]
fn config_read_arguments_from_file() {
bat_with_config()
@@ -795,6 +816,17 @@ fn does_not_print_unwanted_file_named_cache() {
bat_with_config().arg("cach").assert().failure();
}
#[test]
fn accepts_no_custom_assets_arg() {
// Just make sure --no-custom-assets is considered a valid arg
// Don't bother to actually verify that it works
bat()
.arg("--no-custom-assets")
.arg("test.txt")
.assert()
.success();
}
#[test]
fn unicode_wrap() {
bat_with_config()
@@ -1101,6 +1133,42 @@ fn show_all_mode() {
.stderr("");
}
#[test]
fn no_paging_arg() {
bat()
.arg("--no-paging")
.arg("--color=never")
.arg("--decorations=never")
.arg("single-line.txt")
.assert()
.success()
.stdout("Single Line");
}
#[test]
fn no_paging_short_arg() {
bat()
.arg("-P")
.arg("--color=never")
.arg("--decorations=never")
.arg("single-line.txt")
.assert()
.success()
.stdout("Single Line");
}
#[test]
fn no_pager_arg() {
bat()
.arg("--no-pager")
.arg("--color=never")
.arg("--decorations=never")
.arg("single-line.txt")
.assert()
.success()
.stdout("Single Line");
}
#[test]
fn plain_mode_does_not_add_nonexisting_newline() {
bat()

View File

@@ -26,7 +26,7 @@ fn no_duplicate_extensions() {
let mut extensions = HashSet::new();
for syntax in assets.syntaxes() {
for syntax in assets.get_syntaxes().expect("this is a #[test]") {
for extension in &syntax.file_extensions {
assert!(
KNOWN_EXCEPTIONS.contains(&extension.as_str()) || extensions.insert(extension),

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python3
#
# This script goes through all languages that are supported by 'bat'. For each
# language, it loops over the correspoinding file extensions and searches a
# language, it loops over the corresponding file extensions and searches a
# given folder for matching files. It calls 'bat' for each of these files and
# measures the highlighting speed (number of characters per second). The script
# reports files which lead to slow highlighting speeds or errors during the

View File

@@ -0,0 +1,126 @@
.TH RUSTDOC "1" "<INSERT DATE HERE>" "rustdoc <INSERT VERSION HERE>" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS
.B rustdoc
[\fIOPTIONS\fR] \fIINPUT\fR
.SH DESCRIPTION
This tool generates API reference documentation by extracting comments from
source code written in the Rust language, available at
<\fBhttps://www.rust-lang.org\fR>. It accepts several input formats and
provides several output formats for the generated documentation.
.SH OPTIONS
.TP
\fB\-r\fR, \fB\-\-input\-format\fR \fIFORMAT\fR
rust
.TP
\fB\-w\fR, \fB\-\-output\-format\fR \fIFORMAT\fR
html
.TP
\fB\-o\fR, \fB\-\-output\fR \fIOUTPUT\fR,
where to place the output (default: \fIdoc/\fR for html)
.TP
\fB\-\-passes\fR \fILIST\fR
space\[hy]separated list of passes to run (default: '')
.TP
\fB\-\-no\-defaults\fR
don't run the default passes
.TP
\fB\-\-plugins\fR \fILIST\fR
space-separated list of plugins to run (default: '')
.TP
\fB\-\-plugin\-path\fR \fIDIR\fR
directory to load plugins from (default: \fI/tmp/rustdoc_ng/plugins\fR)
.TP
\fB\-\-target\fR \fITRIPLE\fR
target triple to document
.TP
\fB\-\-crate\-name\fR \fINAME\fR
specify the name of this crate
.TP
\fB\-L\fR, \fB\-\-library\-path\fR \fIDIR\fR
directory to add to crate search path
.TP
\fB\-\-cfg\fR \fISPEC\fR
pass a \fI\-\-cfg\fR to rustc
.TP
\fB\-\-extern\fR \fIVAL\fR
pass an \fI\-\-extern\fR to rustc
.TP
\fB\-\-test\fR
run code examples as tests
.TP
\fB\-\-test\-args\fR \fIARGS\fR
pass arguments to the test runner
.TP
\fB\-\-html\-in\-header\fR \fIFILE\fR
file to add to <head>
.TP
\fB\-\-html\-before\-content\fR \fIFILES\fR
files to include inline between <body> and the content of a rendered Markdown
file or generated documentation
.TP
\fB\-\-markdown\-before\-content\fR \fIFILES\fR
files to include inline between <body> and the content of a rendered
Markdown file or generated documentation
.TP
\fB\-\-html\-after\-content\fR \fIFILES\fR
files to include inline between the content and </body> of a rendered
Markdown file or generated documentation
.TP
\fB\-\-markdown\-after\-content\fR \fIFILES\fR
files to include inline between the content and </body> of a rendered
Markdown file or generated documentation
.TP
\fB\-\-markdown\-css\fR \fIFILES\fR
CSS files to include via <link> in a rendered Markdown file Markdown file or
generated documentation
.TP
\fB\-\-markdown\-playground\-url\fR \fIURL\fR
URL to send code snippets to
.TP
\fB\-\-markdown\-no\-toc\fR
don't include table of contents
.TP
\fB\-h\fR, \fB\-\-extend\-css\fR
to redefine some css rules with a given file to generate doc with your own theme
.TP
\fB\-V\fR, \fB\-\-version\fR
Print rustdoc's version
.SH "OUTPUT FORMATS"
The rustdoc tool can generate output in an HTML format.
If using an HTML format, then the specified output destination will be the root
directory of an HTML structure for all the documentation.
Pages will be placed into this directory, and source files will also
possibly be rendered into it as well.
.SH "EXAMPLES"
To generate documentation for the source in the current directory:
 $ rustdoc hello.rs
List all available passes that rustdoc has, along with default passes:
 $ rustdoc \-\-passes list
The generated HTML can be viewed with any standard web browser.
.SH "SEE ALSO"
.BR rustc (1)
.SH "BUGS"
See <\fBhttps://github.com/rust\-lang/rust/issues\fR>
for issues.
.SH "AUTHOR"
See the version control history or <\fBhttps://thanks.rust\-lang.org\fR>
.SH "COPYRIGHT"
This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
See \fICOPYRIGHT\fR file in the rust source distribution.

View File

@@ -0,0 +1,29 @@
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1
; Function Attrs: noinline norecurse optnone uwtable
define dso_local i32 @main(i32 %0, i8** %1) #0 {
 %3 = alloca i32, align 4
 %4 = alloca i32, align 4
 %5 = alloca i8**, align 8
 store i32 0, i32* %3, align 4
 store i32 %0, i32* %4, align 4
 store i8** %1, i8*** %5, align 8
 %6 = call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0))
 ret i32 1337
}
declare dso_local i32 @puts(i8*) #1
attributes #0 = { noinline norecurse optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 10.0.0-4ubuntu1 "}

View File

@@ -8,7 +8,7 @@
h2 = 4 # this is a comment
"""this is also a comment"""
# Import testt
# Import test
# class test
@@ -16,14 +16,19 @@
class Hello:
 def __init__(self, x):
 self.name = x
 
 def selfprint(self):
 print("hello my name is ", self.name)
 def testprint(self):
 print(1*2, 2+3, 4 % 5, 8-4, 9/4, 23//4)
# Decorators test
class Decorators:
 @classmethod
 def decoratorsTest(self):
 pass
 
H1 = Hello("john")
H1.selfprint()
H1.testprint()
@@ -37,8 +42,8 @@
print(a[2])
print(a[2:])
# dictioary test
# copied from w3school example
# dictionary test
# copied from w3schools example
myfamily = {
 "child1": {
@@ -55,7 +60,7 @@
 }
}
# touple test
# tuple test
testTuple = ("one", 2, "3")
print(testTuple)
@@ -70,7 +75,7 @@
formattest = "teststring is ={}".format(5)
# lamda test
# lambda test
def x2(n):

View File

@@ -0,0 +1,20 @@
doctype html
html lang=locale
 head
 meta charset='utf-8'
 title #{@title ? "#{@title} | Testing" : 'Testing'}
 == stylesheet('app.css')
 body
 header
 h1.title Testing
 - @links.each do |link|
 a href=link.href
 =link.title
 div
 == yield
 - if APP_ENV == 'production'
 footer
 p Testing

View File

@@ -9,3 +9,8 @@
Apr 4 09:30:01 hostname-here CRON[89278]: (root) CMD ([ -x /etc/init.d/anacron ] && if [ ! -d /run/systemd/system ]; then /usr/sbin/invoke-rc.d anacron start >/dev/null; fi)
Apr 4 16:32:07 hostname-here NetworkManager[740]: <info> [1617629527.1101] manager: NetworkManager state is now CONNECTED_GLOBAL
Apr 4 22:00:45 hostname-here dbus-daemon[1094]: [session uid=1000 pid=1094] Successfully activated service 'io.github.celluloid_player.Celluloid'
Aug 11 13:29:06 hostname-here insomnia_insomnia.desktop[142666]: 13:29:06.316 [updater] Updater not running platform=linux dev=false
Aug 11 13:36:34 192.168.220.5 nginx: 2021/08/11 13:36:34 [debug] 2031#2031: epoll add event: fd:6 op:1 ev:00002001
Aug 11 21:31:08 ::1 nginx: 2021/08/11 21:31:08 [debug] 760831#760831: epoll add event: fd:6 op:1 ev:10000001
Aug 11 21:40:31 hostname-here scop hello
Aug 16 21:38:21 hostname-here systemd[1]: Finished Cleanup of Temporary Directories.

View File

@@ -0,0 +1,44 @@
POST /foo/bar?id=4&x=y%20z HTTP/1.1
X-Forwarded-For: 127.0.0.1
Content-Length: 124
Cache-Control: no-cache
X-Forwarded-Proto: https
Content-Type: application/json; charset=utf-8
Host: example.com
Accept: */*; q=0.5, application/xml
Accept-Encoding: gzip
{
 "id": "blahblahblahblah",
 "object": "event",
 "api_version": "2020-03-02",
 "created": 1626790174,
 "data": {
 }
}
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 23 Jul 2021 10:15:12 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private; max-age=0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: origin
Strict-Transport-Security: max-age=31556900
<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>Hello World</title>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,235 @@
The `rustdoc.1` file has been added from https://github.com/rust-lang/rust/blob/a75e74df89230bc429a550e29d5c566de5f95deb/src/doc/man/rustdoc.1 under the following license:
```text
Short version for non-lawyers:
The Rust Project is dual-licensed under Apache 2.0 and MIT
terms.
Longer version:
Copyrights in the Rust project are retained by their contributors. No
copyright assignment is required to contribute to the Rust project.
Some files include explicit copyright notices and/or license notices.
For full authorship information, see the version control history or
https://thanks.rust-lang.org
Except as otherwise noted (below and/or in individual files), Rust is
licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or
<http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
<LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your option.
The Rust Project includes packages written by third parties.
The following third party packages are included, and carry
their own copyright notices and license terms:
* LLVM. Code for this package is found in src/llvm-project.
Copyright (c) 2003-2013 University of Illinois at
Urbana-Champaign. All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal with 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:
* Redistributions of source code must retain the
above copyright notice, this list of conditions
and the following disclaimers.
* Redistributions in binary form must reproduce the
above copyright notice, this list of conditions
and the following disclaimers in the documentation
and/or other materials provided with the
distribution.
* Neither the names of the LLVM Team, University of
Illinois at Urbana-Champaign, nor the names of its
contributors may be used to endorse or promote
products derived from this Software without
specific prior written permission.
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 CONTRIBUTORS 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 WITH THE SOFTWARE.
* Additional libraries included in LLVM carry separate
BSD-compatible licenses. See src/llvm-project/llvm/LICENSE.TXT
for details.
* compiler-rt, in src/compiler-rt is dual licensed under
LLVM's license and MIT:
Copyright (c) 2009-2014 by the contributors listed in
CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal with 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:
* Redistributions of source code must retain the
above copyright notice, this list of conditions
and the following disclaimers.
* Redistributions in binary form must reproduce the
above copyright notice, this list of conditions
and the following disclaimers in the documentation
and/or other materials provided with the
distribution.
* Neither the names of the LLVM Team, University of
Illinois at Urbana-Champaign, nor the names of its
contributors may be used to endorse or promote
products derived from this Software without
specific prior written permission.
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 CONTRIBUTORS 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 WITH THE SOFTWARE.
========================================================
Copyright (c) 2009-2014 by the contributors listed in
CREDITS.TXT
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.
* Portions of the FFI code for interacting with the native ABI
is derived from the Clay programming language, which carries
the following license.
Copyright (C) 2008-2010 Tachyon Technologies.
All rights reserved.
Redistribution and use in source and binary forms, with
or without modification, are permitted provided that the
following conditions are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
2. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
* libbacktrace, under src/libbacktrace:
Copyright (C) 2012-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with
or without modification, are permitted provided that the
following conditions are met:
(1) Redistributions of source code must retain the
above copyright notice, this list of conditions and
the following disclaimer.
(2) Redistributions in binary form must reproduce
the above copyright notice, this list of conditions
and the following disclaimer in the documentation
and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE. */
```

View File

@@ -0,0 +1,126 @@
.TH RUSTDOC "1" "<INSERT DATE HERE>" "rustdoc <INSERT VERSION HERE>" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS
.B rustdoc
[\fIOPTIONS\fR] \fIINPUT\fR
.SH DESCRIPTION
This tool generates API reference documentation by extracting comments from
source code written in the Rust language, available at
<\fBhttps://www.rust-lang.org\fR>. It accepts several input formats and
provides several output formats for the generated documentation.
.SH OPTIONS
.TP
\fB\-r\fR, \fB\-\-input\-format\fR \fIFORMAT\fR
rust
.TP
\fB\-w\fR, \fB\-\-output\-format\fR \fIFORMAT\fR
html
.TP
\fB\-o\fR, \fB\-\-output\fR \fIOUTPUT\fR,
where to place the output (default: \fIdoc/\fR for html)
.TP
\fB\-\-passes\fR \fILIST\fR
space\[hy]separated list of passes to run (default: '')
.TP
\fB\-\-no\-defaults\fR
don't run the default passes
.TP
\fB\-\-plugins\fR \fILIST\fR
space-separated list of plugins to run (default: '')
.TP
\fB\-\-plugin\-path\fR \fIDIR\fR
directory to load plugins from (default: \fI/tmp/rustdoc_ng/plugins\fR)
.TP
\fB\-\-target\fR \fITRIPLE\fR
target triple to document
.TP
\fB\-\-crate\-name\fR \fINAME\fR
specify the name of this crate
.TP
\fB\-L\fR, \fB\-\-library\-path\fR \fIDIR\fR
directory to add to crate search path
.TP
\fB\-\-cfg\fR \fISPEC\fR
pass a \fI\-\-cfg\fR to rustc
.TP
\fB\-\-extern\fR \fIVAL\fR
pass an \fI\-\-extern\fR to rustc
.TP
\fB\-\-test\fR
run code examples as tests
.TP
\fB\-\-test\-args\fR \fIARGS\fR
pass arguments to the test runner
.TP
\fB\-\-html\-in\-header\fR \fIFILE\fR
file to add to <head>
.TP
\fB\-\-html\-before\-content\fR \fIFILES\fR
files to include inline between <body> and the content of a rendered Markdown
file or generated documentation
.TP
\fB\-\-markdown\-before\-content\fR \fIFILES\fR
files to include inline between <body> and the content of a rendered
Markdown file or generated documentation
.TP
\fB\-\-html\-after\-content\fR \fIFILES\fR
files to include inline between the content and </body> of a rendered
Markdown file or generated documentation
.TP
\fB\-\-markdown\-after\-content\fR \fIFILES\fR
files to include inline between the content and </body> of a rendered
Markdown file or generated documentation
.TP
\fB\-\-markdown\-css\fR \fIFILES\fR
CSS files to include via <link> in a rendered Markdown file Markdown file or
generated documentation
.TP
\fB\-\-markdown\-playground\-url\fR \fIURL\fR
URL to send code snippets to
.TP
\fB\-\-markdown\-no\-toc\fR
don't include table of contents
.TP
\fB\-h\fR, \fB\-\-extend\-css\fR
to redefine some css rules with a given file to generate doc with your own theme
.TP
\fB\-V\fR, \fB\-\-version\fR
Print rustdoc's version
.SH "OUTPUT FORMATS"
The rustdoc tool can generate output in an HTML format.
If using an HTML format, then the specified output destination will be the root
directory of an HTML structure for all the documentation.
Pages will be placed into this directory, and source files will also
possibly be rendered into it as well.
.SH "EXAMPLES"
To generate documentation for the source in the current directory:
$ rustdoc hello.rs
List all available passes that rustdoc has, along with default passes:
$ rustdoc \-\-passes list
The generated HTML can be viewed with any standard web browser.
.SH "SEE ALSO"
.BR rustc (1)
.SH "BUGS"
See <\fBhttps://github.com/rust\-lang/rust/issues\fR>
for issues.
.SH "AUTHOR"
See the version control history or <\fBhttps://thanks.rust\-lang.org\fR>
.SH "COPYRIGHT"
This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
See \fICOPYRIGHT\fR file in the rust source distribution.

29
tests/syntax-tests/source/LLVM/test.ll vendored Normal file
View File

@@ -0,0 +1,29 @@
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1
; Function Attrs: noinline norecurse optnone uwtable
define dso_local i32 @main(i32 %0, i8** %1) #0 {
%3 = alloca i32, align 4
%4 = alloca i32, align 4
%5 = alloca i8**, align 8
store i32 0, i32* %3, align 4
store i32 %0, i32* %4, align 4
store i8** %1, i8*** %5, align 8
%6 = call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0))
ret i32 1337
}
declare dso_local i32 @puts(i8*) #1
attributes #0 = { noinline norecurse optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 10.0.0-4ubuntu1 "}

View File

@@ -8,7 +8,7 @@ from time import *
h2 = 4 # this is a comment
"""this is also a comment"""
# Import testt
# Import test
# class test
@@ -16,14 +16,19 @@ h2 = 4 # this is a comment
class Hello:
def __init__(self, x):
self.name = x
def selfprint(self):
print("hello my name is ", self.name)
def testprint(self):
print(1*2, 2+3, 4 % 5, 8-4, 9/4, 23//4)
# Decorators test
class Decorators:
@classmethod
def decoratorsTest(self):
pass
H1 = Hello("john")
H1.selfprint()
H1.testprint()
@@ -37,8 +42,8 @@ print(a[:4])
print(a[2])
print(a[2:])
# dictioary test
# copied from w3school example
# dictionary test
# copied from w3schools example
myfamily = {
"child1": {
@@ -55,7 +60,7 @@ myfamily = {
}
}
# touple test
# tuple test
testTuple = ("one", 2, "3")
print(testTuple)
@@ -70,7 +75,7 @@ bye"""
formattest = "teststring is ={}".format(5)
# lamda test
# lambda test
def x2(n):

View File

@@ -0,0 +1,20 @@
doctype html
html lang=locale
head
meta charset='utf-8'
title #{@title ? "#{@title} | Testing" : 'Testing'}
== stylesheet('app.css')
body
header
h1.title Testing
- @links.each do |link|
a href=link.href
=link.title
div
== yield
- if APP_ENV == 'production'
footer
p Testing

View File

@@ -9,3 +9,8 @@ Apr 4 00:06:29 hostname-here ntpd[952]: receive: Unexpected origin timestamp 0x
Apr 4 09:30:01 hostname-here CRON[89278]: (root) CMD ([ -x /etc/init.d/anacron ] && if [ ! -d /run/systemd/system ]; then /usr/sbin/invoke-rc.d anacron start >/dev/null; fi)
Apr 4 16:32:07 hostname-here NetworkManager[740]: <info> [1617629527.1101] manager: NetworkManager state is now CONNECTED_GLOBAL
Apr 4 22:00:45 hostname-here dbus-daemon[1094]: [session uid=1000 pid=1094] Successfully activated service 'io.github.celluloid_player.Celluloid'
Aug 11 13:29:06 hostname-here insomnia_insomnia.desktop[142666]: 13:29:06.316 [updater] Updater not running platform=linux dev=false
Aug 11 13:36:34 192.168.220.5 nginx: 2021/08/11 13:36:34 [debug] 2031#2031: epoll add event: fd:6 op:1 ev:00002001
Aug 11 21:31:08 ::1 nginx: 2021/08/11 21:31:08 [debug] 760831#760831: epoll add event: fd:6 op:1 ev:10000001
Aug 11 21:40:31 hostname-here scop hello
Aug 16 21:38:21 hostname-here systemd[1]: Finished Cleanup of Temporary Directories.

View File

@@ -0,0 +1,44 @@
POST /foo/bar?id=4&x=y%20z HTTP/1.1
X-Forwarded-For: 127.0.0.1
Content-Length: 124
Cache-Control: no-cache
X-Forwarded-Proto: https
Content-Type: application/json; charset=utf-8
Host: example.com
Accept: */*; q=0.5, application/xml
Accept-Encoding: gzip
{
"id": "blahblahblahblah",
"object": "event",
"api_version": "2020-03-02",
"created": 1626790174,
"data": {
}
}
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 23 Jul 2021 10:15:12 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private; max-age=0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: origin
Strict-Transport-Security: max-age=31556900
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
</body>
</html>