diff --git a/src/less.rs b/src/less.rs new file mode 100644 index 00000000..d7c60f2a --- /dev/null +++ b/src/less.rs @@ -0,0 +1,49 @@ +use std::process::Command; + +pub fn retrieve_less_version() -> Option { + let cmd = Command::new("less").arg("--version").output().ok()?; + parse_less_version(&cmd.stdout) +} + +fn parse_less_version(output: &[u8]) -> Option { + if output.starts_with(b"less ") { + let version = std::str::from_utf8(&output[5..]).ok()?; + let end = version.find(' ')?; + version[..end].parse::().ok() + } else { + None + } +} + +#[test] +fn test_parse_less_version_487() { + let output = b"less 487 (GNU regular expressions) +Copyright (C) 1984-2016 Mark Nudelman + +less comes with NO WARRANTY, to the extent permitted by law. +For information about the terms of redistribution, +see the file named README in the less distribution. +Homepage: http://www.greenwoodsoftware.com/less"; + + assert_eq!(Some(487), parse_less_version(output)); +} + +#[test] +fn test_parse_less_version_551() { + let output = b"less 551 (PCRE regular expressions) +Copyright (C) 1984-2019 Mark Nudelman + +less comes with NO WARRANTY, to the extent permitted by law. +For information about the terms of redistribution, +see the file named README in the less distribution. +Home page: http://www.greenwoodsoftware.com/less"; + + assert_eq!(Some(551), parse_less_version(output)); +} + +#[test] +fn test_parse_less_version_wrong_program() { + let output = b"more from util-linux 2.34"; + + assert_eq!(None, parse_less_version(output)); +} diff --git a/src/lib.rs b/src/lib.rs index 04e3b63a..e6743644 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ mod decorations; mod diff; pub mod dirs; pub mod inputfile; +mod less; pub mod line_range; mod output; mod preprocessor; diff --git a/src/output.rs b/src/output.rs index 8cf39118..c4d70c90 100644 --- a/src/output.rs +++ b/src/output.rs @@ -7,6 +7,7 @@ use std::process::{Child, Command, Stdio}; use shell_words; use crate::errors::*; +use crate::less::retrieve_less_version; use crate::PagingMode; #[derive(Debug)] @@ -70,10 +71,21 @@ impl OutputType { let mut process = if is_less { let mut p = Command::new(&pager_path); if args.is_empty() || replace_arguments_to_less { - p.args(vec!["--RAW-CONTROL-CHARS", "--no-init"]); + p.arg("--RAW-CONTROL-CHARS"); if quit_if_one_screen { p.arg("--quit-if-one-screen"); } + + // Passing '--no-init' fixes a bug with '--quit-if-one-screen' in older + // versions of 'less'. Unfortunately, it also breaks mouse-wheel support. + // + // See: http://www.greenwoodsoftware.com/less/news.530.html + match retrieve_less_version() { + Some(version) if version < 530 => { + p.arg("--no-init"); + } + _ => {} + } } else { p.args(args); }