Support colors on Windows using ansi_term

We try to enable ANSI color support on Windows using the new APIs.
If that succeeds, we print colors as usual. If it fails, we disable
styles completely.
This commit is contained in:
Gabriel Martinez 2019-02-09 21:28:36 -08:00
commit 495c3e97d9
9 changed files with 44 additions and 15 deletions

9
Cargo.lock generated
View file

@ -13,8 +13,11 @@ dependencies = [
[[package]]
name = "ansi_term"
version = "0.10.2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "app_dirs"
@ -1172,7 +1175,7 @@ dependencies = [
name = "tealdeer"
version = "1.1.0"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy 0.0.174 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1612,7 +1615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7ac5c260f75e4e4ba87b7342be6edcecbcb3eb6741a0507fda7ad115845cc65"

View file

@ -15,7 +15,7 @@ name = "tldr"
path = "src/main.rs"
[dependencies]
ansi_term = "0.10.2"
ansi_term = "0.11.0"
app_dirs = "1.2.1"
clippy = { version = "0.0.174", optional = true }
docopt = "0.8.1"

View file

@ -67,7 +67,7 @@ These are the clients I tried but failed to compile or run:
-v --version Show version information
-l --list List all commands in the cache
-f --render <file> Render a specific markdown file
-o --os <type> Override the operating system [linux, osx, sunos]
-o --os <type> Override the operating system [linux, osx, sunos, windows]
-u --update Update the local cache
-c --clear-cache Clear the local cache
-q --quiet Suppress informational messages

View file

@ -14,7 +14,7 @@ _tealdeer()
return
;;
-o|--os)
COMPREPLY=( $(compgen -W 'linux osx sunos' -- "${cur}") )
COMPREPLY=( $(compgen -W 'linux osx sunos windows' -- "${cur}") )
return
;;
esac

View file

@ -7,7 +7,7 @@ complete -c tldr -s h -l help -d 'Print the help message.' -f
complete -c tldr -s v -l version -d 'Show version information.' -f
complete -c tldr -s l -l list -d 'List all commands in the cache.' -f
complete -c tldr -s f -l render -d 'Render a specific markdown file.' -r
complete -c tldr -s o -l os -d 'Override the operating system.' -xa 'linux osx sunos other'
complete -c tldr -s o -l os -d 'Override the operating system.' -xa 'linux osx sunos windows other'
complete -c tldr -s u -l update -d 'Update the local cache.' -f
complete -c tldr -s c -l clear-cache -d 'Clear the local cache.' -f
complete -c tldr -s q -l quiet -d 'Suppress informational messages.' -f

View file

@ -137,6 +137,7 @@ impl Cache {
OsType::Linux => Some("linux"),
OsType::OsX => Some("osx"),
OsType::SunOs => None, // TODO: Does Rust support SunOS?
OsType::Windows => Some("windows"),
OsType::Other => None,
}
}

View file

@ -162,7 +162,7 @@ fn map_io_err_to_config_err(e: IoError) -> TealdeerError {
}
impl Config {
pub fn load() -> Result<Self, TealdeerError> {
pub fn load(enable_styles: bool) -> Result<Self, TealdeerError> {
debug!("Loading config");
// Determine path
@ -183,7 +183,19 @@ impl Config {
RawConfig::new()
};
Ok(Self::from(raw_config))
Ok(if enable_styles {
Self::from(raw_config)
} else {
Self {
style: StyleConfig {
command_name: Style::default(),
description: Style::default(),
example_text: Style::default(),
example_code: Style::default(),
example_variable: Style::default(),
}
}
})
}
} // impl Config

View file

@ -59,7 +59,7 @@ Options:
-v --version Show version information
-l --list List all commands in the cache
-f --render <file> Render a specific markdown file
-o --os <type> Override the operating system [linux, osx, sunos]
-o --os <type> Override the operating system [linux, osx, sunos, windows]
-u --update Update the local cache
-c --clear-cache Clear the local cache
-q --quiet Suppress informational messages
@ -99,13 +99,13 @@ struct Args {
}
/// Print page by path
fn print_page(path: &Path) -> Result<(), String> {
fn print_page(path: &Path, enable_styles: bool) -> Result<(), String> {
// Open file
let file = File::open(path).map_err(|msg| format!("Could not open file: {}", msg))?;
let reader = BufReader::new(file);
// Look up config file, if none is found fall back to default config.
let config = match Config::load() {
let config = match Config::load(enable_styles) {
Ok(config) => config,
Err(ConfigError(msg)) => {
eprintln!("Could not load config: {}", msg);
@ -172,12 +172,18 @@ fn get_os() -> OsType {
OsType::OsX
}
#[cfg(target_os = "windows")]
fn get_os() -> OsType {
OsType::Windows
}
#[cfg(not(any(target_os = "linux",
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "dragonfly")))]
target_os = "dragonfly",
target_os = "windows")))]
fn get_os() -> OsType {
OsType::Other
}
@ -204,6 +210,11 @@ fn main() {
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);
@ -279,7 +290,7 @@ fn main() {
// Render local file and exit
if let Some(ref file) = args.flag_render {
let path = PathBuf::from(file);
if let Err(msg) = print_page(&path) {
if let Err(msg) = print_page(&path, enable_styles) {
eprintln!("{}", msg);
process::exit(1);
} else {
@ -315,7 +326,7 @@ fn main() {
// Search for command in cache
if let Some(path) = cache.find_page(&command) {
if let Err(msg) = print_page(&path) {
if let Err(msg) = print_page(&path, enable_styles) {
eprintln!("{}", msg);
process::exit(1);
} else {

View file

@ -11,6 +11,7 @@ pub enum OsType {
Linux,
OsX,
SunOs,
Windows,
Other,
}
@ -20,6 +21,7 @@ impl fmt::Display for OsType {
OsType::Linux => write!(f, "Linux"),
OsType::OsX => write!(f, "macOS / BSD"),
OsType::SunOs => write!(f, "SunOS"),
OsType::Windows => write!(f, "Windows"),
OsType::Other => write!(f, "Unknown OS"),
}
}