aboutsummaryrefslogtreecommitdiff
path: root/src/grid/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grid/mod.rs')
-rw-r--r--src/grid/mod.rs68
1 files changed, 53 insertions, 15 deletions
diff --git a/src/grid/mod.rs b/src/grid/mod.rs
index cf66a420..7f648f46 100644
--- a/src/grid/mod.rs
+++ b/src/grid/mod.rs
@@ -17,7 +17,7 @@
use std::cmp::{min, max, Ordering};
use std::ops::{Deref, Range, Index, IndexMut, RangeTo, RangeFrom, RangeFull};
-use index::{self, Point, Line, Column, IndexRange, RangeInclusive};
+use index::{self, Point, Line, Column, IndexRange};
use selection::Selection;
mod row;
@@ -29,11 +29,6 @@ mod tests;
mod storage;
use self::storage::Storage;
-/// Convert a type to a linear index range.
-pub trait ToRange {
- fn to_range(&self) -> RangeInclusive<index::Linear>;
-}
-
/// Bidirection iterator
pub trait BidirectionalIterator: Iterator {
fn prev(&mut self) -> Option<Self::Item>;
@@ -105,8 +100,17 @@ pub struct Grid<T> {
}
pub struct GridIterator<'a, T: 'a> {
+ /// Immutable grid reference
grid: &'a Grid<T>,
- pub cur: Point,
+
+ /// Current position of the iterator within the grid.
+ pub cur: Point<usize>,
+
+ /// Bottom of screen (buffer)
+ bot: usize,
+
+ /// Top of screen (buffer)
+ top: usize,
}
impl<T: Copy + Clone> Grid<T> {
@@ -135,6 +139,28 @@ impl<T: Copy + Clone> Grid<T> {
}
}
+ pub fn visible_to_buffer(&self, point: Point) -> Point<usize> {
+ Point {
+ line: self.visible_line_to_buffer(point.line),
+ col: point.col
+ }
+ }
+
+ pub fn buffer_to_visible(&self, point: Point<usize>) -> Point {
+ Point {
+ line: self.buffer_line_to_visible(point.line),
+ col: point.col
+ }
+ }
+
+ pub fn buffer_line_to_visible(&self, line: usize) -> Line {
+ self.offset_to_line(line - self.display_offset)
+ }
+
+ pub fn visible_line_to_buffer(&self, line: Line) -> usize {
+ self.line_to_offset(line) + self.display_offset
+ }
+
pub fn scroll_display(&mut self, count: isize) {
self.display_offset = min(
max((self.display_offset as isize) + count, 0isize) as usize,
@@ -224,6 +250,7 @@ impl<T: Copy + Clone> Grid<T> {
let prev = self.lines;
+ self.selection = None;
self.raw.rotate(*prev as isize - *target as isize);
self.raw.set_visible_lines(target);
self.lines = target;
@@ -240,6 +267,12 @@ impl<T: Copy + Clone> Grid<T> {
*(self.num_lines() - line - 1)
}
+ pub fn offset_to_line(&self, offset: usize) -> Line {
+ assert!(offset < *self.num_lines());
+
+ self.lines - offset - 1
+ }
+
#[inline]
pub fn scroll_down(&mut self, region: &Range<index::Line>, positions: index::Line) {
// Whether or not there is a scrolling region active, as long as it
@@ -251,6 +284,9 @@ impl<T: Copy + Clone> Grid<T> {
// Rotate the entire line buffer. If there's a scrolling region
// active, the bottom lines are restored in the next step.
self.raw.rotate_up(*positions);
+ if let Some(ref mut selection) = self.selection {
+ selection.rotate(-(*positions as isize));
+ }
self.decrease_scroll_limit(*positions);
@@ -292,6 +328,9 @@ impl<T: Copy + Clone> Grid<T> {
// Rotate the entire line buffer. If there's a scrolling region
// active, the bottom lines are restored in the next step.
self.raw.rotate(-(*positions as isize));
+ if let Some(ref mut selection) = self.selection {
+ selection.rotate(*positions as isize);
+ }
// Now, restore any lines outside the scroll region
for idx in (*region.end .. *self.num_lines()).rev() {
@@ -334,10 +373,12 @@ impl<T> Grid<T> {
self.cols
}
- pub fn iter_from(&self, point: Point) -> GridIterator<T> {
+ pub fn iter_from(&self, point: Point<usize>) -> GridIterator<T> {
GridIterator {
grid: self,
cur: point,
+ bot: self.display_offset,
+ top: self.display_offset + *self.num_lines() - 1,
}
}
@@ -369,15 +410,12 @@ impl<'a, T> Iterator for GridIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
- let last_line = self.grid.num_lines() - Line(1);
let last_col = self.grid.num_cols() - Column(1);
match self.cur {
- Point { line, col } if
- (line == last_line) &&
- (col == last_col) => None,
+ Point { line, col } if (line == self.bot) && (col == last_col) => None,
Point { col, .. } if
(col == last_col) => {
- self.cur.line += Line(1);
+ self.cur.line -= 1;
self.cur.col = Column(0);
Some(&self.grid[self.cur.line][self.cur.col])
},
@@ -394,9 +432,9 @@ impl<'a, T> BidirectionalIterator for GridIterator<'a, T> {
let num_cols = self.grid.num_cols();
match self.cur {
- Point { line: Line(0), col: Column(0) } => None,
+ Point { line, col: Column(0) } if line == self.top => None,
Point { col: Column(0), .. } => {
- self.cur.line -= Line(1);
+ self.cur.line += 1;
self.cur.col = num_cols - Column(1);
Some(&self.grid[self.cur.line][self.cur.col])
},