1
0
mirror of https://github.com/sharkdp/bat synced 2026-08-03 18:51:44 +00:00

Compare commits

...

20 Commits

Author SHA1 Message Date
sharkdp ba4d5a2e7d Bump version number 2018-09-01 00:30:43 +02:00
sharkdp 026273a05c Enable ANSI support on Windows 2018-09-01 00:23:15 +02:00
sharkdp 8903b64830 Fix for Rust 1.26 2018-08-31 23:57:27 +02:00
sharkdp 194155f062 Fix relative-path computation for Windows 2018-08-31 23:57:27 +02:00
sharkdp a6ff3b900d Fix terminal width to 80 characters in tests 2018-08-31 23:57:27 +02:00
sharkdp 8a52bcf92d Add hidden --terminal-width option 2018-08-31 23:57:27 +02:00
sharkdp 0b1535f63b Split snapshot tests into individual tests 2018-08-31 23:57:27 +02:00
sharkdp 0a5b3eaf3e Re-enable tests on windows 2018-08-31 23:57:27 +02:00
sharkdp 11294249f8 Add new key for AppVeyor 2018-08-31 23:57:27 +02:00
anykao 35a1236ad0 Update tests.rs 2018-08-31 23:57:27 +02:00
anykao af8da50c2c Update appveyor.yml 2018-08-31 23:57:27 +02:00
anykao 649d1e3df2 Update appveyor.yml 2018-08-31 23:57:27 +02:00
anykao 199cfd4519 Update appveyor.yml 2018-08-31 23:57:27 +02:00
David Peter c7cce0752b Add AppVeyor badge 2018-08-31 23:57:27 +02:00
anykao 3a89486189 Create before_deploy.ps1 2018-08-31 23:57:27 +02:00
anykao 720a2fb7a5 Create appveyor.yml 2018-08-31 23:57:27 +02:00
sharkdp e3c990f11e Respect color settings for list-themes and list-languages 2018-08-31 21:57:18 +02:00
sharkdp 90c7d0c365 Use stdout locks 2018-08-31 21:48:26 +02:00
mchlrhw 56002267d2 Fix panic when running bat --list-languages | head
Fixes: https://github.com/sharkdp/bat/issues/232
2018-08-31 21:43:49 +02:00
David Peter 84734eac9d Update alternatives.md 2018-08-31 00:39:26 +02:00
11 changed files with 184 additions and 58 deletions
Generated
+1 -1
View File
@@ -35,7 +35,7 @@ dependencies = [
[[package]]
name = "bat"
version = "0.6.0"
version = "0.6.1"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+1 -1
View File
@@ -7,7 +7,7 @@ license = "MIT/Apache-2.0"
name = "bat"
readme = "README.md"
repository = "https://github.com/sharkdp/bat"
version = "0.6.0"
version = "0.6.1"
exclude = [
"assets/syntaxes/*",
"assets/themes/*",
+2 -1
View File
@@ -1,6 +1,7 @@
<p align="center">
<img src="doc/logo-header.svg" alt="bat - a cat clone with wings"><br>
<a href="https://travis-ci.org/sharkdp/bat"><img src="https://travis-ci.org/sharkdp/bat.svg?branch=master" alt="Build Status"></a>
<a href="https://ci.appveyor.com/project/sharkdp/bat"><img src="https://ci.appveyor.com/api/projects/status/cptsmtbiwbnr2vhf?svg=true"></a>
<img src="https://img.shields.io/crates/l/bat.svg" alt="license">
<a href="https://crates.io/crates/bat"><img src="https://img.shields.io/crates/v/bat.svg?colorB=319e8c" alt="Version info"></a><br>
A <i>cat(1)</i> clone with syntax highlighting and Git integration.
@@ -82,7 +83,7 @@ bat f - g # output 'f', then stdin, then 'g'.
Download the latest `.deb` package from the [release page](https://github.com/sharkdp/bat/releases)
and install it via:
``` bash
sudo dpkg -i bat_0.6.0_amd64.deb # adapt version number and architecture
sudo dpkg -i bat_0.6.1_amd64.deb # adapt version number and architecture
```
### On Arch Linux
+49
View File
@@ -0,0 +1,49 @@
environment:
global:
TARGET: x86_64-pc-windows-msvc
RUST_VERSION: stable
CRATE_NAME: bat
CARGO_HOME: "c:\\cargo"
RUSTUP_HOME: "c:\\rustup"
install:
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init.exe -y --default-host %TARGET%
- set PATH=%PATH%;C:\cargo\bin
- rustc -Vv
- cargo -V
build: false
test_script:
- cargo test --target %TARGET% --verbose
- cargo run --target %TARGET% -- src/main.rs README.md --paging=never
before_deploy:
# Generate artifacts for release
- cargo build --release --verbose
- ps: ci\before_deploy.ps1
deploy:
description: 'Automatically deployed release'
artifact: /.*\.zip/
# Here's how:
# - Go to 'https://github.com/settings/tokens/new' and generate a Token with only the
# `public_repo` scope enabled
# - Then go to 'https://ci.appveyor.com/tools/encrypt' and enter the newly generated token.
# - Enter the "encrypted value" below
auth_token:
secure: oO4/J+hcFXgXcEqEc8gzlQNqLG0IxU78s4EyH+uczGdsyWajb3yipxPR6nXUvmoj
provider: GitHub
on:
RUST_VERSION: stable
appveyor_repo_tag: true
cache:
- C:\Users\appveyor\.cargo\registry
- target
notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false
+26
View File
@@ -0,0 +1,26 @@
# This script takes care of packaging the build artifacts that will go in the
# release zipfile
$SRC_DIR = $PWD.Path
$STAGE = [System.Guid]::NewGuid().ToString()
Set-Location $ENV:Temp
New-Item -Type Directory -Name $STAGE
Set-Location $STAGE
$ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip"
Copy-Item "$SRC_DIR\target\release\bat.exe" '.\'
# readme and license
Copy-Item $SRC_DIR\README.md '.\'
Copy-Item $SRC_DIR\LICENSE-MIT '.\'
Copy-Item $SRC_DIR\LICENSE-APACHE '.\'
7z a "$ZIP" *
Push-AppveyorArtifact "$ZIP"
Set-Location ..
Remove-Item $STAGE -Force -Recurse
Set-Location $SRC_DIR
+1 -1
View File
@@ -6,7 +6,7 @@ if you are not looking for a program like `bat`, this comparison might not be fo
| | bat | [pygments](http://pygments.org/) | [highlight](http://www.andre-simon.de/doku/highlight/highlight.php) | [ccat](https://github.com/jingweno/ccat) | [source-highlight](https://www.gnu.org/software/src-highlite/) | [hicat](https://github.com/rstacruz/hicat) | [coderay](https://github.com/rubychan/coderay) | [rouge](https://github.com/jneen/rouge) |
|----------------------------------------------|---------------------------------------------------------------------|----------------------------------|---------------------------------------------------------------------|------------------------------------------|----------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------|
| Drop-in `cat` replacement | (:heavy_check_mark:) [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: |
| Drop-in `cat` replacement | :heavy_check_mark: [*](https://github.com/sharkdp/bat/issues/134) | :x: | :x: | (:heavy_check_mark:) | :x: | :x: [*](https://github.com/rstacruz/hicat/issues/6) | :x: | :x: |
| Git integration | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
| Automatic paging | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: | :x: | :x: |
| Languages (circa) | 60 | 300 | 200 | 7 | 80 | 130 | 30 | 130 |
+22 -6
View File
@@ -271,6 +271,13 @@ impl App {
'unbuffered'). The output is always unbuffered - this option \
is simply ignored.",
),
).arg(
Arg::with_name("terminal-width")
.long("terminal-width")
.takes_value(true)
.value_name("width")
.hidden(true)
.help("Set the width of the terminal"),
).subcommand(
SubCommand::with_name("cache")
.about("Modify the syntax-definition and theme cache")
@@ -328,6 +335,15 @@ impl App {
pub fn config(&self) -> Result<Config> {
let files = self.files();
let colored_output = match self.matches.value_of("color") {
Some("always") => true,
Some("never") => false,
Some("auto") | _ => self.interactive_output,
};
#[cfg(windows)]
let colored_output = colored_output && ansi_term::enable_ansi_support().is_ok();
Ok(Config {
true_color: is_truecolor_terminal(),
output_components: self.output_components()?,
@@ -342,11 +358,7 @@ impl App {
Some("never") | _ => OutputWrap::None,
}
},
colored_output: match self.matches.value_of("color") {
Some("always") => true,
Some("never") => false,
Some("auto") | _ => self.interactive_output,
},
colored_output,
paging_mode: match self.matches.value_of("paging") {
Some("always") => PagingMode::Always,
Some("never") => PagingMode::Never,
@@ -367,7 +379,11 @@ impl App {
}
},
},
term_width: Term::stdout().size().1 as usize,
term_width: self
.matches
.value_of("terminal-width")
.and_then(|w| w.parse().ok())
.unwrap_or(Term::stdout().size().1 as usize),
loop_through: !(self.interactive_output
|| self.matches.value_of("color") == Some("always")
|| self.matches.value_of("decorations") == Some("always")),
+7 -4
View File
@@ -15,11 +15,14 @@ pub type LineChanges = HashMap<u32, LineChange>;
pub fn get_git_diff(filename: &str) -> Option<LineChanges> {
let repo = Repository::discover(&filename).ok()?;
let path_absolute = fs::canonicalize(&filename).ok()?;
let path_relative_to_repo = path_absolute.strip_prefix(repo.workdir()?).ok()?;
let repo_path_absolute = fs::canonicalize(repo.workdir()?).ok()?;
let filepath_absolute = fs::canonicalize(&filename).ok()?;
let filepath_relative_to_repo = filepath_absolute.strip_prefix(&repo_path_absolute).ok()?;
let mut diff_options = DiffOptions::new();
let pathspec = path_relative_to_repo.into_c_string().ok()?;
let pathspec = filepath_relative_to_repo.into_c_string().ok()?;
diff_options.pathspec(pathspec);
diff_options.context_lines(0);
@@ -42,7 +45,7 @@ pub fn get_git_diff(filename: &str) -> Option<LineChanges> {
Some(&mut |delta, hunk| {
let path = delta.new_file().path().unwrap_or_else(|| Path::new(""));
if path_relative_to_repo != path {
if filepath_relative_to_repo != path {
return false;
}
+44 -16
View File
@@ -30,6 +30,7 @@ mod terminal;
use std::collections::HashSet;
use std::io;
use std::io::Write;
use std::path::Path;
use std::process;
@@ -80,13 +81,13 @@ fn run_cache_subcommand(matches: &clap::ArgMatches) -> Result<()> {
} else if matches.is_present("clear") {
clear_assets();
} else if matches.is_present("config-dir") {
println!("{}", config_dir());
writeln!(io::stdout(), "{}", config_dir())?;
}
Ok(())
}
pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
pub fn list_languages(assets: &HighlightingAssets, config: &Config) -> Result<()> {
let mut languages = assets
.syntax_set
.syntaxes()
@@ -104,10 +105,19 @@ pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
let comma_separator = ", ";
let separator = " ";
// Line-wrapping for the possible file extension overflow.
let desired_width = term_width - longest - separator.len();
let desired_width = config.term_width - longest - separator.len();
let stdout = io::stdout();
let mut stdout = stdout.lock();
let style = if config.colored_output {
Green.normal()
} else {
Style::default()
};
for lang in languages {
print!("{:width$}{}", lang.name, separator, width = longest);
write!(stdout, "{:width$}{}", lang.name, separator, width = longest)?;
// Number of characters on this line so far, wrap before `desired_width`
let mut num_chars = 0;
@@ -118,32 +128,50 @@ pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
let new_chars = word.len() + comma_separator.len();
if num_chars + new_chars >= desired_width {
num_chars = 0;
print!("\n{:width$}{}", "", separator, width = longest);
write!(stdout, "\n{:width$}{}", "", separator, width = longest)?;
}
num_chars += new_chars;
print!("{}", Green.paint(&word[..]));
write!(stdout, "{}", style.paint(&word[..]))?;
if extension.peek().is_some() {
print!("{}", comma_separator);
write!(stdout, "{}", comma_separator)?;
}
}
println!();
writeln!(stdout)?;
}
Ok(())
}
pub fn list_themes(assets: &HighlightingAssets, cfg: &Config) {
pub fn list_themes(assets: &HighlightingAssets, cfg: &Config) -> Result<()> {
let themes = &assets.theme_set.themes;
let mut config = cfg.clone();
let mut style = HashSet::new();
style.insert(OutputComponent::Plain);
config.files = vec![InputFile::ThemePreviewFile];
config.output_components = OutputComponents(style);
for (theme, _) in themes.iter() {
println!("Theme: {}\n", Style::new().bold().paint(theme.to_string()));
config.theme = theme.to_string();
let _controller = Controller::new(&config, &assets).run();
println!()
let stdout = io::stdout();
let mut stdout = stdout.lock();
if config.colored_output {
for (theme, _) in themes.iter() {
writeln!(
stdout,
"Theme: {}\n",
Style::new().bold().paint(theme.to_string())
)?;
config.theme = theme.to_string();
let _controller = Controller::new(&config, &assets).run();
writeln!(stdout)?;
}
} else {
for (theme, _) in themes.iter() {
writeln!(stdout, "{}", theme)?;
}
}
Ok(())
}
/// Returns `Err(..)` upon fatal errors. Otherwise, returns `Some(true)` on full success and
@@ -161,11 +189,11 @@ fn run() -> Result<bool> {
let assets = HighlightingAssets::new();
if app.matches.is_present("list-languages") {
list_languages(&assets, config.term_width);
list_languages(&assets, &config)?;
Ok(true)
} else if app.matches.is_present("list-themes") {
list_themes(&assets, &config);
list_themes(&assets, &config)?;
Ok(true)
} else {
+1
View File
@@ -44,6 +44,7 @@ impl BatTester {
.args(&[
"sample.rs",
"--decorations=always",
"--terminal-width=80",
&format!("--style={}", style),
]).output()
.expect("bat failed");
+30 -28
View File
@@ -2,32 +2,34 @@ mod tester;
use tester::BatTester;
static STYLES: &'static [&'static str] = &[
"changes",
"grid",
"header",
"numbers",
"changes,grid",
"changes,header",
"changes,numbers",
"grid,header",
"grid,numbers",
"header,numbers",
"changes,grid,header",
"changes,grid,numbers",
"changes,header,numbers",
"grid,header,numbers",
"changes,grid,header,numbers",
"full",
"plain",
];
#[test]
fn test_snapshots() {
let bat_tester = BatTester::new();
for style in STYLES {
println!("testing {}", style);
bat_tester.test_snapshot(&*style);
}
macro_rules! snapshot_tests {
($($test_name: ident: $style: expr,)*) => {
$(
#[test]
fn $test_name() {
let bat_tester = BatTester::new();
bat_tester.test_snapshot($style);
}
)*
};
}
snapshot_tests! {
changes: "changes",
grid: "grid",
header: "header",
numbers: "numbers",
changes_grid: "changes,grid",
changes_header: "changes,header",
changes_numbers: "changes,numbers",
grid_header: "grid,header",
grid_numbers: "grid,numbers",
header_numbers: "header,numbers",
changes_grid_header: "changes,grid,header",
changes_grid_numbers: "changes,grid,numbers",
changes_header_numbers: "changes,header,numbers",
grid_header_numbers: "grid,header,numbers",
changes_grid_header_numbers: "changes,grid,header,numbers",
full: "full",
plain: "plain",
}