From f8579ff53e443cfe0f1485886536fced2324e15b Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Sun, 3 Jul 2016 21:58:35 -0700 Subject: [PATCH] Make ansi::Handler methods strongly typed ansi::Handler methods dealing with lines or columns now accept a `Line` or `Column` where appropriate instead of ambiguous `i64`. --- src/ansi.rs | 95 ++++++++++++++++++++++++++++------------------------- src/term.rs | 85 +++++++++++++++++++++++------------------------ 2 files changed, 92 insertions(+), 88 deletions(-) diff --git a/src/ansi.rs b/src/ansi.rs index 3d068516..d951d0c2 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -30,6 +30,8 @@ //! aren't necessary for everyday terminal usage. If you feel like something that's not supported //! should be, feel free to add it. Please try not to become overzealous and adding support for //! sequences only used by folks trapped in 1988. +use std::ops::Range; + use index::{Column, Line}; use ::Rgb; @@ -229,37 +231,37 @@ pub trait Handler { fn input(&mut self, _c: char) {} /// Set cursor to position - fn goto(&mut self, _x: i64, _y: i64) {} + fn goto(&mut self, Line, Column) {} /// Set cursor to specific row - fn goto_row(&mut self, _y: i64) {} + fn goto_line(&mut self, Line) {} /// Set cursor to specific column - fn goto_col(&mut self, _x: i64) {} + fn goto_col(&mut self, Column) {} - /// Insert blank characters - fn insert_blank(&mut self, _num: i64) {} + /// Insert blank characters in current line starting from cursor + fn insert_blank(&mut self, usize) {} /// Move cursor up `rows` - fn move_up(&mut self, _rows: i64) {} + fn move_up(&mut self, Line) {} /// Move cursor down `rows` - fn move_down(&mut self, _rows: i64) {} + fn move_down(&mut self, Line) {} /// Identify the terminal (should write back to the pty stream) fn identify_terminal(&mut self) {} /// Move cursor forward `cols` - fn move_forward(&mut self, _cols: i64) {} + fn move_forward(&mut self, Column) {} /// Move cursor backward `cols` - fn move_backward(&mut self, _cols: i64) {} + fn move_backward(&mut self, Column) {} /// Move cursor down `rows` and set to column 1 - fn move_down_and_cr(&mut self, _rows: i64) {} + fn move_down_and_cr(&mut self, Line) {} /// Move cursor up `rows` and set to column 1 - fn move_up_and_cr(&mut self, _rows: i64) {} + fn move_up_and_cr(&mut self, Line) {} /// Put `count` tabs fn put_tab(&mut self, _count: i64) {} @@ -288,26 +290,27 @@ pub trait Handler { fn set_horizontal_tabstop(&mut self) {} /// Scroll up `rows` rows - fn scroll_up(&mut self, _rows: i64) {} + fn scroll_up(&mut self, Line) {} /// Scroll down `rows` rows - fn scroll_down(&mut self, _rows: i64) {} + fn scroll_down(&mut self, Line) {} /// Insert `count` blank lines - fn insert_blank_lines(&mut self, _count: i64) {} + fn insert_blank_lines(&mut self, Line) {} /// Delete `count` lines - fn delete_lines(&mut self, _count: i64) {} + fn delete_lines(&mut self, Line) {} - /// Erase `count` chars + /// Erase `count` chars in current line following cursor /// - /// TODO figure out AND comment what it means to "erase" chars - fn erase_chars(&mut self, _count: i64) {} + /// Erase means resetting to the default state (default colors, no content, no mode flags) + fn erase_chars(&mut self, Column) {} /// Delete `count` chars /// - /// TODO figure out AND comment what it means to "delete" chars - fn delete_chars(&mut self, _count: i64) {} + /// Deleting a character is like the delete key on the keyboard - everything to the right of the + /// deleted things is shifted left. + fn delete_chars(&mut self, Column) {} /// Move backward `count` tabs fn move_backward_tabs(&mut self, _count: i64) {} @@ -349,7 +352,7 @@ pub trait Handler { fn unset_mode(&mut self, Mode) {} /// DECSTBM - Set the terminal scrolling region - fn set_scrolling_region(&mut self, _top: i64, _bot: i64) {} + fn set_scrolling_region(&mut self, Range) {} } impl Parser { @@ -514,7 +517,7 @@ impl Parser { macro_rules! arg_or_default { ($arg:expr, $default:expr) => { - if $arg == 0 { $default } else { $arg } + if $arg == ::std::num::Zero::zero() { $default } else { $arg } } } @@ -530,18 +533,16 @@ impl Parser { } match raw[0] { - '@' => handler.insert_blank(arg_or_default!(args[0], 1)), + '@' => handler.insert_blank(arg_or_default!(args[0] as usize, 1)), 'A' => { - handler.move_up(arg_or_default!(args[0], 1)); + handler.move_up(Line(arg_or_default!(args[0] as usize, 1))); }, - 'B' | 'e' => handler.move_down(arg_or_default!(args[0], 1)), + 'B' | 'e' => handler.move_down(Line(arg_or_default!(args[0] as usize, 1))), 'c' => handler.identify_terminal(), - 'C' | 'a' => { - handler.move_forward(arg_or_default!(args[0], 1)) - }, - 'D' => handler.move_backward(arg_or_default!(args[0], 1)), - 'E' => handler.move_down_and_cr(arg_or_default!(args[0], 1)), - 'F' => handler.move_up_and_cr(arg_or_default!(args[0], 1)), + 'C' | 'a' => handler.move_forward(Column(arg_or_default!(args[0] as usize, 1))), + 'D' => handler.move_backward(Column(arg_or_default!(args[0] as usize, 1))), + 'E' => handler.move_down_and_cr(Line(arg_or_default!(args[0] as usize, 1))), + 'F' => handler.move_up_and_cr(Line(arg_or_default!(args[0] as usize, 1))), 'g' => { let mode = match args[0] { 0 => TabulationClearMode::Current, @@ -551,11 +552,11 @@ impl Parser { handler.clear_tabs(mode); }, - 'G' | '`' => handler.goto_col(arg_or_default!(args[0], 1) - 1), + 'G' | '`' => handler.goto_col(Column(arg_or_default!(args[0] as usize, 1) - 1)), 'H' | 'f' => { - let y = arg_or_default!(args[0], 1); - let x = arg_or_default!(args[1], 1); - handler.goto(x - 1, y - 1); + let y = arg_or_default!(args[0] as usize, 1); + let x = arg_or_default!(args[1] as usize, 1); + handler.goto(Line(x - 1), Column(y - 1)); }, 'I' => handler.move_forward_tabs(arg_or_default!(args[0], 1)), 'J' => { @@ -578,9 +579,9 @@ impl Parser { handler.clear_line(mode); }, - 'S' => handler.scroll_up(arg_or_default!(args[0], 1)), - 'T' => handler.scroll_down(arg_or_default!(args[0], 1)), - 'L' => handler.insert_blank_lines(arg_or_default!(args[0], 1)), + 'S' => handler.scroll_up(Line(arg_or_default!(args[0] as usize, 1))), + 'T' => handler.scroll_down(Line(arg_or_default!(args[0] as usize, 1))), + 'L' => handler.insert_blank_lines(Line(arg_or_default!(args[0] as usize, 1))), 'l' => { let mode = Mode::from_primitive(private, args[0]); match mode { @@ -588,11 +589,11 @@ impl Parser { None => unhandled!(), } }, - 'M' => handler.delete_lines(arg_or_default!(args[0], 1)), - 'X' => handler.erase_chars(arg_or_default!(args[0], 1)), - 'P' => handler.delete_chars(arg_or_default!(args[0], 1)), + 'M' => handler.delete_lines(Line(arg_or_default!(args[0] as usize, 1))), + 'X' => handler.erase_chars(Column(arg_or_default!(args[0] as usize, 1))), + 'P' => handler.delete_chars(Column(arg_or_default!(args[0] as usize, 1))), 'Z' => handler.move_backward_tabs(arg_or_default!(args[0], 1)), - 'd' => handler.goto_row(arg_or_default!(args[0], 1) - 1), + 'd' => handler.goto_line(Line(arg_or_default!(args[0] as usize, 1) - 1)), 'h' => { let mode = Mode::from_primitive(private, args[0]); match mode { @@ -689,10 +690,14 @@ impl Parser { if private { unknown!(); } - let top = arg_or_default!(args[0], 1); - let bottom = arg_or_default!(args[1], *handler.lines() as i64); + let top = arg_or_default!(Line(args[0] as usize), Line(1)) - 1; + // Bottom should be included in the range, but range end is not + // usually included. One option would be to use an inclusive + // range, but instead we just let the open range end be 1 + // higher. + let bottom = arg_or_default!(Line(args[1] as usize), handler.lines()); - handler.set_scrolling_region(top - 1, bottom - 1); + handler.set_scrolling_region(top..bottom); }, 's' => handler.save_cursor_position(), 'u' => handler.restore_cursor_position(), diff --git a/src/term.rs b/src/term.rs index aa940d3e..dcf8dba7 100644 --- a/src/term.rs +++ b/src/term.rs @@ -414,59 +414,59 @@ impl ansi::Handler for Term { } #[inline] - fn goto(&mut self, x: i64, y: i64) { - println!("goto: x={}, y={}", x, y); - self.cursor.line = Line(y as usize); - self.cursor.col = Column(x as usize); + fn goto(&mut self, line: Line, col: Column) { + println!("goto: line={}, col={}", line, col); + self.cursor.line = line; + self.cursor.col = col; } #[inline] - fn goto_row(&mut self, row: i64) { - println!("goto_row: {}", row); - self.cursor.line = Line(row as usize); + fn goto_line(&mut self, line: Line) { + println!("goto_line: {}", line); + self.cursor.line = line; } #[inline] - fn goto_col(&mut self, col: i64) { + fn goto_col(&mut self, col: Column) { println!("goto_col: {}", col); - self.cursor.col = Column(col as usize); + self.cursor.col = col; } #[inline] - fn insert_blank(&mut self, num: i64) { println!("insert_blank: {}", num); } + fn insert_blank(&mut self, num: usize) { println!("insert_blank: {}", num); } #[inline] - fn move_up(&mut self, rows: i64) { - println!("move_up: {}", rows); - self.cursor.line -= Line(rows as usize); + fn move_up(&mut self, lines: Line) { + println!("move_up: {}", lines); + self.cursor.line -= lines; } #[inline] - fn move_down(&mut self, rows: i64) { - println!("move_down: {}", rows); - self.cursor.line += Line(rows as usize); + fn move_down(&mut self, lines: Line) { + println!("move_down: {}", lines); + self.cursor.line += lines; } #[inline] - fn move_forward(&mut self, cols: i64) { + fn move_forward(&mut self, cols: Column) { println!("move_forward: {}", cols); - self.cursor.col += Column(cols as usize); + self.cursor.col += cols; } #[inline] - fn move_backward(&mut self, spaces: i64) { - println!("move_backward: {}", spaces); - self.cursor.col -= Column(spaces as usize); + fn move_backward(&mut self, cols: Column) { + println!("move_backward: {}", cols); + self.cursor.col -= cols; } #[inline] fn identify_terminal(&mut self) { println!("identify_terminal"); } #[inline] - fn move_down_and_cr(&mut self, rows: i64) { println!("move_down_and_cr: {}", rows); } + fn move_down_and_cr(&mut self, lines: Line) { println!("move_down_and_cr: {}", lines); } #[inline] - fn move_up_and_cr(&mut self, rows: i64) { println!("move_up_and_cr: {}", rows); } + fn move_up_and_cr(&mut self, lines: Line) { println!("move_up_and_cr: {}", lines); } #[inline] fn put_tab(&mut self, mut count: i64) { @@ -526,46 +526,46 @@ impl ansi::Handler for Term { fn set_horizontal_tabstop(&mut self) { println!("set_horizontal_tabstop"); } #[inline] - fn scroll_up(&mut self, rows: i64) { - println!("scroll_up: {}", rows); - self.scroll(Line(rows as usize), ScrollDirection::Up); + fn scroll_up(&mut self, lines: Line) { + println!("scroll_up: {}", lines); + self.scroll(lines, ScrollDirection::Up); } #[inline] - fn scroll_down(&mut self, rows: i64) { - println!("scroll_down: {}", rows); - self.scroll(Line(rows as usize), ScrollDirection::Down); + fn scroll_down(&mut self, lines: Line) { + println!("scroll_down: {}", lines); + self.scroll(lines, ScrollDirection::Down); } #[inline] - fn insert_blank_lines(&mut self, count: i64) { - println!("insert_blank_lines: {}", count); + fn insert_blank_lines(&mut self, lines: Line) { + println!("insert_blank_lines: {}", lines); if self.scroll_region.contains(self.cursor.line) { - self.scroll(Line(count as usize), ScrollDirection::Down); + self.scroll(lines, ScrollDirection::Down); } } #[inline] - fn delete_lines(&mut self, count: i64) { + fn delete_lines(&mut self, lines: Line) { if self.scroll_region.contains(self.cursor.line) { - self.scroll(Line(count as usize), ScrollDirection::Up); + self.scroll(lines, ScrollDirection::Up); } } #[inline] - fn erase_chars(&mut self, count: i64) { + fn erase_chars(&mut self, count: Column) { println!("erase_chars: {}", count); - let col_index = self.cursor.col; - let count = count as usize; + let start = self.cursor.col; + let end = start + count; let row = &mut self.grid[self.cursor.line]; - for c in &mut row[self.cursor.col..(col_index + count)] { + for c in &mut row[start..end] { c.reset(); } } #[inline] - fn delete_chars(&mut self, count: i64) { println!("delete_chars: {}", count); } + fn delete_chars(&mut self, count: Column) { println!("delete_chars: {}", count); } #[inline] fn move_backward_tabs(&mut self, count: i64) { println!("move_backward_tabs: {}", count); } @@ -701,9 +701,8 @@ impl ansi::Handler for Term { } #[inline] - fn set_scrolling_region(&mut self, top: i64, bot: i64) { - println!("set scroll region: {:?} - {:?}", top, bot); - // 1 is added to bottom for inclusive range - self.scroll_region = Line(top as usize)..Line((bot as usize) + 1); + fn set_scrolling_region(&mut self, region: Range) { + println!("set scroll region: {:?}", region); + self.scroll_region = region; } }