Add a command module.

This commit is contained in:
Blaž Hrastnik 2020-06-08 00:15:39 +09:00
parent 195aad4675
commit e98cdebf1e
3 changed files with 57 additions and 15 deletions

View file

@ -0,0 +1,45 @@
use crate::state::{Direction, Granularity, State};
/// A command is a function that takes the current state and a count, and does a side-effect on the
/// state (usually by creating and applying a transaction).
type Command = fn(state: &mut State, count: usize);
fn move_char_left(state: &mut State, count: usize) {
// TODO: use a transaction
state.selection = state.move_selection(
state.selection,
Direction::Backward,
Granularity::Character,
count,
);
}
fn move_char_right(state: &mut State, count: usize) {
// TODO: use a transaction
state.selection = state.move_selection(
state.selection,
Direction::Forward,
Granularity::Character,
count,
);
}
fn move_line_up(state: &mut State, count: usize) {
// TODO: use a transaction
state.selection = state.move_selection(
state.selection,
Direction::Backward,
Granularity::Line,
count,
);
}
fn move_line_down(state: &mut State, count: usize) {
// TODO: use a transaction
state.selection = state.move_selection(
state.selection,
Direction::Forward,
Granularity::Line,
count,
);
}

View file

@ -1,5 +1,6 @@
#![allow(unused)] #![allow(unused)]
mod buffer; mod buffer;
pub mod commands;
mod graphemes; mod graphemes;
mod selection; mod selection;
mod state; mod state;

View file

@ -3,8 +3,8 @@ use crate::{Buffer, Rope, RopeSlice, Selection, SelectionRange};
/// A state represents the current editor state of a single buffer. /// A state represents the current editor state of a single buffer.
pub struct State { pub struct State {
doc: Buffer, pub(crate) doc: Buffer,
selection: Selection, pub(crate) selection: Selection,
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
@ -59,17 +59,17 @@ impl State {
pos: usize, pos: usize,
dir: Direction, dir: Direction,
granularity: Granularity, granularity: Granularity,
n: usize, count: usize,
) -> usize { ) -> usize {
let text = &self.doc.contents; let text = &self.doc.contents;
match (dir, granularity) { match (dir, granularity) {
(Direction::Backward, Granularity::Character) => { (Direction::Backward, Granularity::Character) => {
nth_prev_grapheme_boundary(&text.slice(..), pos, n) nth_prev_grapheme_boundary(&text.slice(..), pos, count)
} }
(Direction::Forward, Granularity::Character) => { (Direction::Forward, Granularity::Character) => {
nth_next_grapheme_boundary(&text.slice(..), pos, n) nth_next_grapheme_boundary(&text.slice(..), pos, count)
} }
(_, Granularity::Line) => move_vertically(&text.slice(..), dir, pos, n), (_, Granularity::Line) => move_vertically(&text.slice(..), dir, pos, count),
_ => pos, _ => pos,
} }
} }
@ -79,7 +79,7 @@ impl State {
sel: Selection, sel: Selection,
dir: Direction, dir: Direction,
granularity: Granularity, granularity: Granularity,
// TODO: n count: usize,
) -> Selection { ) -> Selection {
// TODO: move all selections according to normal cursor move semantics by collapsing it // TODO: move all selections according to normal cursor move semantics by collapsing it
// into cursors and moving them vertically // into cursors and moving them vertically
@ -93,7 +93,7 @@ impl State {
// range.to() // range.to()
// } // }
// } else { // } else {
let pos = self.move_pos(range.head, dir, granularity, 1); let pos = self.move_pos(range.head, dir, granularity, count);
// }; // };
SelectionRange::new(pos, pos) SelectionRange::new(pos, pos)
}); });
@ -107,10 +107,10 @@ impl State {
sel: Selection, sel: Selection,
dir: Direction, dir: Direction,
granularity: Granularity, granularity: Granularity,
n: usize, count: usize,
) -> Selection { ) -> Selection {
let ranges = sel.ranges.into_iter().map(|range| { let ranges = sel.ranges.into_iter().map(|range| {
let pos = self.move_pos(range.head, dir, granularity, n); let pos = self.move_pos(range.head, dir, granularity, count);
SelectionRange::new(range.anchor, pos) SelectionRange::new(range.anchor, pos)
}); });
@ -138,7 +138,7 @@ pub fn pos_at_coords(text: &RopeSlice, coords: Coords) -> usize {
nth_next_grapheme_boundary(text, line_start, col) nth_next_grapheme_boundary(text, line_start, col)
} }
fn move_vertically(text: &RopeSlice, dir: Direction, pos: usize, n: usize) -> usize { fn move_vertically(text: &RopeSlice, dir: Direction, pos: usize, count: usize) -> usize {
let (line, col) = coords_at_pos(text, pos); let (line, col) = coords_at_pos(text, pos);
let new_line = match dir { let new_line = match dir {
@ -159,10 +159,6 @@ fn move_vertically(text: &RopeSlice, dir: Direction, pos: usize, n: usize) -> us
pos_at_coords(text, (new_line, new_col)) pos_at_coords(text, (new_line, new_col))
} }
/// A command is a function that takes the current state and a count, and does a side-effect on the
/// state (usually by creating and applying a transaction).
type Command = fn(state: &mut State, count: usize) -> bool;
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;