#![deny(unused_imports, unused_must_use)]
use crossterm_utils::impl_display;
#[cfg(windows)]
use crossterm_utils::supports_ansi;
#[doc(no_inline)]
pub use crossterm_utils::{
execute, queue, Command, ErrorKind, ExecutableCommand, Output, QueueableCommand, Result,
};
use cursor::ansi::{self, AnsiCursor};
#[cfg(windows)]
use cursor::windows::WinApiCursor;
use cursor::Cursor;
mod cursor;
mod sys;
pub struct TerminalCursor {
#[cfg(windows)]
cursor: Box<(dyn Cursor + Sync + Send)>,
#[cfg(unix)]
cursor: AnsiCursor,
}
impl TerminalCursor {
pub fn new() -> TerminalCursor {
#[cfg(windows)]
let cursor = if supports_ansi() {
Box::new(AnsiCursor::new()) as Box<(dyn Cursor + Sync + Send)>
} else {
Box::new(WinApiCursor::new()) as Box<(dyn Cursor + Sync + Send)>
};
#[cfg(unix)]
let cursor = AnsiCursor::new();
TerminalCursor { cursor }
}
pub fn goto(&self, column: u16, row: u16) -> Result<()> {
self.cursor.goto(column, row)
}
pub fn pos(&self) -> Result<(u16, u16)> {
self.cursor.pos()
}
pub fn move_up(&mut self, row_count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_up(row_count)?;
Ok(self)
}
pub fn move_right(&mut self, col_count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_right(col_count)?;
Ok(self)
}
pub fn move_down(&mut self, row_count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_down(row_count)?;
Ok(self)
}
pub fn move_left(&mut self, col_count: u16) -> Result<&mut TerminalCursor> {
self.cursor.move_left(col_count)?;
Ok(self)
}
pub fn save_position(&self) -> Result<()> {
self.cursor.save_position()
}
pub fn restore_position(&self) -> Result<()> {
self.cursor.restore_position()
}
pub fn hide(&self) -> Result<()> {
self.cursor.hide()
}
pub fn show(&self) -> Result<()> {
self.cursor.show()
}
pub fn blink(&self, blink: bool) -> Result<()> {
self.cursor.blink(blink)
}
}
pub fn cursor() -> TerminalCursor {
TerminalCursor::new()
}
pub struct Goto(pub u16, pub u16);
impl Command for Goto {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::goto_csi_sequence(self.0, self.1)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().goto(self.0, self.1)
}
}
pub struct Up(pub u16);
impl Command for Up {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_up_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().move_up(self.0)
}
}
pub struct Down(pub u16);
impl Command for Down {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_down_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().move_down(self.0)
}
}
pub struct Left(pub u16);
impl Command for Left {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_left_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().move_left(self.0)
}
}
pub struct Right(pub u16);
impl Command for Right {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_right_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().move_right(self.0)
}
}
pub struct SavePos;
impl Command for SavePos {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::SAVE_POSITION_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().save_position()
}
}
pub struct ResetPos;
impl Command for ResetPos {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::RESTORE_POSITION_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().restore_position()
}
}
pub struct Hide;
impl Command for Hide {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::HIDE_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().hide()
}
}
pub struct Show;
impl Command for Show {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::SHOW_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
WinApiCursor::new().show()
}
}
pub struct BlinkOn;
impl Command for BlinkOn {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::BLINKING_ON_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
Ok(())
}
}
pub struct BlinkOff;
impl Command for BlinkOff {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::BLINKING_OFF_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
Ok(())
}
}
impl_display!(for Goto);
impl_display!(for Up);
impl_display!(for Down);
impl_display!(for Left);
impl_display!(for Right);
impl_display!(for SavePos);
impl_display!(for ResetPos);
impl_display!(for Hide);
impl_display!(for Show);
impl_display!(for BlinkOn);
impl_display!(for BlinkOff);