diff --git a/src/common/commands/mod.rs b/src/common/commands/mod.rs index a56241c..42d02cf 100644 --- a/src/common/commands/mod.rs +++ b/src/common/commands/mod.rs @@ -5,23 +5,23 @@ use std::io::Result; pub mod shared_commands; -#[cfg(target_os = "unix")] +#[cfg(not(target_os = "windows"))] pub mod unix_command; #[cfg(target_os = "windows")] pub mod win_commands; -#[cfg(target_os = "windows")] -pub use self::win_commands::*; -#[cfg(target_os = "unix")] -pub use self::unix_commands::*; - -pub use self::shared_commands::*; /// This trait provides a way to execute some state changing commands. pub trait IStateCommand { - fn execute(&mut self) -> bool; - fn undo(&mut self) -> bool; + fn execute(&mut self) -> Result<()>; + fn undo(&mut self) -> Result<()>; +} + +pub trait IEnableAnsiCommand +{ + fn enable(&mut self) -> bool; + fn disable(&mut self) -> bool; } /// This trait provides an interface for switching to alternate screen and back. diff --git a/src/common/commands/shared_commands.rs b/src/common/commands/shared_commands.rs index 23955f2..596e4bc 100644 --- a/src/common/commands/shared_commands.rs +++ b/src/common/commands/shared_commands.rs @@ -8,8 +8,8 @@ use std::io::Result; pub struct ToAlternateScreenCommand; impl ToAlternateScreenCommand { - pub fn new() -> Box { - return Box::new(ToAlternateScreenCommand {}); + pub fn new() -> ToAlternateScreenCommand { + return ToAlternateScreenCommand {}; } } diff --git a/src/common/commands/unix_command.rs b/src/common/commands/unix_command.rs index 4c5f17b..0f85796 100644 --- a/src/common/commands/unix_command.rs +++ b/src/common/commands/unix_command.rs @@ -10,41 +10,30 @@ use std::io::{Result,Error, ErrorKind}; /// This command is used for switching to NoncanonicalMode. #[derive(Copy, Clone)] -pub struct NoncanonicalModeCommand { - key: u16, -} +pub struct NoncanonicalModeCommand; impl NoncanonicalModeCommand { - pub fn new(state_manager: &Mutex) -> u16 { - let mut state = state_manager.lock().unwrap(); - { - let key = state.get_changes_count(); - let command = NoncanonicalModeCommand { key: key }; - - state.register_change(Box::from(command), key); - key - } + pub fn new() -> NoncanonicalModeCommand { + NoncanonicalModeCommand { } } } impl IStateCommand for NoncanonicalModeCommand { - fn execute(&mut self) -> bool { + fn execute(&mut self) -> Result<()> { // Set noncanonical mode 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, - }; + tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)?; } else { - return false; + return Err(Error::new(ErrorKind::Other,"Could not set console mode when enabling raw mode")) } + Ok(()) } - fn undo(&mut self) -> bool { + fn undo(&mut self) -> Result<()> { // Disable noncanonical mode if let Ok(orig) = Termios::from_fd(FD_STDIN) { let mut noncan = orig.clone(); @@ -52,13 +41,11 @@ impl IStateCommand for NoncanonicalModeCommand { noncan.c_lflag &= ECHO; noncan.c_lflag &= CREAD; - match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) { - Ok(_) => return true, - Err(_) => return false, - }; + tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)?; } else { - return false; + return Err(Error::new(ErrorKind::Other,"Could not set console mode when enabling raw mode")) } + Ok(()) } } diff --git a/src/common/commands/win_commands.rs b/src/common/commands/win_commands.rs index 48b705f..8309ee4 100644 --- a/src/common/commands/win_commands.rs +++ b/src/common/commands/win_commands.rs @@ -1,6 +1,6 @@ //! This module contains the commands that can be used for windows systems. -use super::{ ScreenManager, IStateCommand, IAlternateScreenCommand, IRawScreenCommand}; +use super::{ ScreenManager, IEnableAnsiCommand, IAlternateScreenCommand, IRawScreenCommand}; use kernel::windows_kernel::{ansi_support, csbi, handle, kernel}; use std::mem; @@ -18,16 +18,16 @@ pub struct EnableAnsiCommand { } impl EnableAnsiCommand { - pub fn new() -> Box { + pub fn new() -> EnableAnsiCommand { let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING, }; - Box::from(command) + command } } -impl IStateCommand for EnableAnsiCommand { - fn execute(&mut self) -> bool { +impl IEnableAnsiCommand for EnableAnsiCommand { + fn enable(&mut self) -> bool { // 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() { return ansi_support::windows_supportable(); @@ -47,7 +47,7 @@ impl IStateCommand for EnableAnsiCommand { } } - fn undo(&mut self) -> bool { + fn disable(&mut self) -> bool { if ansi_support::ansi_enabled() { let output_handle = handle::get_output_handle().unwrap(); @@ -122,16 +122,16 @@ impl IRawScreenCommand for EnableRawModeCommand { /// This command is used for switching to alternate screen and back to main screen. /// check https://docs.microsoft.com/en-us/windows/console/reading-and-writing-blocks-of-characters-and-attributes for more info -pub struct ToAlternateScreenBufferCommand; +pub struct ToAlternateScreenCommand; -impl ToAlternateScreenBufferCommand { - pub fn new() -> Box{ - return Box::from(ToAlternateScreenBufferCommand {}); +impl ToAlternateScreenCommand { + pub fn new() -> ToAlternateScreenCommand{ + return ToAlternateScreenCommand {}; } } -impl IAlternateScreenCommand for ToAlternateScreenBufferCommand { - fn to_alternate_screen(&self, screen_manager: &mut ScreenManager) -> Result<()>{ +impl IAlternateScreenCommand for ToAlternateScreenCommand { + fn enable(&self, screen_manager: &mut ScreenManager) -> Result<()>{ use super::super::super::manager::WinApiScreenManager; let handle = handle::get_output_handle()?; @@ -163,7 +163,7 @@ impl IAlternateScreenCommand for ToAlternateScreenBufferCommand { Ok(()) } - fn to_main_screen(&self, screen_manager: &mut ScreenManager) -> Result<()>{ + fn disable(&self, screen_manager: &mut ScreenManager) -> Result<()>{ let handle = handle::get_output_handle()?; csbi::set_active_screen_buffer(handle); diff --git a/src/common/crossterm.rs b/src/common/crossterm.rs index 1a7ceb8..5057bf3 100644 --- a/src/common/crossterm.rs +++ b/src/common/crossterm.rs @@ -75,7 +75,7 @@ impl<'crossterm> Crossterm return self.enable_alternate_screen(); }, Some(ref mut alternate_screen) => { - alternate_screen.to_alternate_screen(&mut self.active_screen)?; + alternate_screen.enable(&mut self.active_screen)?; self.alternate_mode = true; }, } @@ -92,7 +92,7 @@ impl<'crossterm> Crossterm return self.disable_alternate_screen(); }, Some(ref mut alternate_screen) => { - alternate_screen.to_main_screen(&mut self.active_screen)?; + alternate_screen.disable(&mut self.active_screen)?; self.alternate_mode = false; }, } @@ -122,7 +122,7 @@ impl Drop for Crossterm fn drop(&mut self) { if let Some(ref mut screen) = self.alternate_screen { - screen.to_main_screen(&mut self.active_screen); + screen.disable(&mut self.active_screen); } if let Some(ref mut raw_terminal) = self.raw_terminal { @@ -133,34 +133,34 @@ impl Drop for Crossterm -/// 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)); - /// } - /// - /// ``` +// 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, diff --git a/src/common/screen/alternate.rs b/src/common/screen/alternate.rs index 07e51b2..cefbb23 100644 --- a/src/common/screen/alternate.rs +++ b/src/common/screen/alternate.rs @@ -35,8 +35,8 @@ impl AlternateScreen { pub fn new() -> Box { #[cfg(target_os = "windows")] let command = functions::get_module::>( - commands::win_commands::ToAlternateScreenBufferCommand::new(), - commands::shared_commands::ToAlternateScreenBufferCommand::new(), + Box::from(commands::win_commands::ToAlternateScreenCommand::new()), + Box::from(commands::shared_commands::ToAlternateScreenCommand::new()), ).unwrap(); #[cfg(not(target_os = "windows"))] diff --git a/src/common/screen/raw.rs b/src/common/screen/raw.rs index 2370db7..8461a16 100644 --- a/src/common/screen/raw.rs +++ b/src/common/screen/raw.rs @@ -13,9 +13,10 @@ //! With these modes you can easier design the terminal screen. #[cfg(not(windows))] -use common::commands::EnableRawModeCommand; +use common::commands::unix_command::EnableRawModeCommand; + #[cfg(windows)] -use common::commands::EnableRawModeCommand; +use common::commands::win_commands::EnableRawModeCommand; use super::{functions, ScreenManager}; use super::commands; diff --git a/src/kernel/unix_kernel/terminal.rs b/src/kernel/unix_kernel/terminal.rs index f6636fd..e44e917 100644 --- a/src/kernel/unix_kernel/terminal.rs +++ b/src/kernel/unix_kernel/terminal.rs @@ -3,12 +3,18 @@ use libc; pub use libc::termios; use self::libc::{c_int, c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ}; -use common::commands::{NoncanonicalModeCommand, EnableRawModeCommand}; +use common::commands::unix_command::{NoncanonicalModeCommand, EnableRawModeCommand}; use std::io::Error; use std::os::unix::io::AsRawFd; use std::{fs, io, mem}; use termios::{cfmakeraw, tcsetattr, Termios, TCSADRAIN}; +use std::io::ErrorKind; +use std::io::Read; +use std::time::{SystemTime, Duration}; + + +use Crossterm; /// A representation of the size of the current terminal. #[repr(C)] @@ -41,14 +47,9 @@ pub fn terminal_size() -> (u16, u16) { } } - -use std::time::{SystemTime, Duration}; -use std::io::ErrorKind; -use Terminal; -use std::io::Read; /// Get the current cursor position. pub fn pos() -> (u16, u16) { - let crossterm = Terminal::new(); + let crossterm = Crossterm::new(); let input = crossterm.input(); let delimiter = b'R'; diff --git a/src/kernel/windows_kernel/ansi_support.rs b/src/kernel/windows_kernel/ansi_support.rs index 59c820e..c91bc97 100644 --- a/src/kernel/windows_kernel/ansi_support.rs +++ b/src/kernel/windows_kernel/ansi_support.rs @@ -7,14 +7,15 @@ static mut IS_ANSI_ON_WINDOWS_ENABLED: Option = None; static mut DOES_WINDOWS_SUPPORT_ANSI: Option = None; static ENABLE_ANSI: Once = ONCE_INIT; -use common::commands::{EnableAnsiCommand, IStateCommand}; +use common::commands::win_commands::{EnableAnsiCommand}; +use common::commands::IEnableAnsiCommand; /// Try enable `ANSI escape codes` and return the result. pub fn try_enable_ansi_support() -> bool { ENABLE_ANSI.call_once(|| { let mut command = EnableAnsiCommand::new(); - let success = command.execute(); + let success = command.enable(); set_is_windows_ansi_supportable(success); set_ansi_enabled(success); diff --git a/src/modules/style/color.rs b/src/modules/style/color.rs index ebc26de..1e3dc20 100644 --- a/src/modules/style/color.rs +++ b/src/modules/style/color.rs @@ -38,7 +38,7 @@ impl<'terminal> TerminalColor<'terminal> { ).unwrap(); #[cfg(not(target_os = "windows"))] - let color = AnsiColor::new() as Box; + let color = Box::from(AnsiColor::new()) as Box; TerminalColor { color, diff --git a/src/modules/style/objectstyle.rs b/src/modules/style/objectstyle.rs index 72c4454..bc079cb 100644 --- a/src/modules/style/objectstyle.rs +++ b/src/modules/style/objectstyle.rs @@ -5,7 +5,7 @@ use super::{ScreenManager, Color, StyledObject}; use std::fmt::Display; #[cfg(unix)] -use super::super::Attribute; +use super::Attribute; /// Struct that contains the style properties that can be applied to an displayable object. #[derive(Clone)] diff --git a/src/modules/style/styledobject.rs b/src/modules/style/styledobject.rs index 4715c42..d50a14f 100644 --- a/src/modules/style/styledobject.rs +++ b/src/modules/style/styledobject.rs @@ -6,7 +6,7 @@ use std::fmt::{self, Display}; use std::io::Write; #[cfg(unix)] -use super::super::Attribute; +use super::Attribute; #[cfg(windows)] use super::super::super::manager::WinApiScreenManager; @@ -90,55 +90,55 @@ impl<'terminal,D: Display> StyledObject<'terminal,D> { /// Increase the font intensity. #[cfg(unix)] #[inline(always)] - pub fn bold(self) -> StyledObject { + pub fn bold(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Bold) } /// Faint (decreased intensity) (Not widely supported). #[cfg(unix)] #[inline(always)] - pub fn dim(self) -> StyledObject { + pub fn dim(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Dim) } /// Make the font italic (Not widely supported; Sometimes treated as inverse). #[cfg(unix)] #[inline(always)] - pub fn italic(self) -> StyledObject { + pub fn italic(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Italic) } /// Underline font. #[cfg(unix)] #[inline(always)] - pub fn underlined(self) -> StyledObject { + pub fn underlined(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Underlined) } /// Slow Blink (less than 150 per minute; not widely supported). #[cfg(unix)] #[inline(always)] - pub fn slow_blink(self) -> StyledObject { + pub fn slow_blink(self) -> StyledObject<'terminal,D> { self.attr(Attribute::SlowBlink) } /// Rapid Blink (MS-DOS ANSI.SYS; 150+ per minute; not widely supported). #[cfg(unix)] #[inline(always)] - pub fn rapid_blink(self) -> StyledObject { + pub fn rapid_blink(self) -> StyledObject<'terminal,D> { self.attr(Attribute::RapidBlink) } /// Swap foreground and background colors. #[cfg(unix)] #[inline(always)] - pub fn reverse(self) -> StyledObject { + pub fn reverse(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Reverse) } /// Hide text (Not widely supported). #[cfg(unix)] #[inline(always)] - pub fn hidden(self) -> StyledObject { + pub fn hidden(self) -> StyledObject<'terminal,D> { self.attr(Attribute::Hidden) } /// Characters legible, but marked for deletion. Not widely supported. #[cfg(unix)] #[inline(always)] - pub fn crossed_out(self) -> StyledObject { + pub fn crossed_out(self) -> StyledObject<'terminal,D> { self.attr(Attribute::CrossedOut) } } diff --git a/src/modules/terminal/terminal.rs b/src/modules/terminal/terminal.rs index 1241761..20fe2fc 100644 --- a/src/modules/terminal/terminal.rs +++ b/src/modules/terminal/terminal.rs @@ -37,7 +37,7 @@ impl<'terminal> Terminal<'terminal> { ).unwrap(); #[cfg(not(target_os = "windows"))] - let terminal = AnsiTerminal::new() as Box; + let terminal = Box::from(AnsiTerminal::new()) as Box; Terminal { terminal,