diff --git a/examples/Crossterm 0.3.1/bin.rs b/examples/Crossterm 0.3.1/bin.rs index 85d614d..b2f98ed 100644 --- a/examples/Crossterm 0.3.1/bin.rs +++ b/examples/Crossterm 0.3.1/bin.rs @@ -26,11 +26,9 @@ use crossterm::style::Color; use std::{thread, time}; fn main() { - let term = Crossterm::new(); - let mut cursor = term.cursor(); - cursor.goto(10, 10); - cursor.print("test"); - term.terminal().set_size(20,20); - let mut color = term.color(); - color.set_fg(Color::Red); + use crossterm::Crossterm; + + let mut term = Crossterm::new(); + let cursor = term.cursor(); + let a = term.color(); } diff --git a/examples/Crossterm 0.3.1/input/keyboard/input.rs b/examples/Crossterm 0.3.1/input/keyboard/input.rs index 2b1612b..0912931 100644 --- a/examples/Crossterm 0.3.1/input/keyboard/input.rs +++ b/examples/Crossterm 0.3.1/input/keyboard/input.rs @@ -1,7 +1,6 @@ extern crate crossterm; -use self::crossterm::input::input; -use self::crossterm::Context; +use self::crossterm::Crossterm; pub fn read_char() { let context = Context::new(); @@ -14,8 +13,8 @@ pub fn read_char() { } pub fn read_line() { - let context = Context::new(); - let input = input(&context); + let crossterm = Crossterm::new(); + let input = crossterm.input(); match input.read_line() { Ok(s) => println!("string typed: {}", s), diff --git a/src/common/commands/mod.rs b/src/common/commands/mod.rs index eb35d21..a56241c 100644 --- a/src/common/commands/mod.rs +++ b/src/common/commands/mod.rs @@ -1,7 +1,4 @@ -//! This module is used for managing the state changes of the terminal. -//! -//! If `crossterm` changes some core state of the terminal like: enabling ANSI or enabling raw mode it should be reverted when the current process ends. -//! It would be a little lame to let the terminal in raw mode after the the current process ends for the user of this library. +//! This module contains some commands that could be executed for specific task. use super::super::manager::ScreenManager; use std::io::Result; @@ -21,19 +18,20 @@ pub use self::unix_commands::*; pub use self::shared_commands::*; -/// This command is used for complex commands whits change the terminal state. -/// By passing an `Context` instance this command will register it self to notify the terminal state change. +/// This trait provides a way to execute some state changing commands. pub trait IStateCommand { fn execute(&mut self) -> bool; fn undo(&mut self) -> bool; } +/// This trait provides an interface for switching to alternate screen and back. pub trait IAlternateScreenCommand { - fn to_alternate_screen(&self,screen_manager: &mut ScreenManager) -> Result<()>; - fn to_main_screen(&self, screen_manager: &mut ScreenManager) -> Result<()>; + fn enable(&self,screen_manager: &mut ScreenManager) -> Result<()>; + fn disable(&self, screen_manager: &mut ScreenManager) -> Result<()>; } +/// This trait provides an interface for switching to raw mode and back. pub trait IRawScreenCommand { fn enable(&mut self) -> Result<()>; diff --git a/src/common/commands/shared_commands.rs b/src/common/commands/shared_commands.rs index d0dde5d..23955f2 100644 --- a/src/common/commands/shared_commands.rs +++ b/src/common/commands/shared_commands.rs @@ -1,24 +1,27 @@ -//! This module contains the commands that can be used for both unix and windows systems. Or else said terminals that support ansi codes. +//! This module contains the commands that can be used for both unix and windows 10 systems because they support ANSI escape codes + use super::{IAlternateScreenCommand, ScreenManager}; use std::io::Result; /// This command is used for switching to alternate screen and back to main screen. -pub struct ToAlternateScreenBufferCommand; +pub struct ToAlternateScreenCommand; -impl ToAlternateScreenBufferCommand { - pub fn new() -> Box { - return Box::new(ToAlternateScreenBufferCommand {}); +impl ToAlternateScreenCommand { + pub fn new() -> Box { + return Box::new(ToAlternateScreenCommand {}); } } -impl IAlternateScreenCommand for ToAlternateScreenBufferCommand { - fn to_alternate_screen(&self, screen_manager: &mut ScreenManager) -> Result<()> { +impl IAlternateScreenCommand for ToAlternateScreenCommand { + /// enable alternate screen. + fn enable(&self, screen_manager: &mut ScreenManager) -> Result<()> { screen_manager.write_str(csi!("?1049h")); Ok(()) } - fn to_main_screen(&self, screen_manager: &mut ScreenManager) -> Result<()> { + /// disable alternate screen. + fn disable(&self, screen_manager: &mut ScreenManager) -> Result<()> { screen_manager.write_str(csi!("?1049l")); Ok(()) } diff --git a/src/common/crossterm.rs b/src/common/crossterm.rs index cb5af17..1a7ceb8 100644 --- a/src/common/crossterm.rs +++ b/src/common/crossterm.rs @@ -14,12 +14,13 @@ use std::io::Result; pub struct Crossterm { raw_mode: bool, alternate_mode: bool, - active_screen: manager::ScreenManager, + pub active_screen: manager::ScreenManager, raw_terminal: Option>, alternate_screen: Option> } -impl Crossterm{ +impl<'crossterm> Crossterm +{ pub fn new() -> Crossterm { Crossterm @@ -98,6 +99,7 @@ impl Crossterm{ return Ok(()) } + pub fn cursor(&self) -> cursor::TerminalCursor { cursor::TerminalCursor::new(&self.active_screen) } @@ -127,4 +129,41 @@ impl Drop for Crossterm raw_terminal.disable(); } } -} \ No newline at end of file +} + + + +/// Wraps an displayable object so it can be formatted with colors and attributes. + /// + /// Check `/examples/color` in the libary for more spesific examples. + /// + /// #Example + /// + /// ```rust + /// extern crate crossterm; + /// + /// use self::crossterm::style::{paint,Color}; + /// + /// fn main() + /// { + /// // Create an styledobject object from the text 'Unstyled font' + /// // Currently it has the default foregroundcolor and backgroundcolor. + /// println!("{}",paint("Unstyled font")); + /// + /// // Create an displayable object from the text 'Colored font', + /// // Paint this with the `Red` foreground color and `Blue` backgroundcolor. + /// // Print the result. + /// let styledobject = paint("Colored font").with(Color::Red).on(Color::Blue); + /// println!("{}", styledobject); + /// + /// // Or all in one line + /// println!("{}", paint("Colored font").with(Color::Red).on(Color::Blue)); + /// } + /// + /// ``` +// pub fn paint(&self, val: D) -> style::StyledObject +// where +// D: fmt::Display, +// { +// style::ObjectStyle::new().apply_to(val, self.context.clone()) +// } \ No newline at end of file diff --git a/src/common/screen/alternate.rs b/src/common/screen/alternate.rs index 61b6afd..07e51b2 100644 --- a/src/common/screen/alternate.rs +++ b/src/common/screen/alternate.rs @@ -16,72 +16,11 @@ //! //! 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 `Context` -//! -//! // create context. -//! let context = crossterm::Context::new(); -//! // create instance of Alternatescreen by the given context, this wil also switch to it. -//! let mut screen = crossterm::AlternateScreen::from(context.clone()); -//! // write to the alternate screen. -//! write!(screen, "test"); -//! //! Create alternate screen from `Crossterm`: //! -//! // create crossterm. -//! let crossterm = ::crossterm::Crossterm::new(); -//! // create instance of Alternatescreen by the given refrence to crossterm, this wil also switch to it. -//! let mut screen = crossterm::AlternateScreen::from(&crossterm); -//! // write to the alternate screen. -//! write!(screen, "test"); //! -//! 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. +//! Todo: example //! -//! -//! Please check the documentation of `Context` for more info. -//! But basically this Context is a wrapper for a type that provides access to the current screen whether it would be the main screen or alternate screen. -//! -//! -//! An example of what I mean by that: -//! -//! // create context. -//! let context = crossterm::Context::new(); -//! -//! let mut cursor = ::crossterm::cursor::cursor(&context); -//! cursor.goto(10,10); -//! -//! // create instance of Alternatescreen by the given refrence to crossterm, this wil also switch to it. -//! let mut screen = crossterm::AlternateScreen::from(&context); -//! -//! // now this cursor will be moving on the alternate screen sice it is using the same context as we have passed to the alternatescreen. -//! cursor.goto(5,4) -//! -//! To make things easier you can better use `Crossterm` type for the interactions with alternate screen. -//! This type will manage the `Context` internally. -//! -//! So when using this type to switch to AlternateScreen. It will use the `Context` from the type `Crossterm` for the `AlternateSceen`. -//! -//! For example: -//! -//! // create crossterm instance. -//! let crossterm = ::crossterm::Crossterm::new(); -//! -//! let mut cursor = crossterm.cursor(); -//! cursor.goto(10,10); -//! -//! // create instance of Alternatescreen by the given refrence to crossterm, this wil also switch to it. -//! let mut screen = crossterm::AlternateScreen::from(&crossterm); -//! -//! // this cursor will be moving on the alternate screen since the current screen is the alternate screen. -//! let mut cursor = crossterm.cursor(); -//! cursor.goto(10,10); -//! -//! As you can see because we are using `Crossterm` we won't have to bother about the `Context`. use super::{functions, ScreenManager}; use super::commands; @@ -92,9 +31,7 @@ use std::io::{self, Write}; pub struct AlternateScreen; impl AlternateScreen { - /// Get the alternate screen from the context. - /// By calling this method the current screen will be changed to the alternate screen. - /// And you get back an handle for that screen. + /// Create an new alternate screen type. pub fn new() -> Box { #[cfg(target_os = "windows")] let command = functions::get_module::>( diff --git a/src/common/screen/mod.rs b/src/common/screen/mod.rs index 1f1e711..e954da9 100644 --- a/src/common/screen/mod.rs +++ b/src/common/screen/mod.rs @@ -1,3 +1,5 @@ +//! This module provides some modules to work with the terminal screen. Like raw and alternate screen. + mod raw; mod alternate; diff --git a/src/common/screen/raw.rs b/src/common/screen/raw.rs index 89a3b18..2370db7 100644 --- a/src/common/screen/raw.rs +++ b/src/common/screen/raw.rs @@ -26,6 +26,7 @@ use std::io::{self, Write}; pub struct RawScreen; impl RawScreen { + /// Create a new RawScreen type. pub fn new() -> Box { Box::from(EnableRawModeCommand::new()) } diff --git a/src/kernel/windows_kernel/csbi.rs b/src/kernel/windows_kernel/csbi.rs index de07996..3505ac0 100644 --- a/src/kernel/windows_kernel/csbi.rs +++ b/src/kernel/windows_kernel/csbi.rs @@ -1,3 +1,5 @@ +//! This contains the logic for working with the console buffer. + use winapi::shared::minwindef::{FALSE, TRUE}; use winapi::shared::ntdef::NULL; use winapi::um::minwinbase::SECURITY_ATTRIBUTES; diff --git a/src/kernel/windows_kernel/handle.rs b/src/kernel/windows_kernel/handle.rs index af1c98f..1cebf77 100644 --- a/src/kernel/windows_kernel/handle.rs +++ b/src/kernel/windows_kernel/handle.rs @@ -1,3 +1,5 @@ +//! This module contains some logic for working with the console handle. + use winapi::um::processenv::GetStdHandle; use winapi::um::handleapi::INVALID_HANDLE_VALUE; use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE}; diff --git a/src/kernel/windows_kernel/kernel.rs b/src/kernel/windows_kernel/kernel.rs index fd40a23..e93c28e 100644 --- a/src/kernel/windows_kernel/kernel.rs +++ b/src/kernel/windows_kernel/kernel.rs @@ -1,4 +1,4 @@ -//! This module is the core of all the `WINAPI` actions. All unsafe `WINAPI` function call are done here. +//! This module contains some basic winapi calls. use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode}; use winapi::um::winnt::HANDLE; diff --git a/src/kernel/windows_kernel/terminal.rs b/src/kernel/windows_kernel/terminal.rs index 34f9549..8401c16 100644 --- a/src/kernel/windows_kernel/terminal.rs +++ b/src/kernel/windows_kernel/terminal.rs @@ -1,3 +1,5 @@ +//! This module contains terminal specific logic. + use super::{csbi, handle, ScreenManager}; /// Get the terminal size diff --git a/src/kernel/windows_kernel/writing.rs b/src/kernel/windows_kernel/writing.rs index 748343c..9d3afbf 100644 --- a/src/kernel/windows_kernel/writing.rs +++ b/src/kernel/windows_kernel/writing.rs @@ -1,3 +1,5 @@ +//! This module contains the logic to write to the terminal. + use winapi::ctypes::c_void; use winapi::shared::ntdef::NULL; use winapi::um::consoleapi::WriteConsoleW; diff --git a/src/modules/cursor/cursor.rs b/src/modules/cursor/cursor.rs index 1d7e1cd..f52f3b7 100644 --- a/src/modules/cursor/cursor.rs +++ b/src/modules/cursor/cursor.rs @@ -9,6 +9,30 @@ use std::io::Write; use std::fmt::Display; /// Struct that stores an specific platform implementation for cursor related actions. +/// +/// Check `/examples/version/cursor` in the library for more specific examples. +/// +/// #Example +/// +/// ```rust +/// +/// extern crate crossterm; +/// use self::crossterm::Crossterm; +/// +/// let term = Crossterm::new(); +/// let mut cursor = term.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<'cursor> { screen_manager: &'cursor ScreenManager, terminal_cursor: Box, @@ -38,19 +62,11 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// pub fn goto() - /// { - /// let context = Context::new(); - /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // Set the cursor to position X: 10, Y: 5 in the terminal - /// cursor.goto(10,5); - /// } + /// // change the cursor to position, x: 4 and y: 5 + /// cursor.goto(4,5); /// /// ``` pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor<'cursor> { @@ -64,19 +80,11 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// pub fn pos() - /// { - /// let context = Context::new(); - /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // get the cursor position. - /// let (x,y) = cursor.pos(); - /// } + /// // get the current cursor pos + /// let (x,y) = cursor.pos(); /// /// ``` pub fn pos(&self) -> (u16, u16) { @@ -84,24 +92,15 @@ impl<'cursor> TerminalCursor<'cursor> { } /// Move the current cursor position `n` times up. - /// /// #Example /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// pub fn move_up() - /// { - /// let context = Context::new(); - /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // Move the cursor to position 3 times to the up in the terminal - /// cursor.move_up(3); - /// } + /// // 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<'cursor> { @@ -114,19 +113,12 @@ impl<'cursor> TerminalCursor<'cursor> { /// #Example /// /// ```rust - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; /// - /// pub fn move_right() - /// { - /// let context = Context::new(); + /// 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); /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // 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<'cursor> { self.terminal_cursor.move_right(count, &self.screen_manager); @@ -139,19 +131,11 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// pub fn move_down() - /// { - /// let context = Context::new(); - /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // 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<'cursor> { @@ -165,19 +149,11 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// pub fn move_left() - /// { - /// let context = Context::new(); - /// - /// // Get the cursor - /// let mut cursor = cursor(&context); - /// // Move the cursor to position 3 times to the left in the terminal - /// cursor.move_left(3); - /// } + /// // Move the cursor to position 3 times to the left in the terminal + /// cursor.move_left(3); /// /// ``` pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor<'cursor> { @@ -208,10 +184,11 @@ impl<'cursor> TerminalCursor<'cursor> { /// use std; /// use std::io::Write; /// - /// let context = Context::new(); + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// /// // of course we can just do this. - /// cursor::cursor(&context).goto(10,10); + /// cursor.goto(10,10); /// print!("@"); /// std::io::stdout().flush(); /// @@ -239,12 +216,10 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::Context; - /// use self::crossterm::cursor; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// let context = Context::new(); - /// cursor::cursor(&context).safe_position(); + /// cursor.safe_position(); /// /// ``` pub fn save_position(&self) { @@ -259,12 +234,10 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::cursor::cursor; - /// use self::crossterm::Context; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// let context = Context::new(); - /// cursor(&context).reset_position(); + /// cursor.reset_position(); /// /// ``` pub fn reset_position(&self) { @@ -277,12 +250,10 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::cursor::cursor; - /// use self::crossterm::Context; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// let context = Context::new(); - /// cursor(&context).hide(); + /// cursor.hide(); /// /// ``` pub fn hide(&self) { @@ -295,12 +266,10 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::cursor::cursor; - /// use self::crossterm::Context; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// let context = Context::new(); - /// cursor(&context).show(); + /// cursor.show(); /// /// ``` pub fn show(&self) { @@ -315,12 +284,9 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ```rust /// - /// extern crate crossterm; - /// use self::crossterm::cursor::cursor; - /// use self::crossterm::Context; + /// let crossterm = Crossterm::new(); + /// let cursor = crossterm.cursor(); /// - /// let context = Context::new(); - /// let cursor = cursor(&context); /// cursor.blink(true); /// cursor.blink(false); /// @@ -330,33 +296,7 @@ impl<'cursor> TerminalCursor<'cursor> { } } -// Get an TerminalCursor implementation whereon cursor related actions can be performed. -// -// Check `/examples/version/cursor` in the libary for more spesific examples. -// -// #Example -// -// ```rust -// -// extern crate crossterm; -// use self::crossterm::Context; -// use self::crossterm::cursor; -// -// let context = Context::new(); -// -// // Get cursor and goto pos X: 5, Y: 10 -// let mut cursor = cursor::cursor(&context); -// cursor.goto(5,10); -// -// cursor.show(); -// cursor.hide(); -// cursor.blink(); -// cursor.move_left(2); -// -// //Or you can do it in one line. -// cursor::cursor(&context).goto(5,10); -// -// ``` +/// Get an TerminalCursor implementation whereon cursor related actions can be performed. pub fn cursor(screen_manager: &ScreenManager) -> TerminalCursor { TerminalCursor::new(screen_manager) } diff --git a/src/modules/cursor/mod.rs b/src/modules/cursor/mod.rs index 6e0a546..6cb6a58 100644 --- a/src/modules/cursor/mod.rs +++ b/src/modules/cursor/mod.rs @@ -1,12 +1,5 @@ -//! This trait defines the actions that can be preformed with the terminal cursor. -//! This trait can be implemented so that an concrete implementation of the ITerminalCursor can for fill -//! the wishes to work on an specific platform. -//! -//! ## For example: -//! -//! This trait is implemented to work with WINAPI (Windows specific) and ANSI (Unix specific), -//! so that the cursor related actions can be preformed on both unix and windows systems. -//! +//! With this module you can perform actions that are cursor related. +//! Like moving the cursor position;saving and resetting the cursor position; hiding showing and control the blinking of the cursor. mod cursor; diff --git a/src/modules/cursor/winapi_cursor.rs b/src/modules/cursor/winapi_cursor.rs index 9bbb6a8..48c7c48 100644 --- a/src/modules/cursor/winapi_cursor.rs +++ b/src/modules/cursor/winapi_cursor.rs @@ -1,6 +1,7 @@ //! This is an WINAPI specific implementation for cursor related action. //! This module is used for windows terminals that do not support ANSI escape codes. //! Note that the cursor position is 0 based. This means that we start counting at 0 when setting the cursor position ect. + use super::super::manager::{ScreenManager, WinApiScreenManager}; use super::ITerminalCursor; diff --git a/src/modules/input/input.rs b/src/modules/input/input.rs index 1646ecc..7051ca2 100644 --- a/src/modules/input/input.rs +++ b/src/modules/input/input.rs @@ -1,13 +1,36 @@ +//! With this module you can perform actions that are input related. +//! Like reading a line, reading a character and reading asynchronously. + use std::io; 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. +/// +/// #Example +/// +/// ```rust +/// +/// extern crate crossterm; +/// use self::crossterm::Crossterm; +/// +/// let crossterm = Crossterm::new(); +/// let input = crossterm.input(); +/// +/// let result = input.read_line(); +/// let pressed_char = input.read_char(); +/// +/// ``` pub struct TerminalInput<'terminal> { terminal_input: Box, screen_manager: &'terminal ScreenManager } impl<'terminal> TerminalInput<'terminal> { + + /// Create new instance of TerminalInput whereon input related actions could be preformed. pub fn new(screen_manager: &'terminal ScreenManager) -> TerminalInput<'terminal> { #[cfg(target_os = "windows")] let input = Box::from(WindowsInput::new()); @@ -21,23 +44,111 @@ impl<'terminal> TerminalInput<'terminal> { } } + /// Read one line from the user input. + /// + /// #Example + /// + /// ```rust + /// let crossterm = Crossterm::new(); + /// match crossterm.input().read_line() { + /// Ok(s) => println!("string typed: {}", s), + /// Err(e) => println!("error: {}", e), + /// } + /// + /// ``` pub fn read_line(&self) -> io::Result { self.terminal_input.read_line(&self.screen_manager) } + /// Read one character from the user input + /// + /// #Example + /// + /// ```rust + /// let crossterm = Crossterm::new(); + /// match crossterm.input().read_char() { + /// Ok(c) => println!("character pressed: {}", c), + /// Err(e) => println!("error: {}", e), + // } + /// + /// ``` pub fn read_char(&self) -> io::Result { return self.terminal_input.read_char(&self.screen_manager); } + /// Read the input asynchronously from the user. + /// + /// #Example + /// + /// ```rust + /// let crossterm = Crossterm::new(); + /// + /// // 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 mut stdin = crossterm.input().read_async().bytes(); + /// + /// for i in 0..100 { + /// + /// // Get the next character typed. This is None if nothing is pressed. And Some(Ok(u8 value of character)) + /// let a = stdin.next(); + /// + /// println!("pressed key: {:?}", a); + /// + /// if let Some(Ok(b'x')) = a { + /// println!("The key: `x` was pressed and program is terminated."); + /// break; + /// } + /// // simulate some timeout so that we can see the character on the screen. + /// thread::sleep(time::Duration::from_millis(50)); + /// } + /// + /// ``` pub fn read_async(&self) -> AsyncReader { self.terminal_input.read_async(&self.screen_manager) } + /// Read the input asynchronously until a certain character is hit. + /// + /// #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 mut stdin = input.read_until_async(b'\r').bytes(); + /// + /// for i in 0..100 { + /// terminal.clear(ClearType::All); + /// cursor.goto(1, 1); + /// let a = stdin.next(); + /// + /// println!("pressed key: {:?}", a); + /// + /// if let Some(Ok(b'\r')) = a { + /// println!("The enter key is hit and program is not listening to input anymore."); + /// break; + /// } + /// + /// if let Some(Ok(b'x')) = a { + /// println!("The key: x was pressed and program is terminated."); + /// break; + /// } + /// + /// thread::sleep(time::Duration::from_millis(100)); + /// } + /// ``` pub fn read_until_async(&self, delimiter: u8) -> AsyncReader { self.terminal_input.read_until_async(delimiter,&self.screen_manager) } } +/// Get an Terminal Input implementation whereon input related actions can be performed. pub fn input(screen_manager: &ScreenManager) -> TerminalInput { return TerminalInput::new(screen_manager) } diff --git a/src/modules/input/mod.rs b/src/modules/input/mod.rs index 87be14f..19c733f 100644 --- a/src/modules/input/mod.rs +++ b/src/modules/input/mod.rs @@ -1,3 +1,6 @@ +//! With this module you can perform actions that are input related. +//! Like reading a line, reading a character and reading asynchronously. + mod input; #[cfg(not(target_os = "windows"))] @@ -16,15 +19,28 @@ use super::ScreenManager; use std::io::{Read, self}; use std::sync::mpsc; +/// This trait defines the actions that can be preformed with the terminal color. +/// This trait can be implemented so that an concrete implementation of the ITerminalColor can forfill +/// the wishes to work on an specific platform. +/// +/// ## For example: +/// +/// This trait is implemented for Windows and UNIX systems. +/// Unix is using the tty and windows is using libc C functions to read the input. trait ITerminalInput { + /// Read one line from the user input fn read_line(&self, screen_manger: &ScreenManager) -> io::Result; - + /// Read one character from the user input fn read_char(&self, screen_manger: &ScreenManager) -> io::Result; - + /// Read the input asynchronously from the user. fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader; + /// Read the input asynchronously until a certain character is hit. fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader; } +/// This is a wrapper for reading from the input asynchronously. +/// This wrapper has a channel receiver that receives the input from the user whenever it typed something. +/// You only need to check whether there are new characters available. pub struct AsyncReader { recv: mpsc::Receiver>, } diff --git a/src/modules/input/unix_input.rs b/src/modules/input/unix_input.rs index abe4281..8cadc76 100644 --- a/src/modules/input/unix_input.rs +++ b/src/modules/input/unix_input.rs @@ -1,3 +1,5 @@ +//! This is an UNIX specific implementation for input related action. + use std::char; use std::io::{self, Read, Write}; use std::sync::mpsc; diff --git a/src/modules/input/windows_input.rs b/src/modules/input/windows_input.rs index 3b06b37..0e058a8 100644 --- a/src/modules/input/windows_input.rs +++ b/src/modules/input/windows_input.rs @@ -1,3 +1,5 @@ +//! This is an WINDOWS specific implementation for input related action. + use std::char; use std::io::{self,Write}; use std::sync::mpsc; @@ -78,7 +80,6 @@ impl ITerminalInput for WindowsInput { thread::spawn(move || { loop { - // _getwch is without echo and _getwche is with echo let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } }; @@ -123,7 +124,6 @@ impl ITerminalInput for WindowsInput { } } - fn is_line_end(key: char) -> bool { if key as u8 == 13 { return true; diff --git a/src/modules/manager/ansi_manager.rs b/src/modules/manager/ansi_manager.rs index c6862b0..c40bc6a 100644 --- a/src/modules/manager/ansi_manager.rs +++ b/src/modules/manager/ansi_manager.rs @@ -6,13 +6,14 @@ use super::IScreenManager; use std::any::Any; use std::io::{self, Read, Write}; -use std::sync::Mutex; +use std::cell::RefCell ; use std::str::from_utf8; +/// This struct is an ANSI escape code implementation for screen related actions. pub struct AnsiScreenManager { is_alternate_screen: bool, is_raw_screen: bool, - output: Mutex> + output: RefCell> } impl IScreenManager for AnsiScreenManager { @@ -33,28 +34,21 @@ impl IScreenManager for AnsiScreenManager { } fn write_str(&self, string: &str) -> io::Result { - { - let mx = &self.output; - - let mut output = mx.lock().unwrap(); - write!(output, "{}", string)?; - } - self.flush(); + let mut output = self.output.borrow_mut(); + write!(output, "{}", string)?; Ok(0) } fn write(&self, buf: &[u8]) -> io::Result { { - let mx = &self.output; - let mut output = mx.lock().unwrap(); + let mut output = self.output.borrow_mut(); output.write(buf)?; } Ok(0) } fn flush(&self) -> io::Result<()> { - let mx = &self.output; - let mut output = mx.lock().unwrap(); + let mut output = self.output.borrow_mut(); output.flush() } @@ -70,7 +64,7 @@ impl IScreenManager for AnsiScreenManager { impl AnsiScreenManager { pub fn new() -> Self { AnsiScreenManager { - output: Mutex::new(Box::from(io::stdout()) as Box), + output: RefCell::new(Box::from(io::stdout()) as Box), is_alternate_screen: false, is_raw_screen: false, } diff --git a/src/modules/manager/manager.rs b/src/modules/manager/manager.rs index 23374ea..5eb4658 100644 --- a/src/modules/manager/manager.rs +++ b/src/modules/manager/manager.rs @@ -1,5 +1,22 @@ -//! This module provides an interface for working with the screen. With that I mean that you can get or wirte to the handle of the current screen. stdout. -//! Because crossterm can work with alternate screen, we need a place that holds the handle to the current screen so we can write to that screen. +//! 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. use super::*; @@ -28,7 +45,7 @@ impl ScreenManager { let screen_manager = Box::from(AnsiScreenManager::new()) as Box; ScreenManager { - screen_manager: screen_manager, + screen_manager, } } @@ -68,12 +85,12 @@ impl ScreenManager { self.screen_manager.write_str(string) } - /// Can be used to get an specific implementation used for the current platform. + /// Can be used to get an reference to an specific implementation used for the current platform. pub fn as_any(&self) -> &Any { self.screen_manager.as_any() } - /// Can be used to get an specific implementation used for the current platform. + /// Can be used to get an mutable reference to an specific implementation used for the current platform. pub fn as_any_mut(&mut self) -> &mut Any { self.screen_manager.as_any_mut() } diff --git a/src/modules/manager/mod.rs b/src/modules/manager/mod.rs index 7a0b884..a962d30 100644 --- a/src/modules/manager/mod.rs +++ b/src/modules/manager/mod.rs @@ -16,7 +16,7 @@ //! //! 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 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. mod manager; @@ -34,6 +34,14 @@ use super::functions; use std::any::Any; use std::io; +/// 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 +/// the wishes to work on an specific platform. +/// +/// ## For example: +/// +/// 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 IScreenManager { fn set_is_raw_screen(&mut self, value: bool); fn set_is_alternate_screen(&mut self, value: bool); diff --git a/src/modules/manager/win_manager.rs b/src/modules/manager/win_manager.rs index 6403e36..f25f7af 100644 --- a/src/modules/manager/win_manager.rs +++ b/src/modules/manager/win_manager.rs @@ -6,6 +6,7 @@ use winapi::um::winnt::HANDLE; use std::any::Any; use std::io::{self, Write}; +/// This struct is an WINAPI implementation for screen related actions. pub struct WinApiScreenManager { is_alternate_screen: bool, is_raw_screen: bool, @@ -54,8 +55,9 @@ impl IScreenManager for WinApiScreenManager { } } -// for winapi we have some custom implementation that will be used by windows only. You can get a reference to this implementation by using the any and that cast it to this struct. +// for winapi we have some custom implementation that will be used by windows only. You can get a reference to this implementation by using the `as_any()` and that cast it to this struct. impl WinApiScreenManager { + /// Create a new instance. pub fn new() -> Self { WinApiScreenManager { output: handle::get_output_handle().unwrap(), diff --git a/src/modules/style/ansi_color.rs b/src/modules/style/ansi_color.rs index fc12ece..b06d24b 100644 --- a/src/modules/style/ansi_color.rs +++ b/src/modules/style/ansi_color.rs @@ -3,7 +3,7 @@ use super::{ITerminalColor, Color, ScreenManager, ColorType}; -/// This struct is an ansi implementation for color related actions. +/// This struct is an ANSI escape code implementation for color related actions. pub struct AnsiColor; impl AnsiColor { diff --git a/src/modules/style/color.rs b/src/modules/style/color.rs index 0512ac7..ebc26de 100644 --- a/src/modules/style/color.rs +++ b/src/modules/style/color.rs @@ -2,10 +2,27 @@ //! Like styling the font, foreground color and background. use super::*; - use std::io; /// Struct that stores an specific platform implementation for color related actions. +/// +/// Check `/examples/version/color` in the library for more specific examples. +/// +/// #Example +/// +/// ```rust +/// +/// let crossterm = Crossterm::new(); +/// let colored_terminal = crossterm.color(); +/// +/// // set foreground color +/// colored_terminal.set_fg(Color::Red); +/// // set background color +/// colored_terminal.set_bg(Color::Red); +/// // reset color to default +/// colored_terminal.reset(); +/// +/// ``` pub struct TerminalColor<'terminal> { color: Box, screen_manager: &'terminal ScreenManager @@ -34,15 +51,8 @@ impl<'terminal> TerminalColor<'terminal> { /// #Example /// /// ```rust - /// extern crate crossterm; - /// - /// use self::crossterm::style::{ color, Color}; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// - /// // Get colored terminal instance - /// let mut colored_terminal = color(&context); + /// let crossterm = Crossterm::new(); + /// let colored_terminal = crossterm.color(); /// /// // Set foreground color of the font /// colored_terminal.set_fg(Color::Red); @@ -60,15 +70,8 @@ impl<'terminal> TerminalColor<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// - /// use self::crossterm::style::{ color, Color}; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// - /// // Get colored terminal instance - /// let mut colored_terminal = color(&context); + /// let crossterm = Crossterm::new(); + /// let colored_terminal = crossterm.color(); /// /// // Set background color of the font /// colored_terminal.set_bg(Color::Red); @@ -84,15 +87,9 @@ impl<'terminal> TerminalColor<'terminal> { /// # Example /// /// ```rust - /// extern crate crossterm; /// - /// use self::crossterm::style::color; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// - /// // Get colored terminal instance - /// let mut colored_terminal = color(&context); + /// let crossterm = Crossterm::new(); + /// let colored_terminal = crossterm.color(); /// /// colored_terminal.reset(); /// @@ -118,10 +115,7 @@ impl<'terminal> TerminalColor<'terminal> { } } -/// Get an Color implementation whereon color related actions can be performed. -/// -/// Check `/examples/version/color` in the library for more specific examples. -/// +/// Get an Terminal Color implementation whereon color related actions can be performed. pub fn color(screen_manager: &ScreenManager) -> TerminalColor { TerminalColor::new(screen_manager) } diff --git a/src/modules/style/mod.rs b/src/modules/style/mod.rs index 01b5d05..b276bd9 100644 --- a/src/modules/style/mod.rs +++ b/src/modules/style/mod.rs @@ -1,3 +1,5 @@ +//! Module that contains all the actions related to the styling of the terminal. like coloring adding attributes etc. + pub mod color; pub mod objectstyle; pub mod styledobject; @@ -18,14 +20,14 @@ pub use self::styledobject::StyledObject; pub use self::objectstyle::ObjectStyle; use super::{ScreenManager, functions}; -///! This trait defines the actions that can be preformed with the terminal color. -///! This trait can be implemented so that an concrete implementation of the ITerminalColor can forfill -///! the wishes to work on an specific platform. -///! -///! ## For example: -///! -///! 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. +/// This trait defines the actions that can be preformed with the terminal color. +/// This trait can be implemented so that an concrete implementation of the ITerminalColor can forfill +/// the wishes to work on an specific platform. +/// +/// ## For example: +/// +/// 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 ITerminalColor { /// Set the foreground color to the given color. fn set_fg(&self, fg_color: Color, screen_manager: &ScreenManager); @@ -37,6 +39,7 @@ pub trait ITerminalColor { fn color_value(&self, color: Color, color_type: ColorType) -> String; } +/// Attributes that could be applied on some text. #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)] pub enum Attribute { Bold = 1, @@ -50,7 +53,7 @@ pub enum Attribute { CrossedOut = 9, } -/// Colors that are available for coloring the termainal font. +/// Colors that are available for coloring the terminal font. #[derive(Debug, Copy, Clone)] pub enum Color { Black, diff --git a/src/modules/style/objectstyle.rs b/src/modules/style/objectstyle.rs index 6a5f5dc..72c4454 100644 --- a/src/modules/style/objectstyle.rs +++ b/src/modules/style/objectstyle.rs @@ -30,7 +30,7 @@ impl Default for ObjectStyle { impl ObjectStyle { /// Apply an `StyledObject` to the passed displayable object. - pub fn apply_to<'style, D: Display>(&self, val: D, screen_manager: &'style ScreenManager) -> StyledObject<'style,D> { + pub fn apply_to<'style, D: Display>(&self, val: D, screen_manager: &'style mut ScreenManager) -> StyledObject<'style,D> { StyledObject { object_style: self.clone(), screen_manager: screen_manager, @@ -61,6 +61,7 @@ impl ObjectStyle { } #[cfg(unix)] + /// Add an attribute to the current text. Like italic or bold. pub fn add_attr(&mut self, attr: Attribute) { self.attrs.push(attr); } diff --git a/src/modules/style/styledobject.rs b/src/modules/style/styledobject.rs index f659465..4715c42 100644 --- a/src/modules/style/styledobject.rs +++ b/src/modules/style/styledobject.rs @@ -1,4 +1,5 @@ //! This module contains the logic to style an object that contains some state witch can be styled. + use super::{ScreenManager, ObjectStyle, Color}; use std::fmt::{self, Display}; @@ -14,7 +15,7 @@ use super::super::super::manager::WinApiScreenManager; pub struct StyledObject<'terminal, D: Display> { pub object_style: ObjectStyle, pub content: D, - pub screen_manager: &'terminal ScreenManager, + pub screen_manager: &'terminal mut ScreenManager, } impl<'terminal,D: Display> StyledObject<'terminal,D> { @@ -144,7 +145,7 @@ impl<'terminal,D: Display> StyledObject<'terminal,D> { impl<'terminal, D: Display> Display for StyledObject<'terminal,D> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let mut colored_terminal = super::super::super::style::color::color(&self.screen_manager); + let mut colored_terminal = super::super::super::style::color::color(self.screen_manager); let mut reset = true; if let Some(bg) = self.object_style.bg_color { diff --git a/src/modules/style/winapi_color.rs b/src/modules/style/winapi_color.rs index 77830fc..ac0372c 100644 --- a/src/modules/style/winapi_color.rs +++ b/src/modules/style/winapi_color.rs @@ -1,3 +1,8 @@ +//! This is an `WINAPI` specific implementation for styling related action. +//! This module is used for non supporting `ANSI` windows terminals. +//! +//! Windows versions lower then windows 10 are not supporting ANSI codes. Those versions will use this implementation instead. + use super::super::super::manager::WinApiScreenManager; use super::{Color, ColorType, ITerminalColor, ScreenManager}; use kernel::windows_kernel::{csbi, kernel}; diff --git a/src/modules/terminal/ansi_terminal.rs b/src/modules/terminal/ansi_terminal.rs index 39f7077..6ef1fac 100644 --- a/src/modules/terminal/ansi_terminal.rs +++ b/src/modules/terminal/ansi_terminal.rs @@ -4,7 +4,7 @@ use super::super::cursor::cursor; use super::{ClearType, ITerminal, ScreenManager, functions}; -/// This struct is an ansi implementation for terminal related actions. +/// This struct is an ansi escape code implementation for terminal related actions. pub struct AnsiTerminal; impl AnsiTerminal { diff --git a/src/modules/terminal/mod.rs b/src/modules/terminal/mod.rs index 143d3b0..e64646e 100644 --- a/src/modules/terminal/mod.rs +++ b/src/modules/terminal/mod.rs @@ -1,10 +1,4 @@ -//! Module that contains all the actions related to the terminal. -//! -//! We can think of: -//! - alternate screen -//! - raw mode -//! - clearing resizing scrolling the terminal. -//! +//! Module that contains all the actions related to the terminal. like clearing, resizing and scrolling the terminal. pub mod terminal; @@ -19,7 +13,7 @@ use self::ansi_terminal::AnsiTerminal; pub use self::terminal::Terminal; use super::{ ScreenManager, functions }; -/// Enum that can be used for the kind of clearing that can be done in the terminal. +/// Enum that specifies a way of clearing. pub enum ClearType { All, FromCursorDown, @@ -28,14 +22,14 @@ pub enum ClearType { UntilNewLine, } -///! This trait defines the actions that can be preformed with the terminal. -///! This trait can be implemented so that an concrete implementation of the ITerminal can forfill -///! the wishes to work on an specific platform. -///! -///! ## For example: -///! -///! This trait is implemented for `WINAPI` (Windows specific) and `ANSI` (Unix specific), -///! so that cursor related actions can be preformed on both unix and windows systems. +/// This trait defines the actions that can be preformed with the terminal color. +/// This trait can be implemented so that an concrete implementation of the ITerminalColor can forfill +/// the wishes to work on an specific platform. +/// +/// ## For example: +/// +/// 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 ITerminal { /// Clear the current cursor by specifying the clear type fn clear(&self, clear_type: ClearType, screen_manager: &ScreenManager); diff --git a/src/modules/terminal/terminal.rs b/src/modules/terminal/terminal.rs index ed17126..1241761 100644 --- a/src/modules/terminal/terminal.rs +++ b/src/modules/terminal/terminal.rs @@ -7,6 +7,21 @@ use std::fmt; use std::io::Write; /// Struct that stores an specific platform implementation for terminal related actions. +/// +/// Check `/examples/version/terminal` in the library for more specific examples. +/// +/// #Example +/// +/// ```rust +/// +/// let crossterm = Crossterm::new(); +/// let term = crossterm.terminal(); +/// +/// term.scroll_down(5); +/// term.scroll_up(4); +/// let (with, height) = term.terminal_size(); +/// +/// ``` pub struct Terminal<'terminal> { terminal: Box, screen_manager: &'terminal ScreenManager, @@ -36,12 +51,8 @@ impl<'terminal> Terminal<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// // clear all cells in terminal. /// term.clear(terminal::ClearType::All); @@ -55,8 +66,8 @@ impl<'terminal> Terminal<'terminal> { /// term.clear(terminal::ClearType::UntilNewLine); /// /// ``` - pub fn clear(&self, clear_type: ClearType) { - self.terminal.clear(clear_type, &self.screen_manager); + pub fn clear(&mut self, clear_type: ClearType) { + self.terminal.clear(clear_type, &mut self.screen_manager); } /// Get the terminal size (x,y). @@ -69,8 +80,8 @@ impl<'terminal> Terminal<'terminal> { /// use crossterm::terminal; /// use crossterm::Context; /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// let size = term.terminal_size(); /// println!("{:?}", size); @@ -86,12 +97,8 @@ impl<'terminal> Terminal<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// // scroll up by 5 lines /// let size = term.scroll_up(5); @@ -107,12 +114,8 @@ impl<'terminal> Terminal<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// // scroll down by 5 lines /// let size = term.scroll_down(5); @@ -128,12 +131,8 @@ impl<'terminal> Terminal<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// // Set of the size to X: 10 and Y: 10 /// let size = term.set_size(10,10); @@ -143,53 +142,14 @@ impl<'terminal> Terminal<'terminal> { self.terminal.set_size(width, height,&self.screen_manager); } - /// Wraps an displayable object so it can be formatted with colors and attributes. - /// - /// Check `/examples/color` in the libary for more spesific examples. - /// - /// #Example - /// - /// ```rust - /// extern crate crossterm; - /// - /// use self::crossterm::style::{paint,Color}; - /// - /// fn main() - /// { - /// // Create an styledobject object from the text 'Unstyled font' - /// // Currently it has the default foregroundcolor and backgroundcolor. - /// println!("{}",paint("Unstyled font")); - /// - /// // Create an displayable object from the text 'Colored font', - /// // Paint this with the `Red` foreground color and `Blue` backgroundcolor. - /// // Print the result. - /// let styledobject = paint("Colored font").with(Color::Red).on(Color::Blue); - /// println!("{}", styledobject); - /// - /// // Or all in one line - /// println!("{}", paint("Colored font").with(Color::Red).on(Color::Blue)); - /// } - /// - /// ``` -// pub fn paint(&self, val: D) -> style::StyledObject -// where -// D: fmt::Display, -// { -// style::ObjectStyle::new().apply_to(val, self.context.clone()) -// } - /// Exit the current process. /// /// #Example /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// let size = term.exit(); /// @@ -204,12 +164,8 @@ impl<'terminal> Terminal<'terminal> { /// /// ```rust /// - /// extern crate crossterm; - /// use crossterm::terminal; - /// use crossterm::Context; - /// - /// let context = Context::new(); - /// let mut term = terminal::terminal(&context); + /// let crossterm = Crossterm::new(); + /// let term = crossterm.terminal(); /// /// let size = term.write("Some text \n Some text on new line"); /// @@ -222,27 +178,7 @@ impl<'terminal> Terminal<'terminal> { } } -/// Get an Terminal implementation whereon terminal related actions can be performed. -/// -/// Check `/examples/version/terminal` in the libary for more spesific examples. -/// -/// #Example -/// -/// ```rust -/// -/// extern crate crossterm; -/// use crossterm::terminal; -/// use crossterm::Context; -/// -/// let context = Context::new(); -/// -/// let mut term = terminal::terminal(&context); -/// -/// // scroll down by 5 lines -/// let size = term.scroll_down(5); -/// -/// ``` -/// -pub fn terminal(screen_manager: &ScreenManager) -> Terminal { +/// Get an terminal implementation whereon terminal related actions could performed +pub fn terminal(screen_manager: &mut ScreenManager) -> Terminal { Terminal::new(screen_manager) } diff --git a/src/modules/terminal/winapi_terminal.rs b/src/modules/terminal/winapi_terminal.rs index 7b46c6a..835f57e 100644 --- a/src/modules/terminal/winapi_terminal.rs +++ b/src/modules/terminal/winapi_terminal.rs @@ -1,12 +1,14 @@ //! This is an `WINAPI` specific implementation for terminal related action. //! This module is used for non supporting `ANSI` windows terminals. +//! +//! Windows versions lower then windows 10 are not supporting ANSI codes. Those versions will use this implementation instead. use super::{ClearType, ITerminal, ScreenManager, functions}; use super::super::super::cursor::cursor; use kernel::windows_kernel::{csbi, kernel, terminal, writing}; use winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT}; -/// This struct is an windows implementation for terminal related actions. +/// This struct is an winapi implementation for terminal related actions. pub struct WinApiTerminal; impl WinApiTerminal { @@ -21,7 +23,7 @@ impl ITerminal for WinApiTerminal { let pos = cursor(screen_manager).pos(); match clear_type { - ClearType::All => clear_entire_screen(csbi, &screen_manager), + ClearType::All => { clear_entire_screen(csbi, screen_manager); }, ClearType::FromCursorDown => clear_after_cursor(pos, csbi, screen_manager), ClearType::FromCursorUp => clear_before_cursor(pos, csbi, screen_manager), ClearType::CurrentLine => clear_current_line(pos, csbi, screen_manager), @@ -57,8 +59,6 @@ impl ITerminal for WinApiTerminal { // Set srctWindow to the current window size and location. let mut srct_window = csbi.srWindow; - // panic!("window top: {} , window bottom: {} | {}, {}", srct_window.Top, srct_window.Bottom, csbi.dwSize.Y, csbi.dwSize.X); - // Set srctWindow to the current window size and location. srct_window = csbi.srWindow; @@ -201,7 +201,7 @@ pub fn clear_before_cursor( // get sum cells before cursor let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1); - clear(start_location, cells_to_write, &screen_manager); + clear(start_location, cells_to_write, screen_manager); } pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, screen_manager: &ScreenManager) { @@ -222,7 +222,7 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, screen_manager: &Sc clear(start_location, cells_to_write, &screen_manager); // put the cursor back at (0, 0) - cursor(&screen_manager).goto(0, 0); + cursor(screen_manager).goto(0, 0); } pub fn clear_current_line( @@ -247,7 +247,7 @@ pub fn clear_current_line( clear(start_location, cells_to_write, screen_manager); // put the cursor back at 1 cell on current row - cursor(&screen_manager).goto(0, y); + cursor(screen_manager).goto(0, y); } pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, screen_manager: &ScreenManager) { @@ -264,7 +264,7 @@ pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, scree clear(start_location, cells_to_write, &screen_manager); // put the cursor back at original cursor position - cursor(&screen_manager).goto(x, y); + cursor(screen_manager).goto(x, y); } fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &ScreenManager) { @@ -292,6 +292,6 @@ fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &ScreenMana ); if !success { - panic!("Couldnot reset attributes after cursor"); + panic!("Could not reset attributes after cursor"); } } diff --git a/write_test/Cargo.toml b/write_test/Cargo.toml new file mode 100644 index 0000000..0272728 --- /dev/null +++ b/write_test/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "write_test" +version = "0.1.0" +authors = ["TimonPost "] + +[dependencies] diff --git a/write_test/src/main.rs b/write_test/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/write_test/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}