2018-01-18 09:06:45 +11:00
|
|
|
//! 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.
|
2018-03-11 03:33:06 +11:00
|
|
|
|
2018-07-02 06:43:43 +10:00
|
|
|
use super::super::shared::functions;
|
|
|
|
use super::super::style;
|
2018-03-06 08:06:43 +11:00
|
|
|
use super::*;
|
2018-06-17 04:10:51 +10:00
|
|
|
use Context;
|
2018-01-18 09:06:45 +11:00
|
|
|
|
2018-06-23 05:04:30 +10:00
|
|
|
use std::fmt;
|
2018-07-10 03:37:07 +10:00
|
|
|
use std::io::Write;
|
|
|
|
|
2018-06-23 05:04:30 +10:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2018-01-18 09:06:45 +11:00
|
|
|
/// Struct that stores an specific platform implementation for terminal related actions.
|
2018-06-23 05:04:30 +10:00
|
|
|
pub struct Terminal {
|
2018-07-09 06:13:32 +10:00
|
|
|
terminal: Box<ITerminal>,
|
2018-07-02 06:43:43 +10:00
|
|
|
context: Rc<Context>,
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
2018-06-23 05:04:30 +10:00
|
|
|
impl Terminal {
|
2018-01-31 07:20:11 +11:00
|
|
|
/// Create new terminal instance whereon terminal related actions can be performed.
|
2018-06-23 05:04:30 +10:00
|
|
|
pub fn new(context: Rc<Context>) -> Terminal {
|
2018-03-04 01:40:51 +11:00
|
|
|
#[cfg(target_os = "windows")]
|
2018-07-02 06:43:43 +10:00
|
|
|
let terminal = functions::get_module::<Box<ITerminal>>(
|
|
|
|
WinApiTerminal::new(context.clone()),
|
|
|
|
AnsiTerminal::new(context.clone()),
|
2018-07-09 06:13:32 +10:00
|
|
|
).unwrap();
|
2018-02-04 03:17:28 +11:00
|
|
|
|
2018-03-04 01:40:51 +11:00
|
|
|
#[cfg(not(target_os = "windows"))]
|
2018-07-09 06:13:32 +10:00
|
|
|
let terminal = AnsiTerminal::new(context.clone()) as Box<ITerminal>;
|
2018-01-31 07:20:11 +11:00
|
|
|
|
2018-07-02 06:43:43 +10:00
|
|
|
Terminal {
|
|
|
|
terminal,
|
|
|
|
context: context,
|
|
|
|
}
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Clear the current cursor by specifying the clear type
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // clear all cells in terminal.
|
2018-03-11 03:33:06 +11:00
|
|
|
/// term.clear(terminal::ClearType::All);
|
2018-01-31 07:20:11 +11:00
|
|
|
/// // clear all cells from the cursor position downwards in terminal.
|
2018-03-11 03:33:06 +11:00
|
|
|
/// term.clear(terminal::ClearType::FromCursorDown);
|
2018-01-31 07:20:11 +11:00
|
|
|
/// // clear all cells from the cursor position upwards in terminal.
|
2018-03-11 03:33:06 +11:00
|
|
|
/// term.clear(terminal::ClearType::FromCursorUp);
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // clear current line cells in terminal.
|
2018-03-11 03:33:06 +11:00
|
|
|
/// term.clear(terminal::ClearType::CurrentLine);
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // clear all cells from cursor position until new line in terminal.
|
2018-03-11 03:33:06 +11:00
|
|
|
/// term.clear(terminal::ClearType::UntilNewLine);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn clear(&self, clear_type: ClearType) {
|
2018-07-09 06:13:32 +10:00
|
|
|
self.terminal.clear(clear_type);
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the terminal size (x,y).
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
2018-03-11 03:33:06 +11:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
|
|
|
/// let size = term.terminal_size();
|
|
|
|
/// println!("{:?}", size);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn terminal_size(&self) -> (u16, u16) {
|
2018-07-09 06:13:32 +10:00
|
|
|
return self.terminal.terminal_size();
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Scroll `n` lines up in the current terminal.
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // scroll up by 5 lines
|
|
|
|
/// let size = term.scroll_up(5);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn scroll_up(&self, count: i16) {
|
2018-07-09 06:13:32 +10:00
|
|
|
self.terminal.scroll_up(count);
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Scroll `n` lines up in the current terminal.
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // scroll down by 5 lines
|
|
|
|
/// let size = term.scroll_down(5);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn scroll_down(&self, count: i16) {
|
2018-07-09 06:13:32 +10:00
|
|
|
self.terminal.scroll_down(count);
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
2018-01-26 04:26:08 +11:00
|
|
|
|
2018-01-28 04:26:08 +11:00
|
|
|
/// Set the terminal size. Note that not all terminals can be set to a very small scale.
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
|
|
|
///
|
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-01-28 04:26:08 +11:00
|
|
|
///
|
|
|
|
/// // Set of the size to X: 10 and Y: 10
|
|
|
|
/// let size = term.set_size(10,10);
|
2018-07-02 06:43:43 +10:00
|
|
|
///
|
2018-01-28 04:26:08 +11:00
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn set_size(&self, width: i16, height: i16) {
|
2018-07-09 06:13:32 +10:00
|
|
|
self.terminal.set_size(width, height);
|
2018-01-26 04:26:08 +11:00
|
|
|
}
|
2018-06-17 04:10:51 +10:00
|
|
|
|
|
|
|
/// 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));
|
|
|
|
/// }
|
2018-07-04 06:48:04 +10:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// ```
|
2018-07-04 06:48:04 +10:00
|
|
|
pub fn paint<D>(&self, val: D) -> style::StyledObject<D> where D: fmt::Display
|
2018-06-17 04:10:51 +10:00
|
|
|
{
|
2018-06-23 05:04:30 +10:00
|
|
|
style::ObjectStyle::new().apply_to(val, self.context.clone())
|
2018-06-17 04:10:51 +10:00
|
|
|
}
|
2018-06-24 03:48:22 +10:00
|
|
|
|
2018-07-12 03:43:12 +10:00
|
|
|
/// Exit the current process.
|
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
|
|
|
/// use crossterm::terminal;
|
|
|
|
/// use crossterm::Context;
|
|
|
|
///
|
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
|
|
|
///
|
|
|
|
/// let size = term.exit();
|
|
|
|
///
|
|
|
|
/// ```
|
2018-07-02 06:43:43 +10:00
|
|
|
pub fn exit(&self) {
|
2018-07-09 06:13:32 +10:00
|
|
|
self.terminal.exit();
|
2018-06-27 04:21:47 +10:00
|
|
|
}
|
2018-07-02 06:40:07 +10:00
|
|
|
|
2018-07-04 06:48:04 +10:00
|
|
|
/// Write any displayable content to the current terminal screen.
|
2018-07-12 03:43:12 +10:00
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
|
|
|
/// use crossterm::terminal;
|
|
|
|
/// use crossterm::Context;
|
|
|
|
///
|
|
|
|
/// let context = Context::new();
|
|
|
|
/// let mut term = terminal::terminal(&context);
|
|
|
|
///
|
|
|
|
/// let size = term.write("Some text \n Some text on new line");
|
|
|
|
///
|
|
|
|
/// ```
|
2018-07-12 06:59:54 +10:00
|
|
|
pub fn write<D: fmt::Display>(&self, value: D) {
|
2018-07-02 06:40:07 +10:00
|
|
|
let mut mutex = &self.context.screen_manager;
|
|
|
|
{
|
|
|
|
let mut screen_manager = mutex.lock().unwrap();
|
|
|
|
|
|
|
|
use std::fmt::Write;
|
|
|
|
let mut string = String::new();
|
|
|
|
write!(string, "{}", value).unwrap();
|
|
|
|
|
2018-07-09 06:13:32 +10:00
|
|
|
screen_manager.write_string(string);
|
2018-07-10 03:37:07 +10:00
|
|
|
screen_manager.flush();
|
2018-07-02 06:40:07 +10:00
|
|
|
}
|
|
|
|
}
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get an Terminal implementation whereon terminal related actions can be performed.
|
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// Check `/examples/version/terminal` in the libary for more spesific examples.
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
|
|
|
/// #Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
///
|
|
|
|
/// extern crate crossterm;
|
2018-03-11 03:33:06 +11:00
|
|
|
/// use crossterm::terminal;
|
2018-06-17 04:10:51 +10:00
|
|
|
/// use crossterm::Context;
|
|
|
|
///
|
|
|
|
/// let context = Context::new();
|
2018-01-18 09:06:45 +11:00
|
|
|
///
|
2018-06-17 04:10:51 +10:00
|
|
|
/// let mut term = terminal::terminal(&context);
|
2018-01-31 07:20:11 +11:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// // scroll down by 5 lines
|
|
|
|
/// let size = term.scroll_down(5);
|
2018-01-31 07:20:11 +11:00
|
|
|
///
|
2018-01-18 09:06:45 +11:00
|
|
|
/// ```
|
2018-01-31 07:20:11 +11:00
|
|
|
///
|
2018-06-23 05:04:30 +10:00
|
|
|
pub fn terminal(context: Rc<Context>) -> Box<Terminal> {
|
|
|
|
Box::from(Terminal::new(context.clone()))
|
2018-01-18 09:06:45 +11:00
|
|
|
}
|