From 0879116a45d3b9794a9d0cba40ca9e07052e0f38 Mon Sep 17 00:00:00 2001 From: jdvr Date: Mon, 11 Mar 2019 10:52:12 +0100 Subject: [PATCH] Add pager support --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +++- README.md | 12 ++++++++++++ src/config.rs | 20 ++++++++++++++++++++ src/main.rs | 41 ++++++++++++++++++++++++++++++++++++----- tests/config.toml | 3 +++ tests/lib.rs | 18 ++++++++++++++++++ 7 files changed, 131 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb4669c..9d674de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,6 +262,25 @@ dependencies = [ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "errno" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "escargot" version = "0.3.1" @@ -345,6 +364,11 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "getopts" version = "0.2.18" @@ -734,6 +758,15 @@ dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pager" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot" version = "0.6.4" @@ -1184,6 +1217,7 @@ dependencies = [ "escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "predicates 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1193,6 +1227,7 @@ dependencies = [ "toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "utime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1645,6 +1680,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum encoding_rs 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ca20350a7cb5aab5b9034731123d6d412caf3e92d4985e739e411ba0955fd0eb" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" +"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum escargot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19db1f7e74438642a5018cdf263bb1325b2e792f02dd0a3ca6d6c0f0d7b1d5a5" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3b0c7353385f92079524de3b7116cf99d73947c08a7472774e9b3b04bff3b901" @@ -1656,6 +1693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed" "checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581" @@ -1699,6 +1737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b69ced2bfa977c4541743a7427b89c94120684791a9629941fe6028dccab6528" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" diff --git a/Cargo.toml b/Cargo.toml index 208e485..133434a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,12 +22,14 @@ docopt = "0.8.1" env_logger = { version = "0.5", optional = true } flate2 = "1.0" log = "0.4" +pager = "0.15" +reqwest = "0.9.5" serde = "1.0.21" serde_derive = "1.0.21" tar = "0.4.14" toml = "0.4.6" walkdir = "2.0.1" -reqwest = "0.9.5" +xdg = "2.1.0" [dev-dependencies] assert_cmd = "0.10" diff --git a/README.md b/README.md index 60d1dd5..3ff998f 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ These are the clients I tried but failed to compile or run: -o --os Override the operating system [linux, osx, sunos, windows] -u --update Update the local cache -c --clear-cache Clear the local cache + -p --pager Use a pager to page output -q --quiet Suppress informational messages --config-path Show config file path --seed-config Create a basic config @@ -177,6 +178,17 @@ Example customization: Screenshot of customized version +### Display + +Using `display` config you can customize whether the pager should be use by +default or not (default `false`). + + [display] + use_pager = true + +When enabled, `less -R` is used as pager. To override the pager command used, +set the `PAGER` environment variable. + ## Autocompletion diff --git a/src/config.rs b/src/config.rs index c9226cd..d73250b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -108,9 +108,16 @@ struct RawStyleConfig { pub example_variable: RawStyle, } +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] +struct RawDisplayConfig { + #[serde(default)] + pub use_pager: bool, +} + #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)] struct RawConfig { style: RawStyleConfig, + display: RawDisplayConfig, } impl RawConfig { @@ -123,6 +130,7 @@ impl RawConfig { raw_config.style.example_code.foreground = Some(RawColor::Cyan); raw_config.style.example_variable.foreground = Some(RawColor::Cyan); raw_config.style.example_variable.underline = true; + raw_config.display.use_pager = false; raw_config } @@ -137,9 +145,15 @@ pub struct StyleConfig { pub example_variable: Style, } +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct DisplayConfig { + pub use_pager: bool, +} + #[derive(Copy, Clone, Debug, PartialEq)] pub struct Config { pub style: StyleConfig, + pub display: DisplayConfig, } impl From for Config { @@ -152,6 +166,9 @@ impl From for Config { example_code: raw_config.style.example_code.into(), example_variable: raw_config.style.example_variable.into(), }, + display: DisplayConfig { + use_pager: false, + }, } } } @@ -193,6 +210,9 @@ impl Config { example_text: Style::default(), example_code: Style::default(), example_variable: Style::default(), + }, + display: DisplayConfig { + use_pager: false, } } }) diff --git a/src/main.rs b/src/main.rs index 8bd2cda..e9bef5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ use std::time::Duration; use ansi_term::Color; use app_dirs::AppInfo; use docopt::Docopt; +use pager::Pager; use serde_derive::Deserialize; mod cache; @@ -62,6 +63,7 @@ Options: -o --os Override the operating system [linux, osx, sunos, windows] -u --update Update the local cache -c --clear-cache Clear the local cache + -p --pager Use a pager to page output -q --quiet Suppress informational messages --config-path Show config file path --seed-config Create a basic config @@ -81,6 +83,7 @@ To render a local file (for testing): $ tldr --render /path/to/file.md "; const ARCHIVE_URL: &str = "https://github.com/tldr-pages/tldr/archive/master.tar.gz"; +const PAGER_COMMAND: &str = "less -R"; const MAX_CACHE_AGE: Duration = Duration::from_secs(2_592_000); // 30 days #[derive(Debug, Deserialize)] @@ -93,6 +96,7 @@ struct Args { flag_os: Option, flag_update: bool, flag_clear_cache: bool, + flag_pager: bool, flag_quiet: bool, flag_config_path: bool, flag_seed_config: bool, @@ -124,6 +128,29 @@ fn print_page(path: &Path, enable_styles: bool) -> Result<(), String> { Ok(()) } +/// Set up display pager +fn configure_pager(args: &Args, enable_styles: bool) { + if args.flag_pager { + Pager::with_default_pager(PAGER_COMMAND).setup(); + } else { + let config = match Config::load(enable_styles) { + Ok(config) => config, + Err(ConfigError(msg)) => { + eprintln!("Could not load config: {}", msg); + process::exit(1); + } + Err(e) => { + eprintln!("Could not load config: {}", e); + process::exit(1); + } + }; + + if config.display.use_pager { + Pager::with_default_pager(PAGER_COMMAND).setup(); + } + } +} + /// Check the cache for freshness fn check_cache(args: &Args, cache: &Cache) { if !args.flag_update { @@ -204,17 +231,21 @@ fn main() { process::exit(0); } + // Determine the usage of styles + #[cfg(target_os = "windows")] + let enable_styles = ansi_term::enable_ansi_support().is_ok(); + #[cfg(not(target_os = "windows"))] + let enable_styles = true; + + // Configure pager + configure_pager(&args, enable_styles); + // Specify target OS let os: OsType = match args.flag_os { Some(os) => os, None => get_os(), }; - #[cfg(target_os = "windows")] - let enable_styles = ansi_term::enable_ansi_support().is_ok(); - #[cfg(not(target_os = "windows"))] - let enable_styles = true; - // Initialize cache let cache = Cache::new(ARCHIVE_URL, os); diff --git a/tests/config.toml b/tests/config.toml index 7440a82..5319e7a 100644 --- a/tests/config.toml +++ b/tests/config.toml @@ -15,3 +15,6 @@ underline = false [style.example_variable] underline = true bold = false + +[display] +use_pager = false diff --git a/tests/lib.rs b/tests/lib.rs index b22dcc4..bb1e2d3 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -275,3 +275,21 @@ fn test_spaces_find_command() { .assert() .success(); } + +#[test] +fn test_pager_flag_enable() { + let testenv = TestEnv::new(); + + testenv + .command() + .args(&["--update"]) + .assert() + .success() + .stdout(contains("Successfully updated cache.")); + + testenv + .command() + .args(&["--pager", "tar"]) + .assert() + .success(); +}