Introduced more cursor commands. (#327)

This commit is contained in:
Timon 2019-11-29 17:46:50 +01:00 committed by GitHub
parent ffee84f2cf
commit 5b2ecf3381
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 25 deletions

View File

@ -7,6 +7,7 @@
documentation
* Replace `docs/UPGRADE.md` with the [Upgrade Paths](https://github.com/crossterm-rs/crossterm/wiki#upgrade-paths)
documentation
- Add `MoveToColumn`, `MoveToPreviousLine`, `MoveToNextLine` commands
# Version 0.13.3

View File

@ -72,6 +72,68 @@ impl Command for MoveTo {
}
}
/// A command that moves the terminal cursor up the given number of lines,
/// and moves it to the first column.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
pub struct MoveToNextLine(u16);
impl Command for MoveToNextLine {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_to_next_line_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::move_to_next_line(self.0)
}
}
/// A command that moves the terminal cursor down the given number of lines,
/// and moves it to the first column.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
pub struct MoveToPreviousLine(u16);
impl Command for MoveToPreviousLine {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_to_previous_line_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::move_to_previous_line(self.0)
}
}
/// A command that moves the terminal cursor to the given column on the current row.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
pub struct MoveToColumn(u16);
impl Command for MoveToColumn {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_to_column_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::move_to_column(self.0)
}
}
/// A command that moves the terminal cursor a given number of rows up.
///
/// # Notes
@ -92,6 +154,26 @@ impl Command for MoveUp {
}
}
/// A command that moves the terminal cursor a given number of columns to the right.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
pub struct MoveRight(pub u16);
impl Command for MoveRight {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_right_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::move_right(self.0)
}
}
/// A command that moves the terminal cursor a given number of rows down.
///
/// # Notes
@ -132,13 +214,6 @@ impl Command for MoveLeft {
}
}
/// A command that moves the terminal cursor a given number of columns to the right.
///
/// # Notes
///
/// Commands must be executed/queued for execution otherwise they do nothing.
pub struct MoveRight(pub u16);
/// A command that saves the current terminal cursor position.
///
/// See the [RestorePosition](./struct.RestorePosition.html) command.
@ -149,19 +224,6 @@ pub struct MoveRight(pub u16);
/// - Commands must be executed/queued for execution otherwise they do nothing.
pub struct SavePosition;
impl Command for MoveRight {
type AnsiType = String;
fn ansi_code(&self) -> Self::AnsiType {
ansi::move_right_csi_sequence(self.0)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::move_right(self.0)
}
}
impl Command for SavePosition {
type AnsiType = &'static str;

View File

@ -22,6 +22,18 @@ pub(crate) fn move_left_csi_sequence(count: u16) -> String {
format!(csi!("{}D"), count)
}
pub(crate) fn move_to_column_csi_sequence(count: u16) -> String {
format!(csi!("{}G"), count)
}
pub(crate) fn move_to_previous_line_csi_sequence(count: u16) -> String {
format!(csi!("{}F"), count)
}
pub(crate) fn move_to_next_line_csi_sequence(count: u16) -> String {
format!(csi!("{}E"), count)
}
pub(crate) const SAVE_POSITION_CSI_SEQUENCE: &str = "\x1B7";
pub(crate) const RESTORE_POSITION_CSI_SEQUENCE: &str = "\x1B8";
pub(crate) const HIDE_CSI_SEQUENCE: &str = csi!("?25l");

View File

@ -6,8 +6,8 @@ pub use self::unix::position;
pub use self::windows::position;
#[cfg(windows)]
pub(crate) use self::windows::{
move_down, move_left, move_right, move_to, move_up, restore_position, save_position,
show_cursor,
move_down, move_left, move_right, move_to, move_to_column, move_to_next_line,
move_to_previous_line, move_up, restore_position, save_position, show_cursor,
};
#[cfg(windows)]

View File

@ -58,6 +58,24 @@ pub(crate) fn move_left(count: u16) -> Result<()> {
Ok(())
}
pub(crate) fn move_to_column(new_column: u16) -> Result<()> {
let (_, row) = position()?;
move_to(new_column, row)?;
Ok(())
}
pub(crate) fn move_to_next_line(count: u16) -> Result<()> {
let (_, row) = position()?;
move_to(0, row + count)?;
Ok(())
}
pub(crate) fn move_to_previous_line(count: u16) -> Result<()> {
let (_, row) = position()?;
move_to(0, row - count)?;
Ok(())
}
pub(crate) fn save_position() -> Result<()> {
ScreenBufferCursor::output()?.save_position()?;
Ok(())
@ -166,8 +184,8 @@ impl From<Handle> for ScreenBufferCursor {
#[cfg(test)]
mod tests {
use super::{
move_down, move_left, move_right, move_to, move_up, position, restore_position,
save_position,
move_down, move_left, move_right, move_to, move_to_column, move_to_next_line,
move_to_previous_line, move_up, position, restore_position, save_position,
};
#[test]
@ -206,6 +224,33 @@ mod tests {
assert_eq!(position().unwrap(), (0, 0));
}
#[test]
fn test_move_to_next_line_winapi() {
move_to(0, 2).unwrap();
move_to_next_line(2).unwrap();
assert_eq!(position().unwrap(), (0, 4));
}
#[test]
fn test_move_to_previous_line_winapi() {
move_to(0, 2).unwrap();
move_to_previous_line(2).unwrap();
assert_eq!(position().unwrap(), (0, 0));
}
#[test]
fn test_move_to_column_winapi() {
move_to(0, 2).unwrap();
move_to_column(12).unwrap();
assert_eq!(position().unwrap(), (12, 2));
}
#[test]
fn test_move_down_winapi() {
move_to(0, 0).unwrap();

View File

@ -46,7 +46,8 @@
//! [`SavePosition`](cursor/struct.SavePosition.html), [`RestorePosition`](cursor/struct.RestorePosition.html),
//! [`MoveUp`](cursor/struct.MoveUp.html), [`MoveDown`](cursor/struct.MoveDown.html),
//! [`MoveLeft`](cursor/struct.MoveLeft.html), [`MoveRight`](cursor/struct.MoveRight.html),
//! [`MoveTo`](cursor/struct.MoveTo.html)
//! [`MoveTo`](cursor/struct.MoveTo.html), [`MoveToColumn`](cursor/struct.MoveToColumn.html),
//! [`MoveToNextLine`](cursor/struct.MoveToNextLine.html), [`MoveToPreviousLine`](cursor/struct.MoveToPreviousLine.html),
//! - Module `event`
//! - Mouse events - [`EnableMouseCapture`](event/struct.EnableMouseCapture.html),
//! [`DisableMouseCapture`](event/struct.DisableMouseCapture.html)