diff --git a/src/term/mod.rs b/src/term/mod.rs index 5babaf2f..92e5463d 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -15,7 +15,7 @@ //! Exports the `Term` type which is a high-level API for the Grid use std::ops::{Deref, Range}; use std::ptr; -use std::cmp; +use std::cmp::min; use std::io; use ansi::{self, Color, NamedColor, Attr, Handler}; @@ -168,8 +168,9 @@ impl<'a> Iterator for RenderableCellsIter<'a> { /// coerce val to be between min and max #[inline] -fn limit(val: T, min: T, max: T) -> T { - cmp::min(cmp::max(min, val), max) +fn limit(val: T, min_limit: T, max_limit: T) -> T { + use std::cmp::max; + min(max(min_limit, val), max_limit) } pub mod mode { @@ -202,8 +203,12 @@ pub struct Term { /// The grid grid: Grid, - /// Wrap on next input - wrap: bool, + /// Tracks if the next call to input will need to first handle wrapping. + /// This is true after the last column is set with the input function. Any function that + /// implicitly sets the line or column needs to set this to false to avoid wrapping twice. + /// input_needs_wrap ensures that cursor.col is always valid for use into indexing into + /// arrays. Without it we wold have to sanitize cursor.col every time we used it. + input_needs_wrap: bool, /// Alternate grid alt_grid: Grid, @@ -274,8 +279,8 @@ impl SizeInfo { let line = Line(y / (self.cell_height as usize)); Some(Point { - line: cmp::min(line, self.lines() - 1), - col: cmp::min(col, self.cols() - 1) + line: min(line, self.lines() - 1), + col: min(col, self.cols() - 1) }) } } @@ -300,7 +305,7 @@ impl Term { Term { dirty: false, - wrap: false, + input_needs_wrap: false, grid: grid, alt_grid: alt, alt: false, @@ -352,7 +357,7 @@ impl Term { ) -> Option> { let line = &grid[line]; let line_length = line.line_length(); - let line_end = cmp::min(line_length, cols.end + 1); + let line_end = min(line_length, cols.end + 1); if cols.start >= line_end { None @@ -617,7 +622,7 @@ impl ansi::Handler for Term { #[inline] fn input(&mut self, c: char) { - if self.wrap { + if self.input_needs_wrap { debug_println!("wrapping"); @@ -638,7 +643,7 @@ impl ansi::Handler for Term { } self.cursor.col = Column(0); - self.wrap = false; + self.input_needs_wrap = false; } { @@ -650,7 +655,7 @@ impl ansi::Handler for Term { if (self.cursor.col + 1) < self.grid.num_cols() { self.cursor.col += 1; } else { - self.wrap = true; + self.input_needs_wrap = true; } } @@ -658,30 +663,30 @@ impl ansi::Handler for Term { #[inline] fn goto(&mut self, line: Line, col: Column) { debug_println!("goto: line={}, col={}", line, col); - self.cursor.line = cmp::min(line, self.grid.num_lines() - 1); - self.cursor.col = cmp::min(col, self.grid.num_cols() - 1); - self.wrap = false; + self.cursor.line = min(line, self.grid.num_lines() - 1); + self.cursor.col = min(col, self.grid.num_cols() - 1); + self.input_needs_wrap = false; } #[inline] fn goto_line(&mut self, line: Line) { debug_println!("goto_line: {}", line); - self.cursor.line = cmp::min(line, self.grid.num_lines() - 1); - self.wrap = false; + self.cursor.line = min(line, self.grid.num_lines() - 1); + self.input_needs_wrap = false; } #[inline] fn goto_col(&mut self, col: Column) { debug_println!("goto_col: {}", col); - self.cursor.col = cmp::min(col, self.grid.num_cols() - 1); - self.wrap = false; + self.cursor.col = min(col, self.grid.num_cols() - 1); + self.input_needs_wrap = false; } #[inline] fn insert_blank(&mut self, count: Column) { // Ensure inserting within terminal bounds - let count = cmp::min(count, self.size_info.cols() - self.cursor.col); + let count = min(count, self.size_info.cols() - self.cursor.col); let source = self.cursor.col; let destination = self.cursor.col + count; @@ -708,29 +713,28 @@ impl ansi::Handler for Term { #[inline] fn move_up(&mut self, lines: Line) { debug_println!("move_up: {}", lines); - let lines = cmp::min(self.cursor.line, lines); - self.cursor.line = cmp::min(self.cursor.line - lines, self.grid.num_lines() -1); + let lines = min(self.cursor.line, lines); + self.cursor.line = min(self.cursor.line - lines, self.grid.num_lines() -1); } #[inline] fn move_down(&mut self, lines: Line) { debug_println!("move_down: {}", lines); - self.cursor.line = cmp::min(self.cursor.line + lines, self.grid.num_lines() - 1); + self.cursor.line = min(self.cursor.line + lines, self.grid.num_lines() - 1); } #[inline] fn move_forward(&mut self, cols: Column) { debug_println!("move_forward: {}", cols); - self.cursor.col = cmp::min(self.cursor.col + cols, self.grid.num_cols() - 1); - self.wrap = false; + self.cursor.col = min(self.cursor.col + cols, self.grid.num_cols() - 1); + self.input_needs_wrap = false; } #[inline] fn move_backward(&mut self, cols: Column) { debug_println!("move_backward: {}", cols); - let cols = cmp::min(self.cursor.col, cols); - self.cursor.col = cmp::min(self.cursor.col - cols, self.grid.num_cols() - 1); - self.wrap = false; + self.cursor.col -= min(self.cursor.col, cols); + self.input_needs_wrap = false; } #[inline] @@ -764,7 +768,7 @@ impl ansi::Handler for Term { } self.cursor.col = col; - self.wrap = false; + self.input_needs_wrap = false; } /// Backspace `count` characters @@ -773,7 +777,7 @@ impl ansi::Handler for Term { debug_println!("backspace"); if self.cursor.col > Column(0) { self.cursor.col -= 1; - self.wrap = false; + self.input_needs_wrap = false; } } @@ -782,7 +786,7 @@ impl ansi::Handler for Term { fn carriage_return(&mut self) { debug_println!("carriage_return"); self.cursor.col = Column(0); - self.wrap = false; + self.input_needs_wrap = false; } /// Linefeed @@ -851,7 +855,7 @@ impl ansi::Handler for Term { fn erase_chars(&mut self, count: Column) { debug_println!("erase_chars: {}, {}", count, self.cursor.col); let start = self.cursor.col; - let end = cmp::min(start + count, self.grid.num_cols() - 1); + let end = min(start + count, self.grid.num_cols() - 1); let row = &mut self.grid[self.cursor.line]; let template = self.empty_cell; @@ -863,10 +867,10 @@ impl ansi::Handler for Term { #[inline] fn delete_chars(&mut self, count: Column) { // Ensure deleting within terminal bounds - let count = cmp::min(count, self.size_info.cols()); + let count = min(count, self.size_info.cols()); let start = self.cursor.col; - let end = cmp::min(start + count, self.grid.num_cols() - 1); + let end = min(start + count, self.grid.num_cols() - 1); let n = (self.size_info.cols() - end).0; let line = self.cursor.line; // borrowck