mirror of
https://github.com/tealdeer-rs/tealdeer.git
synced 2026-08-21 23:54:18 +02:00
Merge pull request #111 from LovecraftianHorror/better-color-detection
Improved color detection with --color argument and NO_COLOR env variable. Fixes #81.
This commit is contained in:
commit
4c413d7e40
9 changed files with 125 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1178,6 +1178,7 @@ dependencies = [
|
|||
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs2 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"assert_cmd 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"escargot 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ path = "src/main.rs"
|
|||
[dependencies]
|
||||
ansi_term = "0.12.0"
|
||||
app_dirs = { version = "2", package = "app_dirs2" }
|
||||
atty = "0.2"
|
||||
docopt = "1"
|
||||
env_logger = { version = "0.7", optional = true }
|
||||
flate2 = "1"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ _tealdeer()
|
|||
COMPREPLY=( $(compgen -W 'linux osx sunos windows' -- "${cur}") )
|
||||
return
|
||||
;;
|
||||
--color)
|
||||
COMPREPLY=( $(compgen -W 'always auto never' -- "${cur}") )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ $cur == -* ]]; then
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ complete -c tldr -s m -l markdown -d 'Display the raw markdown instead of ren
|
|||
complete -c tldr -s q -l quiet -d 'Suppress informational messages.' -f
|
||||
complete -c tldr -l config-path -d 'Show config file path.' -f
|
||||
complete -c tldr -l seed-config -d 'Create a basic config.' -f
|
||||
complete -c tldr -l color -d 'Controls when to use color.' -xa 'always auto never'
|
||||
|
||||
function __tealdeer_entries
|
||||
tldr --list | string replace -a -i -r "\,\s" "\n"
|
||||
|
|
|
|||
42
src/main.rs
42
src/main.rs
|
|
@ -16,14 +16,16 @@
|
|||
#[cfg(feature = "logging")]
|
||||
extern crate env_logger;
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
|
||||
use ansi_term::Color;
|
||||
use ansi_term::{Color, Style};
|
||||
use app_dirs::AppInfo;
|
||||
use atty::Stream;
|
||||
use docopt::Docopt;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use pager::Pager;
|
||||
|
|
@ -41,7 +43,7 @@ use crate::config::{get_config_path, make_default_config, Config, MAX_CACHE_AGE}
|
|||
use crate::error::TealdeerError::{CacheError, ConfigError, UpdateError};
|
||||
use crate::formatter::print_lines;
|
||||
use crate::tokenizer::Tokenizer;
|
||||
use crate::types::OsType;
|
||||
use crate::types::{ColorOptions, OsType};
|
||||
|
||||
const NAME: &str = "tealdeer";
|
||||
const APP_INFO: AppInfo = AppInfo {
|
||||
|
|
@ -69,6 +71,7 @@ Options:
|
|||
-q --quiet Suppress informational messages
|
||||
--config-path Show config file path
|
||||
--seed-config Create a basic config
|
||||
--color <when> Control when to use color [always, auto, never] [default: auto]
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
@ -104,6 +107,7 @@ struct Args {
|
|||
flag_config_path: bool,
|
||||
flag_seed_config: bool,
|
||||
flag_markdown: bool,
|
||||
flag_color: ColorOptions,
|
||||
}
|
||||
|
||||
/// Print page by path
|
||||
|
|
@ -144,15 +148,23 @@ fn should_update_cache(args: &Args, config: &Config) -> bool {
|
|||
}
|
||||
|
||||
/// Check the cache for freshness
|
||||
fn check_cache(args: &Args) {
|
||||
fn check_cache(args: &Args, enable_styles: bool) {
|
||||
match Cache::last_update() {
|
||||
Some(ago) if ago > MAX_CACHE_AGE => {
|
||||
if args.flag_quiet {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only use color if enabled
|
||||
let warning_style = if enable_styles {
|
||||
Style::new().fg(Color::Yellow)
|
||||
} else {
|
||||
Style::default()
|
||||
};
|
||||
|
||||
eprintln!(
|
||||
"{}",
|
||||
Color::Yellow.paint(format!(
|
||||
warning_style.paint(format!(
|
||||
"The cache hasn't been updated for more than {} days.\n\
|
||||
You should probably run `tldr --update` soon.",
|
||||
MAX_CACHE_AGE.as_secs() / 24 / 3600
|
||||
|
|
@ -305,9 +317,23 @@ fn main() {
|
|||
|
||||
// Determine the usage of styles
|
||||
#[cfg(target_os = "windows")]
|
||||
let enable_styles = ansi_term::enable_ansi_support().is_ok();
|
||||
let ansi_support = ansi_term::enable_ansi_support().is_ok();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let enable_styles = true;
|
||||
let ansi_support = true;
|
||||
|
||||
let enable_styles = match args.flag_color {
|
||||
// Attempt to use styling if instructed
|
||||
ColorOptions::Always => true,
|
||||
// Enable styling if:
|
||||
// * There is `ansi_support`
|
||||
// * NO_COLOR env var isn't set: https://no-color.org/
|
||||
// * The output stream is stdout (not being piped)
|
||||
ColorOptions::Auto => {
|
||||
ansi_support && env::var_os("NO_COLOR").is_none() && atty::is(Stream::Stdout)
|
||||
}
|
||||
// Disable styling
|
||||
ColorOptions::Never => false,
|
||||
};
|
||||
|
||||
// Look up config file, if none is found fall back to default config.
|
||||
let config = match Config::load(enable_styles) {
|
||||
|
|
@ -363,7 +389,7 @@ fn main() {
|
|||
if args.flag_list {
|
||||
if !cache_updated {
|
||||
// Check cache for freshness
|
||||
check_cache(&args);
|
||||
check_cache(&args, enable_styles);
|
||||
}
|
||||
|
||||
// Get list of pages
|
||||
|
|
@ -387,7 +413,7 @@ fn main() {
|
|||
|
||||
if !cache_updated {
|
||||
// Check cache for freshness
|
||||
check_cache(&args);
|
||||
check_cache(&args, enable_styles);
|
||||
}
|
||||
|
||||
// Search for command in cache
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ impl fmt::Display for OsType {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ColorOptions {
|
||||
Always,
|
||||
Auto,
|
||||
Never,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum LineType {
|
||||
Empty,
|
||||
|
|
|
|||
28
tests/inkscape-default-no-color.expected
Normal file
28
tests/inkscape-default-no-color.expected
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
An SVG (Scalable Vector Graphics) editing program.
|
||||
Use -z to not open the GUI and only process files in the console.
|
||||
|
||||
Open an SVG file in the Inkscape GUI:
|
||||
|
||||
inkscape filename.svg
|
||||
|
||||
Export an SVG file into a bitmap with the default format (PNG) and the default resolution (90 DPI):
|
||||
|
||||
inkscape filename.svg -e filename.png
|
||||
|
||||
Export an SVG file into a bitmap of 600x400 pixels (aspect ratio distortion may occur):
|
||||
|
||||
inkscape filename.svg -e filename.png -w 600 -h 400
|
||||
|
||||
Export a single object, given its ID, into a bitmap:
|
||||
|
||||
inkscape filename.svg -i id -e object.png
|
||||
|
||||
Export an SVG document to PDF, converting all texts to paths:
|
||||
|
||||
inkscape filename.svg | inkscape | inkscape --export-pdf=inkscape.pdf | inkscape | inkscape --export-text-to-path
|
||||
|
||||
Duplicate the object with id="path123", rotate the duplicate 90 degrees, save the file, and quit Inkscape:
|
||||
|
||||
inkscape filename.svg --select=path123 --verb=EditDuplicate --verb=ObjectRotate90 --verb=FileSave --verb=FileQuit
|
||||
|
||||
49
tests/lib.rs
49
tests/lib.rs
|
|
@ -241,7 +241,12 @@ fn test_markdown_rendering() {
|
|||
.stdout(similar(expected));
|
||||
}
|
||||
|
||||
fn _test_correct_rendering(input_file: &str, filename: &str) {
|
||||
fn _test_correct_rendering(
|
||||
input_file: &str,
|
||||
filename: &str,
|
||||
expected: &'static str,
|
||||
color_option: &str,
|
||||
) {
|
||||
let testenv = TestEnv::new();
|
||||
|
||||
// Create input file
|
||||
|
|
@ -250,10 +255,9 @@ fn _test_correct_rendering(input_file: &str, filename: &str) {
|
|||
let mut file = File::create(&file_path).unwrap();
|
||||
file.write_all(input_file.as_bytes()).unwrap();
|
||||
|
||||
let expected = include_str!("inkscape-default.expected");
|
||||
testenv
|
||||
.command()
|
||||
.args(&["-f", &file_path.to_str().unwrap()])
|
||||
.args(&["--color", color_option, "-f", &file_path.to_str().unwrap()])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(similar(expected));
|
||||
|
|
@ -262,13 +266,46 @@ fn _test_correct_rendering(input_file: &str, filename: &str) {
|
|||
/// An end-to-end integration test for direct file rendering (v1 syntax).
|
||||
#[test]
|
||||
fn test_correct_rendering_v1() {
|
||||
_test_correct_rendering(include_str!("inkscape-v1.md"), "inkscape-v1.md");
|
||||
_test_correct_rendering(
|
||||
include_str!("inkscape-v1.md"),
|
||||
"inkscape-v1.md",
|
||||
include_str!("inkscape-default.expected"),
|
||||
"always",
|
||||
);
|
||||
}
|
||||
|
||||
/// An end-to-end integration test for direct file rendering (v2 syntax).
|
||||
#[test]
|
||||
fn test_correct_rendering_v2() {
|
||||
_test_correct_rendering(include_str!("inkscape-v2.md"), "inkscape-v2.md");
|
||||
_test_correct_rendering(
|
||||
include_str!("inkscape-v2.md"),
|
||||
"inkscape-v2.md",
|
||||
include_str!("inkscape-default.expected"),
|
||||
"always",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// An end-to-end integration test for direct file rendering with the `--color auto` option. This
|
||||
/// will not use styling since output is not stdout.
|
||||
fn test_rendering_color_auto() {
|
||||
_test_correct_rendering(
|
||||
include_str!("inkscape-v2.md"),
|
||||
"inkscape-v2.md",
|
||||
include_str!("inkscape-default-no-color.expected"),
|
||||
"auto",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// An end-to-end integration test for direct file rendering with the `--color never` option.
|
||||
fn test_rendering_color_never() {
|
||||
_test_correct_rendering(
|
||||
include_str!("inkscape-v2.md"),
|
||||
"inkscape-v2.md",
|
||||
include_str!("inkscape-default-no-color.expected"),
|
||||
"never",
|
||||
);
|
||||
}
|
||||
|
||||
/// An end-to-end integration test for rendering with constom syntax config.
|
||||
|
|
@ -299,7 +336,7 @@ fn test_correct_rendering_with_config() {
|
|||
|
||||
testenv
|
||||
.command()
|
||||
.args(&["-f", &file_path.to_str().unwrap()])
|
||||
.args(&["--color", "always", "-f", &file_path.to_str().unwrap()])
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(similar(expected));
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ _tealdeer() {
|
|||
"($I -q --quiet)"{-q,--quiet}"[Suppress informational messages]"
|
||||
"($I)--config-path[Show config file path]"
|
||||
"($I)--seed-config[Create a basic config]"
|
||||
"($I --color)"{--color}'[Controls when to use color]:when:((
|
||||
always
|
||||
auto
|
||||
never
|
||||
))'
|
||||
'(- *)'{-h,--help}'[Display help]'
|
||||
'(- *)'{-v,--version}'[Show version information]'
|
||||
'*:file:_files'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue