Skip to content

Commit

Permalink
Merge pull request #111 from LovecraftianHorror/better-color-detection
Browse files Browse the repository at this point in the history
Improved color detection with --color argument and NO_COLOR env variable.

Fixes #81.
  • Loading branch information
dbrgn authored Aug 30, 2020
2 parents 09d73c2 + dc6af5a commit 4c413d7
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions bash_tealdeer
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions fish_tealdeer
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
42 changes: 34 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -104,6 +107,7 @@ struct Args {
flag_config_path: bool,
flag_seed_config: bool,
flag_markdown: bool,
flag_color: ColorOptions,
}

/// Print page by path
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions tests/inkscape-default-no-color.expected
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 6 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
Expand All @@ -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.
Expand Down Expand Up @@ -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));
Expand Down
5 changes: 5 additions & 0 deletions zsh_tealdeer
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit 4c413d7

Please sign in to comment.