Unwrap crossterm::Result<T, ErrorKind>
to std::io::Result
. (#765)
This commit is contained in:
parent
41901c6382
commit
a2c9350ff2
@ -109,7 +109,7 @@ use crossterm::{
|
||||
event,
|
||||
};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> std::io::Result<()> {
|
||||
// using the macro
|
||||
execute!(
|
||||
stdout(),
|
||||
|
@ -2,14 +2,13 @@
|
||||
//!
|
||||
//! cargo run --example event-poll-read
|
||||
|
||||
use std::{io::stdout, time::Duration};
|
||||
use std::{io, time::Duration};
|
||||
|
||||
use crossterm::{
|
||||
cursor::position,
|
||||
event::{poll, read, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode},
|
||||
Result,
|
||||
};
|
||||
|
||||
const HELP: &str = r#"Blocking poll() & non-blocking read()
|
||||
@ -19,7 +18,7 @@ const HELP: &str = r#"Blocking poll() & non-blocking read()
|
||||
- Use Esc to quit
|
||||
"#;
|
||||
|
||||
fn print_events() -> Result<()> {
|
||||
fn print_events() -> io::Result<()> {
|
||||
loop {
|
||||
// Wait up to 1s for another event
|
||||
if poll(Duration::from_millis(1_000))? {
|
||||
@ -44,12 +43,12 @@ fn print_events() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> io::Result<()> {
|
||||
println!("{}", HELP);
|
||||
|
||||
enable_raw_mode()?;
|
||||
|
||||
let mut stdout = stdout();
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnableMouseCapture)?;
|
||||
|
||||
if let Err(e) = print_events() {
|
||||
|
@ -3,12 +3,11 @@
|
||||
//!
|
||||
//! cargo run --example event-read-char-line
|
||||
|
||||
use crossterm::{
|
||||
event::{self, Event, KeyCode, KeyEvent},
|
||||
Result,
|
||||
};
|
||||
use std::io;
|
||||
|
||||
pub fn read_char() -> Result<char> {
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEvent};
|
||||
|
||||
pub fn read_char() -> io::Result<char> {
|
||||
loop {
|
||||
if let Event::Key(KeyEvent {
|
||||
code: KeyCode::Char(c),
|
||||
@ -20,7 +19,7 @@ pub fn read_char() -> Result<char> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_line() -> Result<String> {
|
||||
pub fn read_line() -> io::Result<String> {
|
||||
let mut line = String::new();
|
||||
while let Event::Key(KeyEvent { code, .. }) = event::read()? {
|
||||
match code {
|
||||
|
@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! cargo run --example event-read
|
||||
|
||||
use std::io::stdout;
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::{
|
||||
poll, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
|
||||
@ -15,7 +15,6 @@ use crossterm::{
|
||||
},
|
||||
execute, queue,
|
||||
terminal::{disable_raw_mode, enable_raw_mode},
|
||||
Result,
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -25,7 +24,7 @@ const HELP: &str = r#"Blocking read()
|
||||
- Use Esc to quit
|
||||
"#;
|
||||
|
||||
fn print_events() -> Result<()> {
|
||||
fn print_events() -> io::Result<()> {
|
||||
loop {
|
||||
// Blocking read
|
||||
let event = read()?;
|
||||
@ -63,12 +62,12 @@ fn flush_resize_events(first_resize: (u16, u16)) -> ((u16, u16), (u16, u16)) {
|
||||
(first_resize, last_resize)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> io::Result<()> {
|
||||
println!("{}", HELP);
|
||||
|
||||
enable_raw_mode()?;
|
||||
|
||||
let mut stdout = stdout();
|
||||
let mut stdout = io::stdout();
|
||||
|
||||
let supports_keyboard_enhancement = matches!(
|
||||
crossterm::terminal::supports_keyboard_enhancement(),
|
||||
|
@ -12,7 +12,6 @@ use crossterm::{
|
||||
event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream, KeyCode},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode},
|
||||
Result,
|
||||
};
|
||||
|
||||
const HELP: &str = r#"EventStream based on futures_util::stream::Stream with async-std
|
||||
@ -52,7 +51,7 @@ async fn print_events() {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> std::io::Result<()> {
|
||||
println!("{}", HELP);
|
||||
|
||||
enable_raw_mode()?;
|
||||
|
@ -12,7 +12,6 @@ use crossterm::{
|
||||
event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream, KeyCode},
|
||||
execute,
|
||||
terminal::{disable_raw_mode, enable_raw_mode},
|
||||
Result,
|
||||
};
|
||||
|
||||
const HELP: &str = r#"EventStream based on futures_util::Stream with tokio
|
||||
@ -53,7 +52,7 @@ async fn print_events() {
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
async fn main() -> std::io::Result<()> {
|
||||
println!("{}", HELP);
|
||||
|
||||
enable_raw_mode()?;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![allow(clippy::cognitive_complexity)]
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::KeyEventKind;
|
||||
pub use crossterm::{
|
||||
@ -8,7 +8,7 @@ pub use crossterm::{
|
||||
event::{self, Event, KeyCode, KeyEvent},
|
||||
execute, queue, style,
|
||||
terminal::{self, ClearType},
|
||||
Command, Result,
|
||||
Command,
|
||||
};
|
||||
|
||||
#[macro_use]
|
||||
@ -33,9 +33,9 @@ Available tests:
|
||||
Select test to run ('1', '2', ...) or hit 'q' to quit.
|
||||
"#;
|
||||
|
||||
fn run<W>(w: &mut W) -> Result<()>
|
||||
fn run<W>(w: &mut W) -> io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
W: io::Write,
|
||||
{
|
||||
execute!(w, terminal::EnterAlternateScreen)?;
|
||||
|
||||
@ -80,7 +80,7 @@ where
|
||||
terminal::disable_raw_mode()
|
||||
}
|
||||
|
||||
pub fn read_char() -> Result<char> {
|
||||
pub fn read_char() -> std::io::Result<char> {
|
||||
loop {
|
||||
if let Ok(Event::Key(KeyEvent {
|
||||
code: KeyCode::Char(c),
|
||||
@ -94,11 +94,11 @@ pub fn read_char() -> Result<char> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_size() -> Result<(u16, u16)> {
|
||||
pub fn buffer_size() -> io::Result<(u16> {
|
||||
terminal::size()
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> std::io::Result<()> {
|
||||
let mut stdout = io::stdout();
|
||||
run(&mut stdout)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ const ATTRIBUTES: [(style::Attribute, style::Attribute); 10] = [
|
||||
(style::Attribute::SlowBlink, style::Attribute::NoBlink),
|
||||
];
|
||||
|
||||
fn test_set_display_attributes<W>(w: &mut W) -> Result<()>
|
||||
fn test_set_display_attributes<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -48,7 +48,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run<W>(w: &mut W) -> Result<()>
|
||||
pub fn run<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ const COLORS: [Color; 21] = [
|
||||
Color::Rgb { r: 0, g: 0, b: 255 },
|
||||
];
|
||||
|
||||
fn test_set_foreground_color<W>(w: &mut W) -> Result<()>
|
||||
fn test_set_foreground_color<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -63,7 +63,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_set_background_color<W>(w: &mut W) -> Result<()>
|
||||
fn test_set_background_color<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -98,7 +98,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_color_values_matrix_16x16<W, F>(w: &mut W, title: &str, color: F) -> Result<()>
|
||||
fn test_color_values_matrix_16x16<W, F>(w: &mut W, title: &str, color: F) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
F: Fn(u16, u16) -> Color,
|
||||
@ -140,7 +140,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_color_ansi_values<W>(w: &mut W) -> Result<()>
|
||||
fn test_color_ansi_values<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -149,7 +149,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn test_rgb_red_values<W>(w: &mut W) -> Result<()>
|
||||
fn test_rgb_red_values<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -160,7 +160,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn test_rgb_green_values<W>(w: &mut W) -> Result<()>
|
||||
fn test_rgb_green_values<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -171,7 +171,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn test_rgb_blue_values<W>(w: &mut W) -> Result<()>
|
||||
fn test_rgb_blue_values<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -182,7 +182,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run<W>(w: &mut W) -> Result<()>
|
||||
pub fn run<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
|
@ -2,40 +2,39 @@
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use crate::Result;
|
||||
use crossterm::{cursor, execute, queue, style, Command, style::Stylize};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
fn test_move_cursor_up<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_up<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
draw_cursor_box(w, "Move Up (2)", |_, _| cursor::MoveUp(2))
|
||||
}
|
||||
|
||||
fn test_move_cursor_down<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_down<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
draw_cursor_box(w, "Move Down (2)", |_, _| cursor::MoveDown(2))
|
||||
}
|
||||
|
||||
fn test_move_cursor_left<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_left<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
draw_cursor_box(w, "Move Left (2)", |_, _| cursor::MoveLeft(2))
|
||||
}
|
||||
|
||||
fn test_move_cursor_right<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_right<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
draw_cursor_box(w, "Move Right (2)", |_, _| cursor::MoveRight(2))
|
||||
}
|
||||
|
||||
fn test_move_cursor_to_previous_line<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_to_previous_line<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -44,14 +43,14 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn test_move_cursor_to_next_line<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_to_next_line<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
draw_cursor_box(w, "MoveToNextLine (1)", |_, _| cursor::MoveToNextLine(1))
|
||||
}
|
||||
|
||||
fn test_move_cursor_to_column<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_to_column<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -60,21 +59,21 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn test_hide_cursor<W>(w: &mut W) -> Result<()>
|
||||
fn test_hide_cursor<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
execute!(w, style::Print("HideCursor"), cursor::Hide)
|
||||
}
|
||||
|
||||
fn test_show_cursor<W>(w: &mut W) -> Result<()>
|
||||
fn test_show_cursor<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
execute!(w, style::Print("ShowCursor"), cursor::Show)
|
||||
}
|
||||
|
||||
fn test_cursor_blinking_block<W>(w: &mut W) -> Result<()>
|
||||
fn test_cursor_blinking_block<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -86,7 +85,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
fn test_cursor_blinking_underscore<W>(w: &mut W) -> Result<()>
|
||||
fn test_cursor_blinking_underscore<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -98,7 +97,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
fn test_cursor_blinking_bar<W>(w: &mut W) -> Result<()>
|
||||
fn test_cursor_blinking_bar<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -111,7 +110,7 @@ where
|
||||
}
|
||||
|
||||
|
||||
fn test_move_cursor_to<W>(w: &mut W) -> Result<()>
|
||||
fn test_move_cursor_to<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -122,7 +121,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
fn test_save_restore_cursor_position<W>(w: &mut W) -> Result<()>
|
||||
fn test_save_restore_cursor_position<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -143,7 +142,7 @@ where
|
||||
}
|
||||
|
||||
/// Draws a box with an colored center, this center can be taken as a reference point after running the given cursor command.
|
||||
fn draw_cursor_box<W, F, T>(w: &mut W, description: &str, cursor_command: F) -> Result<()>
|
||||
fn draw_cursor_box<W, F, T>(w: &mut W, description: &str, cursor_command: F) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
F: Fn(u16, u16) -> T,
|
||||
@ -199,7 +198,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run<W>(w: &mut W) -> Result<()>
|
||||
pub fn run<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
|
@ -3,13 +3,13 @@
|
||||
use crossterm::{
|
||||
cursor::position,
|
||||
event::{read, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
|
||||
execute, Result,
|
||||
execute,
|
||||
};
|
||||
use std::io::Write;
|
||||
use std::io;
|
||||
|
||||
fn test_event<W>(w: &mut W) -> Result<()>
|
||||
fn test_event<W>(w: &mut W) -> io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
W: io::Write,
|
||||
{
|
||||
execute!(w, EnableMouseCapture)?;
|
||||
|
||||
@ -33,7 +33,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run<W>(w: &mut W) -> Result<()>
|
||||
pub fn run<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
|
@ -2,9 +2,7 @@ use std::io::Write;
|
||||
|
||||
use crossterm::{cursor, execute, style::Print, SynchronizedUpdate};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
fn render_slowly<W>(w: &mut W) -> Result<()>
|
||||
fn render_slowly<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -15,7 +13,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_slow_rendering<W>(w: &mut W) -> Result<()>
|
||||
fn test_slow_rendering<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
@ -34,7 +32,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run<W>(w: &mut W) -> Result<()>
|
||||
pub fn run<W>(w: &mut W) -> std::io::Result<()>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
//!
|
||||
//! cargo run --example stderr
|
||||
|
||||
use std::io::{stderr, Write};
|
||||
use std::io;
|
||||
|
||||
use crossterm::{
|
||||
cursor::{Hide, MoveTo, Show},
|
||||
@ -17,7 +17,6 @@ use crossterm::{
|
||||
execute, queue,
|
||||
style::Print,
|
||||
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
|
||||
Result,
|
||||
};
|
||||
|
||||
const TEXT: &str = r#"
|
||||
@ -46,9 +45,9 @@ Hit any key to quit this screen:
|
||||
Any other key will print this text (so that you may copy-paste)
|
||||
"#;
|
||||
|
||||
fn run_app<W>(write: &mut W) -> Result<char>
|
||||
fn run_app<W>(write: &mut W) -> io::Result<char>
|
||||
where
|
||||
W: Write,
|
||||
W: io::Write,
|
||||
{
|
||||
queue!(
|
||||
write,
|
||||
@ -73,7 +72,7 @@ where
|
||||
Ok(user_char)
|
||||
}
|
||||
|
||||
pub fn read_char() -> Result<char> {
|
||||
pub fn read_char() -> io::Result<char> {
|
||||
loop {
|
||||
if let Event::Key(KeyEvent {
|
||||
code: KeyCode::Char(c),
|
||||
@ -87,7 +86,7 @@ pub fn read_char() -> Result<char> {
|
||||
|
||||
// cargo run --example stderr
|
||||
fn main() {
|
||||
match run_app(&mut stderr()).unwrap() {
|
||||
match run_app(&mut io::stderr()).unwrap() {
|
||||
'1' => print!(".."),
|
||||
'2' => print!("/"),
|
||||
'3' => print!("~"),
|
||||
|
@ -4,8 +4,6 @@ use crossterm_winapi::{ConsoleMode, Handle};
|
||||
use parking_lot::Once;
|
||||
use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// Enable virtual terminal processing.
|
||||
///
|
||||
/// This method attempts to enable virtual terminal processing for this
|
||||
@ -15,7 +13,7 @@ use crate::Result;
|
||||
/// When virtual terminal processing is enabled, characters emitted to the
|
||||
/// console are parsed for VT100 and similar control character sequences
|
||||
/// that control color and other similar operations.
|
||||
fn enable_vt_processing() -> Result<()> {
|
||||
fn enable_vt_processing() -> std::io::Result<()> {
|
||||
let mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
|
||||
let console_mode = ConsoleMode::from(Handle::current_out_handle()?);
|
||||
|
@ -3,8 +3,6 @@ use std::io::{self, Write};
|
||||
|
||||
use crate::terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate};
|
||||
|
||||
use super::error::Result;
|
||||
|
||||
/// An interface for a command that performs an action on the terminal.
|
||||
///
|
||||
/// Crossterm provides a set of commands,
|
||||
@ -26,7 +24,7 @@ pub trait Command {
|
||||
///
|
||||
/// This method does not need to be accessed manually, as it is used by the crossterm's [Command API](./index.html#command-api)
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()>;
|
||||
fn execute_winapi(&self) -> io::Result<()>;
|
||||
|
||||
/// Returns whether the ANSI code representation of this command is supported by windows.
|
||||
///
|
||||
@ -45,7 +43,7 @@ impl<T: Command + ?Sized> Command for &T {
|
||||
|
||||
#[inline]
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
T::execute_winapi(self)
|
||||
}
|
||||
|
||||
@ -59,13 +57,13 @@ impl<T: Command + ?Sized> Command for &T {
|
||||
/// An interface for types that can queue commands for further execution.
|
||||
pub trait QueueableCommand {
|
||||
/// Queues the given command for further execution.
|
||||
fn queue(&mut self, command: impl Command) -> Result<&mut Self>;
|
||||
fn queue(&mut self, command: impl Command) -> io::Result<&mut Self>;
|
||||
}
|
||||
|
||||
/// An interface for types that can directly execute commands.
|
||||
pub trait ExecutableCommand {
|
||||
/// Executes the given command directly.
|
||||
fn execute(&mut self, command: impl Command) -> Result<&mut Self>;
|
||||
fn execute(&mut self, command: impl Command) -> io::Result<&mut Self>;
|
||||
}
|
||||
|
||||
impl<T: Write + ?Sized> QueueableCommand for T {
|
||||
@ -86,12 +84,11 @@ impl<T: Write + ?Sized> QueueableCommand for T {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{Write, stdout};
|
||||
/// use std::io::{self, Write};
|
||||
/// use crossterm::{QueueableCommand, style::Print};
|
||||
///
|
||||
/// use crossterm::{Result, QueueableCommand, style::Print};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// let mut stdout = stdout();
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// let mut stdout = io::stdout();
|
||||
///
|
||||
/// // `Print` will executed executed when `flush` is called.
|
||||
/// stdout
|
||||
@ -121,7 +118,7 @@ impl<T: Write + ?Sized> QueueableCommand for T {
|
||||
/// and can therefore not be written to the given `writer`.
|
||||
/// Therefore, there is no difference between [execute](./trait.ExecutableCommand.html)
|
||||
/// and [queue](./trait.QueueableCommand.html) for those old Windows versions.
|
||||
fn queue(&mut self, command: impl Command) -> Result<&mut Self> {
|
||||
fn queue(&mut self, command: impl Command) -> io::Result<&mut Self> {
|
||||
#[cfg(windows)]
|
||||
if !command.is_ansi_code_supported() {
|
||||
// There may be queued commands in this writer, but `execute_winapi` will execute the
|
||||
@ -151,13 +148,12 @@ impl<T: Write + ?Sized> ExecutableCommand for T {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{Write, stdout};
|
||||
/// use std::io;
|
||||
/// use crossterm::{ExecutableCommand, style::Print};
|
||||
///
|
||||
/// use crossterm::{Result, ExecutableCommand, style::Print};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// // will be executed directly
|
||||
/// stdout()
|
||||
/// io::stdout()
|
||||
/// .execute(Print("sum:\n".to_string()))?
|
||||
/// .execute(Print(format!("1 + 1= {} ", 1 + 1)))?;
|
||||
///
|
||||
@ -166,7 +162,7 @@ impl<T: Write + ?Sized> ExecutableCommand for T {
|
||||
/// // ==== Output ====
|
||||
/// // sum:
|
||||
/// // 1 + 1 = 2
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Have a look over at the [Command API](./index.html#command-api) for more details.
|
||||
@ -179,7 +175,7 @@ impl<T: Write + ?Sized> ExecutableCommand for T {
|
||||
/// and can therefore not be written to the given `writer`.
|
||||
/// Therefore, there is no difference between [execute](./trait.ExecutableCommand.html)
|
||||
/// and [queue](./trait.QueueableCommand.html) for those old Windows versions.
|
||||
fn execute(&mut self, command: impl Command) -> Result<&mut Self> {
|
||||
fn execute(&mut self, command: impl Command) -> io::Result<&mut Self> {
|
||||
self.queue(command)?;
|
||||
self.flush()?;
|
||||
Ok(self)
|
||||
@ -189,7 +185,7 @@ impl<T: Write + ?Sized> ExecutableCommand for T {
|
||||
/// An interface for types that support synchronized updates.
|
||||
pub trait SynchronizedUpdate {
|
||||
/// Performs a set of actions against the given type.
|
||||
fn sync_update<T>(&mut self, operations: impl FnOnce(&mut Self) -> T) -> Result<T>;
|
||||
fn sync_update<T>(&mut self, operations: impl FnOnce(&mut Self) -> T) -> io::Result<T>;
|
||||
}
|
||||
|
||||
impl<W: std::io::Write + ?Sized> SynchronizedUpdate for W {
|
||||
@ -207,19 +203,18 @@ impl<W: std::io::Write + ?Sized> SynchronizedUpdate for W {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{Write, stdout};
|
||||
/// use std::io;
|
||||
/// use crossterm::{ExecutableCommand, SynchronizedUpdate, style::Print};
|
||||
///
|
||||
/// use crossterm::{Result, ExecutableCommand, SynchronizedUpdate, style::Print};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// let mut stdout = stdout();
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// let mut stdout = io::stdout();
|
||||
///
|
||||
/// stdout.sync_update(|stdout| {
|
||||
/// stdout.execute(Print("foo 1\n".to_string()))?;
|
||||
/// stdout.execute(Print("foo 2".to_string()))?;
|
||||
/// // The effects of the print command will not be present in the terminal
|
||||
/// // buffer, but not visible in the terminal.
|
||||
/// crossterm::Result::Ok(())
|
||||
/// std::io::Result::Ok(())
|
||||
/// })?;
|
||||
///
|
||||
/// // The effects of the commands will be visible.
|
||||
@ -247,7 +242,7 @@ impl<W: std::io::Write + ?Sized> SynchronizedUpdate for W {
|
||||
/// again the renderer may fetch the latest screen buffer state again, effectively avoiding the tearing effect
|
||||
/// by unintentionally rendering in the middle a of an application screen update.
|
||||
///
|
||||
fn sync_update<T>(&mut self, operations: impl FnOnce(&mut Self) -> T) -> Result<T> {
|
||||
fn sync_update<T>(&mut self, operations: impl FnOnce(&mut Self) -> T) -> io::Result<T> {
|
||||
self.queue(BeginSynchronizedUpdate)?;
|
||||
let result = operations(self);
|
||||
self.execute(EndSynchronizedUpdate)?;
|
||||
|
@ -13,17 +13,17 @@
|
||||
//! Please have a look at [command documentation](../index.html#command-api) for a more detailed documentation.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use std::io::{self, Write};
|
||||
//!
|
||||
//! use crossterm::{
|
||||
//! ExecutableCommand, execute, Result,
|
||||
//! ExecutableCommand, execute,
|
||||
//! cursor::{DisableBlinking, EnableBlinking, MoveTo, RestorePosition, SavePosition}
|
||||
//! };
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! // with macro
|
||||
//! execute!(
|
||||
//! stdout(),
|
||||
//! io::stdout(),
|
||||
//! SavePosition,
|
||||
//! MoveTo(10, 10),
|
||||
//! EnableBlinking,
|
||||
@ -32,7 +32,7 @@
|
||||
//! );
|
||||
//!
|
||||
//! // with function
|
||||
//! stdout()
|
||||
//! io::stdout()
|
||||
//! .execute(MoveTo(11,11))?
|
||||
//! .execute(RestorePosition);
|
||||
//!
|
||||
@ -44,8 +44,6 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(windows)]
|
||||
use crate::Result;
|
||||
use crate::{csi, impl_display, Command};
|
||||
|
||||
pub(crate) mod sys;
|
||||
@ -67,7 +65,7 @@ impl Command for MoveTo {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_to(self.0, self.1)
|
||||
}
|
||||
}
|
||||
@ -89,7 +87,7 @@ impl Command for MoveToNextLine {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
if self.0 != 0 {
|
||||
sys::move_to_next_line(self.0)?;
|
||||
}
|
||||
@ -114,7 +112,7 @@ impl Command for MoveToPreviousLine {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
if self.0 != 0 {
|
||||
sys::move_to_previous_line(self.0)?;
|
||||
}
|
||||
@ -137,7 +135,7 @@ impl Command for MoveToColumn {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_to_column(self.0)
|
||||
}
|
||||
}
|
||||
@ -157,7 +155,7 @@ impl Command for MoveToRow {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_to_row(self.0)
|
||||
}
|
||||
}
|
||||
@ -178,7 +176,7 @@ impl Command for MoveUp {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_up(self.0)
|
||||
}
|
||||
}
|
||||
@ -199,7 +197,7 @@ impl Command for MoveRight {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_right(self.0)
|
||||
}
|
||||
}
|
||||
@ -220,7 +218,7 @@ impl Command for MoveDown {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_down(self.0)
|
||||
}
|
||||
}
|
||||
@ -241,7 +239,7 @@ impl Command for MoveLeft {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::move_left(self.0)
|
||||
}
|
||||
}
|
||||
@ -263,7 +261,7 @@ impl Command for SavePosition {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::save_position()
|
||||
}
|
||||
}
|
||||
@ -285,7 +283,7 @@ impl Command for RestorePosition {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::restore_position()
|
||||
}
|
||||
}
|
||||
@ -304,7 +302,7 @@ impl Command for Hide {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::show_cursor(false)
|
||||
}
|
||||
}
|
||||
@ -323,7 +321,7 @@ impl Command for Show {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::show_cursor(true)
|
||||
}
|
||||
}
|
||||
@ -342,7 +340,7 @@ impl Command for EnableBlinking {
|
||||
f.write_str(csi!("?12h"))
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -361,7 +359,7 @@ impl Command for DisableBlinking {
|
||||
f.write_str(csi!("?12l"))
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -404,7 +402,7 @@ impl Command for SetCursorStyle {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use std::{
|
||||
use crate::{
|
||||
event::{filter::CursorPositionFilter, poll_internal, read_internal, InternalEvent},
|
||||
terminal::{disable_raw_mode, enable_raw_mode, sys::is_raw_mode_enabled},
|
||||
Result,
|
||||
};
|
||||
|
||||
/// Returns the cursor position (column, row).
|
||||
@ -15,7 +14,7 @@ use crate::{
|
||||
///
|
||||
/// On unix systems, this function will block and possibly time out while
|
||||
/// [`crossterm::event::read`](crate::event::read) or [`crossterm::event::poll`](crate::event::poll) are being called.
|
||||
pub fn position() -> Result<(u16, u16)> {
|
||||
pub fn position() -> io::Result<(u16, u16)> {
|
||||
if is_raw_mode_enabled() {
|
||||
read_position_raw()
|
||||
} else {
|
||||
@ -23,14 +22,14 @@ pub fn position() -> Result<(u16, u16)> {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_position() -> Result<(u16, u16)> {
|
||||
fn read_position() -> io::Result<(u16, u16)> {
|
||||
enable_raw_mode()?;
|
||||
let pos = read_position_raw();
|
||||
disable_raw_mode()?;
|
||||
pos
|
||||
}
|
||||
|
||||
fn read_position_raw() -> Result<(u16, u16)> {
|
||||
fn read_position_raw() -> io::Result<(u16, u16)> {
|
||||
// Use `ESC [ 6 n` to and retrieve the cursor position.
|
||||
let mut stdout = io::stdout();
|
||||
stdout.write_all(b"\x1B[6n")?;
|
||||
|
@ -10,8 +10,6 @@ use winapi::{
|
||||
um::wincon::{SetConsoleCursorInfo, SetConsoleCursorPosition, CONSOLE_CURSOR_INFO, COORD},
|
||||
};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// The position of the cursor, written when you save the cursor's position.
|
||||
///
|
||||
/// This is `u64::MAX` initially. Otherwise, it stores the cursor's x position bit-shifted left 16
|
||||
@ -21,7 +19,7 @@ static SAVED_CURSOR_POS: AtomicU64 = AtomicU64::new(u64::MAX);
|
||||
// The 'y' position of the cursor is not relative to the window but absolute to screen buffer.
|
||||
// We can calculate the relative cursor position by subtracting the top position of the terminal window from the y position.
|
||||
// This results in an 1-based coord zo subtract 1 to make cursor position 0-based.
|
||||
pub fn parse_relative_y(y: i16) -> Result<i16> {
|
||||
pub fn parse_relative_y(y: i16) -> std::io::Result<i16> {
|
||||
let window = ScreenBuffer::current()?.info()?;
|
||||
|
||||
let window_size = window.terminal_window();
|
||||
@ -37,7 +35,7 @@ pub fn parse_relative_y(y: i16) -> Result<i16> {
|
||||
/// Returns the cursor position (column, row).
|
||||
///
|
||||
/// The top left cell is represented `0,0`.
|
||||
pub fn position() -> Result<(u16, u16)> {
|
||||
pub fn position() -> io::Result<(u16, u16)> {
|
||||
let cursor = ScreenBufferCursor::output()?;
|
||||
let mut position = cursor.position()?;
|
||||
// if position.y != 0 {
|
||||
@ -46,70 +44,70 @@ pub fn position() -> Result<(u16, u16)> {
|
||||
Ok(position.into())
|
||||
}
|
||||
|
||||
pub(crate) fn show_cursor(show_cursor: bool) -> Result<()> {
|
||||
pub(crate) fn show_cursor(show_cursor: bool) -> std::io::Result<()> {
|
||||
ScreenBufferCursor::from(Handle::current_out_handle()?).set_visibility(show_cursor)
|
||||
}
|
||||
|
||||
pub(crate) fn move_to(column: u16, row: u16) -> Result<()> {
|
||||
pub(crate) fn move_to(column: u16, row: u16) -> std::io::Result<()> {
|
||||
let cursor = ScreenBufferCursor::output()?;
|
||||
cursor.move_to(column as i16, row as i16)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_up(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_up(count: u16) -> std::io::Result<()> {
|
||||
let (column, row) = position()?;
|
||||
move_to(column, row - count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_right(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_right(count: u16) -> std::io::Result<()> {
|
||||
let (column, row) = position()?;
|
||||
move_to(column + count, row)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_down(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_down(count: u16) -> std::io::Result<()> {
|
||||
let (column, row) = position()?;
|
||||
move_to(column, row + count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_left(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_left(count: u16) -> std::io::Result<()> {
|
||||
let (column, row) = position()?;
|
||||
move_to(column - count, row)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_to_column(new_column: u16) -> Result<()> {
|
||||
pub(crate) fn move_to_column(new_column: u16) -> std::io::Result<()> {
|
||||
let (_, row) = position()?;
|
||||
move_to(new_column, row)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_to_row(new_row: u16) -> Result<()> {
|
||||
pub(crate) fn move_to_row(new_row: u16) -> std::io::Result<()> {
|
||||
let (col, _) = position()?;
|
||||
move_to(col, new_row)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_to_next_line(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_to_next_line(count: u16) -> std::io::Result<()> {
|
||||
let (_, row) = position()?;
|
||||
move_to(0, row + count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn move_to_previous_line(count: u16) -> Result<()> {
|
||||
pub(crate) fn move_to_previous_line(count: u16) -> std::io::Result<()> {
|
||||
let (_, row) = position()?;
|
||||
move_to(0, row - count)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn save_position() -> Result<()> {
|
||||
pub(crate) fn save_position() -> std::io::Result<()> {
|
||||
ScreenBufferCursor::output()?.save_position()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn restore_position() -> Result<()> {
|
||||
pub(crate) fn restore_position() -> std::io::Result<()> {
|
||||
ScreenBufferCursor::output()?.restore_position()?;
|
||||
Ok(())
|
||||
}
|
||||
@ -120,17 +118,17 @@ struct ScreenBufferCursor {
|
||||
}
|
||||
|
||||
impl ScreenBufferCursor {
|
||||
fn output() -> Result<ScreenBufferCursor> {
|
||||
fn output() -> std::io::Result<ScreenBufferCursor> {
|
||||
Ok(ScreenBufferCursor {
|
||||
screen_buffer: ScreenBuffer::from(Handle::new(HandleType::CurrentOutputHandle)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn position(&self) -> Result<Coord> {
|
||||
fn position(&self) -> std::io::Result<Coord> {
|
||||
Ok(self.screen_buffer.info()?.cursor_pos())
|
||||
}
|
||||
|
||||
fn move_to(&self, x: i16, y: i16) -> Result<()> {
|
||||
fn move_to(&self, x: i16, y: i16) -> std::io::Result<()> {
|
||||
if x < 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
@ -160,7 +158,7 @@ impl ScreenBufferCursor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_visibility(&self, visible: bool) -> Result<()> {
|
||||
fn set_visibility(&self, visible: bool) -> std::io::Result<()> {
|
||||
let cursor_info = CONSOLE_CURSOR_INFO {
|
||||
dwSize: 100,
|
||||
bVisible: if visible { TRUE } else { FALSE },
|
||||
@ -179,7 +177,7 @@ impl ScreenBufferCursor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn restore_position(&self) -> Result<()> {
|
||||
fn restore_position(&self) -> std::io::Result<()> {
|
||||
if let Ok(val) = u32::try_from(SAVED_CURSOR_POS.load(Ordering::Relaxed)) {
|
||||
let x = (val >> 16) as i16;
|
||||
let y = val as i16;
|
||||
@ -189,7 +187,7 @@ impl ScreenBufferCursor {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn save_position(&self) -> Result<()> {
|
||||
fn save_position(&self) -> std::io::Result<()> {
|
||||
let position = self.position()?;
|
||||
|
||||
let bits = u64::from(u32::from(position.x as u16) << 16 | u32::from(position.y as u16));
|
||||
|
@ -1,8 +0,0 @@
|
||||
//! Module containing error handling logic.
|
||||
|
||||
use std::io;
|
||||
|
||||
/// The `crossterm` result type.
|
||||
pub type Result<T> = std::result::Result<T, ErrorKind>;
|
||||
|
||||
pub type ErrorKind = io::Error;
|
53
src/event.rs
53
src/event.rs
@ -30,7 +30,7 @@
|
||||
//! ```no_run
|
||||
//! use crossterm::event::{read, Event};
|
||||
//!
|
||||
//! fn print_events() -> crossterm::Result<()> {
|
||||
//! fn print_events() -> std::io::Result<()> {
|
||||
//! loop {
|
||||
//! // `read()` blocks until an `Event` is available
|
||||
//! match read()? {
|
||||
@ -50,11 +50,11 @@
|
||||
//! Non-blocking read:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::time::Duration;
|
||||
//! use std::{time::Duration, io};
|
||||
//!
|
||||
//! use crossterm::event::{poll, read, Event};
|
||||
//!
|
||||
//! fn print_events() -> crossterm::Result<()> {
|
||||
//! fn print_events() -> io::Result<()> {
|
||||
//! loop {
|
||||
//! // `poll()` waits for an `Event` for a given time period
|
||||
//! if poll(Duration::from_millis(500))? {
|
||||
@ -141,11 +141,10 @@ fn try_lock_internal_event_reader_for(
|
||||
/// Return immediately:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::time::Duration;
|
||||
/// use std::{time::Duration, io};
|
||||
/// use crossterm::{event::poll};
|
||||
///
|
||||
/// use crossterm::{event::poll, Result};
|
||||
///
|
||||
/// fn is_event_available() -> Result<bool> {
|
||||
/// fn is_event_available() -> io::Result<bool> {
|
||||
/// // Zero duration says that the `poll` function must return immediately
|
||||
/// // with an `Event` availability information
|
||||
/// poll(Duration::from_secs(0))
|
||||
@ -155,17 +154,17 @@ fn try_lock_internal_event_reader_for(
|
||||
/// Wait up to 100ms:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::time::Duration;
|
||||
/// use std::{time::Duration, io};
|
||||
///
|
||||
/// use crossterm::{event::poll, Result};
|
||||
/// use crossterm::event::poll;
|
||||
///
|
||||
/// fn is_event_available() -> Result<bool> {
|
||||
/// fn is_event_available() -> io::Result<bool> {
|
||||
/// // Wait for an `Event` availability for 100ms. It returns immediately
|
||||
/// // if an `Event` is/becomes available.
|
||||
/// poll(Duration::from_millis(100))
|
||||
/// }
|
||||
/// ```
|
||||
pub fn poll(timeout: Duration) -> crate::Result<bool> {
|
||||
pub fn poll(timeout: Duration) -> std::io::Result<bool> {
|
||||
poll_internal(Some(timeout), &EventFilter)
|
||||
}
|
||||
|
||||
@ -179,9 +178,10 @@ pub fn poll(timeout: Duration) -> crate::Result<bool> {
|
||||
/// Blocking read:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use crossterm::{event::read, Result};
|
||||
/// use crossterm::event::read;
|
||||
/// use std::io;
|
||||
///
|
||||
/// fn print_events() -> Result<bool> {
|
||||
/// fn print_events() -> io::Result<bool> {
|
||||
/// loop {
|
||||
/// // Blocks until an `Event` is available
|
||||
/// println!("{:?}", read()?);
|
||||
@ -193,10 +193,11 @@ pub fn poll(timeout: Duration) -> crate::Result<bool> {
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::time::Duration;
|
||||
/// use std::io;
|
||||
///
|
||||
/// use crossterm::{event::{read, poll}, Result};
|
||||
/// use crossterm::event::{read, poll};
|
||||
///
|
||||
/// fn print_events() -> Result<bool> {
|
||||
/// fn print_events() -> io::Result<bool> {
|
||||
/// loop {
|
||||
/// if poll(Duration::from_millis(100))? {
|
||||
/// // It's guaranteed that `read` won't block, because `poll` returned
|
||||
@ -208,7 +209,7 @@ pub fn poll(timeout: Duration) -> crate::Result<bool> {
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read() -> crate::Result<Event> {
|
||||
pub fn read() -> std::io::Result<Event> {
|
||||
match read_internal(&EventFilter)? {
|
||||
InternalEvent::Event(event) => Ok(event),
|
||||
#[cfg(unix)]
|
||||
@ -217,7 +218,7 @@ pub fn read() -> crate::Result<Event> {
|
||||
}
|
||||
|
||||
/// Polls to check if there are any `InternalEvent`s that can be read within the given duration.
|
||||
pub(crate) fn poll_internal<F>(timeout: Option<Duration>, filter: &F) -> crate::Result<bool>
|
||||
pub(crate) fn poll_internal<F>(timeout: Option<Duration>, filter: &F) -> std::io::Result<bool>
|
||||
where
|
||||
F: Filter,
|
||||
{
|
||||
@ -235,7 +236,7 @@ where
|
||||
}
|
||||
|
||||
/// Reads a single `InternalEvent`.
|
||||
pub(crate) fn read_internal<F>(filter: &F) -> crate::Result<InternalEvent>
|
||||
pub(crate) fn read_internal<F>(filter: &F) -> std::io::Result<InternalEvent>
|
||||
where
|
||||
F: Filter,
|
||||
{
|
||||
@ -296,7 +297,7 @@ impl Command for EnableMouseCapture {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::windows::enable_mouse_capture()
|
||||
}
|
||||
|
||||
@ -325,7 +326,7 @@ impl Command for DisableMouseCapture {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::windows::disable_mouse_capture()
|
||||
}
|
||||
|
||||
@ -349,7 +350,7 @@ impl Command for EnableFocusChange {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
// Focus events are always enabled on Windows
|
||||
Ok(())
|
||||
}
|
||||
@ -365,7 +366,7 @@ impl Command for DisableFocusChange {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
// Focus events can't be disabled on Windows
|
||||
Ok(())
|
||||
}
|
||||
@ -388,7 +389,7 @@ impl Command for EnableBracketedPaste {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Unsupported,
|
||||
"Bracketed paste not implemented in the legacy Windows API.",
|
||||
@ -408,7 +409,7 @@ impl Command for DisableBracketedPaste {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -458,7 +459,7 @@ impl Command for PushKeyboardEnhancementFlags {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
use std::io;
|
||||
|
||||
Err(io::Error::new(
|
||||
@ -487,7 +488,7 @@ impl Command for PopKeyboardEnhancementFlags {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> crate::Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
use std::io;
|
||||
|
||||
Err(io::Error::new(
|
||||
|
@ -7,7 +7,6 @@ use crate::event::source::windows::WindowsEventSource;
|
||||
#[cfg(feature = "event-stream")]
|
||||
use crate::event::sys::Waker;
|
||||
use crate::event::{filter::Filter, source::EventSource, timeout::PollTimeout, InternalEvent};
|
||||
use crate::Result;
|
||||
|
||||
/// Can be used to read `InternalEvent`s.
|
||||
pub(crate) struct InternalEventReader {
|
||||
@ -40,7 +39,7 @@ impl InternalEventReader {
|
||||
self.source.as_ref().expect("reader source not set").waker()
|
||||
}
|
||||
|
||||
pub(crate) fn poll<F>(&mut self, timeout: Option<Duration>, filter: &F) -> Result<bool>
|
||||
pub(crate) fn poll<F>(&mut self, timeout: Option<Duration>, filter: &F) -> io::Result<bool>
|
||||
where
|
||||
F: Filter,
|
||||
{
|
||||
@ -95,7 +94,7 @@ impl InternalEventReader {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read<F>(&mut self, filter: &F) -> Result<InternalEvent>
|
||||
pub(crate) fn read<F>(&mut self, filter: &F) -> io::Result<InternalEvent>
|
||||
where
|
||||
F: Filter,
|
||||
{
|
||||
@ -131,8 +130,6 @@ mod tests {
|
||||
use std::io;
|
||||
use std::{collections::VecDeque, time::Duration};
|
||||
|
||||
use crate::ErrorKind;
|
||||
|
||||
#[cfg(unix)]
|
||||
use super::super::filter::CursorPositionFilter;
|
||||
use super::{
|
||||
@ -312,11 +309,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_poll_propagates_error() {
|
||||
let source = FakeSource::with_error(ErrorKind::from(io::ErrorKind::Other));
|
||||
|
||||
let mut reader = InternalEventReader {
|
||||
events: VecDeque::new(),
|
||||
source: Some(Box::new(source)),
|
||||
source: Some(Box::new(FakeSource::new(&[]))),
|
||||
skipped_events: Vec::with_capacity(32),
|
||||
};
|
||||
|
||||
@ -324,18 +319,16 @@ mod tests {
|
||||
reader
|
||||
.poll(Some(Duration::from_secs(0)), &InternalEventFilter)
|
||||
.err()
|
||||
.map(|e| format!("{:?}", &e)),
|
||||
Some(format!("{:?}", ErrorKind::from(io::ErrorKind::Other)))
|
||||
.map(|e| format!("{:?}", &e.kind())),
|
||||
Some(format!("{:?}", io::ErrorKind::Other))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_propagates_error() {
|
||||
let source = FakeSource::with_error(ErrorKind::from(io::ErrorKind::Other));
|
||||
|
||||
let mut reader = InternalEventReader {
|
||||
events: VecDeque::new(),
|
||||
source: Some(Box::new(source)),
|
||||
source: Some(Box::new(FakeSource::new(&[]))),
|
||||
skipped_events: Vec::with_capacity(32),
|
||||
};
|
||||
|
||||
@ -343,8 +336,8 @@ mod tests {
|
||||
reader
|
||||
.read(&InternalEventFilter)
|
||||
.err()
|
||||
.map(|e| format!("{:?}", &e)),
|
||||
Some(format!("{:?}", ErrorKind::from(io::ErrorKind::Other)))
|
||||
.map(|e| format!("{:?}", &e.kind())),
|
||||
Some(format!("{:?}", io::ErrorKind::Other))
|
||||
);
|
||||
}
|
||||
|
||||
@ -352,7 +345,7 @@ mod tests {
|
||||
fn test_poll_continues_after_error() {
|
||||
const EVENT: InternalEvent = InternalEvent::Event(Event::Resize(10, 10));
|
||||
|
||||
let source = FakeSource::new(&[EVENT, EVENT], ErrorKind::from(io::ErrorKind::Other));
|
||||
let source = FakeSource::new(&[EVENT, EVENT]);
|
||||
|
||||
let mut reader = InternalEventReader {
|
||||
events: VecDeque::new(),
|
||||
@ -371,7 +364,7 @@ mod tests {
|
||||
fn test_read_continues_after_error() {
|
||||
const EVENT: InternalEvent = InternalEvent::Event(Event::Resize(10, 10));
|
||||
|
||||
let source = FakeSource::new(&[EVENT, EVENT], ErrorKind::from(io::ErrorKind::Other));
|
||||
let source = FakeSource::new(&[EVENT, EVENT]);
|
||||
|
||||
let mut reader = InternalEventReader {
|
||||
events: VecDeque::new(),
|
||||
@ -387,14 +380,14 @@ mod tests {
|
||||
#[derive(Default)]
|
||||
struct FakeSource {
|
||||
events: VecDeque<InternalEvent>,
|
||||
error: Option<ErrorKind>,
|
||||
error: Option<io::Error>,
|
||||
}
|
||||
|
||||
impl FakeSource {
|
||||
fn new(events: &[InternalEvent], error: ErrorKind) -> FakeSource {
|
||||
fn new(events: &[InternalEvent]) -> FakeSource {
|
||||
FakeSource {
|
||||
events: events.to_vec().into(),
|
||||
error: Some(error),
|
||||
error: Some(io::Error::new(io::ErrorKind::Other, "")),
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,20 +397,10 @@ mod tests {
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn with_error(error: ErrorKind) -> FakeSource {
|
||||
FakeSource {
|
||||
events: VecDeque::new(),
|
||||
error: Some(error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventSource for FakeSource {
|
||||
fn try_read(
|
||||
&mut self,
|
||||
_timeout: Option<Duration>,
|
||||
) -> Result<Option<InternalEvent>, ErrorKind> {
|
||||
fn try_read(&mut self, _timeout: Option<Duration>) -> io::Result<Option<InternalEvent>> {
|
||||
// Return error if set in case there's just one remaining event
|
||||
if self.events.len() == 1 {
|
||||
if let Some(error) = self.error.take() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::time::Duration;
|
||||
use std::{io, time::Duration};
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
use super::sys::Waker;
|
||||
@ -19,7 +19,7 @@ pub(crate) trait EventSource: Sync + Send {
|
||||
/// for the given timeout
|
||||
///
|
||||
/// Returns `Ok(None)` if there's no event available and timeout expires.
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> crate::Result<Option<InternalEvent>>;
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> io::Result<Option<InternalEvent>>;
|
||||
|
||||
/// Returns a `Waker` allowing to wake/force the `try_read` method to return `Ok(None)`.
|
||||
#[cfg(feature = "event-stream")]
|
||||
|
@ -3,8 +3,6 @@ use std::{collections::VecDeque, io, time::Duration};
|
||||
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
|
||||
use signal_hook_mio::v0_8::Signals;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
use crate::event::sys::Waker;
|
||||
use crate::event::{
|
||||
@ -35,11 +33,11 @@ pub(crate) struct UnixInternalEventSource {
|
||||
}
|
||||
|
||||
impl UnixInternalEventSource {
|
||||
pub fn new() -> Result<Self> {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
UnixInternalEventSource::from_file_descriptor(tty_fd()?)
|
||||
}
|
||||
|
||||
pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> Result<Self> {
|
||||
pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> io::Result<Self> {
|
||||
let poll = Poll::new()?;
|
||||
let registry = poll.registry();
|
||||
|
||||
@ -67,7 +65,7 @@ impl UnixInternalEventSource {
|
||||
}
|
||||
|
||||
impl EventSource for UnixInternalEventSource {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> Result<Option<InternalEvent>> {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> io::Result<Option<InternalEvent>> {
|
||||
if let Some(event) = self.parser.next() {
|
||||
return Ok(Some(event));
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ use signal_hook::low_level::pipe;
|
||||
|
||||
use crate::event::timeout::PollTimeout;
|
||||
use crate::event::Event;
|
||||
use crate::Result;
|
||||
|
||||
use filedescriptor::{poll, pollfd, POLLIN};
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
@ -23,7 +21,7 @@ struct WakePipe {
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
impl WakePipe {
|
||||
fn new() -> Result<Self> {
|
||||
fn new() -> io::Result<Self> {
|
||||
let (receiver, sender) = nonblocking_unix_pair()?;
|
||||
Ok(WakePipe {
|
||||
receiver,
|
||||
@ -46,7 +44,7 @@ pub(crate) struct UnixInternalEventSource {
|
||||
wake_pipe: WakePipe,
|
||||
}
|
||||
|
||||
fn nonblocking_unix_pair() -> Result<(UnixStream, UnixStream)> {
|
||||
fn nonblocking_unix_pair() -> io::Result<(UnixStream, UnixStream)> {
|
||||
let (receiver, sender) = UnixStream::pair()?;
|
||||
receiver.set_nonblocking(true)?;
|
||||
sender.set_nonblocking(true)?;
|
||||
@ -54,11 +52,11 @@ fn nonblocking_unix_pair() -> Result<(UnixStream, UnixStream)> {
|
||||
}
|
||||
|
||||
impl UnixInternalEventSource {
|
||||
pub fn new() -> Result<Self> {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
UnixInternalEventSource::from_file_descriptor(tty_fd()?)
|
||||
}
|
||||
|
||||
pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> Result<Self> {
|
||||
pub(crate) fn from_file_descriptor(input_fd: FileDesc) -> io::Result<Self> {
|
||||
Ok(UnixInternalEventSource {
|
||||
parser: Parser::default(),
|
||||
tty_buffer: [0u8; TTY_BUFFER_SIZE],
|
||||
@ -80,7 +78,7 @@ impl UnixInternalEventSource {
|
||||
///
|
||||
/// Similar to `std::io::Read::read_to_end`, except this function
|
||||
/// only fills the given buffer and does not read beyond that.
|
||||
fn read_complete(fd: &FileDesc, buf: &mut [u8]) -> Result<usize> {
|
||||
fn read_complete(fd: &FileDesc, buf: &mut [u8]) -> io::Result<usize> {
|
||||
loop {
|
||||
match fd.read(buf, buf.len()) {
|
||||
Ok(x) => return Ok(x),
|
||||
@ -94,7 +92,7 @@ fn read_complete(fd: &FileDesc, buf: &mut [u8]) -> Result<usize> {
|
||||
}
|
||||
|
||||
impl EventSource for UnixInternalEventSource {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> Result<Option<InternalEvent>> {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> io::Result<Option<InternalEvent>> {
|
||||
let timeout = PollTimeout::new(timeout);
|
||||
|
||||
fn make_pollfd<F: AsRawFd>(fd: &F) -> pollfd {
|
||||
|
@ -24,7 +24,7 @@ pub(crate) struct WindowsEventSource {
|
||||
}
|
||||
|
||||
impl WindowsEventSource {
|
||||
pub(crate) fn new() -> crate::Result<WindowsEventSource> {
|
||||
pub(crate) fn new() -> std::io::Result<WindowsEventSource> {
|
||||
let console = Console::from(Handle::current_in_handle()?);
|
||||
Ok(WindowsEventSource {
|
||||
console,
|
||||
@ -41,7 +41,7 @@ impl WindowsEventSource {
|
||||
}
|
||||
|
||||
impl EventSource for WindowsEventSource {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> crate::Result<Option<InternalEvent>> {
|
||||
fn try_read(&mut self, timeout: Option<Duration>) -> std::io::Result<Option<InternalEvent>> {
|
||||
let poll_timeout = PollTimeout::new(timeout);
|
||||
|
||||
loop {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
io,
|
||||
pin::Pin,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@ -12,8 +13,6 @@ use std::{
|
||||
|
||||
use futures_core::stream::Stream;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
use crate::event::{
|
||||
filter::EventFilter, lock_internal_event_reader, poll_internal, read_internal, sys::Waker,
|
||||
Event, InternalEvent,
|
||||
@ -100,7 +99,7 @@ struct Task {
|
||||
// We have to wake up the poll_internal (force it to return Ok(false)) and quit
|
||||
// the thread before we drop.
|
||||
impl Stream for EventStream {
|
||||
type Item = Result<Event>;
|
||||
type Item = io::Result<Event>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let result = match poll_internal(Some(Duration::from_secs(0)), &EventFilter) {
|
||||
|
@ -1,12 +1,8 @@
|
||||
use std::io;
|
||||
|
||||
use crate::{
|
||||
event::{
|
||||
Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers,
|
||||
KeyboardEnhancementFlags, MediaKeyCode, ModifierKeyCode, MouseButton, MouseEvent,
|
||||
MouseEventKind,
|
||||
},
|
||||
ErrorKind, Result,
|
||||
use crate::event::{
|
||||
Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers, KeyboardEnhancementFlags,
|
||||
MediaKeyCode, ModifierKeyCode, MouseButton, MouseEvent, MouseEventKind,
|
||||
};
|
||||
|
||||
use super::super::super::InternalEvent;
|
||||
@ -23,11 +19,14 @@ use super::super::super::InternalEvent;
|
||||
// Ok(Some(event)) -> we have event, clear the buffer
|
||||
//
|
||||
|
||||
fn could_not_parse_event_error() -> ErrorKind {
|
||||
fn could_not_parse_event_error() -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, "Could not parse an event.")
|
||||
}
|
||||
|
||||
pub(crate) fn parse_event(buffer: &[u8], input_available: bool) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_event(
|
||||
buffer: &[u8],
|
||||
input_available: bool,
|
||||
) -> io::Result<Option<InternalEvent>> {
|
||||
if buffer.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
@ -135,7 +134,7 @@ fn char_code_to_event(code: KeyCode) -> KeyEvent {
|
||||
KeyEvent::new(code, modifiers)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
|
||||
|
||||
if buffer.len() == 2 {
|
||||
@ -214,7 +213,7 @@ pub(crate) fn parse_csi(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
Ok(input_event.map(InternalEvent::Event))
|
||||
}
|
||||
|
||||
pub(crate) fn next_parsed<T>(iter: &mut dyn Iterator<Item = &str>) -> Result<T>
|
||||
pub(crate) fn next_parsed<T>(iter: &mut dyn Iterator<Item = &str>) -> io::Result<T>
|
||||
where
|
||||
T: std::str::FromStr,
|
||||
{
|
||||
@ -224,7 +223,7 @@ where
|
||||
.map_err(|_| could_not_parse_event_error())
|
||||
}
|
||||
|
||||
fn modifier_and_kind_parsed(iter: &mut dyn Iterator<Item = &str>) -> Result<(u8, u8)> {
|
||||
fn modifier_and_kind_parsed(iter: &mut dyn Iterator<Item = &str>) -> io::Result<(u8, u8)> {
|
||||
let mut sub_split = iter
|
||||
.next()
|
||||
.ok_or_else(could_not_parse_event_error)?
|
||||
@ -239,7 +238,7 @@ fn modifier_and_kind_parsed(iter: &mut dyn Iterator<Item = &str>) -> Result<(u8,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_cursor_position(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_cursor_position(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// ESC [ Cy ; Cx R
|
||||
// Cy - cursor row number (starting from 1)
|
||||
// Cx - cursor column number (starting from 1)
|
||||
@ -257,7 +256,7 @@ pub(crate) fn parse_csi_cursor_position(buffer: &[u8]) -> Result<Option<Internal
|
||||
Ok(Some(InternalEvent::CursorPosition(x, y)))
|
||||
}
|
||||
|
||||
fn parse_csi_keyboard_enhancement_flags(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
fn parse_csi_keyboard_enhancement_flags(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// ESC [ ? flags u
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'[', b'?'])); // ESC [ ?
|
||||
assert!(buffer.ends_with(&[b'u']));
|
||||
@ -289,7 +288,7 @@ fn parse_csi_keyboard_enhancement_flags(buffer: &[u8]) -> Result<Option<Internal
|
||||
Ok(Some(InternalEvent::KeyboardEnhancementFlags(flags)))
|
||||
}
|
||||
|
||||
fn parse_csi_primary_device_attributes(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
fn parse_csi_primary_device_attributes(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// ESC [ 64 ; attr1 ; attr2 ; ... ; attrn ; c
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'[', b'?']));
|
||||
assert!(buffer.ends_with(&[b'c']));
|
||||
@ -346,7 +345,7 @@ fn parse_key_event_kind(kind: u8) -> KeyEventKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
|
||||
//
|
||||
let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
|
||||
@ -495,7 +494,7 @@ fn translate_functional_key_code(codepoint: u32) -> Option<(KeyCode, KeyEventSta
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
|
||||
assert!(buffer.ends_with(&[b'u']));
|
||||
|
||||
@ -617,7 +616,7 @@ pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> Result<Option<Inter
|
||||
Ok(Some(InternalEvent::Event(input_event)))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_special_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_special_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
|
||||
assert!(buffer.ends_with(&[b'~']));
|
||||
|
||||
@ -661,7 +660,7 @@ pub(crate) fn parse_csi_special_key_code(buffer: &[u8]) -> Result<Option<Interna
|
||||
Ok(Some(InternalEvent::Event(input_event)))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_rxvt_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_rxvt_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// rxvt mouse encoding:
|
||||
// ESC [ Cb ; Cx ; Cy ; M
|
||||
|
||||
@ -688,7 +687,7 @@ pub(crate) fn parse_csi_rxvt_mouse(buffer: &[u8]) -> Result<Option<InternalEvent
|
||||
}))))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_normal_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_normal_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// Normal mouse encoding: ESC [ M CB Cx Cy (6 characters only).
|
||||
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'[', b'M'])); // ESC [ M
|
||||
@ -716,7 +715,7 @@ pub(crate) fn parse_csi_normal_mouse(buffer: &[u8]) -> Result<Option<InternalEve
|
||||
}))))
|
||||
}
|
||||
|
||||
pub(crate) fn parse_csi_sgr_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_sgr_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// ESC [ < Cb ; Cx ; Cy (;) (M or m)
|
||||
|
||||
assert!(buffer.starts_with(&[b'\x1B', b'[', b'<'])); // ESC [ <
|
||||
@ -774,7 +773,7 @@ pub(crate) fn parse_csi_sgr_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>
|
||||
/// - mouse is dragging
|
||||
/// - button number
|
||||
/// - button number
|
||||
fn parse_cb(cb: u8) -> Result<(MouseEventKind, KeyModifiers)> {
|
||||
fn parse_cb(cb: u8) -> io::Result<(MouseEventKind, KeyModifiers)> {
|
||||
let button_number = (cb & 0b0000_0011) | ((cb & 0b1100_0000) >> 4);
|
||||
let dragging = cb & 0b0010_0000 == 0b0010_0000;
|
||||
|
||||
@ -809,7 +808,7 @@ fn parse_cb(cb: u8) -> Result<(MouseEventKind, KeyModifiers)> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "bracketed-paste")]
|
||||
pub(crate) fn parse_csi_bracketed_paste(buffer: &[u8]) -> Result<Option<InternalEvent>> {
|
||||
pub(crate) fn parse_csi_bracketed_paste(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
|
||||
// ESC [ 2 0 0 ~ pasted text ESC 2 0 1 ~
|
||||
assert!(buffer.starts_with(b"\x1B[200~"));
|
||||
|
||||
@ -821,7 +820,7 @@ pub(crate) fn parse_csi_bracketed_paste(buffer: &[u8]) -> Result<Option<Internal
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_utf8_char(buffer: &[u8]) -> Result<Option<char>> {
|
||||
pub(crate) fn parse_utf8_char(buffer: &[u8]) -> io::Result<Option<char>> {
|
||||
match std::str::from_utf8(buffer) {
|
||||
Ok(s) => {
|
||||
let ch = s.chars().next().ok_or_else(could_not_parse_event_error)?;
|
||||
|
@ -2,8 +2,6 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use ::mio::{Registry, Token};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// Allows to wake up the `mio::Poll::poll()` method.
|
||||
/// This type wraps `mio::Waker`, for more information see its documentation.
|
||||
#[derive(Clone, Debug)]
|
||||
@ -13,7 +11,7 @@ pub(crate) struct Waker {
|
||||
|
||||
impl Waker {
|
||||
/// Create a new `Waker`.
|
||||
pub(crate) fn new(registry: &Registry, waker_token: Token) -> Result<Self> {
|
||||
pub(crate) fn new(registry: &Registry, waker_token: Token) -> std::io::Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Arc::new(Mutex::new(mio::Waker::new(registry, waker_token)?)),
|
||||
})
|
||||
@ -22,7 +20,7 @@ impl Waker {
|
||||
/// Wake up the [`Poll`] associated with this `Waker`.
|
||||
///
|
||||
/// Readiness is set to `Ready::readable()`.
|
||||
pub(crate) fn wake(&self) -> Result<()> {
|
||||
pub(crate) fn wake(&self) -> std::io::Result<()> {
|
||||
self.inner.lock().unwrap().wake()
|
||||
}
|
||||
|
||||
@ -30,7 +28,7 @@ impl Waker {
|
||||
///
|
||||
/// This function is not impl
|
||||
#[allow(dead_code, clippy::clippy::unnecessary_wraps)]
|
||||
pub(crate) fn reset(&self) -> Result<()> {
|
||||
pub(crate) fn reset(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
use std::{
|
||||
io::Write,
|
||||
io::{self, Write},
|
||||
os::unix::net::UnixStream,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// Allows to wake up the EventSource::try_read() method.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Waker {
|
||||
@ -23,16 +21,8 @@ impl Waker {
|
||||
/// Wake up the [`Poll`] associated with this `Waker`.
|
||||
///
|
||||
/// Readiness is set to `Ready::readable()`.
|
||||
pub(crate) fn wake(&self) -> Result<()> {
|
||||
pub(crate) fn wake(&self) -> io::Result<()> {
|
||||
self.inner.lock().unwrap().write(&[0])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Resets the state so the same waker can be reused.
|
||||
///
|
||||
/// This function is not impl
|
||||
#[allow(dead_code, clippy::clippy::unnecessary_wraps)]
|
||||
pub(crate) fn reset(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,6 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use crossterm_winapi::{ConsoleMode, Handle};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
pub(crate) mod parse;
|
||||
pub(crate) mod poll;
|
||||
#[cfg(feature = "event-stream")]
|
||||
@ -30,12 +28,12 @@ fn init_original_console_mode(original_mode: u32) {
|
||||
}
|
||||
|
||||
/// Returns the original console color, make sure to call `init_console_color` before calling this function. Otherwise this function will panic.
|
||||
fn original_console_mode() -> Result<u32> {
|
||||
fn original_console_mode() -> std::io::Result<u32> {
|
||||
u32::try_from(ORIGINAL_CONSOLE_MODE.load(Ordering::Relaxed))
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Initial console modes not set"))
|
||||
}
|
||||
|
||||
pub(crate) fn enable_mouse_capture() -> Result<()> {
|
||||
pub(crate) fn enable_mouse_capture() -> std::io::Result<()> {
|
||||
let mode = ConsoleMode::from(Handle::current_in_handle()?);
|
||||
init_original_console_mode(mode.mode()?);
|
||||
mode.set_mode(ENABLE_MOUSE_MODE)?;
|
||||
@ -43,7 +41,7 @@ pub(crate) fn enable_mouse_capture() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn disable_mouse_capture() -> Result<()> {
|
||||
pub(crate) fn disable_mouse_capture() -> std::io::Result<()> {
|
||||
let mode = ConsoleMode::from(Handle::current_in_handle()?);
|
||||
mode.set_mode(original_console_mode()?)?;
|
||||
Ok(())
|
||||
|
@ -12,12 +12,8 @@ use winapi::um::{
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
event::{
|
||||
Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseButton, MouseEvent,
|
||||
MouseEventKind,
|
||||
},
|
||||
Result,
|
||||
use crate::event::{
|
||||
Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseButton, MouseEvent, MouseEventKind,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@ -301,7 +297,7 @@ fn parse_key_event_record(key_event: &KeyEventRecord) -> Option<WindowsKeyEvent>
|
||||
|
||||
// The 'y' position of a mouse event or resize event is not relative to the window but absolute to screen buffer.
|
||||
// This means that when the mouse cursor is at the top left it will be x: 0, y: 2295 (e.g. y = number of cells conting from the absolute buffer height) instead of relative x: 0, y: 0 to the window.
|
||||
pub fn parse_relative_y(y: i16) -> Result<i16> {
|
||||
pub fn parse_relative_y(y: i16) -> std::io::Result<i16> {
|
||||
let window_size = ScreenBuffer::current()?.info()?.terminal_window();
|
||||
Ok(y - window_size.top)
|
||||
}
|
||||
@ -309,7 +305,7 @@ pub fn parse_relative_y(y: i16) -> Result<i16> {
|
||||
fn parse_mouse_event_record(
|
||||
event: &crossterm_winapi::MouseEvent,
|
||||
buttons_pressed: &MouseButtonsPressed,
|
||||
) -> Result<Option<MouseEvent>> {
|
||||
) -> std::io::Result<Option<MouseEvent>> {
|
||||
let modifiers = KeyModifiers::from(&event.control_key_state);
|
||||
|
||||
let xpos = event.mouse_position.x as u16;
|
||||
|
@ -10,8 +10,6 @@ use winapi::{
|
||||
},
|
||||
};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
pub(crate) use super::waker::Waker;
|
||||
|
||||
@ -28,7 +26,7 @@ impl WinApiPoll {
|
||||
}
|
||||
|
||||
#[cfg(feature = "event-stream")]
|
||||
pub(crate) fn new() -> Result<WinApiPoll> {
|
||||
pub(crate) fn new() -> std::io::Result<WinApiPoll> {
|
||||
Ok(WinApiPoll {
|
||||
waker: Waker::new()?,
|
||||
})
|
||||
@ -36,7 +34,7 @@ impl WinApiPoll {
|
||||
}
|
||||
|
||||
impl WinApiPoll {
|
||||
pub fn poll(&mut self, timeout: Option<Duration>) -> Result<Option<bool>> {
|
||||
pub fn poll(&mut self, timeout: Option<Duration>) -> std::io::Result<Option<bool>> {
|
||||
let dw_millis = if let Some(duration) = timeout {
|
||||
duration.as_millis() as u32
|
||||
} else {
|
||||
|
@ -2,8 +2,6 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use crossterm_winapi::Semaphore;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// Allows to wake up the `WinApiPoll::poll()` method.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Waker {
|
||||
@ -15,7 +13,7 @@ impl Waker {
|
||||
///
|
||||
/// `Waker` is based on the `Semaphore`. You have to use the semaphore
|
||||
/// handle along with the `WaitForMultipleObjects`.
|
||||
pub(crate) fn new() -> Result<Self> {
|
||||
pub(crate) fn new() -> std::io::Result<Self> {
|
||||
let inner = Semaphore::new()?;
|
||||
|
||||
Ok(Self {
|
||||
@ -24,13 +22,13 @@ impl Waker {
|
||||
}
|
||||
|
||||
/// Wakes the `WaitForMultipleObjects`.
|
||||
pub(crate) fn wake(&self) -> Result<()> {
|
||||
pub(crate) fn wake(&self) -> std::io::Result<()> {
|
||||
self.inner.lock().unwrap().release()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Replaces the current semaphore with a new one allowing us to reuse the same `Waker`.
|
||||
pub(crate) fn reset(&self) -> Result<()> {
|
||||
pub(crate) fn reset(&self) -> std::io::Result<()> {
|
||||
*self.inner.lock().unwrap() = Semaphore::new()?;
|
||||
Ok(())
|
||||
}
|
||||
|
24
src/lib.rs
24
src/lib.rs
@ -155,7 +155,7 @@
|
||||
//! Macros:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{Write, stdout};
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use crossterm::{execute, ExecutableCommand, cursor};
|
||||
//!
|
||||
//! let mut stdout = stdout();
|
||||
@ -172,14 +172,14 @@
|
||||
//! Functions:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use std::io::{self, Write};
|
||||
//! use crossterm::{
|
||||
//! ExecutableCommand, QueueableCommand,
|
||||
//! terminal, cursor, style::{self, Stylize}, Result
|
||||
//! terminal, cursor, style::{self, Stylize}
|
||||
//! };
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! let mut stdout = stdout();
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! let mut stdout = io::stdout();
|
||||
//!
|
||||
//! stdout.execute(terminal::Clear(terminal::ClearType::All))?;
|
||||
//!
|
||||
@ -201,14 +201,14 @@
|
||||
//! Macros:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use std::io::{self, Write};
|
||||
//! use crossterm::{
|
||||
//! execute, queue,
|
||||
//! style::{self, Stylize}, cursor, terminal, Result
|
||||
//! style::{self, Stylize}, cursor, terminal
|
||||
//! };
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! let mut stdout = stdout();
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! let mut stdout = io::stdout();
|
||||
//!
|
||||
//! execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
|
||||
//!
|
||||
@ -230,10 +230,7 @@
|
||||
//! [stderr]: https://doc.rust-lang.org/std/io/fn.stderr.html
|
||||
//! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
|
||||
|
||||
pub use crate::{
|
||||
command::{Command, ExecutableCommand, QueueableCommand, SynchronizedUpdate},
|
||||
error::{ErrorKind, Result},
|
||||
};
|
||||
pub use crate::command::{Command, ExecutableCommand, QueueableCommand, SynchronizedUpdate};
|
||||
|
||||
/// A module to work with the terminal cursor
|
||||
pub mod cursor;
|
||||
@ -252,7 +249,6 @@ pub mod tty;
|
||||
/// A module that exposes one function to check if the current terminal supports ANSI sequences.
|
||||
pub mod ansi_support;
|
||||
mod command;
|
||||
mod error;
|
||||
pub(crate) mod macros;
|
||||
|
||||
#[cfg(all(windows, not(feature = "windows")))]
|
||||
|
@ -238,11 +238,9 @@ mod tests {
|
||||
use std::fmt;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::FakeWrite;
|
||||
use crate::command::Command;
|
||||
use crate::error::Result as CrosstermResult;
|
||||
|
||||
// We need to test two different APIs: WinAPI and the write api. We
|
||||
// don't know until runtime which we're supporting (via
|
||||
@ -274,7 +272,7 @@ mod tests {
|
||||
f.write_str(self.value)
|
||||
}
|
||||
|
||||
fn execute_winapi(&self) -> CrosstermResult<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
self.stream.borrow_mut().push(self.value);
|
||||
Ok(())
|
||||
}
|
||||
@ -293,9 +291,9 @@ mod tests {
|
||||
// If the stream was populated, it tests that the two arrays are equal.
|
||||
// If the writer was populated, it tests that the contents of the
|
||||
// write buffer are equal to the concatenation of `stream_result`.
|
||||
fn test_harness<E: Debug>(
|
||||
fn test_harness(
|
||||
stream_result: &[&'static str],
|
||||
test: impl FnOnce(&mut FakeWrite, &mut WindowsEventStream) -> Result<(), E>,
|
||||
test: impl FnOnce(&mut FakeWrite, &mut WindowsEventStream) -> std::io::Result<()>,
|
||||
) {
|
||||
let mut stream = WindowsEventStream::default();
|
||||
let mut writer = FakeWrite::default();
|
||||
|
39
src/style.rs
39
src/style.rs
@ -28,14 +28,13 @@
|
||||
//! Using the Command API to color text.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//!
|
||||
//! use crossterm::{execute, Result};
|
||||
//! use std::io::{self, Write};
|
||||
//! use crossterm::execute;
|
||||
//! use crossterm::style::{Print, SetForegroundColor, SetBackgroundColor, ResetColor, Color, Attribute};
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! execute!(
|
||||
//! stdout(),
|
||||
//! io::stdout(),
|
||||
//! // Blue foreground
|
||||
//! SetForegroundColor(Color::Blue),
|
||||
//! // Red background
|
||||
@ -68,14 +67,14 @@
|
||||
//! Using the Command API to set attributes.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use std::io::{self, Write};
|
||||
//!
|
||||
//! use crossterm::{execute, Result, style::Print};
|
||||
//! use crossterm::{execute, style::Print};
|
||||
//! use crossterm::style::{SetAttribute, Attribute};
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! execute!(
|
||||
//! stdout(),
|
||||
//! io::stdout(),
|
||||
//! // Set to bold
|
||||
//! SetAttribute(Attribute::Bold),
|
||||
//! Print("Bold text here.".to_string()),
|
||||
@ -118,8 +117,6 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::command::execute_fmt;
|
||||
#[cfg(windows)]
|
||||
use crate::Result;
|
||||
use crate::{csi, impl_display, Command};
|
||||
|
||||
pub use self::{
|
||||
@ -188,7 +185,7 @@ impl Command for SetForegroundColor {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::windows::set_foreground_color(self.0)
|
||||
}
|
||||
}
|
||||
@ -212,7 +209,7 @@ impl Command for SetBackgroundColor {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::windows::set_background_color(self.0)
|
||||
}
|
||||
}
|
||||
@ -236,7 +233,7 @@ impl Command for SetUnderlineColor {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"SetUnderlineColor not supported by winapi.",
|
||||
@ -280,7 +277,7 @@ impl Command for SetColors {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
if let Some(color) = self.0.foreground {
|
||||
sys::windows::set_foreground_color(color)?;
|
||||
}
|
||||
@ -307,7 +304,7 @@ impl Command for SetAttribute {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
// attributes are not supported by WinAPI.
|
||||
Ok(())
|
||||
}
|
||||
@ -334,7 +331,7 @@ impl Command for SetAttributes {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
// attributes are not supported by WinAPI.
|
||||
Ok(())
|
||||
}
|
||||
@ -367,7 +364,7 @@ impl Command for SetStyle {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
panic!("tried to execute SetStyle command using WinAPI, use ANSI instead");
|
||||
}
|
||||
|
||||
@ -434,7 +431,7 @@ impl<D: Display> Command for PrintStyledContent<D> {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -453,7 +450,7 @@ impl Command for ResetColor {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
sys::windows::reset()
|
||||
}
|
||||
}
|
||||
@ -470,7 +467,7 @@ impl<T: Display> Command for Print<T> {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||
panic!("tried to execute Print command using WinAPI, use ANSI instead");
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,6 @@ use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use crossterm_winapi::{Console, Handle, HandleType, ScreenBuffer};
|
||||
use winapi::um::wincon;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
use super::super::{Color, Colored};
|
||||
|
||||
const FG_GREEN: u16 = wincon::FOREGROUND_GREEN;
|
||||
@ -18,7 +16,7 @@ const BG_RED: u16 = wincon::BACKGROUND_RED;
|
||||
const BG_BLUE: u16 = wincon::BACKGROUND_BLUE;
|
||||
const BG_INTENSITY: u16 = wincon::BACKGROUND_INTENSITY;
|
||||
|
||||
pub(crate) fn set_foreground_color(fg_color: Color) -> Result<()> {
|
||||
pub(crate) fn set_foreground_color(fg_color: Color) -> std::io::Result<()> {
|
||||
init_console_color()?;
|
||||
|
||||
let color_value: u16 = Colored::ForegroundColor(fg_color).into();
|
||||
@ -42,7 +40,7 @@ pub(crate) fn set_foreground_color(fg_color: Color) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_background_color(bg_color: Color) -> Result<()> {
|
||||
pub(crate) fn set_background_color(bg_color: Color) -> std::io::Result<()> {
|
||||
init_console_color()?;
|
||||
|
||||
let color_value: u16 = Colored::BackgroundColor(bg_color).into();
|
||||
@ -66,7 +64,7 @@ pub(crate) fn set_background_color(bg_color: Color) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn reset() -> Result<()> {
|
||||
pub(crate) fn reset() -> std::io::Result<()> {
|
||||
if let Ok(original_color) = u16::try_from(ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed)) {
|
||||
Console::from(Handle::new(HandleType::CurrentOutputHandle)?)
|
||||
.set_text_attribute(original_color)?;
|
||||
@ -76,7 +74,7 @@ pub(crate) fn reset() -> Result<()> {
|
||||
}
|
||||
|
||||
/// Initializes the default console color. It will will be skipped if it has already been initialized.
|
||||
pub(crate) fn init_console_color() -> Result<()> {
|
||||
pub(crate) fn init_console_color() -> std::io::Result<()> {
|
||||
if ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed) == u32::MAX {
|
||||
let screen_buffer = ScreenBuffer::current()?;
|
||||
let attr = screen_buffer.info()?.attributes();
|
||||
|
@ -154,7 +154,7 @@ Attribute! {
|
||||
}
|
||||
|
||||
impl Display for Attribute {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", SetAttribute(*self))?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use std::{convert::AsRef, convert::TryFrom, result::Result, str::FromStr};
|
||||
use std::{
|
||||
convert::{AsRef, TryFrom},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use std::fmt;
|
||||
|
@ -63,27 +63,27 @@
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::io::{stdout, Write};
|
||||
//! use crossterm::{execute, Result, terminal::{ScrollUp, SetSize, size}};
|
||||
//! use std::io::{self, Write};
|
||||
//! use crossterm::{execute, terminal::{ScrollUp, SetSize, size}};
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! fn main() -> io::Result<()> {
|
||||
//! let (cols, rows) = size()?;
|
||||
//! // Resize terminal and scroll up.
|
||||
//! execute!(
|
||||
//! stdout(),
|
||||
//! io::stdout(),
|
||||
//! SetSize(10, 10),
|
||||
//! ScrollUp(5)
|
||||
//! )?;
|
||||
//!
|
||||
//! // Be a good citizen, cleanup
|
||||
//! execute!(stdout(), SetSize(cols, rows))?;
|
||||
//! execute!(io::stdout(), SetSize(cols, rows))?;
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! For manual execution control check out [crossterm::queue](../macro.queue.html).
|
||||
|
||||
use std::fmt;
|
||||
use std::{fmt, io};
|
||||
|
||||
#[cfg(windows)]
|
||||
use crossterm_winapi::{ConsoleMode, Handle, ScreenBuffer};
|
||||
@ -94,7 +94,7 @@ use winapi::um::wincon::ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
|
||||
#[doc(no_inline)]
|
||||
use crate::Command;
|
||||
use crate::{csi, impl_display, Result};
|
||||
use crate::{csi, impl_display};
|
||||
|
||||
pub(crate) mod sys;
|
||||
|
||||
@ -104,7 +104,7 @@ pub use sys::supports_keyboard_enhancement;
|
||||
/// Tells whether the raw mode is enabled.
|
||||
///
|
||||
/// Please have a look at the [raw mode](./index.html#raw-mode) section.
|
||||
pub fn is_raw_mode_enabled() -> Result<bool> {
|
||||
pub fn is_raw_mode_enabled() -> io::Result<bool> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
Ok(sys::is_raw_mode_enabled())
|
||||
@ -119,21 +119,21 @@ pub fn is_raw_mode_enabled() -> Result<bool> {
|
||||
/// Enables raw mode.
|
||||
///
|
||||
/// Please have a look at the [raw mode](./index.html#raw-mode) section.
|
||||
pub fn enable_raw_mode() -> Result<()> {
|
||||
pub fn enable_raw_mode() -> io::Result<()> {
|
||||
sys::enable_raw_mode()
|
||||
}
|
||||
|
||||
/// Disables raw mode.
|
||||
///
|
||||
/// Please have a look at the [raw mode](./index.html#raw-mode) section.
|
||||
pub fn disable_raw_mode() -> Result<()> {
|
||||
pub fn disable_raw_mode() -> io::Result<()> {
|
||||
sys::disable_raw_mode()
|
||||
}
|
||||
|
||||
/// Returns the terminal size `(columns, rows)`.
|
||||
///
|
||||
/// The top left cell is represented `(1, 1)`.
|
||||
pub fn size() -> Result<(u16, u16)> {
|
||||
pub fn size() -> io::Result<(u16, u16)> {
|
||||
sys::size()
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ impl Command for DisableLineWrap {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
let screen_buffer = ScreenBuffer::current()?;
|
||||
let console_mode = ConsoleMode::from(screen_buffer.handle().clone());
|
||||
let new_mode = console_mode.mode()? & !ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
@ -166,7 +166,7 @@ impl Command for EnableLineWrap {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
let screen_buffer = ScreenBuffer::current()?;
|
||||
let console_mode = ConsoleMode::from(screen_buffer.handle().clone());
|
||||
let new_mode = console_mode.mode()? | ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
@ -185,15 +185,15 @@ impl Command for EnableLineWrap {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::{stdout, Write};
|
||||
/// use crossterm::{execute, Result, terminal::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||
/// use std::io::{self, Write};
|
||||
/// use crossterm::{execute, terminal::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// execute!(stdout(), EnterAlternateScreen)?;
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// execute!(io::stdout(), EnterAlternateScreen)?;
|
||||
///
|
||||
/// // Do anything on the alternate screen
|
||||
///
|
||||
/// execute!(stdout(), LeaveAlternateScreen)
|
||||
/// execute!(io::stdout(), LeaveAlternateScreen)
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
@ -206,7 +206,7 @@ impl Command for EnterAlternateScreen {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
let alternate_screen = ScreenBuffer::create()?;
|
||||
alternate_screen.show()?;
|
||||
Ok(())
|
||||
@ -223,15 +223,15 @@ impl Command for EnterAlternateScreen {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::{stdout, Write};
|
||||
/// use crossterm::{execute, Result, terminal::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||
/// use std::io::{self, Write};
|
||||
/// use crossterm::{execute, terminal::{EnterAlternateScreen, LeaveAlternateScreen}};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// execute!(stdout(), EnterAlternateScreen)?;
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// execute!(io::stdout(), EnterAlternateScreen)?;
|
||||
///
|
||||
/// // Do anything on the alternate screen
|
||||
///
|
||||
/// execute!(stdout(), LeaveAlternateScreen)
|
||||
/// execute!(io::stdout(), LeaveAlternateScreen)
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
@ -244,7 +244,7 @@ impl Command for LeaveAlternateScreen {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
let screen_buffer = ScreenBuffer::from(Handle::current_out_handle()?);
|
||||
screen_buffer.show()?;
|
||||
Ok(())
|
||||
@ -286,7 +286,7 @@ impl Command for ScrollUp {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
sys::scroll_up(self.0)
|
||||
}
|
||||
}
|
||||
@ -308,7 +308,7 @@ impl Command for ScrollDown {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
sys::scroll_down(self.0)
|
||||
}
|
||||
}
|
||||
@ -336,7 +336,7 @@ impl Command for Clear {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
sys::clear(self.0)
|
||||
}
|
||||
}
|
||||
@ -355,7 +355,7 @@ impl Command for SetSize {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
sys::set_size(self.0, self.1)
|
||||
}
|
||||
}
|
||||
@ -374,7 +374,7 @@ impl<T: fmt::Display> Command for SetTitle<T> {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
sys::set_window_title(&self.0)
|
||||
}
|
||||
}
|
||||
@ -399,15 +399,15 @@ impl<T: fmt::Display> Command for SetTitle<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::{stdout, Write};
|
||||
/// use crossterm::{execute, Result, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}};
|
||||
/// use std::io::{self, Write};
|
||||
/// use crossterm::{execute, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// execute!(stdout(), BeginSynchronizedUpdate)?;
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// execute!(io::stdout(), BeginSynchronizedUpdate)?;
|
||||
///
|
||||
/// // Anything performed here will not be rendered until EndSynchronizedUpdate is called.
|
||||
///
|
||||
/// execute!(stdout(), EndSynchronizedUpdate)?;
|
||||
/// execute!(io::stdout(), EndSynchronizedUpdate)?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
@ -421,7 +421,7 @@ impl Command for BeginSynchronizedUpdate {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -452,15 +452,15 @@ impl Command for BeginSynchronizedUpdate {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::{stdout, Write};
|
||||
/// use crossterm::{execute, Result, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}};
|
||||
/// use std::io::{self, Write};
|
||||
/// use crossterm::{execute, terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate}};
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// execute!(stdout(), BeginSynchronizedUpdate)?;
|
||||
/// fn main() -> io::Result<()> {
|
||||
/// execute!(io::stdout(), BeginSynchronizedUpdate)?;
|
||||
///
|
||||
/// // Anything performed here will not be rendered until EndSynchronizedUpdate is called.
|
||||
///
|
||||
/// execute!(stdout(), EndSynchronizedUpdate)?;
|
||||
/// execute!(io::stdout(), EndSynchronizedUpdate)?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
@ -474,7 +474,7 @@ impl Command for EndSynchronizedUpdate {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn execute_winapi(&self) -> Result<()> {
|
||||
fn execute_winapi(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,6 @@ use std::{
|
||||
|
||||
use libc::size_t;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// A file descriptor wrapper.
|
||||
///
|
||||
/// It allows to retrieve raw file descriptor, write to the file descriptor and
|
||||
@ -31,7 +29,7 @@ impl FileDesc {
|
||||
FileDesc { fd, close_on_drop }
|
||||
}
|
||||
|
||||
pub fn read(&self, buffer: &mut [u8], size: usize) -> Result<usize> {
|
||||
pub fn read(&self, buffer: &mut [u8], size: usize) -> io::Result<usize> {
|
||||
let result = unsafe {
|
||||
libc::read(
|
||||
self.fd,
|
||||
@ -73,7 +71,7 @@ impl AsRawFd for FileDesc {
|
||||
}
|
||||
|
||||
/// Creates a file descriptor pointing to the standard input or `/dev/tty`.
|
||||
pub fn tty_fd() -> Result<FileDesc> {
|
||||
pub fn tty_fd() -> io::Result<FileDesc> {
|
||||
let (fd, close_on_drop) = if unsafe { libc::isatty(libc::STDIN_FILENO) == 1 } {
|
||||
(libc::STDIN_FILENO, false)
|
||||
} else {
|
||||
|
@ -12,8 +12,6 @@ use std::os::unix::io::{IntoRawFd, RawFd};
|
||||
|
||||
use std::{io, mem, process};
|
||||
|
||||
use crate::error::Result;
|
||||
|
||||
// Some(Termios) -> we're in the raw mode and this is the previous mode
|
||||
// None -> we're not in the raw mode
|
||||
static TERMINAL_MODE_PRIOR_RAW_MODE: Mutex<Option<Termios>> = parking_lot::const_mutex(None);
|
||||
@ -23,7 +21,7 @@ pub(crate) fn is_raw_mode_enabled() -> bool {
|
||||
}
|
||||
|
||||
#[allow(clippy::useless_conversion)]
|
||||
pub(crate) fn size() -> Result<(u16, u16)> {
|
||||
pub(crate) fn size() -> io::Result<(u16, u16)> {
|
||||
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
|
||||
let mut size = winsize {
|
||||
ws_row: 0,
|
||||
@ -50,7 +48,7 @@ pub(crate) fn size() -> Result<(u16, u16)> {
|
||||
tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
|
||||
}
|
||||
|
||||
pub(crate) fn enable_raw_mode() -> Result<()> {
|
||||
pub(crate) fn enable_raw_mode() -> io::Result<()> {
|
||||
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock();
|
||||
|
||||
if original_mode.is_some() {
|
||||
@ -76,7 +74,7 @@ pub(crate) fn enable_raw_mode() -> Result<()> {
|
||||
/// More precisely, reset the whole termios mode to what it was before the first call
|
||||
/// to [enable_raw_mode]. If you don't mess with termios outside of crossterm, it's
|
||||
/// effectively disabling the raw mode and doing nothing else.
|
||||
pub(crate) fn disable_raw_mode() -> Result<()> {
|
||||
pub(crate) fn disable_raw_mode() -> io::Result<()> {
|
||||
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock();
|
||||
|
||||
if let Some(original_mode_ios) = original_mode.as_ref() {
|
||||
@ -94,7 +92,7 @@ pub(crate) fn disable_raw_mode() -> Result<()> {
|
||||
/// On unix systems, this function will block and possibly time out while
|
||||
/// [`crossterm::event::read`](crate::event::read) or [`crossterm::event::poll`](crate::event::poll) are being called.
|
||||
#[cfg(feature = "events")]
|
||||
pub fn supports_keyboard_enhancement() -> Result<bool> {
|
||||
pub fn supports_keyboard_enhancement() -> io::Result<bool> {
|
||||
if is_raw_mode_enabled() {
|
||||
read_supports_keyboard_enhancement_raw()
|
||||
} else {
|
||||
@ -103,7 +101,7 @@ pub fn supports_keyboard_enhancement() -> Result<bool> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "events")]
|
||||
fn read_supports_keyboard_enhancement_flags() -> Result<bool> {
|
||||
fn read_supports_keyboard_enhancement_flags() -> io::Result<bool> {
|
||||
enable_raw_mode()?;
|
||||
let flags = read_supports_keyboard_enhancement_raw();
|
||||
disable_raw_mode()?;
|
||||
@ -111,7 +109,7 @@ fn read_supports_keyboard_enhancement_flags() -> Result<bool> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "events")]
|
||||
fn read_supports_keyboard_enhancement_raw() -> Result<bool> {
|
||||
fn read_supports_keyboard_enhancement_raw() -> io::Result<bool> {
|
||||
use crate::event::{
|
||||
filter::{KeyboardEnhancementFlagsFilter, PrimaryDeviceAttributesFilter},
|
||||
poll_internal, read_internal, InternalEvent,
|
||||
@ -201,7 +199,7 @@ fn raw_terminal_attr(termios: &mut Termios) {
|
||||
unsafe { cfmakeraw(termios) }
|
||||
}
|
||||
|
||||
fn get_terminal_attr(fd: RawFd) -> Result<Termios> {
|
||||
fn get_terminal_attr(fd: RawFd) -> io::Result<Termios> {
|
||||
unsafe {
|
||||
let mut termios = mem::zeroed();
|
||||
wrap_with_result(tcgetattr(fd, &mut termios))?;
|
||||
@ -209,11 +207,11 @@ fn get_terminal_attr(fd: RawFd) -> Result<Termios> {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_terminal_attr(fd: RawFd, termios: &Termios) -> Result<()> {
|
||||
fn set_terminal_attr(fd: RawFd, termios: &Termios) -> io::Result<()> {
|
||||
wrap_with_result(unsafe { tcsetattr(fd, TCSANOW, termios) })
|
||||
}
|
||||
|
||||
fn wrap_with_result(result: i32) -> Result<()> {
|
||||
fn wrap_with_result(result: i32) -> io::Result<()> {
|
||||
if result == -1 {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! WinAPI related logic for terminal manipulation.
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use std::io;
|
||||
use std::io::{self};
|
||||
|
||||
use crossterm_winapi::{Console, ConsoleMode, Coord, Handle, ScreenBuffer, Size};
|
||||
use winapi::{
|
||||
@ -9,12 +9,12 @@ use winapi::{
|
||||
um::wincon::{SetConsoleTitleW, ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT},
|
||||
};
|
||||
|
||||
use crate::{cursor, terminal::ClearType, ErrorKind, Result};
|
||||
use crate::{cursor, terminal::ClearType};
|
||||
|
||||
/// bits which can't be set in raw mode
|
||||
const NOT_RAW_MODE_MASK: DWORD = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT;
|
||||
|
||||
pub(crate) fn is_raw_mode_enabled() -> Result<bool> {
|
||||
pub(crate) fn is_raw_mode_enabled() -> std::io::Result<bool> {
|
||||
let console_mode = ConsoleMode::from(Handle::current_in_handle()?);
|
||||
|
||||
let dw_mode = console_mode.mode()?;
|
||||
@ -25,7 +25,7 @@ pub(crate) fn is_raw_mode_enabled() -> Result<bool> {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn enable_raw_mode() -> Result<()> {
|
||||
pub(crate) fn enable_raw_mode() -> std::io::Result<()> {
|
||||
let console_mode = ConsoleMode::from(Handle::current_in_handle()?);
|
||||
|
||||
let dw_mode = console_mode.mode()?;
|
||||
@ -37,7 +37,7 @@ pub(crate) fn enable_raw_mode() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn disable_raw_mode() -> Result<()> {
|
||||
pub(crate) fn disable_raw_mode() -> std::io::Result<()> {
|
||||
let console_mode = ConsoleMode::from(Handle::current_in_handle()?);
|
||||
|
||||
let dw_mode = console_mode.mode()?;
|
||||
@ -49,7 +49,7 @@ pub(crate) fn disable_raw_mode() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn size() -> Result<(u16, u16)> {
|
||||
pub(crate) fn size() -> io::Result<(u16, u16)> {
|
||||
let terminal_size = ScreenBuffer::current()?.info()?.terminal_size();
|
||||
// windows starts counting at 0, unix at 1, add one to replicated unix behaviour.
|
||||
Ok((
|
||||
@ -62,11 +62,11 @@ pub(crate) fn size() -> Result<(u16, u16)> {
|
||||
///
|
||||
/// This always returns `Ok(false)` on Windows.
|
||||
#[cfg(feature = "events")]
|
||||
pub fn supports_keyboard_enhancement() -> Result<bool> {
|
||||
pub fn supports_keyboard_enhancement() -> std::io::Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub(crate) fn clear(clear_type: ClearType) -> Result<()> {
|
||||
pub(crate) fn clear(clear_type: ClearType) -> std::io::Result<()> {
|
||||
let screen_buffer = ScreenBuffer::current()?;
|
||||
let csbi = screen_buffer.info()?;
|
||||
|
||||
@ -89,7 +89,7 @@ pub(crate) fn clear(clear_type: ClearType) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn scroll_up(row_count: u16) -> Result<()> {
|
||||
pub(crate) fn scroll_up(row_count: u16) -> std::io::Result<()> {
|
||||
let csbi = ScreenBuffer::current()?;
|
||||
let mut window = csbi.info()?.terminal_window();
|
||||
|
||||
@ -104,7 +104,7 @@ pub(crate) fn scroll_up(row_count: u16) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn scroll_down(row_count: u16) -> Result<()> {
|
||||
pub(crate) fn scroll_down(row_count: u16) -> std::io::Result<()> {
|
||||
let screen_buffer = ScreenBuffer::current()?;
|
||||
let csbi = screen_buffer.info()?;
|
||||
let mut window = csbi.terminal_window();
|
||||
@ -121,16 +121,16 @@ pub(crate) fn scroll_down(row_count: u16) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||
pub(crate) fn set_size(width: u16, height: u16) -> std::io::Result<()> {
|
||||
if width <= 1 {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"terminal width must be at least 1",
|
||||
));
|
||||
}
|
||||
|
||||
if height <= 1 {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"terminal height must be at least 1",
|
||||
));
|
||||
@ -153,7 +153,7 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||
let width = width as i16;
|
||||
if current_size.width < window.left + width {
|
||||
if window.left >= i16::max_value() - width {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"terminal width too large",
|
||||
));
|
||||
@ -165,7 +165,7 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||
let height = height as i16;
|
||||
if current_size.height < window.top + height {
|
||||
if window.top >= i16::max_value() - height {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"terminal height too large",
|
||||
));
|
||||
@ -194,13 +194,13 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||
let bounds = console.largest_window_size()?;
|
||||
|
||||
if width > bounds.x {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
format!("terminal width {width} too large"),
|
||||
));
|
||||
}
|
||||
if height > bounds.y {
|
||||
return Err(ErrorKind::new(
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
format!("terminal height {height} too large"),
|
||||
));
|
||||
@ -209,7 +209,7 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_window_title(title: impl fmt::Display) -> Result<()> {
|
||||
pub(crate) fn set_window_title(title: impl fmt::Display) -> std::io::Result<()> {
|
||||
struct Utf16Encoder(Vec<u16>);
|
||||
impl Write for Utf16Encoder {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
@ -227,11 +227,15 @@ pub(crate) fn set_window_title(title: impl fmt::Display) -> Result<()> {
|
||||
if result != 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::last_os_error())
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_after_cursor(location: Coord, buffer_size: Size, current_attribute: u16) -> Result<()> {
|
||||
fn clear_after_cursor(
|
||||
location: Coord,
|
||||
buffer_size: Size,
|
||||
current_attribute: u16,
|
||||
) -> std::io::Result<()> {
|
||||
let (mut x, mut y) = (location.x, location.y);
|
||||
|
||||
// if cursor position is at the outer right position
|
||||
@ -249,7 +253,11 @@ fn clear_after_cursor(location: Coord, buffer_size: Size, current_attribute: u16
|
||||
clear_winapi(start_location, cells_to_write, current_attribute)
|
||||
}
|
||||
|
||||
fn clear_before_cursor(location: Coord, buffer_size: Size, current_attribute: u16) -> Result<()> {
|
||||
fn clear_before_cursor(
|
||||
location: Coord,
|
||||
buffer_size: Size,
|
||||
current_attribute: u16,
|
||||
) -> std::io::Result<()> {
|
||||
let (xpos, ypos) = (location.x, location.y);
|
||||
|
||||
// one cell after cursor position
|
||||
@ -267,7 +275,7 @@ fn clear_before_cursor(location: Coord, buffer_size: Size, current_attribute: u1
|
||||
clear_winapi(start_location, cells_to_write, current_attribute)
|
||||
}
|
||||
|
||||
fn clear_entire_screen(buffer_size: Size, current_attribute: u16) -> Result<()> {
|
||||
fn clear_entire_screen(buffer_size: Size, current_attribute: u16) -> std::io::Result<()> {
|
||||
// get sum cells before cursor
|
||||
let cells_to_write = buffer_size.width as u32 * buffer_size.height as u32;
|
||||
|
||||
@ -282,7 +290,11 @@ fn clear_entire_screen(buffer_size: Size, current_attribute: u16) -> Result<()>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clear_current_line(location: Coord, buffer_size: Size, current_attribute: u16) -> Result<()> {
|
||||
fn clear_current_line(
|
||||
location: Coord,
|
||||
buffer_size: Size,
|
||||
current_attribute: u16,
|
||||
) -> std::io::Result<()> {
|
||||
// location where to start clearing
|
||||
let start_location = Coord::new(0, location.y);
|
||||
|
||||
@ -297,7 +309,11 @@ fn clear_current_line(location: Coord, buffer_size: Size, current_attribute: u16
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clear_until_line(location: Coord, buffer_size: Size, current_attribute: u16) -> Result<()> {
|
||||
fn clear_until_line(
|
||||
location: Coord,
|
||||
buffer_size: Size,
|
||||
current_attribute: u16,
|
||||
) -> std::io::Result<()> {
|
||||
let (x, y) = (location.x, location.y);
|
||||
|
||||
// location where to start clearing
|
||||
@ -314,7 +330,11 @@ fn clear_until_line(location: Coord, buffer_size: Size, current_attribute: u16)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clear_winapi(start_location: Coord, cells_to_write: u32, current_attribute: u16) -> Result<()> {
|
||||
fn clear_winapi(
|
||||
start_location: Coord,
|
||||
cells_to_write: u32,
|
||||
current_attribute: u16,
|
||||
) -> std::io::Result<()> {
|
||||
let console = Console::from(Handle::current_out_handle()?);
|
||||
console.fill_whit_character(start_location, cells_to_write, ' ')?;
|
||||
console.fill_whit_attribute(start_location, cells_to_write, current_attribute)?;
|
||||
|
Loading…
Reference in New Issue
Block a user