Updated all examples and comments tested unix logic
This commit is contained in:
parent
f31bb1a656
commit
d23ef22a58
@ -15,12 +15,13 @@ extern crate crossterm;
|
||||
mod some_types;
|
||||
mod input;
|
||||
|
||||
|
||||
fn main() {
|
||||
// call some test module function
|
||||
|
||||
terminal::terminal::resize_terminal();
|
||||
|
||||
use crossterm::screen::RawScreen;
|
||||
// terminal::terminal::resize_terminal();
|
||||
input::keyboard::async_input::read_async_demo();
|
||||
// use crossterm::screen::RawScreen;
|
||||
// RawScreen::into_raw_mode();
|
||||
// RawScreen::disable_raw_modes();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ pub fn read_async_until() {
|
||||
}
|
||||
}
|
||||
|
||||
/// this will read pressed characters async until `x` is typed .
|
||||
/// this will read pressed characters async until `x` is typed.
|
||||
pub fn read_async() {
|
||||
let input = input(&Screen::default());
|
||||
|
||||
|
@ -127,10 +127,10 @@ impl<'screen> FirstDepthSearch<'screen>
|
||||
fn find_first_possible_direction(&mut self)
|
||||
{
|
||||
// if there are no elements left in the stack that means we have visited all cell and we van terminate the program.
|
||||
if let Some(previous_cell) = &self.stack.pop()
|
||||
if let &Some(previous_cell) = &self.stack.pop()
|
||||
{
|
||||
// update root pos to previous cell and continue searching for new neighbours
|
||||
self.root_pos = *previous_cell;
|
||||
self.root_pos = previous_cell;
|
||||
self.choose_random_neighbor();
|
||||
}
|
||||
else {
|
||||
|
@ -33,7 +33,7 @@ fn print_wait_screen(screen: &Screen) {
|
||||
}
|
||||
}
|
||||
|
||||
/// print wait screen on alternate screen, then swich back.
|
||||
/// print wait screen on alternate screen, then switch back.
|
||||
pub fn print_wait_screen_on_alternate_window() {
|
||||
|
||||
let screen = Screen::default();
|
||||
|
@ -22,56 +22,139 @@ use common::commands::win_commands;
|
||||
|
||||
use write::Stdout;
|
||||
|
||||
/// This type could be used to access the `cursor, terminal, color, input, styling` module more easily.
|
||||
/// You need to pass a reference to the screen where on you want to perform the actions.
|
||||
///
|
||||
///
|
||||
/// #Example
|
||||
/// If you want to use the default screen you could do it like this:
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor(&Screen::default());
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// If you want to perform actions on the `AlternateScreen` make sure to pass a refrence to the screen of the `AlternateScreen`.
|
||||
///
|
||||
/// ```
|
||||
/// /// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
///
|
||||
/// let main_screen = Screen::default();
|
||||
///
|
||||
/// if let Ok(alternate_srceen) = main_screen.enable_alternate_modes(false)
|
||||
/// {
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor(&alternate_screen.screen);
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub struct Crossterm { }
|
||||
|
||||
impl<'crossterm> Crossterm {
|
||||
|
||||
/// Create a new instance of `Crossterm`
|
||||
pub fn new() -> Crossterm {
|
||||
Crossterm {}
|
||||
}
|
||||
|
||||
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor(&Screen::default());
|
||||
///
|
||||
/// ```
|
||||
pub fn cursor(&self, screen: &'crossterm Screen) -> cursor::TerminalCursor {
|
||||
cursor::TerminalCursor::new(&screen.stdout.clone())
|
||||
}
|
||||
|
||||
/// Get an TerminalInput implementation whereon terminal related actions can be performed.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
/// use crossterm::terminal;
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let input = crossterm.input(&Screen::default());
|
||||
///
|
||||
/// ```
|
||||
pub fn input(&self, screen: &'crossterm Screen) -> input::TerminalInput {
|
||||
return input::TerminalInput::new(&screen.stdout);
|
||||
}
|
||||
|
||||
/// Get an Terminal implementation whereon terminal related actions can be performed.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let mut terminal = crossterm.terminal(&Screen::default());
|
||||
///
|
||||
/// ```
|
||||
pub fn terminal(&self, screen: &'crossterm Screen) -> terminal::Terminal {
|
||||
return terminal::Terminal::new(&screen.stdout);
|
||||
}
|
||||
|
||||
/// Get an TerminalColor implementation whereon color related actions can be performed.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::{Crossterm, Screen};
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let mut terminal = crossterm.terminal(&Screen::default());
|
||||
///
|
||||
/// ```
|
||||
pub fn color(&self, screen: &'crossterm Screen) -> style::TerminalColor {
|
||||
return style::TerminalColor::new(&screen.stdout);
|
||||
}
|
||||
|
||||
// Wraps an displayable object so it can be formatted with colors and attributes.
|
||||
//
|
||||
// Check `/examples/color` in the libary for more spesific examples.
|
||||
/// This could be used to style an Displayable with colors and attributes.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// use crossterm::{ Screen };
|
||||
///
|
||||
/// // get an styled object which could be painted to the terminal.
|
||||
/// let styled_object = style("Some Blue colored text on black background").with(Color::Blue).on(Color::Black);
|
||||
///
|
||||
/// // create an default screen.
|
||||
/// let screen = Screen::default();
|
||||
///
|
||||
/// // print the styled font * times to the current screen.
|
||||
/// for i in 1..10
|
||||
/// {
|
||||
/// styled_object.paint(&screen);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn style<D>(&self, val: D) -> style::StyledObject<D>
|
||||
where
|
||||
D: Display, {
|
||||
style::ObjectStyle::new().apply_to(val)
|
||||
}
|
||||
}
|
||||
|
||||
//impl Write for Crossterm {M
|
||||
// fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
// self.active_screen.write_buf(buf)
|
||||
// }
|
||||
//
|
||||
// fn flush(&mut self) -> Result<()> {
|
||||
// self.active_screen.flush()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//impl Drop for Crossterm {
|
||||
// fn drop(&mut self) {
|
||||
// if let Some(ref mut screen) = self.alternate_screen {
|
||||
// screen.disable(&mut self.active_screen);
|
||||
// }
|
||||
// if let Some(ref mut raw_terminal) = self.raw_terminal {
|
||||
// raw_terminal.disable();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
@ -49,16 +49,19 @@ pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
#[cfg(windows)]
|
||||
use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
|
||||
use kernel::windows_kernel::ansi_support::{try_enable_ansi_support, windows_supportable};
|
||||
|
||||
// Try to enable ansi on windows if not than use WINAPI.
|
||||
does_support = try_enable_ansi_support();
|
||||
if !windows_supportable()
|
||||
{
|
||||
// Try to enable ansi on windows if not than use WINAPI.
|
||||
does_support = try_enable_ansi_support();
|
||||
|
||||
// uncomment this line when you want to use the winapi implementation.
|
||||
does_support = false;
|
||||
if !does_support {
|
||||
term = Some(winapi_impl);
|
||||
}
|
||||
// uncomment this line when you want to use the winapi implementation.
|
||||
// does_support = false;
|
||||
if !does_support {
|
||||
term = Some(winapi_impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if does_support {
|
||||
|
@ -5,22 +5,6 @@
|
||||
//! The alternate buffer is exactly the dimensions of the window, without any scrollback region.
|
||||
//! For an example of this behavior, consider when vim is launched from bash.
|
||||
//! Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
//!
|
||||
//!
|
||||
//! When using alternate screen there is one thing to keep in mind.
|
||||
//! To get the functionalities of `cursor, color, terminal` also working on alternate screen.
|
||||
//! You need to pass it the same `Context` as you have passed to the previous three functions,
|
||||
//! If you don't use the same `Context` the `cursor(), color(), terminal()` these modules will be using main screen to write to.
|
||||
//! So you will see nothing on alternate screen.
|
||||
//!
|
||||
//!
|
||||
//! When you want to switch to alternate screen there are a couple of things to keep in mind for it to work correctly.
|
||||
//! First off some code of how to switch to Alternate screen, for more info check the example folder at github
|
||||
//! Create alternate screen from `Crossterm`:
|
||||
//!
|
||||
//!
|
||||
//! Todo: example
|
||||
//!
|
||||
|
||||
use super::commands::{self, IAlternateScreenCommand};
|
||||
use super::{functions, Screen, Stdout, RawScreen};
|
||||
@ -29,6 +13,7 @@ use std::convert::From;
|
||||
use std::io::{self, Write};
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// With this type you will be able to switch to alternate screen and back to main screen.
|
||||
pub struct AlternateScreen
|
||||
{
|
||||
command: Box<IAlternateScreenCommand + Send>,
|
||||
@ -37,11 +22,19 @@ pub struct AlternateScreen
|
||||
|
||||
impl AlternateScreen {
|
||||
|
||||
/// Create new instance of alternate screen.
|
||||
pub fn new(command: Box<IAlternateScreenCommand + Send>, screen: Screen) -> Self
|
||||
{
|
||||
return AlternateScreen { command, screen }
|
||||
}
|
||||
|
||||
/// Switch to alternate screen. This function will return an `AlternateScreen` instance if everything went well this type will give you control over the `AlternateScreen`.
|
||||
///
|
||||
/// # What is Alternate screen?
|
||||
/// *Nix style applications often utilize an alternate screen buffer, so that they can modify the entire contents of the buffer, without affecting the application that started them.
|
||||
/// The alternate buffer is exactly the dimensions of the window, without any scrollback region.
|
||||
/// For an example of this behavior, consider when vim is launched from bash.
|
||||
/// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
pub fn to_alternate_screen(screen_manager: Stdout) -> io::Result<AlternateScreen> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let command = functions::get_module::<Box<commands::IAlternateScreenCommand + Send>>(
|
||||
@ -57,6 +50,7 @@ impl AlternateScreen {
|
||||
return Ok(AlternateScreen::new(command, Screen::from(stdout)));
|
||||
}
|
||||
|
||||
/// Switch the alternate screen back to main screen.
|
||||
pub fn to_main_screen(&self) -> io::Result<()> {
|
||||
self.command.disable(&self.screen.stdout)?;
|
||||
Ok(())
|
||||
@ -65,8 +59,8 @@ impl AlternateScreen {
|
||||
|
||||
impl Drop for AlternateScreen
|
||||
{
|
||||
/// This will switch back to main screen on drop.
|
||||
fn drop(&mut self) {
|
||||
self.to_main_screen();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
//! - Characters
|
||||
//! The characters are not processed by the terminal driver, but are sent straight through.
|
||||
//! Special character have no meaning, like backspace will not be interpret as backspace but instead will be directly send to the terminal.
|
||||
//! - Escape characters
|
||||
//! Note that in raw modes `\n` will move to the new line but the cursor will be at the same position as before on the new line therefor use `\n\r` to start at the new line at the first cell.
|
||||
//!
|
||||
//! With these modes you can easier design the terminal screen.
|
||||
|
||||
@ -18,16 +20,10 @@ use super::{functions, Screen, Stdout};
|
||||
use std::io::{self, Write};
|
||||
|
||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
||||
pub struct RawScreen
|
||||
{
|
||||
// #[cfg(not(target_os = "windows"))]
|
||||
// command: unix_command::RawModeCommand,
|
||||
// #[cfg(not(target_os = "windows"))]
|
||||
// command: win_commands::RawModeCommand,
|
||||
|
||||
}
|
||||
pub struct RawScreen;
|
||||
|
||||
impl RawScreen {
|
||||
/// Put terminal in raw mode.
|
||||
pub fn into_raw_mode() -> io::Result<()>
|
||||
{
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
@ -35,12 +31,11 @@ impl RawScreen {
|
||||
#[cfg(target_os = "windows")]
|
||||
let mut command = win_commands::RawModeCommand::new();
|
||||
|
||||
// command::new();
|
||||
command.enable()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Put terminal back in original modes.
|
||||
pub fn disable_raw_modes() -> io::Result<()>
|
||||
{
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
@ -48,9 +43,7 @@ impl RawScreen {
|
||||
#[cfg(target_os = "windows")]
|
||||
let mut command = win_commands::RawModeCommand::new();
|
||||
|
||||
let a = command.disable();
|
||||
|
||||
|
||||
command.disable()?;
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,42 @@ use std::io::Write;
|
||||
use std::io::Result;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// This type represents an screen.
|
||||
/// This screen has an stdout which is used by the program to write to or to execute commands with.
|
||||
///
|
||||
/// You have to make sure that you pass the correct `Screen` to the modules `cursor, terminal, color, input, style`.
|
||||
/// Most of the time you just have one screen so you could get an instance of that screen with: `Screen::default()`.
|
||||
///
|
||||
/// Also this screen has an buffer where you can write to. When you want to write the buffer to the screen you could flush the screen.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// // create default screen.
|
||||
/// let screen = Screen::default();
|
||||
/// // create raw screen.
|
||||
/// let mut screen = Screen::new(true);
|
||||
///
|
||||
/// // write some text to the internal buffer of this type.
|
||||
/// screen.write(b"Some text");
|
||||
/// screen.write(b"Some more text");
|
||||
/// screen.write(b"Some more text");
|
||||
///
|
||||
/// // write the above text by flushing the internal buffer of this type.
|
||||
/// screen.flush();
|
||||
///
|
||||
/// // create raw alternate screen from normal screen.
|
||||
/// let screen = Screen::new();
|
||||
///
|
||||
/// if let Ok(alternate_screen) = screen.enable_alternate_modes(true)
|
||||
/// {
|
||||
/// let crossterm = Crossterm::new();
|
||||
///
|
||||
/// // make sure to pass in the screen of the AlternateScreen.
|
||||
/// crossterm.cursor(&alternate_screen.screen);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
pub struct Screen
|
||||
{
|
||||
buffer: Vec<u8>,
|
||||
@ -21,6 +57,8 @@ pub struct Screen
|
||||
|
||||
impl Screen
|
||||
{
|
||||
/// Create new instance of the Screen also specify if the current screen should be in raw mode or normal mode. Check out `RawScreen` type for more info.
|
||||
/// If you are not sure what raw mode is then pass false or use the `Screen::default()` to create an instance.
|
||||
pub fn new(raw_mode: bool) -> Screen
|
||||
{
|
||||
if raw_mode
|
||||
@ -32,16 +70,33 @@ impl Screen
|
||||
return Screen::default();
|
||||
}
|
||||
|
||||
pub fn from(stdout: Stdout) -> Screen
|
||||
{
|
||||
return Screen { stdout: Arc::new(stdout), buffer: Vec::new() };
|
||||
}
|
||||
|
||||
/// This method could be used for enabling raw mode for the terminal.
|
||||
///
|
||||
/// What exactly is raw state:
|
||||
/// - No line buffering.
|
||||
/// Normally the terminals uses line buffering. This means that the input will be send to the terminal line by line.
|
||||
/// With raw mode the input will be send one byte at a time.
|
||||
/// - Input
|
||||
/// All input has to be written manually by the programmer.
|
||||
/// - Characters
|
||||
/// The characters are not processed by the terminal driver, but are sent straight through.
|
||||
/// Special character have no meaning, like backspace will not be interpret as backspace but instead will be directly send to the terminal.
|
||||
/// - Escape characters
|
||||
/// Note that in raw modes `\n` will move to the new line but the cursor will be at the same position as before on the new line therefor use `\n\r` to start at the new line at the first cell.
|
||||
///
|
||||
/// With these modes you can easier design the terminal screen.
|
||||
pub fn enable_raw_modes(&self) -> Result<()> {
|
||||
RawScreen::into_raw_mode()?;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
/// Switch to alternate screen. This function will return an `AlternateScreen` instance if everything went well this type will give you control over the `AlternateScreen`.
|
||||
///
|
||||
/// # What is Alternate screen?
|
||||
/// *Nix style applications often utilize an alternate screen buffer, so that they can modify the entire contents of the buffer, without affecting the application that started them.
|
||||
/// The alternate buffer is exactly the dimensions of the window, without any scrollback region.
|
||||
/// For an example of this behavior, consider when vim is launched from bash.
|
||||
/// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> {
|
||||
let mut stdout = Stdout::new(raw_mode);
|
||||
|
||||
@ -55,8 +110,25 @@ impl Screen
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Stdout> for Screen
|
||||
{
|
||||
/// Create an screen with the given `Stdout`
|
||||
fn from(stdout: Stdout) -> Self {
|
||||
return Screen { stdout: Arc::new(stdout), buffer: Vec::new() };
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<Stdout>> for Screen
|
||||
{
|
||||
/// Create an screen with the given 'Arc<Stdout>'
|
||||
fn from(stdout: Arc<Stdout>) -> Self {
|
||||
return Screen { stdout: stdout, buffer: Vec::new() };
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Screen
|
||||
{
|
||||
/// Create an new screen which will not be in raw mode or alternate mode.
|
||||
fn default() -> Self {
|
||||
return Screen { stdout: Arc::new(Stdout::new(false)), buffer: Vec::new() };
|
||||
}
|
||||
@ -64,6 +136,7 @@ impl Default for Screen
|
||||
|
||||
impl Drop for Screen
|
||||
{
|
||||
/// If the current screen is in raw mode whe need to disable it when the instance goes out of scope.
|
||||
fn drop(&mut self) {
|
||||
if self.stdout.is_in_raw_mode
|
||||
{
|
||||
@ -74,11 +147,15 @@ impl Drop for Screen
|
||||
|
||||
impl Write for Screen
|
||||
{
|
||||
/// Write buffer to an internal buffer. When you want to write the buffer to screen use `flush()`.
|
||||
///
|
||||
/// This function is useful if you want to build up some output and when you are ready you could flush the output to the screen.
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.buffer.write(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
/// Flush the internal buffer to the screen.
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
self.stdout.write_buf(&self.buffer);
|
||||
self.stdout.flush()
|
||||
|
@ -9,6 +9,7 @@ use std::fmt::Display;
|
||||
use std::io::Write;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Struct that stores an specific platform implementation for cursor related actions.
|
||||
///
|
||||
/// Check `/examples/version/cursor` in the library for more specific examples.
|
||||
@ -17,22 +18,19 @@ use std::sync::Arc;
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::Crossterm;
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::cursor::cursor;
|
||||
///
|
||||
/// let term = Crossterm::new();
|
||||
/// let mut cursor = term.cursor();
|
||||
/// let mut cursor = cursor();
|
||||
///
|
||||
/// // Get cursor and goto pos X: 5, Y: 10
|
||||
/// cursor.goto(5,10);
|
||||
///
|
||||
///
|
||||
/// cursor.show();
|
||||
/// cursor.hide();
|
||||
/// cursor.blink(true);
|
||||
/// cursor.move_left(2);
|
||||
///
|
||||
/// // or in one line
|
||||
/// cursor.goto(5,5).move_left(2).move_right(2).print("10");
|
||||
///
|
||||
/// ```
|
||||
pub struct TerminalCursor {
|
||||
screen: Arc<Stdout>,
|
||||
@ -62,11 +60,10 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
///
|
||||
/// // change the cursor to position, x: 4 and y: 5
|
||||
/// cursor.goto(4,5);
|
||||
/// // change the cursor to position, x: 4 and y: 5
|
||||
/// cursor.goto(4,5);
|
||||
///
|
||||
/// ```
|
||||
pub fn goto(&self, x: u16, y: u16) {
|
||||
@ -78,12 +75,11 @@ impl TerminalCursor {
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// // get the current cursor pos
|
||||
/// let (x,y) = cursor.pos();
|
||||
/// // get the current cursor pos
|
||||
/// let (x,y) = cursor.pos();
|
||||
///
|
||||
/// ```
|
||||
pub fn pos(&self) -> (u16, u16) {
|
||||
@ -95,11 +91,9 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// // Move the cursor to position 3 times to the up in the terminal
|
||||
/// cursor.move_up(3);
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// // Move the cursor to position 3 times to the up in the terminal
|
||||
/// cursor.move_up(3);
|
||||
///
|
||||
/// ```
|
||||
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor {
|
||||
@ -113,10 +107,10 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
/// // Move the cursor to position 3 times to the right in the terminal
|
||||
/// cursor.move_right(3);
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
///
|
||||
/// // Move the cursor to position 3 times to the right in the terminal
|
||||
/// cursor.move_right(3);
|
||||
///
|
||||
/// ```
|
||||
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor {
|
||||
@ -130,11 +124,10 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
///
|
||||
/// // Move the cursor to position 3 times to the down in the terminal
|
||||
/// cursor.move_down(3);
|
||||
/// // Move the cursor to position 3 times to the down in the terminal
|
||||
/// cursor.move_down(3);
|
||||
///
|
||||
/// ```
|
||||
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor {
|
||||
@ -148,8 +141,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
///
|
||||
/// // Move the cursor to position 3 times to the left in the terminal
|
||||
/// cursor.move_left(3);
|
||||
@ -168,9 +160,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// cursor.safe_position();
|
||||
///
|
||||
/// ```
|
||||
@ -186,9 +176,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// cursor.reset_position();
|
||||
///
|
||||
/// ```
|
||||
@ -202,9 +190,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// cursor.hide();
|
||||
///
|
||||
/// ```
|
||||
@ -218,9 +204,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// cursor.show();
|
||||
///
|
||||
/// ```
|
||||
@ -236,9 +220,7 @@ impl TerminalCursor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let cursor = crossterm.cursor();
|
||||
///
|
||||
/// let cursor = cursor(&Screen::default());
|
||||
/// cursor.blink(true);
|
||||
/// cursor.blink(false);
|
||||
///
|
||||
@ -249,6 +231,7 @@ impl TerminalCursor {
|
||||
}
|
||||
|
||||
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
|
||||
/// Pass the reference to any screen you want this type to perform actions on.
|
||||
pub fn cursor(screen_manager: &Screen) -> TerminalCursor {
|
||||
TerminalCursor::new(&screen_manager.stdout)
|
||||
}
|
||||
|
@ -45,6 +45,6 @@ pub trait ITerminalCursor {
|
||||
fn hide(&self, screen_manager: &Arc<Stdout>);
|
||||
/// Show the terminal cursor
|
||||
fn show(&self, screen_manager: &Arc<Stdout>);
|
||||
/// enable or disable the blinking of the cursor.
|
||||
/// Enable or disable the blinking of the cursor.
|
||||
fn blink(&self, blink: bool, screen_manager: &Arc<Stdout>);
|
||||
}
|
||||
|
@ -7,18 +7,16 @@ use super::*;
|
||||
|
||||
/// Struct that stores an specific platform implementation for input related actions.
|
||||
///
|
||||
/// Check `/examples/version/input` the examples folder on github for more info.
|
||||
/// Check `/examples/input` the examples folder on github for more info.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::Crossterm;
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let input = crossterm.input();
|
||||
/// use self::crossterm::input::input;
|
||||
///
|
||||
/// let input = input(&Screen::default());
|
||||
/// let result = input.read_line();
|
||||
/// let pressed_char = input.read_char();
|
||||
///
|
||||
@ -48,8 +46,8 @@ impl TerminalInput{
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// match crossterm.input().read_line() {
|
||||
///
|
||||
/// match input(&Screen::default()).read_line() {
|
||||
/// Ok(s) => println!("string typed: {}", s),
|
||||
/// Err(e) => println!("error: {}", e),
|
||||
/// }
|
||||
@ -64,11 +62,11 @@ impl TerminalInput{
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// match crossterm.input().read_char() {
|
||||
///
|
||||
/// match crossterm.input(&Screen::default()).read_char() {
|
||||
/// Ok(c) => println!("character pressed: {}", c),
|
||||
/// Err(e) => println!("error: {}", e),
|
||||
// }
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub fn read_char(&self) -> io::Result<char> {
|
||||
@ -80,12 +78,14 @@ impl TerminalInput{
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let crossterm = Crossterm::new();
|
||||
///
|
||||
/// use crossterm::{Crossterm, Screen}
|
||||
///
|
||||
/// // we need to enable raw mode otherwise the characters will be outputted by default before we are able to read them.
|
||||
/// crossterm.enable_raw_mode();
|
||||
/// let screen = Screen::new(true);
|
||||
/// let crossterm = Crossterm::new();
|
||||
///
|
||||
/// let mut stdin = crossterm.input().read_async().bytes();
|
||||
/// let mut stdin = crossterm.input(&screen).read_async().bytes();
|
||||
///
|
||||
/// for i in 0..100 {
|
||||
///
|
||||
@ -112,13 +112,14 @@ impl TerminalInput{
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let input = crossterm.input();
|
||||
/// let terminal = crossterm.terminal();
|
||||
/// let mut cursor = crossterm.cursor();
|
||||
///
|
||||
/// // we need to enable raw mode otherwise the characters will be outputted by default before we are able to read them.
|
||||
/// crossterm.enable_raw_mode();
|
||||
/// let screen = Screen::new(true);
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let input = crossterm.input(&screen);
|
||||
/// let terminal = crossterm.terminal(&screen);
|
||||
/// let mut cursor = crossterm.cursor(&screen);
|
||||
///
|
||||
///
|
||||
/// let mut stdin = input.read_until_async(b'\r').bytes();
|
||||
///
|
||||
@ -149,6 +150,7 @@ impl TerminalInput{
|
||||
}
|
||||
|
||||
/// Get an Terminal Input implementation whereon input related actions can be performed.
|
||||
/// Pass the reference to any screen you want this type to perform actions on.
|
||||
pub fn input(stdout: &Screen) -> TerminalInput {
|
||||
return TerminalInput::new(&stdout.stdout);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use self::windows_input::WindowsInput;
|
||||
pub use self::input::{input, TerminalInput};
|
||||
use super::Stdout;
|
||||
|
||||
use std::io::{self, Read};
|
||||
use std::io::{self, Read, Error, ErrorKind};
|
||||
use std::sync::{mpsc, Arc};
|
||||
use Screen;
|
||||
|
||||
@ -60,13 +60,13 @@ impl Read for AsyncReader {
|
||||
break;
|
||||
}
|
||||
|
||||
match self.recv.try_recv() {
|
||||
Ok(Ok(b)) => {
|
||||
buf[total] = b;
|
||||
match self.recv.try_iter().next() {
|
||||
Some(Ok(value)) => {
|
||||
buf[total] = value;
|
||||
total += 1;
|
||||
}
|
||||
Ok(Err(e)) => return Err(e),
|
||||
Err(_) => break,
|
||||
},
|
||||
_ => return Err(Error::new(ErrorKind::Other, "No characters pressed.")),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ use Screen;
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let colored_terminal = crossterm.color();
|
||||
/// use crossterm::{Screen, Crossterm}
|
||||
/// let colored_terminal = crossterm.color(&Screen::default());
|
||||
///
|
||||
/// // set foreground color
|
||||
/// colored_terminal.set_fg(Color::Red);
|
||||
@ -52,8 +52,7 @@ impl<'terminal> TerminalColor {
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let colored_terminal = crossterm.color();
|
||||
/// let colored_terminal = crossterm.color(&Screen::default());
|
||||
///
|
||||
/// // Set foreground color of the font
|
||||
/// colored_terminal.set_fg(Color::Red);
|
||||
@ -71,8 +70,7 @@ impl<'terminal> TerminalColor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let colored_terminal = crossterm.color();
|
||||
/// let colored_terminal = crossterm.color(&Screen::default());
|
||||
///
|
||||
/// // Set background color of the font
|
||||
/// colored_terminal.set_bg(Color::Red);
|
||||
@ -89,9 +87,7 @@ impl<'terminal> TerminalColor {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let colored_terminal = crossterm.color();
|
||||
///
|
||||
/// let colored_terminal = crossterm.color(&Screen::default());
|
||||
/// colored_terminal.reset();
|
||||
///
|
||||
/// ```
|
||||
@ -117,6 +113,7 @@ impl<'terminal> TerminalColor {
|
||||
}
|
||||
|
||||
/// Get an Terminal Color implementation whereon color related actions can be performed.
|
||||
/// Pass the reference to any screen you want this type to perform actions on.
|
||||
pub fn color(screen: &Screen) -> TerminalColor {
|
||||
TerminalColor::new(&screen.stdout)
|
||||
}
|
||||
|
@ -41,6 +41,26 @@ pub trait ITerminalColor {
|
||||
fn color_value(&self, color: Color, color_type: ColorType) -> String;
|
||||
}
|
||||
|
||||
/// This could be used to style an Displayable with colors and attributes.
|
||||
///
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// use crossterm::Screen;
|
||||
///
|
||||
/// // get an styled object which could be painted to the terminal.
|
||||
/// let styled_object = style("Some Blue colored text on black background").with(Color::Blue).on(Color::Black);
|
||||
///
|
||||
/// // create an default screen.
|
||||
/// let screen = Screen::default();
|
||||
///
|
||||
/// // print the styled font * times to the current screen.
|
||||
/// for i in 1..10
|
||||
/// {
|
||||
/// styled_object.paint(&screen);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn style<D>(val: D) -> StyledObject<D>
|
||||
where
|
||||
D: Display, {
|
||||
@ -105,12 +125,14 @@ pub enum ColorType {
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Color {
|
||||
/// Get an color from an &str like `Color::from("blue")`
|
||||
fn from(src: &str) -> Self {
|
||||
src.parse().unwrap_or(Color::White)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Color {
|
||||
/// Get an color from an &str like `Color::from(String::from(blue))`
|
||||
fn from(src: String) -> Self {
|
||||
src.parse().unwrap_or(Color::White)
|
||||
}
|
||||
@ -119,6 +141,7 @@ impl From<String> for Color {
|
||||
impl FromStr for Color {
|
||||
type Err = ();
|
||||
|
||||
/// Convert a string to an Color value
|
||||
fn from_str(src: &str) -> Result<Self, Self::Err> {
|
||||
let src = src.to_lowercase();
|
||||
|
||||
|
@ -24,19 +24,21 @@ impl<D: Display> StyledObject<D> {
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::style::{paint,Color};
|
||||
/// use self::crossterm::style::{style,Color};
|
||||
///
|
||||
/// // create an styled object with the foreground color red.
|
||||
/// let styledobject = paint("I am colored red").with(Color::Red);
|
||||
/// let styledobject = style("Some colored text").with(Color::Blue);
|
||||
/// // create an styled object with the foreground color blue.
|
||||
/// let styledobject1 = paint("I am colored blue").with(Color::Blue);
|
||||
/// let styledobject1 = style("Some colored text").with(Color::Blue);
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
///
|
||||
/// // print the styledobject to see the result
|
||||
/// println!("{}", styledobject);
|
||||
/// println!("{}", styledobject1);
|
||||
/// styledobject.paint(&screen);
|
||||
/// styledobject1.paint(&screen);
|
||||
///
|
||||
/// // print an styled object directly.
|
||||
/// println!("{}", paint("I am colored green").with(Color::Green));
|
||||
/// style("Some colored text").with(Color::Blue).paint(&screen);
|
||||
///
|
||||
/// ```
|
||||
pub fn with(mut self, foreground_color: Color) -> StyledObject<D> {
|
||||
@ -49,19 +51,21 @@ impl<D: Display> StyledObject<D> {
|
||||
/// #Example
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::style::{paint,Color};
|
||||
/// use self::crossterm::style::{style,Color};
|
||||
///
|
||||
/// // create an styled object with the background color red.
|
||||
/// let styledobject = paint("I am colored red").on(Color::Red);
|
||||
/// // create an styled object with the background color blue.
|
||||
/// let styledobject1 = paint("I am colored blue").on(Color::Blue);
|
||||
/// let styledobject = style("Some colored text").on(Color::Blue);
|
||||
/// // create an styled object with the foreground color blue.
|
||||
/// let styledobject1 = style("Some colored text").on(Color::Blue);
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
///
|
||||
/// // print the styledobject to see the result
|
||||
/// styledobject.paint(&screen);
|
||||
/// styledobject1.paint(&screen);
|
||||
///
|
||||
/// // print the styledobjects
|
||||
/// println!("{}", styledobject);
|
||||
/// println!("{}", styledobject1);
|
||||
/// // print an styled object directly.
|
||||
/// println!("{}", paint("I am colored green").on(Color::Green))
|
||||
/// style("Some colored text").on(Color::Blue).paint(&screen);
|
||||
///
|
||||
/// ```
|
||||
pub fn on(mut self, background_color: Color) -> StyledObject<D> {
|
||||
@ -76,9 +80,9 @@ impl<D: Display> StyledObject<D> {
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::style::{paint,Attribute};
|
||||
/// use self::crossterm::style::{style,Attribute};
|
||||
///
|
||||
/// println!("{}", paint("Bold").attr(Attribute::Bold));
|
||||
/// style("Some colored text").attr(Attribute::Bold).paint(&screen);
|
||||
///
|
||||
/// ```
|
||||
#[cfg(unix)]
|
||||
@ -142,6 +146,14 @@ impl<D: Display> StyledObject<D> {
|
||||
self.attr(Attribute::CrossedOut)
|
||||
}
|
||||
|
||||
/// This could be used to paint the styled object on the screen. Pass a refrence to the screen whereon you want to perform the painting.
|
||||
///
|
||||
/// ``` rust
|
||||
/// style("Some colored text")
|
||||
/// .with(Color::Blue)
|
||||
/// .on(Color::Black)
|
||||
/// .paint(&screen);
|
||||
/// ```
|
||||
pub fn paint(&self, screen: &Screen)
|
||||
{
|
||||
let mut colored_terminal = super::super::super::style::color::color(&screen);
|
||||
|
@ -50,7 +50,10 @@ impl ITerminal for AnsiTerminal {
|
||||
screen_manager.write_string(format!(csi!("8;{};{}t"), width, height));
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
fn exit(&self,screen_manager: &Arc<Stdout>) {
|
||||
// drop the screen with the current stdout. This will make sure when in raw mode this will be disabled first.
|
||||
let mut screen = Screen::from(screen_manager.clone());
|
||||
drop(screen);
|
||||
functions::exit_terminal();
|
||||
}
|
||||
}
|
||||
|
@ -44,5 +44,5 @@ pub trait ITerminal {
|
||||
/// Resize terminal to the given width and height.
|
||||
fn set_size(&self, width: i16, height: i16, screen_manager: &Arc<Stdout>);
|
||||
/// Close the current terminal
|
||||
fn exit(&self);
|
||||
fn exit(&self,screen_manager: &Arc<Stdout>);
|
||||
}
|
||||
|
@ -14,8 +14,9 @@ use std::io::Write;
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// use crossterm::terminal::terminal;
|
||||
///
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// term.scroll_down(5);
|
||||
/// term.scroll_up(4);
|
||||
@ -51,8 +52,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// // clear all cells in terminal.
|
||||
/// term.clear(terminal::ClearType::All);
|
||||
@ -76,12 +76,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// extern crate crossterm;
|
||||
/// use crossterm::terminal;
|
||||
/// use crossterm::Context;
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// let size = term.terminal_size();
|
||||
/// println!("{:?}", size);
|
||||
@ -97,8 +92,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// // scroll up by 5 lines
|
||||
/// let size = term.scroll_up(5);
|
||||
@ -114,8 +108,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// // scroll down by 5 lines
|
||||
/// let size = term.scroll_down(5);
|
||||
@ -131,8 +124,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// // Set of the size to X: 10 and Y: 10
|
||||
/// let size = term.set_size(10,10);
|
||||
@ -148,14 +140,13 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// let size = term.exit();
|
||||
///
|
||||
/// ```
|
||||
pub fn exit(&self) {
|
||||
self.terminal.exit();
|
||||
self.terminal.exit(&self.screen);
|
||||
}
|
||||
|
||||
/// Write any displayable content to the current terminal screen.
|
||||
@ -164,8 +155,7 @@ impl Terminal {
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// let crossterm = Crossterm::new();
|
||||
/// let term = crossterm.terminal();
|
||||
/// let term = terminal();
|
||||
///
|
||||
/// let size = term.write("Some text \n Some text on new line");
|
||||
///
|
||||
@ -178,7 +168,8 @@ impl Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get an terminal implementation whereon terminal related actions could performed
|
||||
/// Get an terminal implementation whereon terminal related actions could performed.
|
||||
/// Pass the reference to any screen you want this type to perform actions on.
|
||||
pub fn terminal(screen: &Screen) -> Terminal {
|
||||
Terminal::new(&screen.stdout)
|
||||
}
|
||||
|
@ -152,7 +152,10 @@ impl ITerminal for WinApiTerminal {
|
||||
}
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
fn exit(&self, screen_manager: &Arc<Stdout>) {
|
||||
// drop the screen with the current stdout. This will make sure when in raw mode this will be disabled first.
|
||||
let mut screen = Screen::from(screen_manager.clone());
|
||||
drop(screen);
|
||||
functions::exit_terminal();
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::sync::{Arc,Mutex};
|
||||
use std::io::{self, Read, Write,Stdout, stdout};
|
||||
use std::str::from_utf8;
|
||||
|
||||
/// This struct is an ANSI escape code implementation for screen related actions.
|
||||
/// This struct is a wrapper for `Stdout`
|
||||
pub struct AnsiStdout {
|
||||
pub handle: Stdout,
|
||||
}
|
||||
@ -35,7 +35,6 @@ impl IStdout for AnsiStdout {
|
||||
let out = &self.handle;
|
||||
let mut handle = out.lock();
|
||||
handle.flush();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,4 @@
|
||||
//! This module provides one place to work with the screen.
|
||||
//!
|
||||
//! In Rust we can call `stdout()` to get an handle to the current default console handle.
|
||||
//! For example when in unix systems you want to print something to the main screen you can use the following code:
|
||||
//!
|
||||
//! ```
|
||||
//! write!(std::io::stdout(), "{}", "some text").
|
||||
//! ```
|
||||
//!
|
||||
//! But things change when we are in alternate screen modes.
|
||||
//! We can not simply use `stdout()` to get a handle to the alternate screen, since this call returns the current default console handle (mainscreen).
|
||||
//!
|
||||
//! Instead we need to store an handle to the screen output.
|
||||
//! This handle could be used to put into alternate screen modes and back into main screen modes.
|
||||
//! Through this stored handle Crossterm can execute its command on the current screen whether it be alternate screen or main screen.
|
||||
//!
|
||||
//! For unix systems we store the handle gotten from `stdout()` for windows systems that are not supporting ANSI escape codes we store WinApi `HANDLE` struct witch will provide access to the current screen.
|
||||
//!
|
||||
//! This is the reason why this module exits: it is to provide access to the current terminal screen whether it will be the alternate screen and main screen.
|
||||
//! This module provides a way to work with an handle to an screen on different platforms.
|
||||
|
||||
mod stdout;
|
||||
|
||||
@ -35,8 +17,8 @@ use std::io;
|
||||
|
||||
use super::{functions};
|
||||
|
||||
/// This trait defines the actions that could be preformed on the current screen.
|
||||
/// This trait can be implemented so that an concrete implementation of the IScreenManager can forfill
|
||||
/// This trait defines represents an stdout of an screen.
|
||||
/// This trait can be implemented so that an concrete implementation of the IStdout can forfill
|
||||
/// the wishes to work on an specific platform.
|
||||
///
|
||||
/// ## For example:
|
||||
@ -44,7 +26,7 @@ use super::{functions};
|
||||
/// This trait is implemented for `WINAPI` (Windows specific) and `ANSI` (Unix specific),
|
||||
/// so that color related actions can be preformed on both unix and windows systems.
|
||||
pub trait IStdout {
|
||||
/// Write a &str to the current stdout.
|
||||
/// Write an &str to the current stdout and flush the screen.
|
||||
fn write_str(&self, string: &str ) -> io::Result<usize>;
|
||||
/// Write [u8] buffer to console.
|
||||
fn write(&self, buf: &[u8]) -> io::Result<usize>;
|
||||
@ -52,6 +34,5 @@ pub trait IStdout {
|
||||
fn flush(&self) -> io::Result<()>;
|
||||
|
||||
fn as_any(&self) -> &Any;
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut Any;
|
||||
}
|
||||
|
@ -23,13 +23,17 @@ use super::*;
|
||||
use std::any::Any;
|
||||
use std::fmt::Display;
|
||||
use std::io::{self, Write};
|
||||
use std::default::Default;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use winapi::um::winnt::HANDLE;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Struct that stores an specific platform implementation for screen related actions.
|
||||
/// Struct that is an handle to an terminal screen.
|
||||
/// This handle could be used to write to the current screen
|
||||
///
|
||||
/// For unix and windows 10 `stdout()` will be used for handle when on windows systems with versions lower than 10 WinApi `HANDLE` will be used.
|
||||
pub struct Stdout {
|
||||
screen_manager: Box<IStdout + Send>,
|
||||
pub is_in_raw_mode:bool,
|
||||
@ -67,6 +71,7 @@ impl Stdout {
|
||||
self.screen_manager.write_str(string)
|
||||
}
|
||||
|
||||
/// Write buffer to the screen
|
||||
pub fn write_buf(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.screen_manager.write(buf)
|
||||
}
|
||||
@ -74,8 +79,24 @@ impl Stdout {
|
||||
pub fn as_any(&self) -> &Any {
|
||||
self.screen_manager.as_any()
|
||||
}
|
||||
|
||||
pub fn as_any_mut(&mut self) -> &mut Any {
|
||||
self.screen_manager.as_any_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Stdout
|
||||
{
|
||||
/// Get the default handle to the current screen.
|
||||
fn default() -> Self {
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_manager = functions::get_module::<Box<IStdout + Send>>(
|
||||
Box::from(WinApiStdout::new()),
|
||||
Box::from(AnsiStdout::new()),
|
||||
).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_manager = Box::from(AnsiStdout::new()) as Box<IStdout + Send>;
|
||||
|
||||
Stdout { screen_manager , is_in_raw_mode: false}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use std::any::Any;
|
||||
use std::io::{self, Write};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// This struct is an WINAPI implementation for screen related actions.
|
||||
/// This struct is a wrapper for WINAPI `HANDLE`
|
||||
pub struct WinApiStdout {
|
||||
pub handle: HANDLE,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user