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 $LESSOPEN and $LESSCLOSE support #2444

Merged
merged 5 commits into from
Sep 2, 2023
Merged
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 @@ -77,6 +77,7 @@

- Make the default macOS theme depend on Dark Mode. See #2197, #1746 (@Enselic)
- Support for separate system and user config files. See #668 (@patrickpichler)
- Add support for $LESSOPEN and $LESSCLOSE. See #1597, #1739, and #2444 (@Anomalocaridid)

## Bugfixes

Expand Down
89 changes: 89 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 @@ -21,6 +21,7 @@ application = [
"build-assets",
"git",
"minimal-application",
"lessopen",
]
# Mainly for developers that want to iterate quickly
# Be aware that the included features might change in the future
Expand All @@ -33,6 +34,7 @@ minimal-application = [
]
git = ["git2"] # Support indicating git modifications
paging = ["shell-words", "grep-cli"] # Support applying a pager on the output
lessopen = ["run_script", "os_str_bytes"] # Support $LESSOPEN preprocessor
build-assets = ["syntect/yaml-load", "syntect/plist-load", "regex", "walkdir"]

# You need to use one of these if you depend on bat as a library:
Expand Down Expand Up @@ -64,6 +66,8 @@ regex = { version = "1.8.3", optional = true }
walkdir = { version = "2.3", optional = true }
bytesize = { version = "1.2.0" }
encoding_rs = "0.8.32"
os_str_bytes = { version = "~6.4", optional = true }
run_script = { version = "^0.10.0", optional = true}

