From 4212e728d52e4978fc06ea7e4a1a6385b7b3a7d2 Mon Sep 17 00:00:00 2001 From: T Date: Tue, 30 Jan 2018 21:20:11 +0100 Subject: [PATCH 01/11] Issue #3 and #4 are now solved, windows tested unix not yet --- .idea/workspace.xml | 573 +++++++++++++-------- examples/bin.rs | 5 +- examples/color/mod.rs | 4 +- examples/cursor/mod.rs | 30 +- examples/terminal/mod.rs | 45 +- src/crossterm_cursor/ansi_cursor.rs | 2 +- src/crossterm_cursor/base_cursor.rs | 2 +- src/crossterm_cursor/cursor.rs | 80 ++- src/crossterm_cursor/mod.rs | 2 +- src/crossterm_cursor/winapi_cursor.rs | 2 +- src/crossterm_mouse/mod.rs | 0 src/crossterm_style/color/color.rs | 48 +- src/crossterm_style/mod.rs | 2 +- src/crossterm_style/styles/styledobject.rs | 2 +- src/crossterm_terminal/mod.rs | 2 +- src/crossterm_terminal/terminal.rs | 60 +-- src/kernel/windows_kernel/ansi_support.rs | 2 + 17 files changed, 484 insertions(+), 377 deletions(-) delete mode 100644 src/crossterm_mouse/mod.rs diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2d91b20..a0f7c4d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,7 +3,22 @@ - + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -28,8 +138,6 @@ - color - termin Coord winapi kernel32 @@ -55,6 +163,11 @@ handle:: wincon CONSOLE_SCREEN_BUFFER_INFO + safe_position + init + cursor::get() + get() + get crossterm_cursor @@ -75,36 +188,38 @@ @@ -115,10 +230,10 @@ DEFINITION_ORDER - @@ -135,6 +250,8 @@ + + @@ -171,13 +288,24 @@ + + + + + + + + + + + + + + + + - + @@ -437,15 +508,21 @@ - + + + + + + - + @@ -460,7 +537,7 @@ - + @@ -473,7 +550,7 @@ - + @@ -487,43 +564,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -531,13 +571,6 @@ - - - - - - - @@ -545,13 +578,6 @@ - - - - - - - @@ -566,50 +592,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -617,13 +600,6 @@ - - - - - - - @@ -641,27 +617,6 @@ - - - - - - - - - - - - - - - - - - - - - @@ -669,97 +624,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - @@ -767,7 +636,20 @@ - + + + + + + + + + + + + + + @@ -775,76 +657,13 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -852,14 +671,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/bin.rs b/examples/bin.rs index 02257e0..65ea4f0 100644 --- a/examples/bin.rs +++ b/examples/bin.rs @@ -25,6 +25,7 @@ pub mod cursor; pub mod terminal; fn main() { - terminal::clear_all_lines(); - cursor::print(); + color::paint_background(); + color::paint_foreground(); + color::paint_foreground_and_background(); } diff --git a/examples/terminal/mod.rs b/examples/terminal/mod.rs index 6eca10e..8d50a81 100644 --- a/examples/terminal/mod.rs +++ b/examples/terminal/mod.rs @@ -80,7 +80,7 @@ pub fn clear_until_new_line() print_test_data(); // Set terminal cursor position (see example for more info). - crossterm_cursor::cursor().goto(4,7); + crossterm_cursor::cursor().goto(4,20); // Clear all the cells until next line. terminal.clear(ClearType::UntilNewLine); @@ -92,7 +92,7 @@ pub fn print_terminal_size() // Get terminal let mut terminal = terminal(); // Get terminal size - let terminal_size = terminal.terminal_size().unwrap(); + let terminal_size = terminal.terminal_size(); // Print results print!("X: {}, y: {}", terminal_size.0, terminal_size.1); } diff --git a/src/crossterm_cursor/cursor.rs b/src/crossterm_cursor/cursor.rs index 48c9933..73defdb 100644 --- a/src/crossterm_cursor/cursor.rs +++ b/src/crossterm_cursor/cursor.rs @@ -6,9 +6,7 @@ use std::fmt::Display; use Construct; use super::base_cursor::ITerminalCursor; -#[cfg(unix)] use super::AnsiCursor; -#[cfg(windows)] use super::WinApiCursor; /// Struct that stores an specific platform implementation for cursor related actions. @@ -19,12 +17,25 @@ pub struct TerminalCursor { impl TerminalCursor { /// Create new cursor instance whereon cursor related actions can be performed. pub fn new() -> TerminalCursor { - let cursor: Option> = { - #[cfg(unix)] - Some(AnsiCursor::new()); + let mut cursor: Option> = None; + + let mut does_support = true; + if cfg!(target_os = "windows") { #[cfg(windows)] - Some(WinApiCursor::new()) - }; + use kernel::windows_kernel::kernel::try_enable_ansi_support; + + does_support = try_enable_ansi_support(); + // this returns an bool if the current windows console supports ansi. + if !does_support + { + cursor = Some(WinApiCursor::new()); + } + } + + if does_support + { + cursor = Some(AnsiCursor::new()); + } TerminalCursor { terminal_cursor: cursor } } diff --git a/src/crossterm_cursor/mod.rs b/src/crossterm_cursor/mod.rs index 0c2bc82..aee4a3b 100644 --- a/src/crossterm_cursor/mod.rs +++ b/src/crossterm_cursor/mod.rs @@ -1,14 +1,10 @@ mod base_cursor; mod cursor; -#[cfg(unix)] mod ansi_cursor; -#[cfg(windows)] mod winapi_cursor; -#[cfg(unix)] use self::ansi_cursor::AnsiCursor; -#[cfg(windows)] use self::winapi_cursor::WinApiCursor; pub use self::cursor::{ cursor, TerminalCursor }; diff --git a/src/crossterm_style/color/ansi_color.rs b/src/crossterm_style/color/ansi_color.rs index bd1419f..bda84a1 100644 --- a/src/crossterm_style/color/ansi_color.rs +++ b/src/crossterm_style/color/ansi_color.rs @@ -9,15 +9,15 @@ use super::base_color::ITerminalColor; /// This struct is an ansi implementation for color related actions. #[derive(Debug)] -pub struct ANSIColor; +pub struct AnsiColor; -impl Construct for ANSIColor { - fn new() -> Box { - Box::from(ANSIColor {}) +impl Construct for AnsiColor { + fn new() -> Box { + Box::from(AnsiColor {}) } } -impl ITerminalColor for ANSIColor { +impl ITerminalColor for AnsiColor { fn set_fg(&self, fg_color: Color) { let mut some_writer = io::stdout(); write!(&mut some_writer, csi!("{}m"), self.color_value(fg_color, ColorType::Foreground)); @@ -47,7 +47,7 @@ impl ITerminalColor for ANSIColor { }, } - let rgb_val; + let rgb_val: String; let color_val = match color { Color::Black => "5;0", @@ -65,7 +65,9 @@ impl ITerminalColor for ANSIColor { Color::DarkCyan => "5;6", Color::Grey => "5;15", Color::White => "5;7", + #[cfg(unix)] Color::Rgb{r,g,b} => { rgb_val = format!("2;{};{};{}", r,g,b); rgb_val.as_str()}, + #[cfg(unix)] Color::AnsiValue(val) => { rgb_val = format!("5;{}",val); rgb_val.as_str() } }; diff --git a/src/crossterm_style/color/color.rs b/src/crossterm_style/color/color.rs index 1e0a0bf..ca455af 100644 --- a/src/crossterm_style/color/color.rs +++ b/src/crossterm_style/color/color.rs @@ -9,9 +9,7 @@ use crossterm_style::{ObjectStyle, StyledObject}; use super::base_color::ITerminalColor; use super::super::Color; -#[cfg(unix)] -use super::ANSIColor; -#[cfg(windows)] +use super::AnsiColor; use super::WinApiColor; /// Struct that stores an specific platform implementation for color related actions. @@ -22,12 +20,25 @@ pub struct TerminalColor { impl TerminalColor { /// Create new instance whereon color related actions can be performed. pub fn new() -> TerminalColor { - let color: Option> = { - #[cfg(unix)] - Some(ANSIColor::new()); + let mut color: Option> = None; + + let mut does_support = true; + if cfg!(target_os = "windows") { #[cfg(windows)] - Some(WinApiColor::new()) - }; + use kernel::windows_kernel::kernel::try_enable_ansi_support; + + does_support = try_enable_ansi_support(); + // this returns an bool if the current windows console supports ansi. + if !does_support + { + color = Some(WinApiColor::new()); + } + } + + if does_support + { + color = Some(AnsiColor::new()); + } TerminalColor { terminal_color: color } } diff --git a/src/crossterm_style/color/mod.rs b/src/crossterm_style/color/mod.rs index 4f294e0..65acbc3 100644 --- a/src/crossterm_style/color/mod.rs +++ b/src/crossterm_style/color/mod.rs @@ -1,12 +1,8 @@ pub mod base_color; pub mod color; -#[cfg(unix)] mod ansi_color; -#[cfg(windows)] mod winapi_color; -#[cfg(unix)] -use self::ansi_color::ANSIColor; -#[cfg(windows)] +use self::ansi_color::AnsiColor; use self::winapi_color::WinApiColor; diff --git a/src/crossterm_terminal/ansi_terminal.rs b/src/crossterm_terminal/ansi_terminal.rs index 332bb42..d704fe1 100644 --- a/src/crossterm_terminal/ansi_terminal.rs +++ b/src/crossterm_terminal/ansi_terminal.rs @@ -3,21 +3,20 @@ use std::io::Write; use Construct; use super::base_terminal::{ClearType, ITerminal}; -use kernel::linux_kernel::terminal::*; +use shared::functions::resize_terminal; /// This struct is an ansi implementation for terminal related actions. -pub struct UnixTerminal; +pub struct AnsiTerminal ; -impl Construct for UnixTerminal { - fn new() -> Box { - Box::from(UnixTerminal {}) +impl Construct for AnsiTerminal { + fn new() -> Box { + Box::from(AnsiTerminal {}) } } -impl ITerminal for UnixTerminal { +impl ITerminal for AnsiTerminal { fn clear(&self, clear_type: ClearType) { let mut some_writer = io::stdout(); - match clear_type { ClearType::All => { write!(&mut some_writer, csi!("2J")); @@ -37,8 +36,8 @@ impl ITerminal for UnixTerminal { }; } - fn terminal_size(&self) -> Option<(u16, u16)> { - terminal_size() + fn terminal_size(&self) -> (u16, u16) { + resize_terminal() } fn scroll_up(&self, count: i16) { diff --git a/src/crossterm_terminal/base_terminal.rs b/src/crossterm_terminal/base_terminal.rs index b2b0716..ff06f69 100644 --- a/src/crossterm_terminal/base_terminal.rs +++ b/src/crossterm_terminal/base_terminal.rs @@ -11,7 +11,7 @@ pub trait ITerminal { /// Clear the current cursor by specifying the clear type fn clear(&self, clear_type: ClearType); /// Get the terminal size (x,y) - fn terminal_size(&self) -> Option<(u16, u16)>; + fn terminal_size(&self) -> (u16, u16); /// Scroll `n` lines up in the current terminal. fn scroll_up(&self, count: i16); /// Scroll `n` lines down in the current terminal. diff --git a/src/crossterm_terminal/mod.rs b/src/crossterm_terminal/mod.rs index 3f067eb..3a3c0ca 100644 --- a/src/crossterm_terminal/mod.rs +++ b/src/crossterm_terminal/mod.rs @@ -1,14 +1,10 @@ mod base_terminal; mod terminal; -#[cfg(unix)] mod ansi_terminal; -#[cfg(windows)] mod winapi_terminal; -#[cfg(unix)] -use self::ansi_terminal::UnixTerminal; -#[cfg(windows)] +use self::ansi_terminal::AnsiTerminal; use self::winapi_terminal::WinApiTerminal; pub use self::base_terminal::ClearType; diff --git a/src/crossterm_terminal/terminal.rs b/src/crossterm_terminal/terminal.rs index dc321ba..10e32b5 100644 --- a/src/crossterm_terminal/terminal.rs +++ b/src/crossterm_terminal/terminal.rs @@ -1,12 +1,11 @@ //! With this module you can perform actions that are terminal related. //! Like clearing and scrolling in the terminal or getting the size of the terminal. + use Construct; use super::base_terminal::{ClearType, ITerminal}; -#[cfg(unix)] -use super::UnixTerminal; -#[cfg(windows)] +use super::AnsiTerminal; use super::WinApiTerminal; /// Struct that stores an specific platform implementation for terminal related actions. @@ -17,13 +16,25 @@ pub struct Terminal { impl Terminal { /// Create new terminal instance whereon terminal related actions can be performed. pub fn new() -> Terminal { - let term: Option> = + let mut term: Option> = None; + + let mut does_support = true; + if cfg!(target_os = "windows") { + use kernel::windows_kernel::kernel::try_enable_ansi_support; + + does_support = try_enable_ansi_support(); + // this returns an bool if the current windows console supports ansi. + if !does_support + { + term = Some(WinApiTerminal::new()); + } + } + + if does_support { - #[cfg(unix)] - Some(UnixTerminal::new()); - #[cfg(windows)] - Some(WinApiTerminal::new()) - }; + println!("This console does support ansi"); + term = Some(AnsiTerminal::new()); + } Terminal { terminal: term } } @@ -72,13 +83,11 @@ impl Terminal { /// println!("{:?}", size); /// /// ``` - pub fn terminal_size(&mut self) -> Option<(u16, u16)> { + pub fn terminal_size(&mut self) -> (u16, u16) { if let Some(ref terminal) = self.terminal { - let a = terminal.terminal_size(); - a - } else { - None + return terminal.terminal_size() } + (0,0) } /// Scroll `n` lines up in the current terminal. diff --git a/src/crossterm_terminal/winapi_terminal.rs b/src/crossterm_terminal/winapi_terminal.rs index 72032c4..34eca28 100644 --- a/src/crossterm_terminal/winapi_terminal.rs +++ b/src/crossterm_terminal/winapi_terminal.rs @@ -14,6 +14,7 @@ impl Construct for WinApiTerminal { impl ITerminal for WinApiTerminal { fn clear(&self, clear_type: ClearType) { + println! ("Windows!!!"); match clear_type { ClearType::All => terminal::clear_entire_screen(), @@ -24,7 +25,7 @@ impl ITerminal for WinApiTerminal { }; } - fn terminal_size(&self) -> Option<(u16, u16)> { + fn terminal_size(&self) -> (u16, u16) { terminal::terminal_size() } diff --git a/src/kernel/linux_kernel/terminal.rs b/src/kernel/linux_kernel/terminal.rs index f2e814f..14e9a56 100644 --- a/src/kernel/linux_kernel/terminal.rs +++ b/src/kernel/linux_kernel/terminal.rs @@ -16,7 +16,7 @@ pub struct UnixSize { } /// Gets the current terminal size -pub fn terminal_size() -> Option<(u16,u16)> { +pub fn terminal_size() -> (u16,u16) { // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc let us = UnixSize { rows: 0, @@ -29,6 +29,6 @@ pub fn terminal_size() -> Option<(u16,u16)> { // because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results. Some((us.cols -1, us.rows -1)) } else { - None + (0,0) } } \ No newline at end of file diff --git a/src/kernel/windows_kernel/ansi_support.rs b/src/kernel/windows_kernel/ansi_support.rs deleted file mode 100644 index a3978af..0000000 --- a/src/kernel/windows_kernel/ansi_support.rs +++ /dev/null @@ -1,9 +0,0 @@ -///! Notice that this feature is not used. But will be implemented later. - -use super::kernel; - -/// Enables ansi for windows terminals. -pub fn enable_ansi_support() { - let enable_ansi_code: u32 = 7; - kernel::set_console_mode(enable_ansi_code); -} \ No newline at end of file diff --git a/src/kernel/windows_kernel/cursor.rs b/src/kernel/windows_kernel/cursor.rs index e719b9c..0587f59 100644 --- a/src/kernel/windows_kernel/cursor.rs +++ b/src/kernel/windows_kernel/cursor.rs @@ -7,6 +7,7 @@ static mut SAVED_CURSOR_POS:(i16,i16) = (0,0); pub fn set(x: i16, y: i16) { kernel::set_console_cursor_position(x, y ); + } /// Reset to saved cursor position diff --git a/src/kernel/windows_kernel/kernel.rs b/src/kernel/windows_kernel/kernel.rs index 0ee22c9..4c1c649 100644 --- a/src/kernel/windows_kernel/kernel.rs +++ b/src/kernel/windows_kernel/kernel.rs @@ -1,17 +1,19 @@ +use winapi::shared::minwindef::DWORD; use winapi::um::winnt::HANDLE; -use winapi::um::winbase::STD_OUTPUT_HANDLE; +use winapi::um::winbase::{STD_OUTPUT_HANDLE, STD_INPUT_HANDLE }; use winapi::um::handleapi::INVALID_HANDLE_VALUE; use winapi::um::processenv::{GetStdHandle}; -use winapi::um::consoleapi::{SetConsoleMode}; +use winapi::um::consoleapi::{SetConsoleMode,GetConsoleMode}; use winapi::um::wincon::{ SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo, - FillConsoleOutputCharacterA, FillConsoleOutputAttribute, - CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD + FillConsoleOutputCharacterA, FillConsoleOutputAttribute, ENABLE_VIRTUAL_TERMINAL_PROCESSING,ENABLE_VIRTUAL_TERMINAL_INPUT, + CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, DISABLE_NEWLINE_AUTO_RETURN }; use super::{Empty}; static mut CONSOLE_OUTPUT_HANDLE: Option = None; +static mut CONSOLE_INPUT_HANDLE: Option = None; /// Get the std_output_handle of the console pub fn get_output_handle() -> HANDLE { @@ -20,18 +22,43 @@ pub fn get_output_handle() -> HANDLE { handle } else { let handle = GetStdHandle(STD_OUTPUT_HANDLE); + + if !is_valid_handle(&handle) + { + panic!("Cannot get output handle") + } + CONSOLE_OUTPUT_HANDLE = Some(handle); handle } } } +/// Get the std_input_handle of the console +pub fn get_input_handle() -> HANDLE { + unsafe { + if let Some(handle) = CONSOLE_INPUT_HANDLE { + handle + } else { + let handle = GetStdHandle(STD_INPUT_HANDLE); + + if !is_valid_handle(&handle) + { + panic!("Cannot get input handle") + } + + CONSOLE_INPUT_HANDLE = Some(handle); + handle + } + } +} + /// Checks if the console handle is an invalid handle value. pub fn is_valid_handle(handle: &HANDLE) -> bool { if *handle == INVALID_HANDLE_VALUE { - true - } else { false + } else { + true } } @@ -50,6 +77,26 @@ pub fn get_console_screen_buffer_info() -> CONSOLE_SCREEN_BUFFER_INFO { csbi } +/// Enables ansi for windows terminals. +pub fn try_enable_ansi_support() -> bool { + + let output_handle = get_output_handle(); + + let mut dw_mode: DWORD = 0; + if !get_console_mode(&output_handle, &mut dw_mode) + { + return false; + } + + dw_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if !set_console_mode(&output_handle, dw_mode) + { + return false; + } + + return true; +} + pub fn get_largest_console_window_size() -> COORD { let output_handle = get_output_handle(); @@ -64,12 +111,19 @@ pub fn get_original_console_color() -> u16 { console_buffer_info.wAttributes as u16 } -pub fn set_console_mode(console_mode: u32) +pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool { - let output_handle = get_output_handle(); - unsafe { - SetConsoleMode(output_handle, console_mode); + let success = SetConsoleMode(*handle, console_mode); + return is_true(success); + } +} + +pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool +{ + unsafe { + let success = GetConsoleMode(*handle, &mut *current_mode); + return is_true(success); } } @@ -170,9 +224,9 @@ pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: CO fn is_true(value: i32) -> bool { if value == 0{ - false + return false; } else{ - true + return true; } } diff --git a/src/kernel/windows_kernel/mod.rs b/src/kernel/windows_kernel/mod.rs index 3f0d4d7..a5fe20e 100644 --- a/src/kernel/windows_kernel/mod.rs +++ b/src/kernel/windows_kernel/mod.rs @@ -1,6 +1,5 @@ pub mod cursor; pub mod color; -pub mod ansi_support; pub mod kernel; pub mod terminal; mod winapi_extentions; diff --git a/src/kernel/windows_kernel/terminal.rs b/src/kernel/windows_kernel/terminal.rs index e7851cc..f8a36b4 100644 --- a/src/kernel/windows_kernel/terminal.rs +++ b/src/kernel/windows_kernel/terminal.rs @@ -2,13 +2,13 @@ use super::{cursor, kernel}; use winapi::um::wincon::{SMALL_RECT, COORD}; /// Get the terminal size (y,x) -pub fn terminal_size() -> Option<(u16, u16)> { +pub fn terminal_size() -> (u16, u16) { let csbi = kernel::get_console_screen_buffer_info(); - Some(( + ( (csbi.srWindow.Right - csbi.srWindow.Left) as u16, (csbi.srWindow.Bottom - csbi.srWindow.Top) as u16, - )) + ) } /// Scroll down `n` rows diff --git a/src/shared/functions.rs b/src/shared/functions.rs new file mode 100644 index 0000000..8da81f7 --- /dev/null +++ b/src/shared/functions.rs @@ -0,0 +1,9 @@ +#[cfg(unix)] +use kernel::linux_kernel::terminal::terminal_size; +#[cfg(windows)] +use kernel::windows_kernel::terminal::terminal_size; + +pub fn resize_terminal() -> (u16,u16) +{ + terminal_size() +} \ No newline at end of file diff --git a/src/shared/mod.rs b/src/shared/mod.rs index 65134bb..a507168 100644 --- a/src/shared/mod.rs +++ b/src/shared/mod.rs @@ -1,3 +1,4 @@ #[macro_use] pub mod macros; pub mod traits; +pub mod functions; From 524955f8c05dd8bf473bb61288aedcae9328435a Mon Sep 17 00:00:00 2001 From: T Date: Sat, 3 Mar 2018 15:40:51 +0100 Subject: [PATCH 03/11] } --- .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/workspace.xml | 1015 +++++++++-------- Cargo.toml | 11 +- examples/bin.rs | 34 +- src/Terminal.rs | 6 + src/crossterm_cursor/ansi_cursor.rs | 5 +- src/crossterm_cursor/base_cursor.rs | 2 +- src/crossterm_cursor/cursor.rs | 38 +- src/crossterm_cursor/winapi_cursor.rs | 27 +- src/crossterm_state/commands/mod.rs | 45 + .../commands/shared_commands.rs | 36 + src/crossterm_state/commands/unix_command.rs | 95 ++ src/crossterm_state/commands/win_commands.rs | 220 ++++ src/crossterm_state/context.rs | 72 ++ src/crossterm_state/mod.rs | 4 + src/crossterm_style/color/ansi_color.rs | 3 +- src/crossterm_style/color/color.rs | 31 +- src/crossterm_style/color/winapi_color.rs | 107 +- src/crossterm_style/styles/objectstyle.rs | 1 + src/crossterm_style/styles/styledobject.rs | 1 + src/crossterm_terminal/ansi_terminal.rs | 5 +- src/crossterm_terminal/base_terminal.rs | 2 +- src/crossterm_terminal/mod.rs | 6 +- src/crossterm_terminal/raw_terminal.rs | 55 + src/crossterm_terminal/screen/mod.rs | 118 ++ src/crossterm_terminal/terminal.rs | 34 +- src/crossterm_terminal/winapi_terminal.rs | 229 +++- src/kernel/linux_kernel/terminal.rs | 34 - src/kernel/mod.rs | 2 +- .../{linux_kernel => unix_kernel}/mod.rs | 1 + src/kernel/unix_kernel/terminal.rs | 115 ++ src/kernel/windows_kernel/ansi_support.rs | 69 ++ src/kernel/windows_kernel/color.rs | 108 -- src/kernel/windows_kernel/cursor.rs | 21 +- src/kernel/windows_kernel/kernel.rs | 117 +- src/kernel/windows_kernel/mod.rs | 41 +- src/kernel/windows_kernel/terminal.rs | 219 +--- .../windows_kernel/winapi_extentions.rs | 31 - src/lib.rs | 8 +- src/shared/functions.rs | 48 +- src/shared/mod.rs | 2 +- src/shared/traits.rs | 1 + 42 files changed, 2022 insertions(+), 1002 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 src/Terminal.rs create mode 100644 src/crossterm_state/commands/mod.rs create mode 100644 src/crossterm_state/commands/shared_commands.rs create mode 100644 src/crossterm_state/commands/unix_command.rs create mode 100644 src/crossterm_state/commands/win_commands.rs create mode 100644 src/crossterm_state/context.rs create mode 100644 src/crossterm_state/mod.rs create mode 100644 src/crossterm_terminal/raw_terminal.rs create mode 100644 src/crossterm_terminal/screen/mod.rs delete mode 100644 src/kernel/linux_kernel/terminal.rs rename src/kernel/{linux_kernel => unix_kernel}/mod.rs (94%) create mode 100644 src/kernel/unix_kernel/terminal.rs create mode 100644 src/kernel/windows_kernel/ansi_support.rs delete mode 100644 src/kernel/windows_kernel/color.rs delete mode 100644 src/kernel/windows_kernel/winapi_extentions.rs diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f693957..2fec012 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,27 +2,47 @@ - + + + + + + + + + + + + - + + - + - + + + - - + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - + + @@ -99,50 +76,84 @@ - - - - - - + + + - - + + - - - - - - - - + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + - - + + + + @@ -158,42 +169,43 @@ - set - fsr_window - resizeBuffer - set_console_text_attribute - set( - kern - pos - csbi - kernel - success - count - xpos - handle:: - wincon - CONSOLE_SCREEN_BUFFER_INFO - safe_position - init - cursor::get() - get() - get - output_handle - UnixTerminal - size - DISABLE_NE - dwInMode - FillConsoleOutputCharacter - println - terminal - term - AnsiColor + INVALID_HANDLE_VALUE + PCHARINFO + NULL + ToMainscre + main_screen_handle + colored_terminal + clear_entire + mainscreen_handle + outout + handle + <'a> + unw + does + mut context + clear_en + clear + singleton + IState + Context + self.changed_states + context + undo + ICommand + empty + execute + register + ScreenContext + tomain + State + write crossterm_cursor D:\Windows\GIT\crossterm + D:\Windows\GIT\crossterm\src @@ -207,45 +219,57 @@ @@ -256,10 +280,26 @@ DEFINITION_ORDER - + + + + + + + + + + + Android + + + + @@ -276,6 +316,8 @@ + + @@ -317,6 +359,19 @@ + + + + + + + + + + + + + @@ -343,6 +398,13 @@ + + + + + + + @@ -354,7 +416,7 @@ - + @@ -373,18 +435,23 @@ - - + @@ -614,14 +519,16 @@ + + - - + @@ -630,14 +537,14 @@ - + - + @@ -693,147 +600,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -841,13 +607,6 @@ - - - - - - - @@ -855,62 +614,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -919,143 +622,390 @@ - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + - - + + - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cargo.toml b/Cargo.toml index 7396eaf..23a8184 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,10 +21,10 @@ libc = "0.2" termios = "0.3.0" +[lib] +name = "crossterm" +path = "src/lib.rs" [[bin]] -name = "a" -path = "examples//bin.rs" - - - +name = "crosstermexamples" +path = "examples/bin.rs" \ No newline at end of file diff --git a/examples/bin.rs b/examples/bin.rs index eeebe6b..4e2c31f 100644 --- a/examples/bin.rs +++ b/examples/bin.rs @@ -13,45 +13,34 @@ // Import crossterm crate. extern crate crossterm; - -// Add the usings for the crossterms modules to play with crossterm -use self::crossterm::crossterm_style::{paint, Color }; -use self::crossterm::crossterm_cursor; +// +//// Add the usings for the crossterms modules to play with crossterm +//use self::crossterm::crossterm_style::{paint, Color }; +use self::crossterm::crossterm_cursor::cursor; use self::crossterm::crossterm_terminal; +// +//// Import the example modules. +//pub mod color; +//pub mod cursor; +//pub mod terminal; +use std::io::{self, Error, ErrorKind, Write, stdout, stdin, BufRead}; -// Import the example modules. -pub mod color; -pub mod cursor; -pub mod terminal; -use std::io::{Error, ErrorKind, Write}; -use std::io; -use std::{time, thread}; - -use self::crossterm_terminal::screen::AlternateScreen; +//use std::{time, thread}; +// +use crossterm::crossterm_terminal::screen::{AlternateScreen, ToMainScreen, ToAlternateScreen}; use crossterm::crossterm_terminal::IntoRawMode; use crossterm::Context; + +use std::{time, thread}; + fn main() { let mut context = Context::new(); -// - let mut screen = io::stdout().into_raw_mode(&mut context).unwrap(); - { -// let mut screen = io::stdout(); - crossterm_cursor::cursor().goto(10, 10); + let mut screen = stdout(); + write!(screen, "{}", ToAlternateScreen); + write!(screen, "Welcome to the alternate screen.\n\nPlease wait patiently until we arrive back at the main screen in a about three seconds.").unwrap(); + //screen.flush().unwrap(); - let mut curs = crossterm::crossterm_cursor::cursor(); - curs.move_up(1); -// print!("1"); - write!(screen, "{}", "1"); - curs.move_right(1); -// print!("2"); - write!(screen, "{}", "2"); - curs.move_down(1); -// print!("3"); - write!(screen, "{}", "3"); - curs.move_left(1); -// write!()!("4"); - write!(screen, "{}", "4"); - } + thread::sleep(time::Duration::from_secs(3)); } \ No newline at end of file diff --git a/examples/color/mod.rs b/examples/color/mod.rs index d5068fe..e7aaf64 100644 --- a/examples/color/mod.rs +++ b/examples/color/mod.rs @@ -123,7 +123,7 @@ pub fn print_font_with_attributes() #[cfg(unix)]#[cfg(unix)] pub fn print_supported_colors() { - let count = crossterm::crossterm_style::get().get_available_color_count().unwrap(); + let count = crossterm::crossterm_style::color().get_available_color_count().unwrap(); for i in 0..count { diff --git a/src/Terminal.rs b/src/Terminal.rs deleted file mode 100644 index 56e14d0..0000000 --- a/src/Terminal.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub struct Crossterm; - -impl Crossterm -{ - fn -} \ No newline at end of file diff --git a/src/crossterm_cursor/ansi_cursor.rs b/src/crossterm_cursor/ansi_cursor.rs index 18b5aa1..b2979c3 100644 --- a/src/crossterm_cursor/ansi_cursor.rs +++ b/src/crossterm_cursor/ansi_cursor.rs @@ -1,9 +1,8 @@ -use std::io; -use std::io::Write; - use Construct; -use super::base_cursor::ITerminalCursor; use shared::functions; +use super::ITerminalCursor; + +use std::io::{ self, Write }; /// This struct is an ansi implementation for cursor related actions. pub struct AnsiCursor; diff --git a/src/crossterm_cursor/base_cursor.rs b/src/crossterm_cursor/base_cursor.rs deleted file mode 100644 index 9bbddb3..0000000 --- a/src/crossterm_cursor/base_cursor.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! This trait defines the actions that can be preformed with the termial cursor. -//! This trait can be inplemented so that an concrete inplementation of the ITerminalCursor can forfill -//! the wishes to work on an specific platform. -//! -//! ## For example: -//! -//! This trait is inplemented for winapi (Windows specific) and ansi (Unix specific), -//! so that the cursor related actions can be preformed on both unix and windows systems. - -pub trait ITerminalCursor { - /// Goto some location (x,y) in the terminal. - fn goto(&self, x: u16, y: u16); - /// Get the location (x,y) of the current curor in the terminal - fn pos(&self) -> (u16, u16); - /// Move cursor n times up - fn move_up(&self, count: u16); - /// Move the cursor `n` times to the right. - fn move_right(&self, count: u16); - /// Move the cursor `n` times down. - fn move_down(&self, count: u16); - /// Move the cursor `n` times left. - fn move_left(&self, count: u16); - /// Save cursor position for recall later. Note that this position is stored program based not per instance of the cursor struct. - fn save_position(&mut self); - /// Return to saved cursor position - fn reset_position(&self); -} diff --git a/src/crossterm_cursor/cursor.rs b/src/crossterm_cursor/cursor.rs index bf6c4c4..49c5764 100644 --- a/src/crossterm_cursor/cursor.rs +++ b/src/crossterm_cursor/cursor.rs @@ -1,27 +1,21 @@ //! With this module you can perform actions that are cursor related. //! Like changing and displaying the position of the cursor in terminal. //! -use std::fmt::Display; -use std::ops::Drop; - +use super::*; +use shared::functions; use {Construct, Context}; -#[cfg(target_os = "windows")] -use shared::functions::get_module; - -use super::base_cursor::ITerminalCursor; - -use super::AnsiCursor; -#[cfg(target_os = "windows")] -use super::WinApiCursor; +use std::fmt::Display; +use std::ops::Drop; /// Struct that stores an specific platform implementation for cursor related actions. pub struct TerminalCursor { terminal_cursor: Option>, context: Context } + impl TerminalCursor - { +{ /// Create new cursor instance whereon cursor related actions can be performed. pub fn new() -> TerminalCursor { let mut context = Context::new(); @@ -30,7 +24,7 @@ impl TerminalCursor let cursor = get_module::>(WinApiCursor::new(), AnsiCursor::new(), &mut context); #[cfg(not(target_os = "windows"))] - let cursor = Some(AnsiCursor::new()); + let cursor = Some(AnsiCursor::new() as Box); TerminalCursor { terminal_cursor: cursor, context: context } } @@ -260,6 +254,14 @@ impl TerminalCursor } } +impl Drop for TerminalCursor +{ + fn drop(&mut self) + { + self.context.restore_changes(); + } +} + /// Get an TerminalCursor implementation whereon cursor related actions can be performed. /// /// Check `/examples/cursor` in the libary for more spesific examples. diff --git a/src/crossterm_cursor/mod.rs b/src/crossterm_cursor/mod.rs index 608ba70..e332799 100644 --- a/src/crossterm_cursor/mod.rs +++ b/src/crossterm_cursor/mod.rs @@ -1,15 +1,39 @@ -mod base_cursor; -mod cursor; +//! This trait defines the actions that can be preformed with the termial cursor. +//! This trait can be inplemented so that an concrete inplementation of the ITerminalCursor can forfill +//! the wishes to work on an specific platform. +//! +//! ## For example: +//! +//! This trait is inplemented for winapi (Windows specific) and ansi (Unix specific), +//! so that the cursor related actions can be preformed on both unix and windows systems. +//! +mod cursor; +#[cfg(target_os = "windows")] +mod winapi_cursor; mod ansi_cursor; -#[cfg(target_os = "windows")] -mod winapi_cursor; - -use self::ansi_cursor::AnsiCursor; - #[cfg(target_os = "windows")] use self::winapi_cursor::WinApiCursor; +use self::ansi_cursor::AnsiCursor; pub use self::cursor::{ cursor, TerminalCursor }; +pub trait ITerminalCursor { + /// Goto some location (x,y) in the terminal. + fn goto(&self, x: u16, y: u16); + /// Get the location (x,y) of the current curor in the terminal + fn pos(&self) -> (u16, u16); + /// Move cursor n times up + fn move_up(&self, count: u16); + /// Move the cursor `n` times to the right. + fn move_right(&self, count: u16); + /// Move the cursor `n` times down. + fn move_down(&self, count: u16); + /// Move the cursor `n` times left. + fn move_left(&self, count: u16); + /// Save cursor position for recall later. Note that this position is stored program based not per instance of the cursor struct. + fn save_position(&mut self); + /// Return to saved cursor position + fn reset_position(&self); +} \ No newline at end of file diff --git a/src/crossterm_cursor/winapi_cursor.rs b/src/crossterm_cursor/winapi_cursor.rs index 4cd77ea..4acb15a 100644 --- a/src/crossterm_cursor/winapi_cursor.rs +++ b/src/crossterm_cursor/winapi_cursor.rs @@ -1,8 +1,7 @@ use Construct; -use super::base_cursor::ITerminalCursor; +use super::ITerminalCursor; use kernel::windows_kernel::{kernel, cursor}; - /// This struct is an windows implementation for cursor related actions. pub struct WinApiCursor; diff --git a/src/crossterm_state/commands/unix_command.rs b/src/crossterm_state/commands/unix_command.rs index af088cc..0ba355c 100644 --- a/src/crossterm_state/commands/unix_command.rs +++ b/src/crossterm_state/commands/unix_command.rs @@ -25,33 +25,42 @@ impl IContextCommand for NoncanonicalModeCommand { // println!("execute NoncanonicalModeCommand uxix"); // Set noncanonical mode - let orig = Termios::from_fd(FD_STDIN)?; - let mut noncan = orig.clone(); - noncan.c_lflag &= !ICANON; - noncan.c_lflag &= !ECHO; - noncan.c_lflag &= !CREAD; - match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) + if let Ok(orig) = Termios::from_fd(FD_STDIN) + { + let mut noncan = orig.clone(); + noncan.c_lflag &= !ICANON; + noncan.c_lflag &= !ECHO; + noncan.c_lflag &= !CREAD; + match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) { Ok(_) => return true, Err(_) => return false, }; + }else { + return false + } } fn undo(&mut self) -> bool { + // println!("undo NoncanonicalModeCommand unix"); // Disable noncanonical mode - let orig = Termios::from_fd(FD_STDIN)?; - let mut noncan = orig.clone(); - noncan.c_lflag &= ICANON; - noncan.c_lflag &= ECHO; - noncan.c_lflag &= CREAD; - - match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) + if let Ok(orig) = Termios::from_fd(FD_STDIN) { - Ok(_) => return true, - Err(_) => return false, - }; + let mut noncan = orig.clone(); + noncan.c_lflag &= ICANON; + noncan.c_lflag &= ECHO; + noncan.c_lflag &= CREAD; + + match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) + { + Ok(_) => return true, + Err(_) => return false, + }; + }else { + return false; + } } } @@ -68,29 +77,40 @@ impl IContextCommand for EnableRawModeCommand // println!("new EnableRawModeCommand unix"); let key = super::generate_key(); let command = EnableRawModeCommand { original_mode: None, key: key }; - context.state.register_change(Box::from(command), key); + context.register_change(Box::from(command), key); (Box::from(command),key) } fn execute(&mut self) -> bool { // println!("execute EnableRawModeCommand unix"); - self.original_mode = terminal::get_terminal_mode()?; - let mut new_mode = self.original_mode.unwrap(); - new_mode.make_raw(); - terminal::set_terminal_mode(new_mode); - true + if let Ok(original_mode) = terminal::get_terminal_mode() + { + self.original_mode = Some(original_mode); + let mut new_mode = self.original_mode.unwrap(); + terminal::make_raw(&mut new_mode); + terminal::set_terminal_mode(&new_mode); + true + + }else { + return false; + } } fn undo(&mut self) -> bool { // println!("undo EnableRawModeCommand unix"); - let result = terminal::set_terminal_mode(self.original_mode).unwrap(); - - match result + if let Ok(original_mode) = terminal::get_terminal_mode() { - Ok(_) => true, - Err(_) => false + let result = terminal::set_terminal_mode(&self.original_mode.unwrap()); + + match result + { + Ok(()) => true, + Err(_) => false + } + }else { + return false; } } } diff --git a/src/crossterm_style/color/ansi_color.rs b/src/crossterm_style/color/ansi_color.rs index 8efd0a4..d7e68d6 100644 --- a/src/crossterm_style/color/ansi_color.rs +++ b/src/crossterm_style/color/ansi_color.rs @@ -1,11 +1,8 @@ -use std::io; -use std::io::Write; -use std::string::String; - use Construct; +use super::ITerminalColor; use super::super::{Color, ColorType}; -use super::base_color::ITerminalColor; +use std::io::{self, Write}; /// This struct is an ansi implementation for color related actions. #[derive(Debug)] diff --git a/src/crossterm_style/color/base_color.rs b/src/crossterm_style/color/base_color.rs deleted file mode 100644 index 43d3efe..0000000 --- a/src/crossterm_style/color/base_color.rs +++ /dev/null @@ -1,23 +0,0 @@ -///! -///! This trait defines the actions that can be preformed with the termial color. -///! This trait can be inplemented so that an concrete inplementation of the ITerminalColor can forfill -///! the wishes to work on an specific platform. -///! -///! ## For example: -///! -///! This trait is inplemented for winapi (Windows specific) and ansi (Unix specific), -///! so that the color related actions can be preformed on both unix and windows systems. -///! - -use super::super::{Color, ColorType}; - -pub trait ITerminalColor { - /// Set the forground color to the given color. - fn set_fg(&self, fg_color: Color); - /// Set the background color to the given color. - fn set_bg(&self, fg_color: Color); - /// Reset the terminal color to default. - fn reset(&self); - /// Gets an value that represents an color from the given `Color` and `ColorType`. - fn color_value(&self, color: Color, color_type: ColorType) -> String; -} diff --git a/src/crossterm_style/color/color.rs b/src/crossterm_style/color/color.rs index 86eb577..90d2252 100644 --- a/src/crossterm_style/color/color.rs +++ b/src/crossterm_style/color/color.rs @@ -1,24 +1,14 @@ //! With this module you can perform actions that are color related. //! Like styling the font, foreground color and background color. +use super::*; +use shared::functions; +use { Construct, Context }; +use crossterm_style::{Color, ObjectStyle, StyledObject}; use std::ops::Drop; -use std::fmt; -use std::io; +use std::{ fmt, io }; -use {Construct, Context }; -use crossterm_style::{ObjectStyle, StyledObject}; -use super::base_color::ITerminalColor; - -#[cfg(target_os = "windows")] -use shared::functions::get_module; -use super::super::Color; - -use super::AnsiColor; - -#[cfg(target_os = "windows")] -use super::WinApiColor; - -/// Struct that stores an specific platform implementation for color related actions. +/// Struct that stores an specific platform implementation for color related actions. pub struct TerminalColor { terminal_color: Option>, context: Context @@ -30,10 +20,10 @@ impl TerminalColor { let mut context = Context::new(); #[cfg(target_os = "windows")] - let color = get_module::>(WinApiColor::new(), AnsiColor::new(), &mut context); + let color = functions::get_module::>(WinApiColor::new(), AnsiColor::new(), &mut context); #[cfg(not(target_os = "windows"))] - let color = Some(AnsiColor::new()); + let color = Some(AnsiColor::new() as Box); TerminalColor { terminal_color: color, context: context} } @@ -125,6 +115,14 @@ impl TerminalColor { } } +impl Drop for TerminalColor +{ + fn drop(&mut self) + { + self.context.restore_changes(); + } +} + /// Get an TerminalColor implementation whereon color related actions can be performed. /// /// # Example diff --git a/src/crossterm_style/color/mod.rs b/src/crossterm_style/color/mod.rs index 6829156..6a338b2 100644 --- a/src/crossterm_style/color/mod.rs +++ b/src/crossterm_style/color/mod.rs @@ -1,12 +1,33 @@ -pub mod base_color; pub mod color; -mod ansi_color; - #[cfg(target_os = "windows")] mod winapi_color; - -use self::ansi_color::AnsiColor; +mod ansi_color; #[cfg(target_os = "windows")] use self::winapi_color::WinApiColor; +use self::ansi_color::AnsiColor; + +///! +///! This trait defines the actions that can be preformed with the termial color. +///! This trait can be inplemented so that an concrete inplementation of the ITerminalColor can forfill +///! the wishes to work on an specific platform. +///! +///! ## For example: +///! +///! This trait is inplemented for winapi (Windows specific) and ansi (Unix specific), +///! so that the color related actions can be preformed on both unix and windows systems. +///! + +use super::{Color, ColorType}; + +pub trait ITerminalColor { + /// Set the forground color to the given color. + fn set_fg(&self, fg_color: Color); + /// Set the background color to the given color. + fn set_bg(&self, fg_color: Color); + /// Reset the terminal color to default. + fn reset(&self); + /// Gets an value that represents an color from the given `Color` and `ColorType`. + fn color_value(&self, color: Color, color_type: ColorType) -> String; +} \ No newline at end of file diff --git a/src/crossterm_style/color/winapi_color.rs b/src/crossterm_style/color/winapi_color.rs index 3c2f399..6a4a466 100644 --- a/src/crossterm_style/color/winapi_color.rs +++ b/src/crossterm_style/color/winapi_color.rs @@ -1,9 +1,8 @@ use Construct; +use super::ITerminalColor; use super::super::{ColorType, Color}; -use super::base_color::ITerminalColor; - -use kernel::windows_kernel::kernel; use winapi::um::wincon; +use kernel::windows_kernel::kernel; /// This struct is an windows implementation for color related actions. #[derive(Debug)] diff --git a/src/crossterm_style/styles/objectstyle.rs b/src/crossterm_style/styles/objectstyle.rs index a0f14e1..2950826 100644 --- a/src/crossterm_style/styles/objectstyle.rs +++ b/src/crossterm_style/styles/objectstyle.rs @@ -1,5 +1,5 @@ -use crossterm_style::{Color, StyledObject}; use std::fmt::Display; +use crossterm_style::{Color, StyledObject}; #[cfg(unix)] use super::super::Attribute; diff --git a/src/crossterm_style/styles/styledobject.rs b/src/crossterm_style/styles/styledobject.rs index e685c19..426a2d6 100644 --- a/src/crossterm_style/styles/styledobject.rs +++ b/src/crossterm_style/styles/styledobject.rs @@ -1,5 +1,4 @@ -use std; -use std::fmt; +use std::{ fmt, self }; use std::io::Write; #[cfg(unix)] diff --git a/src/crossterm_terminal/ansi_terminal.rs b/src/crossterm_terminal/ansi_terminal.rs index b734985..a29cd0e 100644 --- a/src/crossterm_terminal/ansi_terminal.rs +++ b/src/crossterm_terminal/ansi_terminal.rs @@ -1,11 +1,10 @@ +use Construct; +use shared::functions; +use super::{ClearType, ITerminal}; + use std::io; use std::io::Write; -use Construct; -use super::base_terminal::{ClearType, ITerminal}; - -use shared::functions::get_terminal_size; - /// This struct is an ansi implementation for terminal related actions. pub struct AnsiTerminal ; @@ -38,7 +37,7 @@ impl ITerminal for AnsiTerminal { } fn terminal_size(&self) -> (u16, u16) { - get_terminal_size() + functions::get_terminal_size() } fn scroll_up(&self, count: i16) { diff --git a/src/crossterm_terminal/base_terminal.rs b/src/crossterm_terminal/base_terminal.rs deleted file mode 100644 index f2af6f9..0000000 --- a/src/crossterm_terminal/base_terminal.rs +++ /dev/null @@ -1,21 +0,0 @@ -/// Enum that can be used for the kind of clearing that can be done in the terminal. -pub enum ClearType { - All, - FromCursorDown, - FromCursorUp, - CurrentLine, - UntilNewLine, -} - -pub trait ITerminal{ - /// Clear the current cursor by specifying the clear type - fn clear(&self, clear_type: ClearType); - /// Get the terminal size (x,y) - fn terminal_size(&self) -> (u16, u16); - /// Scroll `n` lines up in the current terminal. - fn scroll_up(&self, count: i16); - /// Scroll `n` lines down in the current terminal. - fn scroll_down(&self, count: i16); - /// Resize terminal to the given width and height. - fn set_size(&self,width: i16, height: i16); -} diff --git a/src/crossterm_terminal/mod.rs b/src/crossterm_terminal/mod.rs index a68461d..db82e9f 100644 --- a/src/crossterm_terminal/mod.rs +++ b/src/crossterm_terminal/mod.rs @@ -1,19 +1,37 @@ mod raw_terminal; -mod base_terminal; mod terminal; -pub mod screen; - -mod ansi_terminal; - #[cfg(target_os = "windows")] mod winapi_terminal; +mod ansi_terminal; -use self::ansi_terminal::AnsiTerminal; +pub mod screen; #[cfg(target_os = "windows")] use self::winapi_terminal::WinApiTerminal; +use self::ansi_terminal::AnsiTerminal; -pub use self::base_terminal::ClearType; pub use self::terminal::{ Terminal, terminal}; -pub use self::raw_terminal::{RawTerminal, IntoRawMode}; \ No newline at end of file +pub use self::raw_terminal::{RawTerminal, IntoRawMode}; + +/// Enum that can be used for the kind of clearing that can be done in the terminal. +pub enum ClearType { + All, + FromCursorDown, + FromCursorUp, + CurrentLine, + UntilNewLine, +} + +pub trait ITerminal{ + /// Clear the current cursor by specifying the clear type + fn clear(&self, clear_type: ClearType); + /// Get the terminal size (x,y) + fn terminal_size(&self) -> (u16, u16); + /// Scroll `n` lines up in the current terminal. + fn scroll_up(&self, count: i16); + /// Scroll `n` lines down in the current terminal. + fn scroll_down(&self, count: i16); + /// Resize terminal to the given width and height. + fn set_size(&self,width: i16, height: i16); +} diff --git a/src/crossterm_terminal/raw_terminal.rs b/src/crossterm_terminal/raw_terminal.rs index 0e077c2..ee43c0a 100644 --- a/src/crossterm_terminal/raw_terminal.rs +++ b/src/crossterm_terminal/raw_terminal.rs @@ -3,13 +3,11 @@ use crossterm_state::commands::unix_command::EnableRawModeCommand; #[cfg(windows)] use crossterm_state::commands::win_commands::EnableRawModeCommand; -use crossterm_state::commands::IContextCommand; +use { Construct, Context }; +use crossterm_state::commands::{ICommand, IContextCommand}; -use shared::traits::Construct; -use crossterm_state::{ Context }; -use crossterm_state::commands::ICommand; +use std::io::{ self, Write}; -use std::io::{self, Write}; pub struct RawTerminal<'a, W: Write> { diff --git a/src/crossterm_terminal/screen/mod.rs b/src/crossterm_terminal/screen/mod.rs index 5616766..5ab9f94 100644 --- a/src/crossterm_terminal/screen/mod.rs +++ b/src/crossterm_terminal/screen/mod.rs @@ -1,14 +1,9 @@ -use std::io::{self, Write}; -use std::ops; -use std::any::Any; - -#[cfg(target_os = "windows")] -use shared::functions::get_module; +use shared::functions; +use { Context, Construct }; use crossterm_state::commands::*; -use shared::traits::Construct; -use Context; -use std::fmt; +use std::{ fmt, ops }; +use std::io::{self, Write}; /// let context = ScreenContext::new(); /// ToMainScreen {}.execute(&mut context); @@ -94,7 +89,7 @@ fn get_to_alternate_screen_command() -> Box let mut context = Context::new(); #[cfg(target_os = "windows")] - let command = get_module::>(win_commands::ToAlternateScreenBufferCommand::new(), shared_commands::ToAlternateScreenBufferCommand::new(), &mut context).unwrap(); + let command = functions::get_module::>(win_commands::ToAlternateScreenBufferCommand::new(), shared_commands::ToAlternateScreenBufferCommand::new(), &mut context).unwrap(); #[cfg(not(target_os = "windows"))] let command = shared_commands::ToAlternateScreenBufferCommand::new(); diff --git a/src/crossterm_terminal/terminal.rs b/src/crossterm_terminal/terminal.rs index 72d9b92..bd00967 100644 --- a/src/crossterm_terminal/terminal.rs +++ b/src/crossterm_terminal/terminal.rs @@ -1,18 +1,11 @@ //! With this module you can perform actions that are terminal related. //! Like clearing and scrolling in the terminal or getting the size of the terminal. +use super::*; +use shared::functions; +use {Construct, Context}; use std::ops::Drop; -use {Construct, Context}; -use super::base_terminal::{ClearType, ITerminal}; -#[cfg(target_os = "windows")] -use shared::functions::get_module; - -use super::AnsiTerminal; - -#[cfg(target_os = "windows")] -use super::WinApiTerminal; - /// Struct that stores an specific platform implementation for terminal related actions. pub struct Terminal { terminal: Option>, @@ -25,10 +18,10 @@ impl Terminal { let mut context = Context::new(); #[cfg(target_os = "windows")] - let terminal = get_module::>(WinApiTerminal::new(), AnsiTerminal::new(), &mut context); + let terminal = functions::get_module::>(WinApiTerminal::new(), AnsiTerminal::new(), &mut context); #[cfg(not(target_os = "windows"))] - let terminal = Some(AnsiTerminal::new()); + let terminal = Some(AnsiTerminal::new() as Box); Terminal { terminal: terminal, context: context } } @@ -149,6 +142,14 @@ impl Terminal { } } +impl Drop for Terminal +{ + fn drop(&mut self) + { + self.context.restore_changes(); + } +} + /// Get an Terminal implementation whereon terminal related actions can be performed. /// /// Check `/examples/terminal` in the libary for more spesific examples. diff --git a/src/kernel/unix_kernel/terminal.rs b/src/kernel/unix_kernel/terminal.rs index c13023e..625fde2 100644 --- a/src/kernel/unix_kernel/terminal.rs +++ b/src/kernel/unix_kernel/terminal.rs @@ -1,12 +1,11 @@ -use libc; -use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int}; -pub use self::libc::{termios, cvt}; +use { libc, Context }; use termios::Termios; -use crossterm_state::commands::{NoncanonicalModeCommand, IContextCommand}; -use Context; -use std::io; -use std::mem; +pub use self::libc::{termios}; +use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int}; +use crossterm_state::commands::{ NoncanonicalModeCommand, IContextCommand} ; +use std::{ io, mem }; +use std::io::Error; /// A representation of the size of the current terminal #[repr(C)] @@ -46,7 +45,7 @@ pub fn pos() -> (u16,u16) let mut context = Context::new(); { - let command = NoncanonicalModeCommand::new(&mut context); + let mut command = NoncanonicalModeCommand::new(&mut context); command.0.execute(); // This code is original written by term_cursor credits to them. @@ -65,7 +64,7 @@ pub fn pos() -> (u16,u16) } // Read rows and cols through a ad-hoc integer parsing function - let read_num = || -> Result<(i32, char), Error> { + let read_num = || -> (i32, char) { let mut num = 0; let mut c; @@ -81,11 +80,12 @@ pub fn pos() -> (u16,u16) } } - Ok((num, c)) + (num, c) }; // Read rows and expect `;` let (rows, c) = read_num(); + if c != ';' { return (0, 0); } @@ -94,7 +94,7 @@ pub fn pos() -> (u16,u16) let (cols, c) = read_num(); // Expect `R` - let res = if c == 'R' { Ok((cols, rows)) } else { return Ok((0, 0)); }; + let res = if c == 'R' { (cols as u16, rows as u16) } else { return (0, 0) }; res } @@ -105,7 +105,14 @@ pub fn set_terminal_mode(termios: &Termios) -> io::Result<()> extern "C" { pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int; } - unsafe { tcsetattr(0, 0, termios) } + is_true(unsafe { tcsetattr(0, 0, termios) }).and(Ok(())) +} + +pub fn make_raw(termios: &mut Termios) { + extern "C" { + pub fn cfmakeraw(termptr: *mut Termios); + } + unsafe { cfmakeraw(termios) } } pub fn get_terminal_mode() -> io::Result @@ -115,7 +122,17 @@ pub fn get_terminal_mode() -> io::Result } unsafe { let mut termios = mem::zeroed(); - cvt(tcgetattr(0, &mut termios))?; + is_true(tcgetattr(0, &mut termios))?; Ok(termios) } +} + +fn is_true(value: i32) -> Result<(), Error> +{ + match value + { + -1 => Err(io::Error::last_os_error()), + 0 => Ok(()), + _ => Err(io::Error::last_os_error()), + } } \ No newline at end of file diff --git a/src/kernel/windows_kernel/ansi_support.rs b/src/kernel/windows_kernel/ansi_support.rs index 409f895..d49d115 100644 --- a/src/kernel/windows_kernel/ansi_support.rs +++ b/src/kernel/windows_kernel/ansi_support.rs @@ -1,10 +1,9 @@ -use crossterm_state::Context; +use { Context, Contstruct }; use crossterm_state::commands::IContextCommand; -use shared::traits::Construct; -static mut IS_ANSI_ON_WINDOWS_ENABLED: Option = None; -static mut DOES_WINDOWS_SUPPORT_ANSI: Option = None; static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false; +static mut IS_ANSI_ON_WINDOWS_ENABLED: Option = None; +static mut DOES_WINDOWS_SUPPORT_ANSI: Option = None; /// Try enable ANSI escape codes and return the result. pub fn try_enable_ansi_support(context: &mut Context) -> bool diff --git a/src/kernel/windows_kernel/cursor.rs b/src/kernel/windows_kernel/cursor.rs index 0820e7c..f3fbfa3 100644 --- a/src/kernel/windows_kernel/cursor.rs +++ b/src/kernel/windows_kernel/cursor.rs @@ -1,5 +1,4 @@ -use super::kernel; -use crossterm_cursor::cursor; +use super::{ kernel, cursor }; /// This stores the cursor pos, at program level. So it can be recalled later. static mut SAVED_CURSOR_POS:(u16,u16) = (0,0); @@ -15,7 +14,7 @@ pub fn reset_to_saved_position() /// Save current cursor position to recall later. pub fn save_cursor_pos() { - let position = cursor().pos(); + let position = pos(); unsafe { SAVED_CURSOR_POS = (position.0, position.1); @@ -25,5 +24,5 @@ pub fn save_cursor_pos() pub fn pos() -> (u16,u16) { let csbi = kernel::get_console_screen_buffer_info(); - ( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16) + ( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16 ) } diff --git a/src/kernel/windows_kernel/kernel.rs b/src/kernel/windows_kernel/kernel.rs index 5bd9c56..4343915 100644 --- a/src/kernel/windows_kernel/kernel.rs +++ b/src/kernel/windows_kernel/kernel.rs @@ -3,17 +3,17 @@ use winapi::um::winbase::{STD_OUTPUT_HANDLE, STD_INPUT_HANDLE }; use winapi::um::handleapi::INVALID_HANDLE_VALUE; use winapi::um::processenv::{GetStdHandle}; use winapi::um::consoleapi::{SetConsoleMode,GetConsoleMode, }; - -use winapi::um::wincon; use winapi::shared::minwindef::{TRUE}; -use winapi::um::wincon::{ SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, CreateConsoleScreenBuffer,SetConsoleActiveScreenBuffer, - GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo, - FillConsoleOutputCharacterA, FillConsoleOutputAttribute, - CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, CHAR_INFO, PSMALL_RECT +use winapi::um::wincon; +use winapi::um::wincon:: +{ + SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, CreateConsoleScreenBuffer,SetConsoleActiveScreenBuffer, + GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo, + FillConsoleOutputCharacterA, FillConsoleOutputAttribute, + CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, CHAR_INFO, PSMALL_RECT }; use super::{Empty}; - static mut CONSOLE_OUTPUT_HANDLE: Option = None; static mut CONSOLE_INPUT_HANDLE: Option = None; @@ -261,11 +261,6 @@ pub fn read_console_output(read_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;16 } } -pub fn write_console() -{ - -} - pub fn write_console_output(write_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;160], buffer_size: COORD, buffer_coord: COORD, source_buffer: PSMALL_RECT) { use self::wincon::WriteConsoleOutputA; diff --git a/src/kernel/windows_kernel/mod.rs b/src/kernel/windows_kernel/mod.rs index a3ae2a3..1ed2d77 100644 --- a/src/kernel/windows_kernel/mod.rs +++ b/src/kernel/windows_kernel/mod.rs @@ -1,13 +1,12 @@ -extern crate winapi; - -use winapi::um::wincon::{COORD, CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT}; -use shared::traits::Empty; - pub mod kernel; pub mod cursor; pub mod terminal; pub mod ansi_support; +use winapi; +use shared::traits::Empty; +use self::winapi::um::wincon::{COORD, CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT}; + impl Empty for COORD { fn empty() -> COORD { COORD { X: 0, Y: 0 } diff --git a/src/lib.rs b/src/lib.rs index 538c952..a86a414 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,3 +18,14 @@ extern crate libc; extern crate termios; extern crate rand; + + +// private mod +// +// public mod +// +// own usings +// +// std usings +// +// extern crate \ No newline at end of file diff --git a/src/shared/functions.rs b/src/shared/functions.rs index ea0c922..26edb7d 100644 --- a/src/shared/functions.rs +++ b/src/shared/functions.rs @@ -1,7 +1,7 @@ //! Some actions need to preformed platform independently. //! -use Context; -use shared::traits::Construct; +use {Context, Construct}; + #[cfg(windows)] use kernel::windows_kernel::terminal::terminal_size; #[cfg(unix)] From 4c14ad836bee473230283bce66db092a23f279d9 Mon Sep 17 00:00:00 2001 From: T Date: Sat, 10 Mar 2018 17:33:06 +0100 Subject: [PATCH 07/11] Refactored namespaces. Added comments where needed. Alternatescreen is working for windows 10 terminals. Refactored usings. Rearanged usings. Raw Mode / alternate screeen windows yet to be tested. Added examples. Refactored code --- .idea/dictionaries/Timon.xml | 7 + .idea/workspace.xml | 1124 +++++++++-------- examples/bin.rs | 30 +- examples/color/mod.rs | 7 +- examples/cursor/mod.rs | 2 +- examples/terminal/alternate_screen.rs | 70 + examples/terminal/mod.rs | 139 +- examples/terminal/raw_mode.rs | 0 examples/terminal/terminal.rs | 136 ++ src/crossterm_state/commands/mod.rs | 45 - src/crossterm_state/context.rs | 72 -- src/crossterm_state/mod.rs | 4 - src/crossterm_style/styles/mod.rs | 2 - src/crossterm_terminal/raw_terminal.rs | 53 - .../ansi_cursor.rs | 3 + src/{crossterm_cursor => cursor}/cursor.rs | 69 +- src/{crossterm_cursor => cursor}/mod.rs | 14 +- .../winapi_cursor.rs | 5 +- src/kernel/mod.rs | 2 + src/kernel/unix_kernel/mod.rs | 2 + src/kernel/unix_kernel/terminal.rs | 14 +- src/kernel/windows_kernel/ansi_support.rs | 14 +- src/kernel/windows_kernel/cursor.rs | 4 +- src/kernel/windows_kernel/kernel.rs | 2 + src/kernel/windows_kernel/mod.rs | 2 + src/lib.rs | 28 +- src/shared/functions.rs | 17 +- src/shared/mod.rs | 2 + src/state/commands/mod.rs | 50 + .../commands/shared_commands.rs | 3 + .../commands/unix_command.rs | 6 +- .../commands/win_commands.rs | 21 +- src/state/context.rs | 51 + src/state/mod.rs | 9 + .../color/ansi_color.rs | 3 + src/{crossterm_style => style}/color/color.rs | 30 +- src/{crossterm_style => style}/color/mod.rs | 16 +- .../color/winapi_color.rs | 8 +- src/{crossterm_style => style}/mod.rs | 3 + src/style/styles/mod.rs | 4 + .../styles/objectstyle.rs | 4 +- .../styles/styledobject.rs | 14 +- .../ansi_terminal.rs | 3 + src/{crossterm_terminal => terminal}/mod.rs | 20 +- src/terminal/raw.rs | 82 ++ .../screen/mod.rs => terminal/screen.rs} | 51 +- .../terminal.rs | 52 +- .../winapi_terminal.rs | 12 +- 48 files changed, 1267 insertions(+), 1044 deletions(-) create mode 100644 .idea/dictionaries/Timon.xml create mode 100644 examples/terminal/alternate_screen.rs create mode 100644 examples/terminal/raw_mode.rs create mode 100644 examples/terminal/terminal.rs delete mode 100644 src/crossterm_state/commands/mod.rs delete mode 100644 src/crossterm_state/context.rs delete mode 100644 src/crossterm_state/mod.rs delete mode 100644 src/crossterm_style/styles/mod.rs delete mode 100644 src/crossterm_terminal/raw_terminal.rs rename src/{crossterm_cursor => cursor}/ansi_cursor.rs (90%) rename src/{crossterm_cursor => cursor}/cursor.rs (80%) rename src/{crossterm_cursor => cursor}/mod.rs (64%) rename src/{crossterm_cursor => cursor}/winapi_cursor.rs (88%) create mode 100644 src/state/commands/mod.rs rename src/{crossterm_state => state}/commands/shared_commands.rs (83%) rename src/{crossterm_state => state}/commands/unix_command.rs (93%) rename src/{crossterm_state => state}/commands/win_commands.rs (90%) create mode 100644 src/state/context.rs create mode 100644 src/state/mod.rs rename src/{crossterm_style => style}/color/ansi_color.rs (93%) rename src/{crossterm_style => style}/color/color.rs (86%) rename src/{crossterm_style => style}/color/mod.rs (70%) rename src/{crossterm_style => style}/color/winapi_color.rs (93%) rename src/{crossterm_style => style}/mod.rs (93%) create mode 100644 src/style/styles/mod.rs rename src/{crossterm_style => style}/styles/objectstyle.rs (92%) rename src/{crossterm_style => style}/styles/styledobject.rs (92%) rename src/{crossterm_terminal => terminal}/ansi_terminal.rs (90%) rename src/{crossterm_terminal => terminal}/mod.rs (58%) create mode 100644 src/terminal/raw.rs rename src/{crossterm_terminal/screen/mod.rs => terminal/screen.rs} (60%) rename src/{crossterm_terminal => terminal}/terminal.rs (74%) rename src/{crossterm_terminal => terminal}/winapi_terminal.rs (97%) diff --git a/.idea/dictionaries/Timon.xml b/.idea/dictionaries/Timon.xml new file mode 100644 index 0000000..c4efce9 --- /dev/null +++ b/.idea/dictionaries/Timon.xml @@ -0,0 +1,7 @@ + + + + swhitching + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index cd75735..600a5bf 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,30 +2,46 @@ + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33,6 +49,7 @@ + - - + + - - + + - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - + + - - + + + + - - + + - - + + - - - - - - + + + + + + + + + + - - + + - - - - - - - - - - - - + + @@ -164,19 +187,11 @@ - outout - handle - <'a> - unw - does - mut context clear_en - clear singleton IState Context self.changed_states - context undo ICommand empty @@ -194,13 +209,21 @@ wincon Empty winapi + HANDLE + Construct + EnableRawModeCommandretu + return + crossterm_ + clear + context + self. crossterm_cursor - D:\Windows\GIT\crossterm D:\Windows\GIT\crossterm\src + D:\Windows\GIT\crossterm @@ -214,57 +237,57 @@ @@ -275,10 +298,10 @@ DEFINITION_ORDER - @@ -311,9 +334,7 @@ - - @@ -326,6 +347,24 @@ + + + + + + + + + + + + + + + + + + @@ -335,25 +374,79 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - + - + @@ -465,29 +356,12 @@ - - - - - - - - - - + + - - @@ -616,73 +480,75 @@ - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -691,47 +557,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + @@ -742,18 +574,11 @@ - - - - - - - + - - + @@ -761,31 +586,27 @@ - - - + - - + - - + @@ -793,87 +614,55 @@ - - - - + + - - + - - - + + - - + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + @@ -881,147 +670,83 @@ - - - + - - - - + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + - - + - - + - - + - - - - - - - - - - - - - - - - - - - - - + - - + - - + + @@ -1033,16 +758,43 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1058,59 +810,108 @@ + + + + + + + - - - + + - + - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/bin.rs b/examples/bin.rs index fa8a2b5..1c28676 100644 --- a/examples/bin.rs +++ b/examples/bin.rs @@ -13,16 +13,7 @@ extern crate crossterm; -mod terminal; - -use terminal::alternate_screen; -use crossterm::Context; -use std::io::{Write, stdout}; - use crossterm::cursor; fn main() { - alternate_screen::manually_switch_to_alternate_screen(); -// cursor::cursor().goto(10,10).print("@"); - } \ No newline at end of file diff --git a/examples/terminal/alternate_screen.rs b/examples/terminal/alternate_screen.rs index f15d274..f8fcea3 100644 --- a/examples/terminal/alternate_screen.rs +++ b/examples/terminal/alternate_screen.rs @@ -1,70 +1,73 @@ -extern crate crossterm; +// alternate screen is not working correctly currently -use crossterm::terminal::screen::{AlternateScreen, ToAlternateScreen, ToMainScreen}; -use crossterm::cursor::cursor; -use crossterm::terminal::{self, ClearType}; -use std::io::{Write, stdout}; -use std::{time, thread}; - -fn print_wait_screen(screen: &mut Write) -{ - terminal::terminal().clear(ClearType::All); - write!(screen, - "Welcome to the wait screen.\n\ - Please wait a few seconds until we arrive back at the main screen.\n\ - Seconds to Go: " - ); - - let mut counter = 5; - // get cursor instance - let mut cursor = cursor(); - - // loop until the counter hits 0 - loop - { - // 1 second delay - thread::sleep(time::Duration::from_secs(1)); - // decrement counter - counter -= 1; - - // print the current counter at the line of `Seconds to Go: {counter}` - cursor.goto(15,2).print(counter); - - if counter <= 0 - { - break; - } - } -} - -pub fn with_alternate_screen_instance() -{ - // create scope. If this scope ends the screen will be switched back to mainscreen. - // becouse `AlternateScreen` switches back to main screen when switching back. - { - // create new alternate screen instance and switch to the alternate screen. - let mut screen = AlternateScreen::from(stdout()); - - // Print the wait screen. - print_wait_screen(&mut screen); - } - - println!("Whe are back at the main screen"); -} - -pub fn manually_switch_to_alternate_screen() -{ - // You can switch to alternate screen manually but if you forget to switch back your terminal may cause some undefined behavior. - - let mut screen = stdout(); - - // switch to alternate screeen - write!(screen, "{}", ToAlternateScreen); - // load wait screen - print_wait_screen(&mut screen); - // switch back - write!(screen,"{}", ToMainScreen); - println!("Whe are back at the main screen"); - -} \ No newline at end of file +//extern crate crossterm; +// +//use crossterm::terminal::screen::{AlternateScreen, ToAlternateScreen, ToMainScreen}; +//use crossterm::cursor::cursor; +//use crossterm::terminal::{self, ClearType}; +// +//use std::io::{Write, stdout}; +//use std::{time, thread}; +// +//fn print_wait_screen(screen: &mut Write) +//{ +// terminal::terminal().clear(ClearType::All); +// write!(screen, +// "Welcome to the wait screen.\n\ +// Please wait a few seconds until we arrive back at the main screen.\n\ +// Seconds to Go: " +// ); +// +// let mut counter = 5; +// // get cursor instance +// let mut cursor = cursor(); +// +// // loop until the counter hits 0 +// loop +// { +// // 1 second delay +// thread::sleep(time::Duration::from_secs(1)); +// // decrement counter +// counter -= 1; +// +// // print the current counter at the line of `Seconds to Go: {counter}` +// cursor.goto(15,2).print(counter); +// +// if counter <= 0 +// { +// break; +// } +// } +//} +// +//pub fn with_alternate_screen_instance() +//{ +// // create scope. If this scope ends the screen will be switched back to mainscreen. +// // becouse `AlternateScreen` switches back to main screen when switching back. +// { +// // create new alternate screen instance and switch to the alternate screen. +// let mut screen = AlternateScreen::from(stdout()); +// +// // Print the wait screen. +// print_wait_screen(&mut screen); +// } +// +// println!("Whe are back at the main screen"); +//} +// +//pub fn manually_switch_to_alternate_screen() +//{ +// // You can switch to alternate screen manually but if you forget to switch back your terminal may cause some undefined behavior. +// +// let mut screen = stdout(); +// +// // switch to alternate screeen +// write!(screen, "{}", ToAlternateScreen); +// // load wait screen +// print_wait_screen(&mut screen); +// // switch back +// write!(screen,"{}", ToMainScreen); +// println!("Whe are back at the main screen"); +// +//} \ No newline at end of file diff --git a/examples/terminal/mod.rs b/examples/terminal/mod.rs index bf3a23a..e609256 100644 --- a/examples/terminal/mod.rs +++ b/examples/terminal/mod.rs @@ -1,3 +1,5 @@ -pub mod alternate_screen; -pub mod raw_mode; +mod alternate_screen; +mod raw_mode; + + pub mod terminal; \ No newline at end of file diff --git a/examples/terminal/raw_mode.rs b/examples/terminal/raw_mode.rs index e69de29..d0454d2 100644 --- a/examples/terminal/raw_mode.rs +++ b/examples/terminal/raw_mode.rs @@ -0,0 +1 @@ +// raw screen is not working correctly currently diff --git a/src/state/commands/shared_commands.rs b/src/state/commands/shared_commands.rs index 3f0ec89..81826f6 100644 --- a/src/state/commands/shared_commands.rs +++ b/src/state/commands/shared_commands.rs @@ -11,13 +11,11 @@ pub struct ToAlternateScreenBufferCommand; impl ICommand for ToAlternateScreenBufferCommand { fn new() -> Box { -// println!("create new unix alternate screen"); Box::from(ToAlternateScreenBufferCommand { }) } fn execute(&mut self) -> bool { -// println!("execute alternate screen"); let mut some_writer = io::stdout(); match write!(some_writer, csi!("?1049h")) { @@ -28,7 +26,6 @@ impl ICommand for ToAlternateScreenBufferCommand fn undo(&mut self) -> bool { -// println!("undo alternate screen"); let mut some_writer = io::stdout(); match write!(some_writer, csi!("?1049l")) { diff --git a/src/state/commands/unix_command.rs b/src/state/commands/unix_command.rs index 903f07b..37510a9 100644 --- a/src/state/commands/unix_command.rs +++ b/src/state/commands/unix_command.rs @@ -17,7 +17,6 @@ pub struct NoncanonicalModeCommand impl IContextCommand for NoncanonicalModeCommand { fn new(context: &mut Context) -> (Box, i16) { -// println!("new new NoncanonicalModeCommand unix"); let key = super::generate_key(); let command = NoncanonicalModeCommand { key: key }; context.register_change(Box::from(command), key); @@ -26,7 +25,6 @@ impl IContextCommand for NoncanonicalModeCommand fn execute(&mut self) -> bool { -// println!("execute NoncanonicalModeCommand uxix"); // Set noncanonical mode if let Ok(orig) = Termios::from_fd(FD_STDIN) { @@ -46,8 +44,6 @@ impl IContextCommand for NoncanonicalModeCommand fn undo(&mut self) -> bool { - -// println!("undo NoncanonicalModeCommand unix"); // Disable noncanonical mode if let Ok(orig) = Termios::from_fd(FD_STDIN) { @@ -78,7 +74,6 @@ pub struct EnableRawModeCommand impl IContextCommand for EnableRawModeCommand { fn new(context: &mut Context) -> (Box, i16) { -// println!("new EnableRawModeCommand unix"); let key = super::generate_key(); let command = EnableRawModeCommand { original_mode: None, key: key }; context.register_change(Box::from(command), key); @@ -87,7 +82,6 @@ impl IContextCommand for EnableRawModeCommand fn execute(&mut self) -> bool { -// println!("execute EnableRawModeCommand unix"); if let Ok(original_mode) = terminal::get_terminal_mode() { self.original_mode = Some(original_mode); @@ -103,7 +97,6 @@ impl IContextCommand for EnableRawModeCommand fn undo(&mut self) -> bool { -// println!("undo EnableRawModeCommand unix"); if let Ok(original_mode) = terminal::get_terminal_mode() { let result = terminal::set_terminal_mode(&self.original_mode.unwrap()); diff --git a/src/state/commands/win_commands.rs b/src/state/commands/win_commands.rs index 0aaa080..510b893 100644 --- a/src/state/commands/win_commands.rs +++ b/src/state/commands/win_commands.rs @@ -20,7 +20,6 @@ pub struct EnableAnsiCommand impl ICommand for EnableAnsiCommand { fn new() -> Box { -// println!("new EnableRawModeCommand winapi"); let key = super::generate_key(); let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING }; Box::from(command) @@ -28,7 +27,6 @@ impl ICommand for EnableAnsiCommand fn execute(&mut self) -> bool { -// println!("exucute EnableAnsiCommand winapi"); // we need to check whether we tried to enable ansi before. If we have we can just return if that had succeeded. if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled() { @@ -57,7 +55,6 @@ impl ICommand for EnableAnsiCommand fn undo(&mut self) -> bool { -// println!("undo EnableAnsiCommand winapi"); if ansi_support::ansi_enabled() { let output_handle = kernel::get_output_handle(); @@ -94,7 +91,6 @@ impl IContextCommand for EnableRawModeCommand fn new(context: &mut Context) -> (Box, i16) { use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_PROCESSED_OUTPUT, ENABLE_WRAP_AT_EOL_OUTPUT, ENABLE_ECHO_INPUT}; -// println!("new EnableRawModeCommand winapi"); let key = super::generate_key(); let command = EnableRawModeCommand { mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT, key: key }; context.register_change(Box::from(command), key); @@ -105,7 +101,6 @@ impl IContextCommand for EnableRawModeCommand { use self::wincon::{ENABLE_LINE_INPUT,ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT}; -// println!("execute EnableRawModeCommand winapi"); let input_handle = kernel::get_input_handle(); let mut dw_mode: DWORD = 0; @@ -126,7 +121,6 @@ impl IContextCommand for EnableRawModeCommand fn undo(&mut self) -> bool { -// println!("undo EnableRawModeCommand winapi"); let output_handle = kernel::get_output_handle(); let mut dw_mode: DWORD = 0; @@ -160,7 +154,6 @@ impl ICommand for ToAlternateScreenBufferCommand fn execute(&mut self) -> bool { -// println!("executte ToAlternateScreenBufferCommand winapi"); let mut chi_buffer: [CHAR_INFO;160] = unsafe {mem::zeroed() }; let handle = kernel::get_output_handle(); @@ -215,7 +208,6 @@ impl ICommand for ToAlternateScreenBufferCommand fn undo(&mut self) -> bool { -// println!("undo ToAlternateScreenBufferCommand winapi"); let handle = kernel::get_output_handle(); kernel::set_active_screen_buffer(handle); true diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index f3a93eb..99e4e75 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -11,8 +11,8 @@ mod terminal; mod winapi_terminal; mod ansi_terminal; -pub mod screen; -pub mod raw; +mod screen; +mod raw; #[cfg(target_os = "windows")] use self::winapi_terminal::WinApiTerminal; From 1a2a4058e2123773629e17a8edade0f612b7fc4e Mon Sep 17 00:00:00 2001 From: Timon Date: Sun, 20 May 2018 14:31:49 +0200 Subject: [PATCH 09/11] Create UPGRADE Manual --- UPGRADE Manual | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 UPGRADE Manual diff --git a/UPGRADE Manual b/UPGRADE Manual new file mode 100644 index 0000000..6a4a6fc --- /dev/null +++ b/UPGRADE Manual @@ -0,0 +1,24 @@ +Upgrade crossterm 0.2 to 0.2.1 + +Namespaces: +I have changed the namespaces. I found the namsespaces to long so I have shoted them like the followin: + +Old: crossterm::crosster_style +New: crossterm::style + +Old: crossterm::crosster_terminal +New: crossterm::terminal + +Old: crossterm::crosster_cursor +New: crossterm::cursor + +Method names that changed [Issue 4](https://github.com/TimonPost/crossterm/issues/4): + +Old: crossterm::crossterm_cursor::get(); +New: use crossterm::cursor::cursor(); + +Old: crossterm::crossterm_terminal::get(); +New: use crossterm::terminal::terminal(); + +Old: crossterm::crossterm_style::color::get(); +New: use crossterm::style::color::color(); From e3efab2611ab7b438a306ecb5318c2cf315d0629 Mon Sep 17 00:00:00 2001 From: Timon Date: Sun, 20 May 2018 14:39:05 +0200 Subject: [PATCH 10/11] Update README.md --- README.md | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fff0df8..31cdce5 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Crossterm aims to be simple and easy to call in code. True the simplicity of cro ## Getting Started +This documentation is only for the newest version of crossterm. See the [Upgrade manual for more info](https://github.com/TimonPost/crossterm/blob/development/UPGRADE%20Manual) + Add the crossterm package to your `Cargo.toml` file. ``` @@ -21,18 +23,17 @@ And use the crossterm modules withs you want to use. extern crate crossterm; // this module is used for styling the terminal -use self::crossterm::crossterm_style::*; +use self::crossterm::style::*; // this module is used for cursor related actions -use self::crossterm::crossterm_cursor::*; +use self::crossterm::cursor::*; // this mudule is used for terminal related actions -use self::crossterm::crossterm_terminal::*; +use self::crossterm::terminal::*; ``` ## Links -Documentation for the code can be found [here](https://atcentra.com/crossterm/index.html) - -Documentation for the code can be found [here](https://docs.rs/crossterm/0.1.0/crossterm/) +Documentation for the code version 0.1 can be found [here](https://docs.rs/crossterm/0.1.0/crossterm/) +Documentation for the code version 0.2 can be found [here](https://docs.rs/crossterm/0.2.0/crossterm/) The Cargo Page can be found [here](https://crates.io/search?q=crossterm) @@ -42,7 +43,7 @@ For detailed examples of all crossterm functionalities check the [examples](http ### Styled font ```rust - use crossterm::crossterm_style::{paint, Color}; + use crossterm::style::{paint, Color}; // Crossterm provides method chaining so that you can style the font nicely. // the `with()` methods sets the foreground color and the `on()` methods sets the background color @@ -77,9 +78,9 @@ For detailed examples of all crossterm functionalities check the [examples](http ### Cursor ```rust - use crossterm::crossterm_cursor::get; + use crossterm::cursor::cursor(); - let mut cursor = get(); + let mut cursor = cursor(); /// Moving the cursor // Set the cursor to position X: 10, Y: 5 in the terminal @@ -117,9 +118,9 @@ For detailed examples of all crossterm functionalities check the [examples](http ### Terminal ```rust - use crossterm::crossterm_terminal::{get,ClearType}; + use crossterm::terminal::{terminal,ClearType}; - let mut terminal = get(); + let mut terminal = terminal(); // Clear all lines in terminal; terminal.clear(ClearType::All); @@ -170,6 +171,16 @@ For detailed examples of all crossterm functionalities check the [examples](http - Storing the current cursor position and resetting to that stored cursor position later. - Resizing the terminal. +### fixes in crossterm 0.2.1 + +- Default ansi escape codes enabled. If not supported than use WINAPI +- Some method refacoring +- Namespace refactoring (issue 4) +- Get position unix fixed +- Removed bin refrence from crate +- method grammer mistake fixed + + ## Tested terminals - Windows Powershell From 2fe20d87a01261034dcec0f1dd90f20fdbbd464e Mon Sep 17 00:00:00 2001 From: TimonPost Date: Sun, 20 May 2018 14:44:14 +0200 Subject: [PATCH 11/11] changed toml and removed bin --- .idea/workspace.xml | 206 +++++++++++++++++++++++--------------------- Cargo.toml | 13 +-- 2 files changed, 113 insertions(+), 106 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index ad371db..0c3021d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,14 +3,7 @@ - - - - - - - - + - - - - - - - - - - + @@ -39,11 +23,20 @@ - - + + - - + + + + + + + + + + + @@ -61,25 +54,40 @@ - + - - + + - - + + + + + + + + - - + + - - + + + + + + + + + + + @@ -93,20 +101,11 @@ - - + + - - - - - - - - - - - + + @@ -167,7 +166,6 @@ @@ -305,6 +304,13 @@ + + + + + + + @@ -481,12 +487,12 @@ - + - @@ -558,7 +564,6 @@ - @@ -575,13 +580,6 @@ - - - - - - - @@ -715,13 +713,6 @@ - - - - - - - @@ -743,19 +734,6 @@ - - - - - - - - - - - - - @@ -770,13 +748,6 @@ - - - - - - - @@ -784,13 +755,6 @@ - - - - - - - @@ -859,13 +823,6 @@ - - - - - - - @@ -904,7 +861,28 @@ - + + + + + + + + + + + + + + + + + + + + + + @@ -915,6 +893,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cargo.toml b/Cargo.toml index 23a8184..068191d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,13 @@ name = "crossterm" version = "0.2.0" authors = ["T Post "] -description = "An crossplarform terminal library for manipulating terminals." +description = "An crossplatform terminal library for manipulating terminals." repository = "https://github.com/TimonPost/crossterm" -documentation = "https://atcentra.com/crossterm/" +documentation = "https://docs.rs/crossterm/0.2.0/crossterm/" license = "MIT" keywords = ["console", "color", "cursor", "terminal", "cli"] exclude = ["target", "Cargo.lock"] +readme = "README.md" [dependencies] rand = "0.4.2" @@ -15,16 +16,10 @@ rand = "0.4.2" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] } - [target.'cfg(unix)'.dependencies] libc = "0.2" termios = "0.3.0" - [lib] name = "crossterm" -path = "src/lib.rs" - -[[bin]] -name = "crosstermexamples" -path = "examples/bin.rs" \ No newline at end of file +path = "src/lib.rs" \ No newline at end of file