Merge branch 'development' of https://github.com/TimonPost/crossterm into development
This commit is contained in:
commit
33d587817e
13
Cargo.toml
13
Cargo.toml
@ -11,22 +11,17 @@ exclude = ["target", "Cargo.lock"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.1.0"
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
|
||||
winapi = { version = "0.3.5", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
libc = "0.2.43"
|
||||
termios = "0.3.0"
|
||||
|
||||
[lib]
|
||||
name = "crossterm"
|
||||
path = "src/lib.rs"
|
||||
|
||||
#[[bin]]
|
||||
# name = "example_bin"
|
||||
# path = "./examples/Crossterm 0.3.1/bin.rs"
|
||||
|
||||
[[example]]
|
||||
name = "examples"
|
||||
path = "examples/examples.rs"
|
||||
@ -36,5 +31,5 @@ name = "logging"
|
||||
path = "examples/program_examples/logging.rs"
|
||||
|
||||
[[example]]
|
||||
name = "duplex"
|
||||
path = "examples/program_examples/duplex.rs"
|
||||
name = "command_bar"
|
||||
path = "examples/program_examples/command_bar.rs"
|
||||
|
33
README.md
33
README.md
@ -10,7 +10,7 @@ Crossterm aims to be simple and easy to call in code.
|
||||
Though the simplicity of Crossterm, you do not have to worry about the platform you are working with.
|
||||
You can just call whatever action you want and behind the scenes it will check what to do based on the current platform.
|
||||
|
||||
This crate supports all unix and windows terminals down to windows XP (not all terminals are tested see [Tested Terminals](Link) for more info)
|
||||
This crate supports all unix and windows terminals down to windows 7 (not all terminals are tested see [Tested Terminals](Link) for more info)
|
||||
|
||||
## Table of contents:
|
||||
- [Getting started](https://github.com/TimonPost/crossterm#getting-started)
|
||||
@ -167,7 +167,7 @@ This module provides the functionalities to work with the terminal cursor.
|
||||
```rust
|
||||
|
||||
use crossterm::Screen;
|
||||
use crossterm::cursor::cursor;
|
||||
use crossterm::cursor;
|
||||
|
||||
// create Screen to wheron the `cursor()` should function.
|
||||
let screen = Screen::default();
|
||||
@ -206,6 +206,32 @@ cursor.blink(true)
|
||||
|
||||
```
|
||||
|
||||
### Input | [see more](LINK)
|
||||
This module provides the functionalities to work with terminal input.
|
||||
|
||||
Check [this](link) for handling async input.
|
||||
|
||||
```rust
|
||||
|
||||
use crossterm::Screen;
|
||||
use crossterm::input;
|
||||
|
||||
// create Screen to wheron the `cursor()` should function.
|
||||
let screen = Screen::default();
|
||||
let mut input = input(&screen);
|
||||
|
||||
match input.read_char() {
|
||||
Ok(s) => println!("char typed: {}", s),
|
||||
Err(e) => println!("char error : {}", e),
|
||||
}
|
||||
|
||||
match input.read_line() {
|
||||
Ok(s) => println!("string typed: {}", s),
|
||||
Err(e) => println!("error: {}", e),
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Terminal | [see more](LINK)
|
||||
This module provides the functionalities to work with the terminal in general.
|
||||
|
||||
@ -254,11 +280,12 @@ Check these links: [AlternateScreen](https://github.com/TimonPost/crossterm/blob
|
||||
- Windows 10 (pro)
|
||||
- Windows CMD
|
||||
- Windows 10 (pro)
|
||||
- Windows 8.1 (N)
|
||||
- Ubuntu Desktop Terminal
|
||||
- Ubuntu 17.10
|
||||
- Arch linux Konsole
|
||||
|
||||
This crate supports all Unix terminals and windows terminals down to Windows XP but not all of them have been tested.
|
||||
This crate supports all Unix terminals and windows terminals down to Windows 7 but not all of them have been tested.
|
||||
If you have used this library for a terminal other than the above list without issues feel free to add it to the above list, I really would appreciate it.
|
||||
|
||||
## Notice
|
||||
|
@ -7,8 +7,6 @@
|
||||
//! - Run program with: `cargo run --example examples`
|
||||
|
||||
extern crate crossterm;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
// modules that could be test
|
||||
mod terminal;
|
||||
@ -17,62 +15,19 @@ mod cursor;
|
||||
mod some_types;
|
||||
mod input;
|
||||
|
||||
use crossterm::{Screen, Crossterm};
|
||||
use crossterm::terminal::{Terminal, ClearType};
|
||||
use crossterm::cursor::TerminalCursor;
|
||||
use std::io::Write;
|
||||
|
||||
use std::{time, thread};
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{Arc,Mutex};
|
||||
use crossterm::cursor::cursor;
|
||||
use std::io::Read;
|
||||
|
||||
fn main() {
|
||||
use crossterm::color;
|
||||
|
||||
let input = CROSSTERM.input();
|
||||
let mut stdin = input.read_async().bytes();
|
||||
CROSSTERM.cursor().hide();
|
||||
|
||||
let mut input_buf = Arc::new(Mutex::new(String::new()));
|
||||
|
||||
loop
|
||||
fn main()
|
||||
{
|
||||
let a = stdin.next();
|
||||
use crossterm::screen::RawScreen;
|
||||
use crossterm::Screen;
|
||||
|
||||
swap_write("dddd", &input_buf.lock().unwrap());
|
||||
let mut screen = Screen::new(true);
|
||||
|
||||
match a {
|
||||
Some(Ok(b'\r')) =>
|
||||
{
|
||||
input_buf.lock().unwrap().clear();
|
||||
write!(screen, "text \n\r");
|
||||
let a = screen.enable_alternate_modes(true).unwrap();
|
||||
|
||||
// need to start receiving again because if pressed enter then async reading will stop
|
||||
stdin = input.read_async().bytes();
|
||||
}
|
||||
Some(Ok(val)) =>
|
||||
{
|
||||
input_buf.lock().unwrap().push(val as char);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
write!(a, "text \n\r");
|
||||
|
||||
thread::sleep(time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn swap_write(msg: &str, input_buf: &String) {
|
||||
let term = CROSSTERM.terminal();
|
||||
let (_, term_height) = term.terminal_size();
|
||||
CROSSTERM.cursor().goto(0, term_height);
|
||||
term.clear(ClearType::CurrentLine);
|
||||
term.write(format!("{}\r\n", msg));
|
||||
term.write(format!(">{}", input_buf));
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref CROSSTERM: Crossterm = {
|
||||
let screen = Screen::new(true);
|
||||
Crossterm::new(&screen)
|
||||
};
|
||||
}
|
||||
|
@ -103,7 +103,6 @@ pub fn async_reading_on_alternate_screen() {
|
||||
|
||||
let screen = Screen::new(false);
|
||||
|
||||
|
||||
// switch to alternate screen
|
||||
if let Ok(alternate) = screen.enable_alternate_modes(true)
|
||||
{
|
||||
|
@ -5,6 +5,17 @@ If you have created a game or something feel free to upload it, would be a great
|
||||
The programs are:
|
||||
|
||||
- First depth search:
|
||||
|
||||
This is an search algorithm implemented visually. This program uses the following functionalities: cursor movement, coloring, alternate screen and terminal clearing.
|
||||
- Duplex: This is a terminal application where there is some kind of conterminous output and with async input. So you could type an command while text is being outputted.
|
||||
- This is an async logging program to demonstrate asynchronous working with crossterm.
|
||||
|
||||
- Snake
|
||||
|
||||
This is a snake game implemented with this library.
|
||||
|
||||
- Command Bar:
|
||||
|
||||
This is a terminal application where multiple threads write to the output while you can enter commands asynchronously.
|
||||
|
||||
- Logging:
|
||||
|
||||
This is an async logging program to demonstrate asynchronous logging with an queue.
|
94
examples/program_examples/command_bar.rs
Normal file
94
examples/program_examples/command_bar.rs
Normal file
@ -0,0 +1,94 @@
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::{Screen, Crossterm};
|
||||
use crossterm::terminal::{terminal,Terminal, ClearType};
|
||||
use crossterm::cursor::TerminalCursor;
|
||||
|
||||
use std::sync::{Arc,Mutex};
|
||||
use std::io::Read;
|
||||
use std::{thread,time};
|
||||
|
||||
fn main() {
|
||||
use crossterm::color;
|
||||
|
||||
let screen = Screen::new(true);
|
||||
let crossterm = Crossterm::new(&screen);
|
||||
|
||||
let input = crossterm.input();
|
||||
let terminal = crossterm.terminal();
|
||||
let cursor = crossterm.cursor();
|
||||
|
||||
let mut stdin = input.read_async().bytes();
|
||||
cursor.hide();
|
||||
|
||||
let mut input_buf = Arc::new(Mutex::new(String::new()));
|
||||
|
||||
let mut count = 0;
|
||||
|
||||
let threads = log(input_buf.clone());
|
||||
|
||||
loop
|
||||
{
|
||||
let a = stdin.next();
|
||||
|
||||
match a {
|
||||
Some(Ok(b'\r')) =>
|
||||
{
|
||||
input_buf.lock().unwrap().clear();
|
||||
|
||||
// need to start receiving again because if pressed enter then async reading will stop
|
||||
stdin = input.read_async().bytes();
|
||||
}
|
||||
Some(Ok(val)) =>
|
||||
{
|
||||
input_buf.lock().unwrap().push(val as char);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
thread::sleep(time::Duration::from_millis(100));
|
||||
count += 1;
|
||||
}
|
||||
|
||||
for thread in threads
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
|
||||
cursor.show();
|
||||
}
|
||||
|
||||
fn log(input_buf: Arc<Mutex<String>>) -> Vec<thread::JoinHandle<()>>
|
||||
{
|
||||
let mut threads = Vec::with_capacity(10);
|
||||
let (_, term_height) = terminal(&Screen::default()).terminal_size();
|
||||
|
||||
for i in 0..10
|
||||
{
|
||||
let input_buffer = input_buf.clone();
|
||||
|
||||
let join = thread::spawn( move || {
|
||||
|
||||
let crossterm = Crossterm::new(&Screen::default());
|
||||
let cursor = crossterm.cursor();
|
||||
let terminal = crossterm.terminal();
|
||||
|
||||
for j in 0..1000
|
||||
{
|
||||
swap_write(format!("Some output: {} from thread: {}", j, i).as_ref(), &input_buffer.lock().unwrap(), &terminal, &cursor, term_height);
|
||||
thread::sleep(time::Duration::from_millis(300));
|
||||
}
|
||||
});
|
||||
|
||||
threads.push(join);
|
||||
}
|
||||
|
||||
return threads;
|
||||
}
|
||||
|
||||
pub fn swap_write(msg: &str, input_buf: &String, terminal: &Terminal, cursor: &TerminalCursor, term_height: u16) {
|
||||
cursor.goto(0, term_height);
|
||||
terminal.clear(ClearType::CurrentLine);
|
||||
terminal.write(format!("{}\r\n", msg));
|
||||
terminal.write(format!(">{}", input_buf));
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
//! This bin folder can be used to try the examples out located in the examples directory.
|
||||
//!
|
||||
//! All you need to do is:
|
||||
//!
|
||||
//! - Download the crossterm source code.
|
||||
//! - Add this in the Cargo.toml file:
|
||||
//! ``` [[bin]]
|
||||
//! name = "example_bin"
|
||||
//! path = "./examples/bin.rs"
|
||||
//! ```
|
||||
//!
|
||||
//! - Run program with: `cargo run`
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::style::Color;
|
||||
use crossterm::Crossterm;
|
||||
use crossterm::terminal::ClearType;
|
||||
use std::thread::sleep;
|
||||
use std::sync::{Arc,Mutex};
|
||||
use std::io::Read;
|
||||
use std::time::Duration;
|
||||
// mod terminal;
|
||||
// mod color;
|
||||
// mod cursor;
|
||||
// mod crossterm_type;
|
||||
// mod input;
|
||||
|
||||
//use input::keyboard::{async_input, input as stdin};
|
||||
|
||||
use std::thread;
|
||||
|
||||
|
||||
}fn main() {
|
||||
let mut terminal = Arc::new(Mutex::new(Crossterm::new()));
|
||||
let input = terminal.lock().unwrap().input().read_async();
|
||||
terminal.lock().unwrap().enable_raw_mode();
|
||||
let mut input_buf = Arc::new(Mutex::new(String::new()));
|
||||
let mut key_buf = [0 as u8; 32];
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
swap_write(&mut terminal.lock().unwrap(), "random program output",&input_buf.lock().unwrap());
|
||||
sleep(Duration::from_millis(100));
|
||||
}
|
||||
});
|
||||
|
||||
loop {
|
||||
let mut term = terminal.lock().unwrap();
|
||||
let (term_width, term_height) = term.terminal().terminal_size();
|
||||
if let Ok(count) = input.read(&mut key_buf) {
|
||||
for idx in 0..count {
|
||||
let b = key_buf.get(idx).unwrap();
|
||||
if *b == 3 {
|
||||
std::process::exit(0); // Ctrl+C = exit immediate
|
||||
} else if *b == 13 {
|
||||
// The return key was pressed.
|
||||
let mut input_buf_tmp = &mut input_buf.lock().unwrap();
|
||||
input_buf.lock().unwrap().clear();
|
||||
swap_write(&mut term, "", &input_buf_tmp);
|
||||
} else {
|
||||
let mut input_buf_tmp = &mut input_buf.lock().unwrap();
|
||||
input_buf_tmp.push(*b as char);
|
||||
swap_write(&mut term, "", &input_buf_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn swap_write(terminal: &mut Crossterm, msg: &str, input_buf: &String) {
|
||||
let (term_width, term_height) = terminal.terminal().terminal_size();
|
||||
terminal.cursor().goto(0, term_height);
|
||||
terminal.terminal().clear(ClearType::CurrentLine);
|
||||
terminal
|
||||
.terminal()
|
||||
.write(format!("{}\n\r>{}", msg, input_buf));
|
||||
}
|
@ -7,7 +7,9 @@ use winapi::um::wincon;
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::um::wincon::{ENABLE_VIRTUAL_TERMINAL_PROCESSING};
|
||||
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// This command is used for enabling and disabling ANSI code support for windows systems,
|
||||
/// For more info check: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences.
|
||||
@ -72,14 +74,12 @@ impl IEnableAnsiCommand for EnableAnsiCommand {
|
||||
pub struct RawModeCommand {
|
||||
mask: DWORD,
|
||||
}
|
||||
|
||||
use self::wincon::{ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT, ENABLE_WRAP_AT_EOL_OUTPUT, ENABLE_PROCESSED_OUTPUT};
|
||||
impl RawModeCommand
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
use self::wincon::{ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT};
|
||||
|
||||
RawModeCommand {
|
||||
mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT,
|
||||
mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,10 +87,11 @@ impl RawModeCommand
|
||||
impl RawModeCommand {
|
||||
/// Enables raw mode.
|
||||
pub fn enable(&mut self) -> Result<()> {
|
||||
let input_handle = handle::get_input_handle()?;
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&input_handle, &mut dw_mode) {
|
||||
let stdout = handle::get_output_handle().unwrap();
|
||||
|
||||
if !kernel::get_console_mode(&stdout, &mut dw_mode) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Could not get console mode when enabling raw mode",
|
||||
@ -99,7 +100,7 @@ impl RawModeCommand {
|
||||
|
||||
let new_mode = dw_mode & !self.mask;
|
||||
|
||||
if !kernel::set_console_mode(&input_handle, new_mode) {
|
||||
if !kernel::set_console_mode(&stdout, new_mode) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Could not set console mode when enabling raw mode",
|
||||
@ -111,10 +112,10 @@ impl RawModeCommand {
|
||||
|
||||
/// Disables raw mode.
|
||||
pub fn disable(&self) -> Result<()> {
|
||||
let output_handle = handle::get_input_handle()?;
|
||||
let stdout = handle::get_output_handle().unwrap();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
|
||||
if !kernel::get_console_mode(&stdout, &mut dw_mode) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Could not get console mode when disabling raw mode",
|
||||
@ -123,7 +124,7 @@ impl RawModeCommand {
|
||||
|
||||
let new_mode = dw_mode | self.mask;
|
||||
|
||||
if !kernel::set_console_mode(&output_handle, new_mode) {
|
||||
if !kernel::set_console_mode(&stdout, new_mode) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
"Could not set console mode when disabling raw mode",
|
||||
|
@ -7,7 +7,7 @@
|
||||
//! Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
|
||||
use super::commands::{self, IAlternateScreenCommand};
|
||||
use super::{functions, Screen, TerminalOutput};
|
||||
use super::{functions, Screen, TerminalOutput,RawScreen};
|
||||
|
||||
use std::io;
|
||||
use std::convert::From;
|
||||
@ -34,7 +34,8 @@ impl AlternateScreen {
|
||||
/// The alternate buffer is exactly the dimensions of the window, without any scrollback region.
|
||||
/// For an example of this behavior, consider when vim is launched from bash.
|
||||
/// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
pub fn to_alternate_screen(stdout: TerminalOutput) -> io::Result<AlternateScreen> {
|
||||
pub fn to_alternate_screen(stdout: TerminalOutput, raw_mode: bool) -> io::Result<AlternateScreen> {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let command = functions::get_module::<Box<commands::IAlternateScreenCommand + Send>>(
|
||||
Box::from(commands::win_commands::ToAlternateScreenCommand::new()),
|
||||
@ -46,7 +47,15 @@ impl AlternateScreen {
|
||||
|
||||
let mut stdout = stdout;
|
||||
command.enable(&mut stdout)?;
|
||||
return Ok(AlternateScreen::new(command, Screen::from(stdout)));
|
||||
|
||||
let screen = Screen::from(stdout);
|
||||
|
||||
if raw_mode
|
||||
{
|
||||
RawScreen::into_raw_mode();
|
||||
}
|
||||
|
||||
return Ok(AlternateScreen::new(command, screen));
|
||||
}
|
||||
|
||||
/// Switch the alternate screen back to main screen.
|
||||
|
@ -15,8 +15,10 @@
|
||||
//! With these modes you can easier design the terminal screen.
|
||||
|
||||
use super::commands::*;
|
||||
use TerminalOutput;
|
||||
|
||||
use std::io;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
||||
pub struct RawScreen;
|
||||
|
@ -55,33 +55,13 @@ impl Screen
|
||||
{
|
||||
if raw_mode
|
||||
{
|
||||
RawScreen::into_raw_mode();;
|
||||
return Screen { stdout: Arc::new(TerminalOutput::new(true)), buffer: Vec::new() };
|
||||
let screen = Screen { stdout: Arc::new(TerminalOutput::new()), buffer: Vec::new() };
|
||||
return screen;
|
||||
}
|
||||
|
||||
return Screen::default();
|
||||
}
|
||||
|
||||
/// This method could be used for enabling raw mode for the terminal.
|
||||
///
|
||||
/// What exactly is raw state:
|
||||
/// - No line buffering.
|
||||
/// Normally the terminals uses line buffering. This means that the input will be send to the terminal line by line.
|
||||
/// With raw mode the input will be send one byte at a time.
|
||||
/// - Input
|
||||
/// All input has to be written manually by the programmer.
|
||||
/// - Characters
|
||||
/// The characters are not processed by the terminal driver, but are sent straight through.
|
||||
/// Special character have no meaning, like backspace will not be interpret as backspace but instead will be directly send to the terminal.
|
||||
/// - Escape characters
|
||||
/// Note that in raw modes `\n` will move to the new line but the cursor will be at the same position as before on the new line therefor use `\n\r` to start at the new line at the first cell.
|
||||
///
|
||||
/// With these modes you can easier design the terminal screen.
|
||||
pub fn enable_raw_modes(&self) -> Result<()> {
|
||||
RawScreen::into_raw_mode()?;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
/// Switch to alternate screen. This function will return an `AlternateScreen` instance if everything went well this type will give you control over the `AlternateScreen`.
|
||||
///
|
||||
/// # What is Alternate screen?
|
||||
@ -90,14 +70,9 @@ impl Screen
|
||||
/// For an example of this behavior, consider when vim is launched from bash.
|
||||
/// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
|
||||
pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> {
|
||||
let stdout = TerminalOutput::new(raw_mode);
|
||||
let stdout = TerminalOutput::new();
|
||||
|
||||
if raw_mode
|
||||
{
|
||||
RawScreen::into_raw_mode();
|
||||
}
|
||||
|
||||
let alternate_screen = AlternateScreen::to_alternate_screen(stdout)?;
|
||||
let alternate_screen = AlternateScreen::to_alternate_screen(stdout, raw_mode)?;
|
||||
return Ok(alternate_screen);
|
||||
}
|
||||
}
|
||||
@ -122,7 +97,7 @@ impl Default for Screen
|
||||
{
|
||||
/// Create an new screen which will not be in raw mode or alternate mode.
|
||||
fn default() -> Self {
|
||||
return Screen { stdout: Arc::new(TerminalOutput::new(false)), buffer: Vec::new() };
|
||||
return Screen { stdout: Arc::new(TerminalOutput::new()), buffer: Vec::new() };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ use Screen;
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::cursor::cursor;
|
||||
/// use self::crossterm::cursor;
|
||||
/// use self::crossterm::Screen;
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
|
@ -11,7 +11,7 @@ use Screen;
|
||||
/// ```rust
|
||||
/// extern crate crossterm;
|
||||
/// use self::crossterm::Screen;
|
||||
/// use self::crossterm::input::input;
|
||||
/// use self::crossterm::input;
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
/// let input = input(&screen);
|
||||
|
@ -22,6 +22,7 @@ use super::*;
|
||||
|
||||
use std::any::Any;
|
||||
use std::default::Default;
|
||||
use screen::RawScreen;
|
||||
|
||||
/// Struct that is an handle to an terminal screen.
|
||||
/// This handle could be used to write to the current screen
|
||||
@ -34,7 +35,7 @@ pub struct TerminalOutput {
|
||||
|
||||
impl TerminalOutput {
|
||||
/// Create new screen write instance whereon screen related actions can be performed.
|
||||
pub fn new(is_in_raw_mode: bool) -> Self {
|
||||
pub fn new() -> Self {
|
||||
#[cfg(target_os = "windows")]
|
||||
let stdout: Box<IStdout + Send + Sync> = functions::get_module::<Box<IStdout + Send + Sync>>(
|
||||
Box::from(WinApiOutput::new()),
|
||||
@ -44,7 +45,7 @@ impl TerminalOutput {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let stdout = Box::from(AnsiOutput::new()) as Box<IStdout + Send + Sync>;
|
||||
|
||||
TerminalOutput { stdout , is_in_raw_mode}
|
||||
TerminalOutput { stdout , is_in_raw_mode: false}
|
||||
}
|
||||
|
||||
/// Write String to the current screen.
|
||||
|
@ -1,4 +1,6 @@
|
||||
use super::IStdout;
|
||||
use screen::RawScreen;
|
||||
use common::commands::win_commands::RawModeCommand;
|
||||
use kernel::windows_kernel::{handle, writing};
|
||||
use winapi::um::winnt::HANDLE;
|
||||
|
||||
@ -9,6 +11,7 @@ use std::io;
|
||||
/// This struct is a wrapper for WINAPI `HANDLE`
|
||||
pub struct WinApiOutput {
|
||||
pub handle: Mutex<HANDLE>,
|
||||
raw_mode: bool,
|
||||
}
|
||||
|
||||
impl IStdout for WinApiOutput {
|
||||
@ -21,7 +24,6 @@ impl IStdout for WinApiOutput {
|
||||
writing::write_char_buffer(&self.handle.lock().unwrap(), buf)
|
||||
}
|
||||
|
||||
|
||||
fn flush(&self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@ -37,7 +39,8 @@ impl IStdout for WinApiOutput {
|
||||
|
||||
impl WinApiOutput {
|
||||
pub fn new() -> Self {
|
||||
WinApiOutput { handle: Mutex::new(handle::get_output_handle().unwrap()) }
|
||||
let handle = handle::get_output_handle().unwrap();
|
||||
WinApiOutput { raw_mode: false, handle: Mutex::new(handle) }
|
||||
}
|
||||
|
||||
pub fn set(&mut self, handle: HANDLE)
|
||||
@ -47,8 +50,7 @@ impl WinApiOutput {
|
||||
|
||||
pub fn get_handle(&self) -> HANDLE
|
||||
{
|
||||
let gx = self.handle.lock();
|
||||
gx.unwrap().clone()
|
||||
return self.handle.lock().unwrap().clone();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,11 +7,14 @@ use Screen;
|
||||
|
||||
/// Struct that stores an specific platform implementation for color related actions.
|
||||
///
|
||||
/// For styling text use the `::crossterm::style()` function. `TerminalColor` will set the colors of the screen permanently and the `style()` will only style the text given.
|
||||
///
|
||||
/// Check `/examples/color` in the library for more specific examples.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// use crossterm::{Screen}
|
||||
/// use crossterm::color::color;
|
||||
/// use crossterm::style::color;
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
/// let colored_terminal = color(&screen);
|
||||
|
@ -140,7 +140,7 @@ impl<D: Display> StyledObject<D> {
|
||||
self.attr(Attribute::CrossedOut)
|
||||
}
|
||||
|
||||
/// This could be used to paint the styled object on the screen. Pass a refrence to the screen whereon you want to perform the painting.
|
||||
/// This could be used to paint the styled object on the screen. Pass a reference to the screen whereon you want to perform the painting.
|
||||
///
|
||||
/// ``` rust
|
||||
/// style("Some colored text")
|
||||
|
@ -10,7 +10,7 @@ use std::fmt;
|
||||
/// Check `/examples/terminal` in the library for more specific examples.
|
||||
///
|
||||
/// ```rust
|
||||
/// use crossterm::terminal::terminal;
|
||||
/// use crossterm::terminal;
|
||||
///
|
||||
/// let screen = Screen::default();
|
||||
/// let term = terminal(&screen);
|
||||
|
Loading…
Reference in New Issue
Block a user