Unify Cursor, Location and name it Point
This commit is contained in:
parent
5ee031f55f
commit
689e0f4ad7
18
src/grid.rs
18
src/grid.rs
|
@ -27,7 +27,7 @@ use std::ops::{Deref, DerefMut, Range, RangeTo, RangeFrom, RangeFull, Index, Ind
|
|||
use std::ops::RangeInclusive;
|
||||
use std::slice::{self, Iter, IterMut};
|
||||
|
||||
use index::{self, Cursor};
|
||||
use index::{self, Point};
|
||||
|
||||
/// Convert a type to a linear index range.
|
||||
pub trait ToRange {
|
||||
|
@ -141,8 +141,8 @@ impl<T> Grid<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn contains(&self, cursor: &Cursor) -> bool {
|
||||
self.lines > cursor.line && self.cols > cursor.col
|
||||
pub fn contains(&self, point: &Point) -> bool {
|
||||
self.lines > point.line && self.cols > point.col
|
||||
}
|
||||
|
||||
/// Swap two lines in the grid
|
||||
|
@ -210,19 +210,19 @@ impl<T> IndexMut<index::Line> for Grid<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'cursor, T> Index<&'cursor Cursor> for Grid<T> {
|
||||
impl<'point, T> Index<&'point Point> for Grid<T> {
|
||||
type Output = T;
|
||||
|
||||
#[inline]
|
||||
fn index<'a>(&'a self, cursor: &Cursor) -> &'a T {
|
||||
&self.raw[cursor.line.0][cursor.col]
|
||||
fn index<'a>(&'a self, point: &Point) -> &'a T {
|
||||
&self.raw[point.line.0][point.col]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cursor, T> IndexMut<&'cursor Cursor> for Grid<T> {
|
||||
impl<'point, T> IndexMut<&'point Point> for Grid<T> {
|
||||
#[inline]
|
||||
fn index_mut<'a, 'b>(&'a mut self, cursor: &'b Cursor) -> &'a mut T {
|
||||
&mut self.raw[cursor.line.0][cursor.col]
|
||||
fn index_mut<'a, 'b>(&'a mut self, point: &'b Point) -> &'a mut T {
|
||||
&mut self.raw[point.line.0][point.col]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
33
src/index.rs
33
src/index.rs
|
@ -29,27 +29,20 @@ pub enum Side {
|
|||
}
|
||||
|
||||
/// Index in the grid using row, column notation
|
||||
#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Cursor {
|
||||
pub line: Line,
|
||||
pub col: Column,
|
||||
}
|
||||
|
||||
/// Location
|
||||
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize, PartialOrd)]
|
||||
pub struct Location {
|
||||
pub struct Point {
|
||||
pub line: Line,
|
||||
pub col: Column,
|
||||
}
|
||||
|
||||
impl Location {
|
||||
pub fn new(line: Line, col: Column) -> Location {
|
||||
Location { line: line, col: col }
|
||||
impl Point {
|
||||
pub fn new(line: Line, col: Column) -> Point {
|
||||
Point { line: line, col: col }
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Location {
|
||||
fn cmp(&self, other: &Location) -> Ordering {
|
||||
impl Ord for Point {
|
||||
fn cmp(&self, other: &Point) -> Ordering {
|
||||
use std::cmp::Ordering::*;
|
||||
match (self.line.cmp(&other.line), self.col.cmp(&other.col)) {
|
||||
(Equal, Equal) => Equal,
|
||||
|
@ -331,15 +324,15 @@ ops!(Linear, Linear);
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Line, Column, Location};
|
||||
use super::{Line, Column, Point};
|
||||
|
||||
#[test]
|
||||
fn location_ordering() {
|
||||
assert!(Location::new(Line(0), Column(0)) == Location::new(Line(0), Column(0)));
|
||||
assert!(Location::new(Line(1), Column(0)) > Location::new(Line(0), Column(0)));
|
||||
assert!(Location::new(Line(0), Column(1)) > Location::new(Line(0), Column(0)));
|
||||
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(0), Column(0)));
|
||||
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(0), Column(1)));
|
||||
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(1), Column(0)));
|
||||
assert!(Point::new(Line(0), Column(0)) == Point::new(Line(0), Column(0)));
|
||||
assert!(Point::new(Line(1), Column(0)) > Point::new(Line(0), Column(0)));
|
||||
assert!(Point::new(Line(0), Column(1)) > Point::new(Line(0), Column(0)));
|
||||
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(0), Column(0)));
|
||||
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(0), Column(1)));
|
||||
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(1), Column(0)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ use glutin::{Mods, mods};
|
|||
use glutin::{TouchPhase, MouseScrollDelta};
|
||||
|
||||
use event::Notify;
|
||||
use index::{Line, Column, Side, Location};
|
||||
use index::{Line, Column, Side, Point};
|
||||
use selection::Selection;
|
||||
use term::mode::{self, TermMode};
|
||||
use term::{self, Term};
|
||||
|
@ -209,7 +209,7 @@ impl<'a, N: Notify + 'a> Processor<'a, N> {
|
|||
if self.ctx.mouse.left_button_state == ElementState::Pressed &&
|
||||
!self.ctx.terminal.mode().contains(mode::MOUSE_REPORT_CLICK)
|
||||
{
|
||||
self.ctx.selection.update(Location {
|
||||
self.ctx.selection.update(Point {
|
||||
line: line,
|
||||
col: column
|
||||
}, self.ctx.mouse.cell_side);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
use std::mem;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use index::{Location, Column, Side, Linear, Line};
|
||||
use index::{Point, Column, Side, Linear, Line};
|
||||
use grid::ToRange;
|
||||
|
||||
/// The area selected
|
||||
|
@ -34,8 +34,8 @@ pub enum Selection {
|
|||
Empty,
|
||||
|
||||
Active {
|
||||
start: Location,
|
||||
end: Location,
|
||||
start: Point,
|
||||
end: Point,
|
||||
start_side: Side,
|
||||
end_side: Side
|
||||
},
|
||||
|
@ -66,7 +66,7 @@ impl Selection {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, location: Location, side: Side) {
|
||||
pub fn update(&mut self, location: Point, side: Side) {
|
||||
let selection = mem::replace(self, Selection::Empty);
|
||||
let selection = match selection {
|
||||
Selection::Empty => {
|
||||
|
@ -172,15 +172,15 @@ pub enum SpanType {
|
|||
/// Represents a span of selected cells
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Span {
|
||||
front: Location,
|
||||
tail: Location,
|
||||
front: Point,
|
||||
tail: Point,
|
||||
|
||||
/// The type says whether ends are included or not.
|
||||
ty: SpanType,
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub fn to_locations(&self, cols: Column) -> (Location, Location) {
|
||||
pub fn to_locations(&self, cols: Column) -> (Point, Point) {
|
||||
match self.ty {
|
||||
SpanType::Inclusive => (self.front, self.tail),
|
||||
SpanType::Exclusive => {
|
||||
|
@ -191,9 +191,9 @@ impl Span {
|
|||
}
|
||||
}
|
||||
|
||||
fn wrap_start(mut start: Location, cols: Column) -> Location {
|
||||
fn wrap_start(mut start: Point, cols: Column) -> Point {
|
||||
if start.col == cols - 1 {
|
||||
Location {
|
||||
Point {
|
||||
line: start.line + 1,
|
||||
col: Column(0),
|
||||
}
|
||||
|
@ -203,14 +203,14 @@ impl Span {
|
|||
}
|
||||
}
|
||||
|
||||
fn wrap_end(end: Location, cols: Column) -> Location {
|
||||
fn wrap_end(end: Point, cols: Column) -> Point {
|
||||
if end.col == Column(0) && end.line != Line(0) {
|
||||
Location {
|
||||
Point {
|
||||
line: end.line - 1,
|
||||
col: cols
|
||||
}
|
||||
} else {
|
||||
Location {
|
||||
Point {
|
||||
line: end.line,
|
||||
col: end.col - 1
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ impl ToRange for Span {
|
|||
/// look like [ B] and [E ].
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use index::{Line, Column, Side, Location};
|
||||
use index::{Line, Column, Side, Point};
|
||||
use super::{Selection, Span, SpanType};
|
||||
|
||||
/// Test case of single cell selection
|
||||
|
@ -269,7 +269,7 @@ mod test {
|
|||
/// 3. [BE]
|
||||
#[test]
|
||||
fn single_cell_left_to_right() {
|
||||
let location = Location { line: Line(0), col: Column(0) };
|
||||
let location = Point { line: Line(0), col: Column(0) };
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(location, Side::Left);
|
||||
selection.update(location, Side::Right);
|
||||
|
@ -288,7 +288,7 @@ mod test {
|
|||
/// 3. [EB]
|
||||
#[test]
|
||||
fn single_cell_right_to_left() {
|
||||
let location = Location { line: Line(0), col: Column(0) };
|
||||
let location = Point { line: Line(0), col: Column(0) };
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(location, Side::Right);
|
||||
selection.update(location, Side::Left);
|
||||
|
@ -308,8 +308,8 @@ mod test {
|
|||
#[test]
|
||||
fn between_adjacent_cells_left_to_right() {
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(Location::new(Line(0), Column(0)), Side::Right);
|
||||
selection.update(Location::new(Line(0), Column(1)), Side::Left);
|
||||
selection.update(Point::new(Line(0), Column(0)), Side::Right);
|
||||
selection.update(Point::new(Line(0), Column(1)), Side::Left);
|
||||
|
||||
assert_eq!(selection.span(), None);
|
||||
}
|
||||
|
@ -322,8 +322,8 @@ mod test {
|
|||
#[test]
|
||||
fn between_adjacent_cells_right_to_left() {
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(Location::new(Line(0), Column(1)), Side::Left);
|
||||
selection.update(Location::new(Line(0), Column(0)), Side::Right);
|
||||
selection.update(Point::new(Line(0), Column(1)), Side::Left);
|
||||
selection.update(Point::new(Line(0), Column(0)), Side::Right);
|
||||
|
||||
assert_eq!(selection.span(), None);
|
||||
}
|
||||
|
@ -340,12 +340,12 @@ mod test {
|
|||
#[test]
|
||||
fn across_adjacent_lines_upward_final_cell_exclusive() {
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(Location::new(Line(1), Column(1)), Side::Right);
|
||||
selection.update(Location::new(Line(0), Column(1)), Side::Right);
|
||||
selection.update(Point::new(Line(1), Column(1)), Side::Right);
|
||||
selection.update(Point::new(Line(0), Column(1)), Side::Right);
|
||||
|
||||
assert_eq!(selection.span().unwrap(), Span {
|
||||
front: Location::new(Line(0), Column(1)),
|
||||
tail: Location::new(Line(1), Column(1)),
|
||||
front: Point::new(Line(0), Column(1)),
|
||||
tail: Point::new(Line(1), Column(1)),
|
||||
ty: SpanType::ExcludeFront
|
||||
});
|
||||
}
|
||||
|
@ -364,13 +364,13 @@ mod test {
|
|||
#[test]
|
||||
fn selection_bigger_then_smaller() {
|
||||
let mut selection = Selection::Empty;
|
||||
selection.update(Location::new(Line(0), Column(1)), Side::Right);
|
||||
selection.update(Location::new(Line(1), Column(1)), Side::Right);
|
||||
selection.update(Location::new(Line(1), Column(0)), Side::Right);
|
||||
selection.update(Point::new(Line(0), Column(1)), Side::Right);
|
||||
selection.update(Point::new(Line(1), Column(1)), Side::Right);
|
||||
selection.update(Point::new(Line(1), Column(0)), Side::Right);
|
||||
|
||||
assert_eq!(selection.span().unwrap(), Span {
|
||||
front: Location::new(Line(0), Column(1)),
|
||||
tail: Location::new(Line(1), Column(0)),
|
||||
front: Point::new(Line(0), Column(1)),
|
||||
tail: Point::new(Line(1), Column(0)),
|
||||
ty: SpanType::ExcludeFront
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use std::io;
|
|||
|
||||
use ansi::{self, Color, NamedColor, Attr, Handler};
|
||||
use grid::{Grid, ClearRegion, ToRange};
|
||||
use index::{self, Cursor, Column, Line, Linear};
|
||||
use index::{self, Point, Column, Line, Linear};
|
||||
use selection::{Span, Selection};
|
||||
|
||||
pub mod cell;
|
||||
|
@ -37,7 +37,7 @@ use self::cell::LineLength;
|
|||
/// draw it, and reverted after drawing to maintain state.
|
||||
pub struct RenderableCellsIter<'a> {
|
||||
grid: &'a mut Grid<Cell>,
|
||||
cursor: &'a Cursor,
|
||||
cursor: &'a Point,
|
||||
mode: TermMode,
|
||||
line: Line,
|
||||
column: Column,
|
||||
|
@ -51,7 +51,7 @@ impl<'a> RenderableCellsIter<'a> {
|
|||
/// cursor.
|
||||
fn new<'b>(
|
||||
grid: &'b mut Grid<Cell>,
|
||||
cursor: &'b Cursor,
|
||||
cursor: &'b Point,
|
||||
mode: TermMode,
|
||||
selection: &Selection,
|
||||
) -> RenderableCellsIter<'b> {
|
||||
|
@ -207,10 +207,10 @@ pub struct Term {
|
|||
alt: bool,
|
||||
|
||||
/// The cursor
|
||||
cursor: Cursor,
|
||||
cursor: Point,
|
||||
|
||||
/// Alt cursor
|
||||
alt_cursor: Cursor,
|
||||
alt_cursor: Point,
|
||||
|
||||
/// Tabstops
|
||||
tabs: Vec<bool>,
|
||||
|
@ -299,8 +299,8 @@ impl Term {
|
|||
grid: grid,
|
||||
alt_grid: alt,
|
||||
alt: false,
|
||||
cursor: Cursor::default(),
|
||||
alt_cursor: Cursor::default(),
|
||||
cursor: Point::default(),
|
||||
alt_cursor: Point::default(),
|
||||
tabs: tabs,
|
||||
mode: Default::default(),
|
||||
scroll_region: scroll_region,
|
||||
|
@ -585,7 +585,7 @@ impl ansi::Handler for Term {
|
|||
if self.cursor.col == self.grid.num_cols() {
|
||||
debug_println!("wrapping");
|
||||
{
|
||||
let location = Cursor {
|
||||
let location = Point {
|
||||
line: self.cursor.line,
|
||||
col: self.cursor.col - 1
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue