Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for LESSOPEN and LESSCLOSE. #1597

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features
- Add SystemVerilog file syntax, see #1580 (@SeanMcLoughlin)
- Add `--preprocessor=lessopen` support, see #1597 (@eth-p)

## Bugfixes

Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ application = [
"paging",
"wild",
"regex-onig",
"preprocessor-lessopen",
]
git = ["git2"] # Support indicating git modifications
paging = ["shell-words"] # Support applying a pager on the output
preprocessor = []
preprocessor-lessopen = ["preprocessor", "os_str_bytes"] # Support LESSOPEN and LESSCLOSE

# 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
Expand All @@ -51,6 +54,7 @@ path_abs = { version = "0.5", default-features = false }
clircle = "0.3"
bugreport = "0.3"
dirs-next = { version = "2.0.0", optional = true }
os_str_bytes = { version = "3.0", optional = true }

[dependencies.git2]
version = "0.13"
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,16 @@ Also, note that this will [not work](https://github.com/sharkdp/bat/issues/1145)
The [`prettybat`](https://github.com/eth-p/bat-extras/blob/master/doc/prettybat.md) script is a wrapper that will format code and print it with `bat`.


#### `lesspipe.sh`

Starting from version `0.19.0`, `bat` has opt-in support for file preprocessing using the `LESSOPEN` and `LESSCLOSE` environment variables.
This can be used with [lesspipe.sh](https://github.com/wofr06/lesspipe) to enable viewing of compressed files, PDFs, and much more.

To enable preprocessing, you need to either pass the `--preprocessor=lessopen` argument through the command line, or add it to bat's [configuration file](https://github.com/sharkdp/bat#configuration-file).

For more information on how to use `LESSOPEN` and `LESSCLOSE`, please check the [Input Preprocessor section of `man less(1)`](https://linux.die.net/man/1/less#~#Input%20Preprocessor#:~:text=You%20may%20define%20an%20%22input%20preprocessor%22%20for%20less.).


## Installation

[![Packaging status](https://repology.org/badge/vertical-allrepos/bat-cat.svg)](https://repology.org/project/bat-cat/versions)
Expand Down
52 changes: 29 additions & 23 deletions src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::BufReader;
use std::path::Path;
use std::path::{Path, PathBuf};

use syntect::dumps::{dump_to_file, from_binary, from_reader};
use syntect::highlighting::{Theme, ThemeSet};
Expand All @@ -13,7 +13,7 @@ use path_abs::PathAbs;
use crate::assets_metadata::AssetsMetadata;
use crate::bat_warning;
use crate::error::*;
use crate::input::{InputReader, OpenedInput, OpenedInputKind};
use crate::input::{InputReader, OpenedInput};
use crate::syntax_mapping::{MappingTarget, SyntaxMapping};

#[derive(Debug)]
Expand Down Expand Up @@ -225,19 +225,15 @@ impl HighlightingAssets {
// Get the path of the file:
// If this was set by the metadata, that will take priority.
// If it wasn't, it will use the real file path (if available).
let path_str =
input
.metadata
.user_provided_name
.as_ref()
.or_else(|| match input.kind {
OpenedInputKind::OrdinaryFile(ref path) => Some(path),
_ => None,
});

if let Some(path_str) = path_str {
let path_str: Option<PathBuf> = input
.metadata
.user_provided_name
.as_ref()
.cloned()
.or_else(|| input.original_name().map(Into::<PathBuf>::into));

if let Some(ref path) = path_str {
// If a path was provided, we try and detect the syntax based on extension mappings.
let path = Path::new(path_str);
let absolute_path = PathAbs::new(path)
.ok()
.map(|p| p.as_path().to_path_buf())
Expand Down Expand Up @@ -299,7 +295,7 @@ mod tests {
use std::io::Write;
use tempfile::TempDir;

use crate::input::Input;
use crate::input::{Input, InputHandle};

struct SyntaxDetectionTest<'a> {
assets: HighlightingAssets,
Expand Down Expand Up @@ -328,8 +324,11 @@ mod tests {
}

let input = Input::ordinary_file(&file_path);
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap();
let input_handle = InputHandle {
stdout_identifier: None,
};

let mut opened_input = input.open(&input_handle).unwrap();

self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
Expand All @@ -342,8 +341,10 @@ mod tests {
let file_path = self.temp_dir.path().join(file_name);
let input = Input::from_reader(Box::new(BufReader::new(first_line.as_bytes())))
.with_name(Some(&file_path));
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap();
let input_handle = InputHandle {
stdout_identifier: None,
};
let mut opened_input = input.open(&input_handle).unwrap();

self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
Expand All @@ -366,8 +367,11 @@ mod tests {
}

fn syntax_for_stdin_with_content(&self, file_name: &str, content: &[u8]) -> String {
let input = Input::stdin().with_name(Some(file_name));
let mut opened_input = input.open(content, None).unwrap();
let input = Input::stdin_with_contents(content).with_name(Some(file_name));
let input_handle = InputHandle {
stdout_identifier: None,
};
let mut opened_input = input.open(&input_handle).unwrap();

self.assets
.get_syntax(None, &mut opened_input, &self.syntax_mapping)
Expand Down Expand Up @@ -523,8 +527,10 @@ mod tests {
symlink(&file_path, &file_path_symlink).expect("creation of symbolic link succeeds");

let input = Input::ordinary_file(&file_path_symlink);
let dummy_stdin: &[u8] = &[];
let mut opened_input = input.open(dummy_stdin, None).unwrap();
let input_handle = InputHandle {
stdout_identifier: None,
};
let mut opened_input = input.open(&input_handle).unwrap();

assert_eq!(
test.assets
Expand Down
20 changes: 20 additions & 0 deletions src/bin/bat/clap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,26 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
)
}

#[cfg(feature = "preprocessor")]
{
let mut preprocessors: Vec<&'static str> = vec!["none"];

#[cfg(feature = "preprocessor-lessopen")]
preprocessors.push("lessopen");

app = app.arg(
Arg::with_name("preprocessor")
.long("preprocessor")
.overrides_with("preprocessor")
.takes_value(true)
.value_name("preprocessor")
.possible_values(&preprocessors)
.default_value("none")
.hide_default_value(true)
.help("Specify the preprocessor to use on input files."),
)
}

app = app.arg(
Arg::with_name("tabs")
.long("tabs")
Expand Down
4 changes: 4 additions & 0 deletions src/bin/bat/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ pub fn generate_config_file() -> bat::error::Result<()> {
# terminal emulators (like tmux, by default):
#--italic-text=always

# Uncomment the following line to enable LESSOPEN/LESSCLOSE preprocessing.
# You can disable preprocessing on the command line with `--preprocessor=none`.
#--preprocessor=lessopen

# Uncomment the following line to disable automatic paging:
#--paging=never

Expand Down
29 changes: 25 additions & 4 deletions src/bin/bat/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use clap::crate_version;
use directories::PROJECT_DIRS;
use globset::GlobMatcher;

#[cfg(feature = "preprocessor")]
use bat::preprocessor::Preprocessor;

use bat::{
assets::HighlightingAssets,
config::Config,
Expand Down Expand Up @@ -215,9 +218,27 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
Ok(())
}

fn run_controller(inputs: Vec<Input>, config: &Config) -> Result<bool> {
#[cfg_attr(not(feature = "preprocessor"), allow(unused_variables))]
fn run_controller<'a>(inputs: Vec<Input<'a>>, config: &'a Config, app: &App) -> Result<bool> {
let assets = assets_from_cache_or_binary()?;
let controller = Controller::new(&config, &assets);

#[cfg(feature = "preprocessor")]
let mut preprocessor: Option<Preprocessor> = None;

#[cfg(feature = "preprocessor-lessopen")]
if app.matches.value_of("preprocessor") == Some("lessopen") {
preprocessor = std::env::var("LESSOPEN").ok().and_then(|lessopen| {
bat::preprocessor::lessopen(lessopen, std::env::var("LESSCLOSE").ok())
});
}

#[cfg(feature = "preprocessor")]
let controller = match preprocessor {
Some(preprocessor) => controller.with_preprocessor(preprocessor),
None => controller,
};

controller.run(inputs)
}

Expand Down Expand Up @@ -271,7 +292,7 @@ fn run() -> Result<bool> {
let inputs = vec![Input::ordinary_file("cache")];
let config = app.config(&inputs)?;

run_controller(inputs, &config)
run_controller(inputs, &config, &app)
}
}
_ => {
Expand All @@ -286,7 +307,7 @@ fn run() -> Result<bool> {
paging_mode: PagingMode::QuitIfOneScreen,
..Default::default()
};
run_controller(inputs, &plain_config)
run_controller(inputs, &plain_config, &app)
} else if app.matches.is_present("list-themes") {
list_themes(&config)?;
Ok(true)
Expand All @@ -303,7 +324,7 @@ fn run() -> Result<bool> {
writeln!(io::stdout(), "{}", cache_dir())?;
Ok(true)
} else {
run_controller(inputs, &config)
run_controller(inputs, &config, &app)
}
}
}
Expand Down
Loading