From 7c6c8179e3280b6e4b74ce8ff715feb3b25b8572 Mon Sep 17 00:00:00 2001 From: Robert Vojta Date: Wed, 18 Sep 2019 19:44:24 +0200 Subject: [PATCH 1/5] ITerminalCursor::pos() -> Result<(u16, u16)> Signed-off-by: Robert Vojta --- crossterm_cursor/src/cursor.rs | 4 +-- crossterm_cursor/src/cursor/ansi_cursor.rs | 18 ++++++++--- crossterm_cursor/src/cursor/cursor.rs | 2 +- crossterm_cursor/src/cursor/winapi_cursor.rs | 27 +++++++++++------ crossterm_cursor/src/sys/unix.rs | 32 +++++--------------- crossterm_cursor/src/sys/winapi.rs | 9 ++---- crossterm_utils/src/error.rs | 14 +++++++++ examples/cursor.rs | 5 +-- 8 files changed, 60 insertions(+), 51 deletions(-) diff --git a/crossterm_cursor/src/cursor.rs b/crossterm_cursor/src/cursor.rs index 0478d1a64..99df5f802 100644 --- a/crossterm_cursor/src/cursor.rs +++ b/crossterm_cursor/src/cursor.rs @@ -29,9 +29,7 @@ trait ITerminalCursor: Sync + Send { /// Goto location (`x`, `y`) in the current terminal window. fn goto(&self, x: u16, y: u16) -> Result<()>; /// Get the cursor location `(x, y)` in the current terminal window. - /// - /// `(0, 0)` is returned in case of an error. - fn pos(&self) -> (u16, u16); + fn pos(&self) -> Result<(u16, u16)>; /// Move cursor `n` times up fn move_up(&self, count: u16) -> Result<()>; /// Move the cursor `n` times to the right. diff --git a/crossterm_cursor/src/cursor/ansi_cursor.rs b/crossterm_cursor/src/cursor/ansi_cursor.rs index d19c370e5..67705920b 100644 --- a/crossterm_cursor/src/cursor/ansi_cursor.rs +++ b/crossterm_cursor/src/cursor/ansi_cursor.rs @@ -51,7 +51,7 @@ impl ITerminalCursor for AnsiCursor { Ok(()) } - fn pos(&self) -> (u16, u16) { + fn pos(&self) -> Result<(u16, u16)> { get_cursor_position() } @@ -115,13 +115,17 @@ mod tests { fn reset_safe_ansi() { if try_enable_ansi() { let cursor = AnsiCursor::new(); - let (x, y) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x, y) = pos.unwrap(); assert!(cursor.save_position().is_ok()); assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.reset_position().is_ok()); - let (x_saved, y_saved) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x_saved, y_saved) = pos.unwrap(); assert_eq!(x, x_saved); assert_eq!(y, y_saved); @@ -134,10 +138,14 @@ mod tests { fn goto_ansi() { if try_enable_ansi() { let cursor = AnsiCursor::new(); - let (x_saved, y_saved) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x_saved, y_saved) = pos.unwrap(); assert!(cursor.goto(5, 5).is_ok()); - let (x, y) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x, y) = pos.unwrap(); assert!(cursor.goto(x_saved, y_saved).is_ok()); diff --git a/crossterm_cursor/src/cursor/cursor.rs b/crossterm_cursor/src/cursor/cursor.rs index 7783fe91b..6b912a9ce 100644 --- a/crossterm_cursor/src/cursor/cursor.rs +++ b/crossterm_cursor/src/cursor/cursor.rs @@ -59,7 +59,7 @@ impl TerminalCursor { /// /// # Remarks /// position is 0-based, which means we start counting at 0. - pub fn pos(&self) -> (u16, u16) { + pub fn pos(&self) -> Result<(u16, u16)> { self.cursor.pos() } diff --git a/crossterm_cursor/src/cursor/winapi_cursor.rs b/crossterm_cursor/src/cursor/winapi_cursor.rs index cba511592..936b90492 100644 --- a/crossterm_cursor/src/cursor/winapi_cursor.rs +++ b/crossterm_cursor/src/cursor/winapi_cursor.rs @@ -24,31 +24,31 @@ impl ITerminalCursor for WinApiCursor { Ok(()) } - fn pos(&self) -> (u16, u16) { - let cursor = Cursor::new().unwrap(); - cursor.position().map(Into::into).unwrap_or((0, 0)) + fn pos(&self) -> Result<(u16, u16)> { + let cursor = Cursor::new()?; + Ok(cursor.position()?.into()) } fn move_up(&self, count: u16) -> Result<()> { - let (xpos, ypos) = self.pos(); + let (xpos, ypos) = self.pos()?; self.goto(xpos, ypos - count)?; Ok(()) } fn move_right(&self, count: u16) -> Result<()> { - let (xpos, ypos) = self.pos(); + let (xpos, ypos) = self.pos()?; self.goto(xpos + count, ypos)?; Ok(()) } fn move_down(&self, count: u16) -> Result<()> { - let (xpos, ypos) = self.pos(); + let (xpos, ypos) = self.pos()?; self.goto(xpos, ypos + count)?; Ok(()) } fn move_left(&self, count: u16) -> Result<()> { - let (xpos, ypos) = self.pos(); + let (xpos, ypos) = self.pos()?; self.goto(xpos - count, ypos)?; Ok(()) } @@ -87,7 +87,9 @@ mod tests { let cursor = WinApiCursor::new(); assert!(cursor.goto(5, 5).is_ok()); - let (x, y) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x, y) = pos.unwrap(); assert_eq!(x, 5); assert_eq!(y, 5); @@ -96,13 +98,18 @@ mod tests { #[test] fn reset_safe_winapi() { let cursor = WinApiCursor::new(); - let (x, y) = cursor.pos(); + + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x, y) = pos.unwrap(); assert!(cursor.save_position().is_ok()); assert!(cursor.goto(5, 5).is_ok()); assert!(cursor.reset_position().is_ok()); - let (x_saved, y_saved) = cursor.pos(); + let pos = cursor.pos(); + assert!(pos.is_ok()); + let (x_saved, y_saved) = pos.unwrap(); assert_eq!(x, x_saved); assert_eq!(y, y_saved); diff --git a/crossterm_cursor/src/sys/unix.rs b/crossterm_cursor/src/sys/unix.rs index dde5c164d..783599c40 100644 --- a/crossterm_cursor/src/sys/unix.rs +++ b/crossterm_cursor/src/sys/unix.rs @@ -7,11 +7,11 @@ use crossterm_utils::{ }; #[cfg(unix)] -pub fn get_cursor_position() -> (u16, u16) { +pub fn get_cursor_position() -> Result<(u16, u16)> { if unsafe { RAW_MODE_ENABLED } { - pos_raw().unwrap_or((0, 0)) + pos_raw() } else { - pos().unwrap_or((0, 0)) + pos() } } @@ -45,33 +45,17 @@ pub fn pos_raw() -> Result<(u16, u16)> { stdin.lock().read_until(b'[', &mut vec![])?; let mut rows = vec![]; - stdin.lock().read_until(b';', &mut rows).unwrap(); + stdin.lock().read_until(b';', &mut rows)?; let mut cols = vec![]; - stdin.lock().read_until(b'R', &mut cols).unwrap(); + stdin.lock().read_until(b'R', &mut cols)?; // remove delimiter rows.pop(); cols.pop(); - let rows = rows - .into_iter() - .map(|b| (b as char)) - .fold(String::new(), |mut acc, n| { - acc.push(n); - acc - }) - .parse::() - .unwrap(); - let cols = cols - .into_iter() - .map(|b| (b as char)) - .fold(String::new(), |mut acc, n| { - acc.push(n); - acc - }) - .parse::() - .unwrap(); + let rows = String::from_utf8(rows)?.parse::()?; + let cols = String::from_utf8(cols)?.parse::()?; - Ok(((cols - 1) as u16, (rows - 1) as u16)) + Ok((cols - 1, rows - 1)) } diff --git a/crossterm_cursor/src/sys/winapi.rs b/crossterm_cursor/src/sys/winapi.rs index 6a1f937ae..ab559a6a7 100644 --- a/crossterm_cursor/src/sys/winapi.rs +++ b/crossterm_cursor/src/sys/winapi.rs @@ -12,12 +12,9 @@ use crossterm_utils::Result; pub use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer}; #[cfg(windows)] -pub fn get_cursor_position() -> (u16, u16) { - if let Ok(cursor) = Cursor::new() { - cursor.position().unwrap().into() - } else { - (0, 0) - } +pub fn get_cursor_position() -> Result<(u16, u16)> { + let cursor = Cursor::new()?; + Ok(cursor.position()?.into()) } #[cfg(windows)] diff --git a/crossterm_utils/src/error.rs b/crossterm_utils/src/error.rs index 7085decd1..52f9d262e 100644 --- a/crossterm_utils/src/error.rs +++ b/crossterm_utils/src/error.rs @@ -13,6 +13,8 @@ pub type Result = std::result::Result; pub enum ErrorKind { IoError(io::Error), FmtError(fmt::Error), + Utf8Error(std::string::FromUtf8Error), + ParseIntError(std::num::ParseIntError), ResizingTerminalFailure(String), #[doc(hidden)] @@ -49,3 +51,15 @@ impl From for ErrorKind { ErrorKind::FmtError(e) } } + +impl From for ErrorKind { + fn from(e: std::string::FromUtf8Error) -> Self { + ErrorKind::Utf8Error(e) + } +} + +impl From for ErrorKind { + fn from(e: std::num::ParseIntError) -> Self { + ErrorKind::ParseIntError(e) + } +} diff --git a/examples/cursor.rs b/examples/cursor.rs index c4476ea41..ed0961086 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -17,13 +17,14 @@ fn goto() -> Result<()> { } /// get the cursor position -fn pos() { +fn pos() -> Result<()> { // Get the cursor let cursor = cursor(); // get the cursor position. - let (x, y) = cursor.pos(); + let (x, y) = cursor.pos()?; println!("{} {}", x, y); + Ok(()) } /// Move the cursor 3 up | demonstration. From c09b8e9a7aa38920055410c382d0ff91317706db Mon Sep 17 00:00:00 2001 From: Robert Vojta Date: Wed, 18 Sep 2019 21:47:15 +0200 Subject: [PATCH 2/5] ITerminal::size() -> Result<(u16, u16)> Signed-off-by: Robert Vojta --- crossterm_terminal/README.md | 18 +++++++++--------- crossterm_terminal/src/sys/unix.rs | 8 +++++--- crossterm_terminal/src/sys/winapi.rs | 11 ++++------- crossterm_terminal/src/terminal.rs | 2 +- .../src/terminal/ansi_terminal.rs | 6 ++++-- crossterm_terminal/src/terminal/terminal.rs | 9 +++------ .../src/terminal/winapi_terminal.rs | 6 ++++-- crossterm_winapi/src/csbi.rs | 4 ++-- examples/command_bar.rs | 8 ++++---- examples/program_examples/snake/src/main.rs | 2 +- examples/terminal.rs | 5 +++-- 11 files changed, 40 insertions(+), 39 deletions(-) diff --git a/crossterm_terminal/README.md b/crossterm_terminal/README.md index b92aa762c..e072ee0f4 100644 --- a/crossterm_terminal/README.md +++ b/crossterm_terminal/README.md @@ -90,26 +90,26 @@ use crossterm::terminal::{terminal,ClearType}; let mut terminal = terminal(); // Clear all lines in terminal; -terminal.clear(ClearType::All); +terminal.clear(ClearType::All)?; // Clear all cells from current cursor position down. -terminal.clear(ClearType::FromCursorDown); +terminal.clear(ClearType::FromCursorDown)?; // Clear all cells from current cursor position down. -terminal.clear(ClearType::FromCursorUp); +terminal.clear(ClearType::FromCursorUp)?; // Clear current line cells. -terminal.clear(ClearType::CurrentLine); +terminal.clear(ClearType::CurrentLine)?; // Clear all the cells until next line. -terminal.clear(ClearType::UntilNewLine); +terminal.clear(ClearType::UntilNewLine)?; // Get terminal size -let (width, height) = terminal.terminal_size(); +let (width, height) = terminal.size()?; print!("X: {}, y: {}", width, height); // Scroll down, up 10 lines. -terminal.scroll_down(10); -terminal.scroll_up(10); +terminal.scroll_down(10)?; +terminal.scroll_up(10)?; // Set terminal size (width, height) -terminal.set_size(10,10); +terminal.set_size(10,10)?; // exit the current process. terminal.exit(); diff --git a/crossterm_terminal/src/sys/unix.rs b/crossterm_terminal/src/sys/unix.rs index fdc3e5e13..b8169b496 100644 --- a/crossterm_terminal/src/sys/unix.rs +++ b/crossterm_terminal/src/sys/unix.rs @@ -1,11 +1,13 @@ use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ}; +use crossterm_utils::Result; + pub fn exit() { ::std::process::exit(0); } /// Get the current terminal size. -pub fn get_terminal_size() -> (u16, u16) { +pub fn get_terminal_size() -> Result<(u16, u16)> { // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc let mut size = winsize { ws_row: 0, @@ -16,8 +18,8 @@ pub fn get_terminal_size() -> (u16, u16) { let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ.into(), &mut size) }; if r == 0 { - (size.ws_col, size.ws_row) + Ok((size.ws_col, size.ws_row)) } else { - (0, 0) + Err(std::io::Error::last_os_error().into()) } } diff --git a/crossterm_terminal/src/sys/winapi.rs b/crossterm_terminal/src/sys/winapi.rs index 32ea08c03..124414343 100644 --- a/crossterm_terminal/src/sys/winapi.rs +++ b/crossterm_terminal/src/sys/winapi.rs @@ -1,3 +1,4 @@ +use crossterm_utils::Result; use crossterm_winapi::ScreenBuffer; /// Exit the current process. @@ -6,11 +7,7 @@ pub fn exit() { } #[cfg(windows)] -pub fn get_terminal_size() -> (u16, u16) { - if let Ok(buffer) = ScreenBuffer::current() { - let size = buffer.info().unwrap().terminal_size(); - ((size.width + 1) as u16, (size.height + 1) as u16) - } else { - (0, 0) - } +pub fn get_terminal_size() -> Result<(u16, u16)> { + let buffer = ScreenBuffer::current()?; + Ok(buffer.info()?.terminal_size().into()) } diff --git a/crossterm_terminal/src/terminal.rs b/crossterm_terminal/src/terminal.rs index 30e27f9ec..db765b40c 100644 --- a/crossterm_terminal/src/terminal.rs +++ b/crossterm_terminal/src/terminal.rs @@ -43,7 +43,7 @@ trait ITerminal { /// Clear the current cursor by specifying the clear type fn clear(&self, clear_type: ClearType) -> Result<()>; /// Get the terminal size (x,y) - fn terminal_size(&self) -> (u16, u16); + fn size(&self) -> Result<(u16, u16)>; /// Scroll `n` lines up in the current terminal. fn scroll_up(&self, count: i16) -> Result<()>; /// Scroll `n` lines down in the current terminal. diff --git a/crossterm_terminal/src/terminal/ansi_terminal.rs b/crossterm_terminal/src/terminal/ansi_terminal.rs index 2a93b7cb8..480d9c9cd 100644 --- a/crossterm_terminal/src/terminal/ansi_terminal.rs +++ b/crossterm_terminal/src/terminal/ansi_terminal.rs @@ -61,7 +61,7 @@ impl ITerminal for AnsiTerminal { Ok(()) } - fn terminal_size(&self) -> (u16, u16) { + fn size(&self) -> Result<(u16, u16)> { get_terminal_size() } @@ -100,7 +100,9 @@ mod tests { // see issue: https://github.com/eminence/terminal-size/issues/11 thread::sleep(time::Duration::from_millis(30)); - let (x, y) = terminal.terminal_size(); + let size = terminal.size(); + assert!(size.is_ok()); + let (x, y) = size.unwrap(); assert_eq!(x, 50); assert_eq!(y, 50); diff --git a/crossterm_terminal/src/terminal/terminal.rs b/crossterm_terminal/src/terminal/terminal.rs index 79f12d257..6ad17ff87 100644 --- a/crossterm_terminal/src/terminal/terminal.rs +++ b/crossterm_terminal/src/terminal/terminal.rs @@ -70,12 +70,9 @@ impl Terminal { self.terminal.clear(clear_type) } - /// Get the terminal size (x,y). - /// - /// # Remark - /// This will return a tuple of (x: u16, y: u16) - pub fn terminal_size(&self) -> (u16, u16) { - self.terminal.terminal_size() + /// Get the terminal size `(x,y)`. + pub fn size(&self) -> Result<(u16, u16)> { + self.terminal.size() } /// Scroll `n` lines up in the current terminal. diff --git a/crossterm_terminal/src/terminal/winapi_terminal.rs b/crossterm_terminal/src/terminal/winapi_terminal.rs index 0d920ade3..fe57eab08 100644 --- a/crossterm_terminal/src/terminal/winapi_terminal.rs +++ b/crossterm_terminal/src/terminal/winapi_terminal.rs @@ -41,7 +41,7 @@ impl ITerminal for WinApiTerminal { Ok(()) } - fn terminal_size(&self) -> (u16, u16) { + fn size(&self) -> Result<(u16, u16)> { get_terminal_size() } @@ -284,7 +284,9 @@ mod tests { assert!(terminal.set_size(30, 30).is_ok()); - let (x, y) = terminal.terminal_size(); + let size = terminal.size(); + assert!(size.is_ok()); + let (x, y) = size.unwrap(); assert_eq!(x, 30); assert_eq!(y, 30); diff --git a/crossterm_winapi/src/csbi.rs b/crossterm_winapi/src/csbi.rs index a360bc507..ece47b852 100644 --- a/crossterm_winapi/src/csbi.rs +++ b/crossterm_winapi/src/csbi.rs @@ -17,14 +17,14 @@ impl ScreenBufferInfo { /// This will return the buffer size. /// - /// Will take `dwSize`from the current screen buffer and convert it into the `Size`. + /// Will take `dwSize` from the current screen buffer and convert it into the `Size`. pub fn buffer_size(&self) -> Size { Size::from(self.0.dwSize) } /// This will return the terminal size. /// - /// Will calculate the whit and height from `srWindow` and convert it into a `Size`. + /// Will calculate the width and height from `srWindow` and convert it into a `Size`. pub fn terminal_size(&self) -> Size { (Size::new( self.0.srWindow.Right - self.0.srWindow.Left, diff --git a/examples/command_bar.rs b/examples/command_bar.rs index ac92878ab..34ba4a9e8 100644 --- a/examples/command_bar.rs +++ b/examples/command_bar.rs @@ -6,10 +6,10 @@ use crossterm::{ Terminal, TerminalCursor, }; -fn log(input_buf: Arc>) -> Vec> { +fn log(input_buf: Arc>) -> Result>> { let mut threads = Vec::with_capacity(10); - let (_, term_height) = terminal().terminal_size(); + let (_, term_height) = terminal().size()?; for i in 0..1 { let input_buffer = input_buf.clone(); @@ -37,7 +37,7 @@ fn log(input_buf: Arc>) -> Vec> { threads.push(join); } - threads + Ok(threads) } fn swap_write( @@ -60,7 +60,7 @@ fn main() -> Result<()> { let input_buf = Arc::new(Mutex::new(String::new())); - let threads = log(input_buf.clone()); + let threads = log(input_buf.clone())?; let mut count = 0; diff --git a/examples/program_examples/snake/src/main.rs b/examples/program_examples/snake/src/main.rs index 0cc6abdef..3b7fa1ad7 100644 --- a/examples/program_examples/snake/src/main.rs +++ b/examples/program_examples/snake/src/main.rs @@ -34,7 +34,7 @@ pub enum Event { fn main() -> Result<()> { // Print the welcome screen and ask for the map size. let crossterm = Crossterm::new(); - let (map_width, map_height) = ask_for_map_size(crossterm.terminal().terminal_size())?; + let (map_width, map_height) = ask_for_map_size(crossterm.terminal().size()?)?; // Switch screen to the raw mode to avoid printing key presses on the screen // and hide the cursor. diff --git a/examples/terminal.rs b/examples/terminal.rs index eff54f452..600629230 100644 --- a/examples/terminal.rs +++ b/examples/terminal.rs @@ -75,14 +75,15 @@ fn clear_until_new_line() -> Result<()> { } /// Print the the current terminal size | demonstration. -fn print_terminal_size() { +fn print_terminal_size() -> Result<()> { let terminal = terminal(); // Get terminal size - let (width, height) = terminal.terminal_size(); + let (width, height) = terminal.size()?; // Print results print!("X: {}, y: {}", width, height); + Ok(()) } /// Set the terminal size to width 10, height: 10 | demonstration. From a30f49ac4b278a3887d0a702f45fe96d96887fd8 Mon Sep 17 00:00:00 2001 From: Robert Vojta Date: Wed, 18 Sep 2019 22:03:20 +0200 Subject: [PATCH 3/5] Fix Travis CI examples check Signed-off-by: Robert Vojta --- .travis.yml | 10 +--------- scripts/test-examples.sh | 13 +++++++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) create mode 100755 scripts/test-examples.sh diff --git a/.travis.yml b/.travis.yml index 762e4ac50..86a8ce723 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,12 +29,4 @@ script: - if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi - cargo build - if [ "$TRAVIS_OS_NAME" = "windows" ]; then cargo test --all -- --nocapture --test-threads 1; else cargo test --all --exclude crossterm_winapi -- --nocapture --test-threads 1; fi - - | - pushd examples/program_examples - for d in */ ; do - pushd "$d" - cargo build - if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi - popd - done - popd + - scripts/test-examples.sh diff --git a/scripts/test-examples.sh b/scripts/test-examples.sh new file mode 100755 index 000000000..4cafc03f5 --- /dev/null +++ b/scripts/test-examples.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -ev +pushd examples/program_examples +for d in */ ; do + pushd "$d" + cargo build + if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then + cargo fmt --all -- --check + fi + popd +done +popd From 2526e1fd6b852713cd58b949ed3b98a881c9b4e7 Mon Sep 17 00:00:00 2001 From: Robert Vojta Date: Wed, 18 Sep 2019 22:45:33 +0200 Subject: [PATCH 4/5] ITerminal scroll_up/down and set_size i16 -> u16 Signed-off-by: Robert Vojta --- crossterm_terminal/src/terminal.rs | 6 +++--- crossterm_terminal/src/terminal/ansi_terminal.rs | 12 ++++++------ crossterm_terminal/src/terminal/terminal.rs | 12 ++++++------ crossterm_terminal/src/terminal/winapi_terminal.rs | 10 +++++++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/crossterm_terminal/src/terminal.rs b/crossterm_terminal/src/terminal.rs index db765b40c..2d3465d99 100644 --- a/crossterm_terminal/src/terminal.rs +++ b/crossterm_terminal/src/terminal.rs @@ -45,9 +45,9 @@ trait ITerminal { /// Get the terminal size (x,y) fn size(&self) -> Result<(u16, u16)>; /// Scroll `n` lines up in the current terminal. - fn scroll_up(&self, count: i16) -> Result<()>; + fn scroll_up(&self, count: u16) -> Result<()>; /// Scroll `n` lines down in the current terminal. - fn scroll_down(&self, count: i16) -> Result<()>; + fn scroll_down(&self, count: u16) -> Result<()>; /// Resize terminal to the given width and height. - fn set_size(&self, width: i16, height: i16) -> Result<()>; + fn set_size(&self, width: u16, height: u16) -> Result<()>; } diff --git a/crossterm_terminal/src/terminal/ansi_terminal.rs b/crossterm_terminal/src/terminal/ansi_terminal.rs index 480d9c9cd..9e9630dea 100644 --- a/crossterm_terminal/src/terminal/ansi_terminal.rs +++ b/crossterm_terminal/src/terminal/ansi_terminal.rs @@ -15,17 +15,17 @@ pub static CLEAR_FROM_CURRENT_LINE: &'static str = csi!("2K"); pub static CLEAR_UNTIL_NEW_LINE: &'static str = csi!("K"); #[inline] -pub fn get_scroll_up_ansi(count: i16) -> String { +pub fn get_scroll_up_ansi(count: u16) -> String { format!(csi!("{}S"), count) } #[inline] -pub fn get_scroll_down_ansi(count: i16) -> String { +pub fn get_scroll_down_ansi(count: u16) -> String { format!(csi!("{}T"), count) } #[inline] -pub fn get_set_size_ansi(width: i16, height: i16) -> String { +pub fn get_set_size_ansi(width: u16, height: u16) -> String { format!(csi!("8;{};{}t"), height, width) } @@ -65,17 +65,17 @@ impl ITerminal for AnsiTerminal { get_terminal_size() } - fn scroll_up(&self, count: i16) -> Result<()> { + fn scroll_up(&self, count: u16) -> Result<()> { write_cout!(get_scroll_up_ansi(count))?; Ok(()) } - fn scroll_down(&self, count: i16) -> Result<()> { + fn scroll_down(&self, count: u16) -> Result<()> { write_cout!(get_scroll_down_ansi(count))?; Ok(()) } - fn set_size(&self, width: i16, height: i16) -> Result<()> { + fn set_size(&self, width: u16, height: u16) -> Result<()> { write_cout!(get_set_size_ansi(width, height))?; Ok(()) } diff --git a/crossterm_terminal/src/terminal/terminal.rs b/crossterm_terminal/src/terminal/terminal.rs index 6ad17ff87..cc71ea523 100644 --- a/crossterm_terminal/src/terminal/terminal.rs +++ b/crossterm_terminal/src/terminal/terminal.rs @@ -79,7 +79,7 @@ impl Terminal { /// /// # Parameter /// - `count`: the number of rows should be shifted up. - pub fn scroll_up(&self, count: i16) -> Result<()> { + pub fn scroll_up(&self, count: u16) -> Result<()> { self.terminal.scroll_up(count) } @@ -87,7 +87,7 @@ impl Terminal { /// /// # Parameter /// - `count`: the number of rows should be shifted down. - pub fn scroll_down(&self, count: i16) -> Result<()> { + pub fn scroll_down(&self, count: u16) -> Result<()> { self.terminal.scroll_down(count) } @@ -100,7 +100,7 @@ impl Terminal { /// // Set of the size to X: 10 and Y: 10 /// let size = term.set_size(10,10); /// ``` - pub fn set_size(&self, width: i16, height: i16) -> Result<()> { + pub fn set_size(&self, width: u16, height: u16) -> Result<()> { self.terminal.set_size(width, height) } @@ -140,7 +140,7 @@ pub fn terminal() -> Terminal { /// When executed, this command will scroll up the terminal buffer by the given number of times. /// /// See `crossterm/examples/command.rs` for more information on how to execute commands. -pub struct ScrollUp(pub i16); +pub struct ScrollUp(pub u16); impl Command for ScrollUp { type AnsiType = String; @@ -158,7 +158,7 @@ impl Command for ScrollUp { /// When executed, this command will scroll down the terminal buffer by the given number of times. /// /// See `crossterm/examples/command.rs` for more information on how to execute commands. -pub struct ScrollDown(pub i16); +pub struct ScrollDown(pub u16); impl Command for ScrollDown { type AnsiType = String; @@ -206,7 +206,7 @@ impl Command for Clear { /// When executed, this command will set the terminal sie to the given (`width` and `height`) /// /// See `crossterm/examples/command.rs` for more information on how to execute commands. -pub struct SetSize(pub i16, pub i16); +pub struct SetSize(pub u16, pub u16); impl Command for SetSize { type AnsiType = String; diff --git a/crossterm_terminal/src/terminal/winapi_terminal.rs b/crossterm_terminal/src/terminal/winapi_terminal.rs index fe57eab08..566f7fb9a 100644 --- a/crossterm_terminal/src/terminal/winapi_terminal.rs +++ b/crossterm_terminal/src/terminal/winapi_terminal.rs @@ -45,11 +45,12 @@ impl ITerminal for WinApiTerminal { get_terminal_size() } - fn scroll_up(&self, count: i16) -> Result<()> { + fn scroll_up(&self, count: u16) -> Result<()> { let csbi = ScreenBuffer::current()?; let mut window = csbi.info()?.terminal_window(); // Check whether the window is too close to the screen buffer top + let count = count as i16; if window.top >= count { window.top -= count; // move top down window.bottom = count; // move bottom down @@ -59,13 +60,14 @@ impl ITerminal for WinApiTerminal { Ok(()) } - fn scroll_down(&self, count: i16) -> Result<()> { + fn scroll_down(&self, count: u16) -> Result<()> { let screen_buffer = ScreenBuffer::current()?; let csbi = screen_buffer.info()?; let mut window = csbi.terminal_window(); let buffer_size = csbi.buffer_size(); // Check whether the window is too close to the screen buffer top + let count = count as i16; if window.bottom < buffer_size.height - count { window.top += count; // move top down window.bottom += count; // move bottom down @@ -76,7 +78,7 @@ impl ITerminal for WinApiTerminal { } /// Set the current terminal size - fn set_size(&self, width: i16, height: i16) -> Result<()> { + fn set_size(&self, width: u16, height: u16) -> Result<()> { if width <= 0 { return Err(ErrorKind::ResizingTerminalFailure(String::from( "Cannot set the terminal width lower than 1", @@ -103,6 +105,7 @@ impl ITerminal for WinApiTerminal { // buffer to be large enough. Include window position. let mut resize_buffer = false; + let width = width as i16; if current_size.width < window.left + width { if window.left >= i16::max_value() - width { return Err(ErrorKind::ResizingTerminalFailure(String::from( @@ -113,6 +116,7 @@ impl ITerminal for WinApiTerminal { new_size.width = window.left + width; resize_buffer = true; } + let height = height as i16; if current_size.height < window.top + height { if window.top >= i16::max_value() - height { return Err(ErrorKind::ResizingTerminalFailure(String::from( From 3dd427a2a59481a9c1169327f50edee1a4150051 Mon Sep 17 00:00:00 2001 From: Robert Vojta Date: Wed, 18 Sep 2019 23:56:55 +0200 Subject: [PATCH 5/5] TerminalCursor::move_* return Result Signed-off-by: Robert Vojta --- crossterm_cursor/src/cursor/cursor.rs | 22 +++++++++++----------- examples/cursor.rs | 27 +++++++++++++++++++-------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/crossterm_cursor/src/cursor/cursor.rs b/crossterm_cursor/src/cursor/cursor.rs index 6b912a9ce..e21b6e779 100644 --- a/crossterm_cursor/src/cursor/cursor.rs +++ b/crossterm_cursor/src/cursor/cursor.rs @@ -64,27 +64,27 @@ impl TerminalCursor { } /// Move the current cursor position `n` times up. - pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor { - self.cursor.move_up(count).unwrap(); - self + pub fn move_up(&mut self, count: u16) -> Result<&mut TerminalCursor> { + self.cursor.move_up(count)?; + Ok(self) } /// Move the current cursor position `n` times right. - pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor { - self.cursor.move_right(count).unwrap(); - self + pub fn move_right(&mut self, count: u16) -> Result<&mut TerminalCursor> { + self.cursor.move_right(count)?; + Ok(self) } /// Move the current cursor position `n` times down. - pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor { - self.cursor.move_down(count).unwrap(); - self + pub fn move_down(&mut self, count: u16) -> Result<&mut TerminalCursor> { + self.cursor.move_down(count)?; + Ok(self) } /// Move the current cursor position `n` times left. - pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor { + pub fn move_left(&mut self, count: u16) -> Result<&mut TerminalCursor> { self.cursor.move_left(count).unwrap(); - self + Ok(self) } /// Save cursor position for recall later. diff --git a/examples/cursor.rs b/examples/cursor.rs index ed0961086..dcfa1b3fb 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -28,26 +28,37 @@ fn pos() -> Result<()> { } /// Move the cursor 3 up | demonstration. -fn move_up() { +fn move_up() -> Result<()> { // Get the cursor let mut cursor = cursor(); // Move the cursor to position 3 times to the up in the terminal - cursor.move_up(10); + cursor.move_up(3)?; + Ok(()) +} + +/// Move the cursor 3 down | demonstration. +fn move_down() -> Result<()> { + let mut cursor = cursor(); + // Move the cursor to position 3 times to the down in the terminal + cursor.move_down(3)?; + Ok(()) } /// Move the cursor 3 to the right | demonstration. -fn move_right() { +fn move_right() -> Result<()> { let mut cursor = cursor(); // Move the cursor to position 3 times to the right in the terminal - cursor.move_right(3); + cursor.move_right(3)?; + Ok(()) } -/// Move the cursor 3 down | demonstration. -fn move_down() { +/// Move the cursor 3 left | demonstration. +fn move_left() -> Result<()> { let mut cursor = cursor(); - // Move the cursor to position 3 times to the down in the terminal - cursor.move_down(3); + // Move the cursor to position 3 times to the left in the terminal + cursor.move_left(3)?; + Ok(()) } /// Save and reset cursor position | demonstration..