parent
3c344b66b9
commit
011a47e93d
5
.github/workflows/crossterm_test.yml
vendored
5
.github/workflows/crossterm_test.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
|||||||
uses: hecrj/setup-rust-action@master
|
uses: hecrj/setup-rust-action@master
|
||||||
with:
|
with:
|
||||||
rust-version: ${{ matrix.rust }}
|
rust-version: ${{ matrix.rust }}
|
||||||
components: rustfmt
|
components: rustfmt,clippy
|
||||||
- name: Toolchain Information
|
- name: Toolchain Information
|
||||||
run: |
|
run: |
|
||||||
rustc --version
|
rustc --version
|
||||||
@ -44,6 +44,9 @@ jobs:
|
|||||||
if: matrix.rust == 'stable'
|
if: matrix.rust == 'stable'
|
||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
continue-on-error: ${{ matrix.can-fail }}
|
continue-on-error: ${{ matrix.can-fail }}
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy -- -D clippy::all
|
||||||
|
continue-on-error: ${{ matrix.can-fail }}
|
||||||
- name: Test Build
|
- name: Test Build
|
||||||
run: cargo build
|
run: cargo build
|
||||||
continue-on-error: ${{ matrix.can-fail }}
|
continue-on-error: ${{ matrix.can-fail }}
|
||||||
|
@ -26,12 +26,14 @@ matrix:
|
|||||||
before_script:
|
before_script:
|
||||||
- export PATH=$PATH:/home/travis/.cargo/bin
|
- export PATH=$PATH:/home/travis/.cargo/bin
|
||||||
- rustup component add rustfmt
|
- rustup component add rustfmt
|
||||||
|
- rustup component add clippy
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cargo fmt --version
|
- cargo fmt --version
|
||||||
- rustup --version
|
- rustup --version
|
||||||
- rustc --version
|
- rustc --version
|
||||||
- if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi
|
- if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi
|
||||||
|
- cargo clippy -- -D clippy::all
|
||||||
- cargo build
|
- cargo build
|
||||||
- cargo test --all-features --no-default-features -- --nocapture --test-threads 1
|
- cargo test --all-features --no-default-features -- --nocapture --test-threads 1
|
||||||
- cargo test --features cursor --no-default-features --lib -- --nocapture --test-threads 1
|
- cargo test --features cursor --no-default-features --lib -- --nocapture --test-threads 1
|
||||||
|
@ -22,9 +22,9 @@ pub(crate) fn move_left_csi_sequence(count: u16) -> String {
|
|||||||
format!(csi!("{}D"), count)
|
format!(csi!("{}D"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) static SAVE_POSITION_CSI_SEQUENCE: &'static str = "\x1B7";
|
pub(crate) const SAVE_POSITION_CSI_SEQUENCE: &str = "\x1B7";
|
||||||
pub(crate) static RESTORE_POSITION_CSI_SEQUENCE: &'static str = "\x1B8";
|
pub(crate) const RESTORE_POSITION_CSI_SEQUENCE: &str = "\x1B8";
|
||||||
pub(crate) static HIDE_CSI_SEQUENCE: &'static str = csi!("?25l");
|
pub(crate) const HIDE_CSI_SEQUENCE: &str = csi!("?25l");
|
||||||
pub(crate) static SHOW_CSI_SEQUENCE: &'static str = csi!("?25h");
|
pub(crate) const SHOW_CSI_SEQUENCE: &str = csi!("?25h");
|
||||||
pub(crate) static ENABLE_BLINKING_CSI_SEQUENCE: &'static str = csi!("?12h");
|
pub(crate) const ENABLE_BLINKING_CSI_SEQUENCE: &str = csi!("?12h");
|
||||||
pub(crate) static DISABLE_BLINKING_CSI_SEQUENCE: &'static str = csi!("?12l");
|
pub(crate) const DISABLE_BLINKING_CSI_SEQUENCE: &str = csi!("?12l");
|
||||||
|
@ -38,18 +38,18 @@ fn read_position_raw() -> Result<(u16, u16)> {
|
|||||||
loop {
|
loop {
|
||||||
match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
|
match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
match read_internal(&CursorPositionFilter) {
|
if let Ok(InternalEvent::CursorPosition(x, y)) =
|
||||||
Ok(InternalEvent::CursorPosition(x, y)) => {
|
read_internal(&CursorPositionFilter)
|
||||||
return Ok((x, y));
|
{
|
||||||
}
|
return Ok((x, y));
|
||||||
_ => { /* unreachable */ }
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
Ok(false) => {
|
Ok(false) => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
"The cursor position could not be read within a normal duration",
|
"The cursor position could not be read within a normal duration",
|
||||||
))?;
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
}
|
}
|
||||||
|
@ -85,24 +85,26 @@ impl ScreenBufferCursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn move_to(&self, x: i16, y: i16) -> Result<()> {
|
fn move_to(&self, x: i16, y: i16) -> Result<()> {
|
||||||
if x < 0 || x >= <i16>::max_value() {
|
if x < 0 {
|
||||||
Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Argument Out of Range Exception when setting cursor position to X: {}",
|
"Argument Out of Range Exception when setting cursor position to X: {}",
|
||||||
x
|
x
|
||||||
),
|
),
|
||||||
))?;
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if y < 0 || y >= <i16>::max_value() {
|
if y < 0 {
|
||||||
Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Argument Out of Range Exception when setting cursor position to Y: {}",
|
"Argument Out of Range Exception when setting cursor position to Y: {}",
|
||||||
y
|
y
|
||||||
),
|
),
|
||||||
))?;
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let position = COORD { X: x, Y: y };
|
let position = COORD { X: x, Y: y };
|
||||||
@ -112,7 +114,7 @@ impl ScreenBufferCursor {
|
|||||||
**self.screen_buffer.handle(),
|
**self.screen_buffer.handle(),
|
||||||
position,
|
position,
|
||||||
)) {
|
)) {
|
||||||
Err(io::Error::last_os_error())?;
|
return Err(io::Error::last_os_error().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -129,7 +131,7 @@ impl ScreenBufferCursor {
|
|||||||
**self.screen_buffer.handle(),
|
**self.screen_buffer.handle(),
|
||||||
&cursor_info,
|
&cursor_info,
|
||||||
)) {
|
)) {
|
||||||
Err(io::Error::last_os_error())?;
|
return Err(io::Error::last_os_error().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -189,15 +189,13 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::event::M
|
|||||||
let ypos = parse_relative_y(event.mouse_position.y)? as u16;
|
let ypos = parse_relative_y(event.mouse_position.y)? as u16;
|
||||||
|
|
||||||
let button_state = event.button_state;
|
let button_state = event.button_state;
|
||||||
let mut button = MouseButton::Left;
|
let button = if button_state.right_button() {
|
||||||
|
MouseButton::Right
|
||||||
if button_state.right_button() {
|
} else if button_state.middle_button() {
|
||||||
button = MouseButton::Right;
|
MouseButton::Middle
|
||||||
}
|
} else {
|
||||||
|
MouseButton::Left
|
||||||
if button_state.middle_button() {
|
};
|
||||||
button = MouseButton::Middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(match event.event_flags {
|
Ok(match event.event_flags {
|
||||||
EventFlags::PressOrRelease => {
|
EventFlags::PressOrRelease => {
|
||||||
@ -272,7 +270,7 @@ impl WinApiPoll {
|
|||||||
unsafe { WaitForMultipleObjects(handles.len() as u32, handles.as_ptr(), 0, dw_millis) };
|
unsafe { WaitForMultipleObjects(handles.len() as u32, handles.as_ptr(), 0, dw_millis) };
|
||||||
|
|
||||||
let result = match output {
|
let result = match output {
|
||||||
output if output == WAIT_OBJECT_0 + 0 => {
|
output if output == WAIT_OBJECT_0 => {
|
||||||
// input handle triggered
|
// input handle triggered
|
||||||
Ok(Some(true))
|
Ok(Some(true))
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ impl AlternateScreen {
|
|||||||
///
|
///
|
||||||
/// You'll be automatically switched to the main screen if this function
|
/// You'll be automatically switched to the main screen if this function
|
||||||
/// fails.
|
/// fails.
|
||||||
|
#[allow(clippy::wrong_self_convention)]
|
||||||
pub fn to_alternate(raw_mode: bool) -> Result<AlternateScreen> {
|
pub fn to_alternate(raw_mode: bool) -> Result<AlternateScreen> {
|
||||||
let alternate = alternate::alternate_screen();
|
let alternate = alternate::alternate_screen();
|
||||||
alternate.enter()?;
|
alternate.enter()?;
|
||||||
|
@ -2,8 +2,8 @@ use crate::{csi, utils::Result, write_cout};
|
|||||||
|
|
||||||
use super::AlternateScreen;
|
use super::AlternateScreen;
|
||||||
|
|
||||||
pub(crate) static ENTER_ALTERNATE_SCREEN_CSI_SEQUENCE: &'static str = csi!("?1049h");
|
pub(crate) const ENTER_ALTERNATE_SCREEN_CSI_SEQUENCE: &str = csi!("?1049h");
|
||||||
pub(crate) static LEAVE_ALTERNATE_SCREEN_CSI_SEQUENCE: &'static str = csi!("?1049l");
|
pub(crate) const LEAVE_ALTERNATE_SCREEN_CSI_SEQUENCE: &str = csi!("?1049l");
|
||||||
|
|
||||||
pub(crate) struct AnsiAlternateScreen;
|
pub(crate) struct AnsiAlternateScreen;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ impl RawModeCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Disables raw mode.
|
/// Disables raw mode.
|
||||||
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||||
pub fn disable(&self) -> Result<()> {
|
pub fn disable(&self) -> Result<()> {
|
||||||
let console_mode = ConsoleMode::from(Handle::input_handle()?);
|
let console_mode = ConsoleMode::from(Handle::input_handle()?);
|
||||||
|
|
||||||
@ -44,6 +45,6 @@ impl RawModeCommand {
|
|||||||
|
|
||||||
console_mode.set_mode(new_mode)?;
|
console_mode.set_mode(new_mode)?;
|
||||||
|
|
||||||
return Ok(());
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ pub(crate) fn set_attr_csi_sequence(attribute: Attribute) -> String {
|
|||||||
format!(csi!("{}m"), attribute as i16)
|
format!(csi!("{}m"), attribute as i16)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) static RESET_CSI_SEQUENCE: &'static str = csi!("0m");
|
pub(crate) const RESET_CSI_SEQUENCE: &str = csi!("0m");
|
||||||
|
|
||||||
impl From<Colored> for String {
|
impl From<Colored> for String {
|
||||||
fn from(colored: Colored) -> Self {
|
fn from(colored: Colored) -> Self {
|
||||||
|
@ -37,7 +37,7 @@ pub(crate) fn set_foreground_color(fg_color: Color) -> Result<()> {
|
|||||||
// background intensity is a separate value in attrs,
|
// background intensity is a separate value in attrs,
|
||||||
// wee need to check if this was applied to the current bg color.
|
// wee need to check if this was applied to the current bg color.
|
||||||
if (attrs & wincon::BACKGROUND_INTENSITY as u16) != 0 {
|
if (attrs & wincon::BACKGROUND_INTENSITY as u16) != 0 {
|
||||||
color = color | wincon::BACKGROUND_INTENSITY as u16;
|
color |= wincon::BACKGROUND_INTENSITY as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::from(screen_buffer.handle().clone()).set_text_attribute(color)?;
|
Console::from(screen_buffer.handle().clone()).set_text_attribute(color)?;
|
||||||
@ -62,7 +62,7 @@ pub(crate) fn set_background_color(bg_color: Color) -> Result<()> {
|
|||||||
// Foreground intensity is a separate value in attrs,
|
// Foreground intensity is a separate value in attrs,
|
||||||
// So we need to check if this was applied to the current fg color.
|
// So we need to check if this was applied to the current fg color.
|
||||||
if (attrs & wincon::FOREGROUND_INTENSITY as u16) != 0 {
|
if (attrs & wincon::FOREGROUND_INTENSITY as u16) != 0 {
|
||||||
color = color | wincon::FOREGROUND_INTENSITY as u16;
|
color |= wincon::FOREGROUND_INTENSITY as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::from(screen_buffer.handle().clone()).set_text_attribute(color)?;
|
Console::from(screen_buffer.handle().clone()).set_text_attribute(color)?;
|
||||||
@ -137,7 +137,7 @@ impl From<Colored> for u16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/
|
/* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/
|
||||||
Color::Rgb { r: _, g: _, b: _ } => 0,
|
Color::Rgb { .. } => 0,
|
||||||
Color::AnsiValue(_val) => 0,
|
Color::AnsiValue(_val) => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ impl From<Colored> for u16 {
|
|||||||
(original_color & !(REMOVE_FG_MASK))
|
(original_color & !(REMOVE_FG_MASK))
|
||||||
}
|
}
|
||||||
/* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/
|
/* WinApi will be used for systems that do not support ANSI, those are windows version less then 10. RGB and 255 (AnsiBValue) colors are not supported in that case.*/
|
||||||
Color::Rgb { r: _, g: _, b: _ } => 0,
|
Color::Rgb { .. } => 0,
|
||||||
Color::AnsiValue(_val) => 0,
|
Color::AnsiValue(_val) => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl Command for Clear {
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn execute_winapi(&self) -> Result<()> {
|
fn execute_winapi(&self) -> Result<()> {
|
||||||
sys::clear(self.0.clone())
|
sys::clear(self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
use crate::csi;
|
use crate::csi;
|
||||||
|
|
||||||
pub(crate) static CLEAR_ALL_CSI_SEQUENCE: &'static str = csi!("2J");
|
pub(crate) const CLEAR_ALL_CSI_SEQUENCE: &str = csi!("2J");
|
||||||
pub(crate) static CLEAR_FROM_CURSOR_DOWN_CSI_SEQUENCE: &'static str = csi!("J");
|
pub(crate) const CLEAR_FROM_CURSOR_DOWN_CSI_SEQUENCE: &str = csi!("J");
|
||||||
pub(crate) static CLEAR_FROM_CURSOR_UP_CSI_SEQUENCE: &'static str = csi!("1J");
|
pub(crate) const CLEAR_FROM_CURSOR_UP_CSI_SEQUENCE: &str = csi!("1J");
|
||||||
pub(crate) static CLEAR_FROM_CURRENT_LINE_CSI_SEQUENCE: &'static str = csi!("2K");
|
pub(crate) const CLEAR_FROM_CURRENT_LINE_CSI_SEQUENCE: &str = csi!("2K");
|
||||||
pub(crate) static CLEAR_UNTIL_NEW_LINE_CSI_SEQUENCE: &'static str = csi!("K");
|
pub(crate) const CLEAR_UNTIL_NEW_LINE_CSI_SEQUENCE: &str = csi!("K");
|
||||||
|
|
||||||
pub(crate) fn scroll_up_csi_sequence(count: u16) -> String {
|
pub(crate) fn scroll_up_csi_sequence(count: u16) -> String {
|
||||||
format!(csi!("{}S"), count)
|
format!(csi!("{}S"), count)
|
||||||
|
@ -55,10 +55,8 @@ pub fn size() -> Result<(u16, u16)> {
|
|||||||
ws_ypixel: 0,
|
ws_ypixel: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(true) =
|
if let Ok(true) = wrap_with_result(unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut size) }) {
|
||||||
wrap_with_result(unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ.into(), &mut size) })
|
Ok((size.ws_col, size.ws_row))
|
||||||
{
|
|
||||||
return Ok((size.ws_col, size.ws_row));
|
|
||||||
} else {
|
} else {
|
||||||
tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
|
tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
|
||||||
}
|
}
|
||||||
|
@ -75,13 +75,13 @@ pub(crate) fn scroll_down(row_count: u16) -> Result<()> {
|
|||||||
|
|
||||||
/// Set the current terminal size
|
/// Set the current terminal size
|
||||||
pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||||
if width <= 0 {
|
if width <= 1 {
|
||||||
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
||||||
"Cannot set the terminal width lower than 1.",
|
"Cannot set the terminal width lower than 1.",
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if height <= 0 {
|
if height <= 1 {
|
||||||
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
||||||
"Cannot set the terminal height lower then 1.",
|
"Cannot set the terminal height lower then 1.",
|
||||||
)));
|
)));
|
||||||
@ -124,15 +124,17 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
|||||||
resize_buffer = true;
|
resize_buffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if resize_buffer {
|
if resize_buffer
|
||||||
if let Err(_) = screen_buffer.set_size(new_size.width - 1, new_size.height - 1) {
|
&& screen_buffer
|
||||||
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
.set_size(new_size.width - 1, new_size.height - 1)
|
||||||
"Something went wrong when setting screen buffer size.",
|
.is_err()
|
||||||
)));
|
{
|
||||||
}
|
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
||||||
|
"Something went wrong when setting screen buffer size.",
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut window = window.clone();
|
let mut window = window;
|
||||||
|
|
||||||
// preserve the position, but change the size.
|
// preserve the position, but change the size.
|
||||||
window.bottom = window.top + height - 1;
|
window.bottom = window.top + height - 1;
|
||||||
@ -140,12 +142,14 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
|||||||
console.set_console_info(true, window)?;
|
console.set_console_info(true, window)?;
|
||||||
|
|
||||||
// if we resized the buffer, un-resize it.
|
// if we resized the buffer, un-resize it.
|
||||||
if resize_buffer {
|
if resize_buffer
|
||||||
if let Err(_) = screen_buffer.set_size(current_size.width - 1, current_size.height - 1) {
|
&& screen_buffer
|
||||||
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
.set_size(current_size.width - 1, current_size.height - 1)
|
||||||
"Something went wrong when setting screen buffer size.",
|
.is_err()
|
||||||
)));
|
{
|
||||||
}
|
return Err(ErrorKind::ResizingTerminalFailure(String::from(
|
||||||
|
"Something went wrong when setting screen buffer size.",
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds = console.largest_window_size();
|
let bounds = console.largest_window_size();
|
||||||
|
@ -101,7 +101,7 @@ impl<T: Display + Clone> Command for Output<T> {
|
|||||||
type AnsiType = T;
|
type AnsiType = T;
|
||||||
|
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
return self.0.clone();
|
self.0.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -20,7 +20,7 @@ pub fn supports_ansi() -> bool {
|
|||||||
// I got the list of terminals from here: https://github.com/keqingrong/supports-ansi/blob/master/index.js
|
// I got the list of terminals from here: https://github.com/keqingrong/supports-ansi/blob/master/index.js
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn is_specific_term() -> bool {
|
fn is_specific_term() -> bool {
|
||||||
const TERMS: [&'static str; 15] = [
|
const TERMS: [&str; 15] = [
|
||||||
"xterm", // xterm, PuTTY, Mintty
|
"xterm", // xterm, PuTTY, Mintty
|
||||||
"rxvt", // RXVT
|
"rxvt", // RXVT
|
||||||
"eterm", // Eterm
|
"eterm", // Eterm
|
||||||
|
@ -80,28 +80,21 @@ macro_rules! queue {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
if $crate::supports_ansi() {
|
if $crate::supports_ansi() {
|
||||||
match write!($write, "{}", $command.ansi_code()) {
|
if let Err(e) = write!($write, "{}", $command.ansi_code()) {
|
||||||
Err(e) => {
|
error = Some(Err($crate::ErrorKind::from(e)));
|
||||||
error = Some(Err($crate::ErrorKind::from(e)));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
match $command.execute_winapi() {
|
if let Err(e) = $command.execute_winapi() {
|
||||||
Err(e) => {
|
error = Some(Err($crate::ErrorKind::from(e)));
|
||||||
error = Some(Err($crate::ErrorKind::from(e)));
|
}
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
match write!($write, "{}", $command.ansi_code()) {
|
{
|
||||||
Err(e) => {
|
if let Err(e) = write!($write, "{}", $command.ansi_code()) {
|
||||||
error = Some(Err($crate::ErrorKind::from(e)));
|
error = Some(Err($crate::ErrorKind::from(e)));
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
};
|
|
||||||
)*
|
)*
|
||||||
|
|
||||||
if let Some(error) = error {
|
if let Some(error) = error {
|
||||||
|
Loading…
Reference in New Issue
Block a user