Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtlawrence authored Nov 11, 2019
2 parents 4af2de0 + 98667ba commit 4ab870f
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 22 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

# New Version

- **[BREAKING CHANGE]:** Replace `winconsole` with `winapi`:
- Changes `set_virtual_terminal` function signature.

# 1.8.0 (April 30, 2019)

- FEAT: support Windows 10 colors
Expand Down
14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ no-color = []

[dependencies]
atty = "0.2.11"
lazy_static = "1.2.0"
lazy_static = "1.4.0"

[target.'cfg(windows)'.dependencies]
winconsole = "0.10.0"
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
default-features = false
features = [
"consoleapi",
"processenv",
"winbase"
]

[dev_dependencies]
ansi_term = "^0.9"
ansi_term = "0.12"
rspec = "=1.0.0-beta.3"
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM rust:latest

ENV SRC_DIR /src
RUN mkdir $SRC_DIR
WORKDIR $SRC_DIR
VOLUME $SRC_DIR

CMD ["/bin/bash"]

19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ dumb_terminal = ["colored/no-color"]
You can use have even finer control by using the
`colored::control::set_override` method.

## Build with Docker

### Install Docker

Use the install instructions located [here](https://docs.docker.com/v17.12/install/)

### Build the Docker image

```docker build -t colored_image .```

### Build the library

```docker run --rm -it -v "$PWD":/src -u `id -u`:`id -g` colored_image /bin/bash -c "cargo build"```

### Test the library

```docker run --rm -it -v "$PWD":/src -u `id -u`:`id -g` colored_image /bin/bash -c "cargo test"```


## Todo

- **More tests ?**: We always welcome more tests! Please contribute!
Expand Down
26 changes: 26 additions & 0 deletions examples/control.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
extern crate colored;
use colored::*;

#[cfg(not(windows))]
fn main() {
both()
}

#[cfg(windows)]
fn main() {
both();

// additional control setting using windows set_virtual_terminal
colored::control::set_virtual_terminal(true);
println!("{}", "stdout: Virtual Terminal is in use".bright_green());
colored::control::set_virtual_terminal(false);
println!("{}", "stderr: Virtual Terminal is NOT in use, escape chars should be visible".bright_red());
colored::control::set_virtual_terminal(true);
println!("{}", "stdout: Virtual Terminal is in use AGAIN and should be green!".bright_green());
colored::control::set_virtual_terminal(true);

// again with stderr
eprintln!("{}", "stderr: Virtual Terminal is in use".bright_green());
colored::control::set_virtual_terminal(false);
eprintln!("{}", "stderr: Virtual Terminal is NOT in use, escape chars should be visible".bright_red());
colored::control::set_virtual_terminal(true);
eprintln!("{}", "stderr: Virtual Terminal is in use AGAIN and should be green!".bright_green());
}

fn both() {
// this will be yellow if your environment allow it
println!("{}", "some warning".yellow());
// now , this will be always yellow
Expand Down
44 changes: 35 additions & 9 deletions src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,55 @@
use std::default::Default;
use std::env;
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(windows)]
use winconsole::{console, errors::WinResult};

/// Sets a flag to the console to use a virtual terminal environment.
/// This is primarily used for Windows 10 environments which will not correctly colorize the outputs based on ansi escape codes.
///
/// This is primarily used for Windows 10 environments which will not correctly colorize
/// the outputs based on ANSI escape codes.
///
/// The returned `Result` is _always_ `Ok(())`, the return type was kept to ensure backwards
/// compatibility.
///
/// # Notes
/// > Only available to `Windows` build targets.
///
/// # Example
/// ```rust
/// use colored::*;
/// control::set_virtual_terminal(false);
/// control::set_virtual_terminal(false).unwrap();
/// println!("{}", "bright cyan".bright_cyan()); // will print 'bright cyan' on windows 10
///
/// control::set_virtual_terminal(true);
/// control::set_virtual_terminal(true).unwrap();
/// println!("{}", "bright cyan".bright_cyan()); // will print correctly
/// ```
#[cfg(windows)]
pub fn set_virtual_terminal(use_virtual: bool) -> WinResult<()> {
let mut mode = console::get_output_mode()?;
mode.VirtualTerminalProcessing = use_virtual;
console::set_output_mode(mode)?;
pub fn set_virtual_terminal(use_virtual: bool) -> Result<(), ()> {
use winapi::{
shared::minwindef::DWORD,
um::{
consoleapi::{GetConsoleMode, SetConsoleMode},
processenv::GetStdHandle,
winbase::STD_OUTPUT_HANDLE,
wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING,
}
};

unsafe {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
let mut original_mode: DWORD = 0;
GetConsoleMode(handle, &mut original_mode);

let enabled = original_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == ENABLE_VIRTUAL_TERMINAL_PROCESSING;

match (use_virtual, enabled) {
// not enabled, should be enabled
(true, false) => SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING | original_mode),
// already enabled, should be disabled
(false, true) => SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING ^ original_mode),
_ => 0,
};
}

Ok(())
}

Expand Down
7 changes: 2 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern crate atty;
#[macro_use]
extern crate lazy_static;
#[cfg(windows)]
extern crate winconsole;
extern crate winapi;

#[cfg(test)]
extern crate rspec;
Expand Down Expand Up @@ -180,11 +180,10 @@ impl ColoredString {
.map(|(idx, _)| idx)
.collect();

let mut idx_in_matches = 0;
let mut input = self.input.clone();
input.reserve(matches.len() * style.len());

for offset in matches {
for (idx_in_matches, offset) in matches.into_iter().enumerate() {
// shift the offset to the end of the reset sequence and take in account
// the number of matches we have escaped (which shift the index to insert)
let mut offset = offset + reset.len() + idx_in_matches * style.len();
Expand All @@ -193,8 +192,6 @@ impl ColoredString {
input.insert(offset, cchar);
offset += 1;
}

idx_in_matches += 1;
}

input
Expand Down
6 changes: 2 additions & 4 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Styles {
}

let res: Vec<Styles> = STYLES
.into_iter()
.iter()
.filter(|&&(ref mask, _)| (0 != (u & mask)))
.map(|&(_, value)| value)
.collect();
Expand All @@ -86,7 +86,7 @@ impl Styles {

impl Style {
pub fn to_str(self) -> String {
let styles = Styles::from_u8(self.0).unwrap_or(Vec::new());
let styles = Styles::from_u8(self.0).unwrap_or_default();
styles
.iter()
.map(|s| s.to_str())
Expand Down Expand Up @@ -114,7 +114,6 @@ mod tests {
fn empty_is_none() {
assert_eq!(None, Styles::from_u8(CLEARV))
}

}

mod u8_to_styles_isomorphism {
Expand Down Expand Up @@ -270,6 +269,5 @@ mod tests {
];
test_combine!(s)
}

}
}
27 changes: 27 additions & 0 deletions tests/ansi_term_compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,30 @@ mod compat_complex {
);
}
}

mod compat_overrides {
use super::ansi_term;
use super::ansi_term::*;
use super::colored;
use super::colored::*;

#[test]
fn overrides1() {
let s = "test string";
let ansi = Colour::Red.on(Colour::Black).on(Colour::Blue).paint(s);
assert_eq!(
ansi.to_string(),
s.red().on_blue().to_string()
);
}

#[test]
fn overrides2() {
let s = "test string";
let ansi = Colour::Green.on(Colour::Yellow).paint(s);
assert_eq!(
ansi.to_string(),
s.green().on_yellow().green().on_yellow().to_string()
);
}
}

0 comments on commit 4ab870f

Please sign in to comment.