Windows done with RC refactor unix yet to be tested

This commit is contained in:
TimonPost 2018-07-29 21:46:15 +02:00
commit 3a02d9b7c0
13 changed files with 95 additions and 105 deletions

View File

@ -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.

View File

@ -8,8 +8,8 @@ use std::io::Result;
pub struct ToAlternateScreenCommand;
impl ToAlternateScreenCommand {
pub fn new() -> Box<ToAlternateScreenCommand> {
return Box::new(ToAlternateScreenCommand {});
pub fn new() -> ToAlternateScreenCommand {
return ToAlternateScreenCommand {};
}
}

View File

@ -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<StateManager>) -> 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(())
}
}

View File

@ -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<EnableAnsiCommand> {
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<ToAlternateScreenBufferCommand>{
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);

View File

@ -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<D>(&self, val: D) -> style::StyledObject<D>
// where
// D: fmt::Display,

View File

@ -35,8 +35,8 @@ impl AlternateScreen {
pub fn new() -> Box<commands::IAlternateScreenCommand> {
#[cfg(target_os = "windows")]
let command = functions::get_module::<Box<commands::IAlternateScreenCommand>>(
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"))]

View File

@ -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;

View File

@ -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';

View File

@ -7,14 +7,15 @@ static mut IS_ANSI_ON_WINDOWS_ENABLED: Option<bool> = None;
static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = 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);

View File

@ -38,7 +38,7 @@ impl<'terminal> TerminalColor<'terminal> {
).unwrap();
#[cfg(not(target_os = "windows"))]
let color = AnsiColor::new() as Box<ITerminalColor>;
let color = Box::from(AnsiColor::new()) as Box<ITerminalColor>;
TerminalColor {
color,

View File

@ -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)]

View File

@ -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<D> {
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<D> {
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<D> {
pub fn italic(self) -> StyledObject<'terminal,D> {
self.attr(Attribute::Italic)
}
/// Underline font.
#[cfg(unix)]
#[inline(always)]
pub fn underlined(self) -> StyledObject<D> {
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<D> {
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<D> {
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<D> {
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<D> {
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<D> {
pub fn crossed_out(self) -> StyledObject<'terminal,D> {
self.attr(Attribute::CrossedOut)
}
}

View File

@ -37,7 +37,7 @@ impl<'terminal> Terminal<'terminal> {
).unwrap();
#[cfg(not(target_os = "windows"))]
let terminal = AnsiTerminal::new() as Box<ITerminal>;
let terminal = Box::from(AnsiTerminal::new()) as Box<ITerminal>;
Terminal {
terminal,