[dependencies.git2]
version = "0.18"
Expand Down
1 change: 1 addition & 0 deletions assets/completions/_bat.ps1.in
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
[CompletionResult]::new('--unbuffered', 'unbuffered', [CompletionResultType]::ParameterName, 'unbuffered')
[CompletionResult]::new('--no-config', 'no-config', [CompletionResultType]::ParameterName, 'Do not use the configuration file')
[CompletionResult]::new('--no-custom-assets', 'no-custom-assets', [CompletionResultType]::ParameterName, 'Do not load custom assets')
[CompletionResult]::new('--no-lessopen', 'no-lessopen', [CompletionResultType]::ParameterName, 'Do not use the $LESSOPEN preprocessor')
[CompletionResult]::new('--config-file', 'config-file', [CompletionResultType]::ParameterName, 'Show path to the configuration file.')
[CompletionResult]::new('--generate-config-file', 'generate-config-file', [CompletionResultType]::ParameterName, 'Generates a default configuration file.')
[CompletionResult]::new('--config-dir', 'config-dir', [CompletionResultType]::ParameterName, 'Show bat''s configuration directory.')
Expand Down
1 change: 1 addition & 0 deletions assets/completions/bat.zsh.in
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ _{{PROJECT_EXECUTABLE}}_main() {
'(: --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]'
'(: --no-lessopen)'--no-lessopen'[Do not use the $LESSOPEN preprocessor]'
'(: --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]'
Expand Down
11 changes: 11 additions & 0 deletions assets/manual/bat.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ If you ever want to remove the custom languages, you can clear the cache with `\
Similarly to custom languages, {{PROJECT_EXECUTABLE}} supports Sublime Text \fB.tmTheme\fR themes.
These can be installed to `\fB$({{PROJECT_EXECUTABLE}} --config-dir)/themes\fR`, and are added to the cache with
`\fB{{PROJECT_EXECUTABLE}} cache --build`.

.SH "INPUT PREPROCESSOR"
Much like less(1) does, {{PROJECT_EXECUTABLE}} supports input preprocessors via the LESSOPEN and LESSCLOSE environment variables.
In addition, {{PROJECT_EXECUTABLE}} attempts to be as compatible with less's preprocessor implementation as possible.

To run {{PROJECT_EXECUTABLE}} without using the preprocessor, call:

\fB{{PROJECT_EXECUTABLE}} --no-lessopen\fR

For more information, see the "INPUT PREPROCESSOR" section of less(1).

.SH "MORE INFORMATION"

For more information and up-to-date documentation, visit the {{PROJECT_EXECUTABLE}} repo:
Expand Down
2 changes: 2 additions & 0 deletions src/bin/bat/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ impl App {
.map(HighlightedLineRanges)
.unwrap_or_default(),
use_custom_assets: !self.matches.get_flag("no-custom-assets"),
#[cfg(feature = "lessopen")]
use_lessopen: !self.matches.get_flag("no-lessopen"),
})
}

Expand Down
15 changes: 14 additions & 1 deletion src/bin/bat/clap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,20 @@ pub fn build_app(interactive_output: bool) -> Command {
.action(ArgAction::SetTrue)
.hide(true)
.help("Do not load custom assets"),
);

#[cfg(feature = "lessopen")]
{
app = app.arg(
Arg::new("no-lessopen")
.long("no-lessopen")
.action(ArgAction::SetTrue)
.hide(true)
.help("Do not use the $LESSOPEN preprocessor"),
)
}

app = app
.arg(
Arg::new("config-file")
.long("config-file")
Expand Down Expand Up @@ -536,7 +549,7 @@ pub fn build_app(interactive_output: bool) -> Command {
.alias("diagnostics")
.action(ArgAction::SetTrue)
.hide_short_help(true)
.help("Show diagnostic information for bug reports.")
.help("Show diagnostic information for bug reports."),
)
.arg(
Arg::new("acknowledgements")
Expand Down
4 changes: 4 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ pub struct Config<'a> {
/// 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,

// Whether or not to use $LESSOPEN if set
#[cfg(feature = "lessopen")]
pub use_lessopen: bool,
}

#[cfg(all(feature = "minimal-application", feature = "paging"))]
Expand Down
24 changes: 22 additions & 2 deletions src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::config::{Config, VisibleLines};
use crate::diff::{get_git_diff, LineChanges};
use crate::error::*;
use crate::input::{Input, InputReader, OpenedInput};
#[cfg(feature = "lessopen")]
use crate::lessopen::LessOpenPreprocessor;
#[cfg(feature = "git")]
use crate::line_range::LineRange;
use crate::line_range::{LineRanges, RangeCheckResult};
Expand All @@ -19,11 +21,18 @@ use clircle::{Clircle, Identifier};
pub struct Controller<'a> {
config: &'a Config<'a>,
assets: &'a HighlightingAssets,
#[cfg(feature = "lessopen")]
preprocessor: Option<LessOpenPreprocessor>,
}

impl<'b> Controller<'b> {
pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {
Controller { config, assets }
Controller {
config,
assets,
#[cfg(feature = "lessopen")]
preprocessor: LessOpenPreprocessor::new().ok(),
}
}

pub fn run(
Expand Down Expand Up @@ -123,7 +132,18 @@ impl<'b> Controller<'b> {
stdout_identifier: Option<&Identifier>,
is_first: bool,
) -> Result<()> {
let mut opened_input = input.open(stdin, stdout_identifier)?;
let mut opened_input = {
#[cfg(feature = "lessopen")]
match self.preprocessor {
Some(ref preprocessor) if self.config.use_lessopen => {
preprocessor.open(input, stdin, stdout_identifier)?
}
_ => input.open(stdin, stdout_identifier)?,
}

#[cfg(not(feature = "lessopen"))]
input.open(stdin, stdout_identifier)?
};
#[cfg(feature = "git")]
let line_changes = if self.config.visible_lines.diff_mode()
|| (!self.config.loop_through && self.config.style_components.changes())
Expand Down
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ pub enum Error {
InvalidPagerValueBat,
#[error("{0}")]
Msg(String),
#[cfg(feature = "lessopen")]
#[error(transparent)]
VarError(#[from] ::std::env::VarError),
#[cfg(feature = "lessopen")]
#[error(transparent)]
CommandParseError(#[from] ::shell_words::ParseError),
}

impl From<&'static str> for Error {
Expand Down
2 changes: 1 addition & 1 deletion src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ pub(crate) struct InputReader<'a> {
}

impl<'a> InputReader<'a> {
fn new<R: BufRead + 'a>(mut reader: R) -> InputReader<'a> {
pub(crate) fn new<R: BufRead + 'a>(mut reader: R) -> InputReader<'a> {
let mut first_line = vec![];
reader.read_until(b'\n', &mut first_line).ok();

Expand Down
Loading