Simplify some more code.

This commit is contained in:
Blaž Hrastnik 2020-09-13 23:38:54 +09:00
parent 0427acd18c
commit 96db02742e
4 changed files with 16 additions and 23 deletions

View file

@ -62,8 +62,8 @@ pub fn append_mode(state: &mut State, _count: usize) {
// TODO: I, A, o and O can share a lot of the primitives.
// calculate line numbers for each selection range
fn selection_lines(state: &State) -> Vec<usize> {
// calculate line numbers for each selection range
let mut lines = state
.selection
.ranges()

View file

@ -100,8 +100,8 @@ impl Range {
#[derive(Debug, Clone)]
pub struct Selection {
// TODO: decide how many ranges to inline SmallVec<[Range; 1]>
pub(crate) ranges: SmallVec<[Range; 1]>,
pub(crate) primary_index: usize,
ranges: SmallVec<[Range; 1]>,
primary_index: usize,
}
impl Selection {
@ -205,6 +205,14 @@ impl Selection {
}
}
// fast path for a single selection (cursor)
if ranges.len() == 1 {
return Selection {
ranges,
primary_index: 0,
};
}
// TODO: only normalize if needed (any ranges out of order)
normalize(ranges, primary_index)
}

View file

@ -122,7 +122,7 @@ impl State {
// TODO: move all selections according to normal cursor move semantics by collapsing it
// into cursors and moving them vertically
let ranges = self.selection.ranges.iter().map(|range| {
self.selection.transform(|range| {
// let pos = if !range.is_empty() {
// // if selection already exists, bump it to the start or end of current select first
// if dir == Direction::Backward {
@ -134,10 +134,7 @@ impl State {
let pos = self.move_pos(range.head, dir, granularity, count);
// };
SelectionRange::new(pos, pos)
});
Selection::new(ranges.collect(), self.selection.primary_index)
// TODO: update selection in state via transaction
})
}
pub fn extend_selection(
@ -146,13 +143,10 @@ impl State {
granularity: Granularity,
count: usize,
) -> Selection {
let ranges = self.selection.ranges.iter().map(|range| {
self.selection.transform(|range| {
let pos = self.move_pos(range.head, dir, granularity, count);
SelectionRange::new(range.anchor, pos)
});
Selection::new(ranges.collect(), self.selection.primary_index)
// TODO: update selection in state via transaction
})
}
}
@ -203,7 +197,6 @@ mod test {
fn test_coords_at_pos() {
let text = Rope::from("ḧëḷḷö\nẅöṛḷḋ");
assert_eq!(coords_at_pos(&text.slice(..), 0), (0, 0));
// TODO: what is the coordinate of newline?
assert_eq!(coords_at_pos(&text.slice(..), 5), (0, 5)); // position on \n
assert_eq!(coords_at_pos(&text.slice(..), 6), (1, 0)); // position on w
assert_eq!(coords_at_pos(&text.slice(..), 7), (1, 1)); // position on o

View file

@ -3,13 +3,6 @@ use crate::{Rope, Selection, SelectionRange, State, Tendril};
/// (from, to, replacement)
pub type Change = (usize, usize, Option<Tendril>);
// TODO: divided into three different operations, I sort of like having just
// Splice { extent, Option<text>, distance } better.
// insert: Splice { extent: 0, text: Some("a"), distance: 2 }
// delete: Splice { extent: 2, text: None, distance: 2 }
// replace: Splice { extent: 2, text: Some("abc"), distance: 2 }
// unchanged?: Splice { extent: 0, text: None, distance: 2 }
// harder to compose though.
#[derive(Debug, Clone, PartialEq, Eq)]
enum Operation {
/// Move cursor by n characters.
@ -364,7 +357,6 @@ impl Transaction {
let mut last = 0;
for (from, to, tendril) in changes {
// TODO: need to fill the in-between ranges too
// Retain from last "to" to current "from"
acc.push(Operation::Retain(from - last));
match tendril {
@ -383,7 +375,7 @@ impl Transaction {
where
F: Fn(&SelectionRange) -> Change,
{
Self::change(state, state.selection.ranges.iter().map(f))
Self::change(state, state.selection.ranges().iter().map(f))
}
/// Insert text at each selection head.