mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 01:46:18 +04:00
Selection: fail early if new() is called with no ranges.
This commit is contained in:
parent
71999cce43
commit
798dbd27c5
@ -126,6 +126,7 @@ pub fn fragment<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> Cow<'b, str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A selection consists of one or more selection ranges.
|
/// A selection consists of one or more selection ranges.
|
||||||
|
/// invariant: A selection can never be empty (always contains at least primary range).
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Selection {
|
pub struct Selection {
|
||||||
ranges: SmallVec<[Range; 1]>,
|
ranges: SmallVec<[Range; 1]>,
|
||||||
@ -205,12 +206,14 @@ pub fn point(pos: usize) -> Self {
|
|||||||
// TODO: consume an iterator or a vec to reduce allocations?
|
// TODO: consume an iterator or a vec to reduce allocations?
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(ranges: SmallVec<[Range; 1]>, primary_index: usize) -> Self {
|
pub fn new(ranges: SmallVec<[Range; 1]>, primary_index: usize) -> Self {
|
||||||
|
assert!(!ranges.is_empty());
|
||||||
|
|
||||||
fn normalize(mut ranges: SmallVec<[Range; 1]>, mut primary_index: usize) -> Selection {
|
fn normalize(mut ranges: SmallVec<[Range; 1]>, mut primary_index: usize) -> Selection {
|
||||||
let primary = ranges[primary_index];
|
let primary = ranges[primary_index];
|
||||||
ranges.sort_unstable_by_key(Range::from);
|
ranges.sort_unstable_by_key(Range::from);
|
||||||
primary_index = ranges.iter().position(|&range| range == primary).unwrap();
|
primary_index = ranges.iter().position(|&range| range == primary).unwrap();
|
||||||
|
|
||||||
let mut result: SmallVec<[Range; 1]> = SmallVec::new();
|
let mut result = SmallVec::new();
|
||||||
|
|
||||||
// TODO: we could do with one vec by removing elements as we mutate
|
// TODO: we could do with one vec by removing elements as we mutate
|
||||||
|
|
||||||
@ -294,7 +297,7 @@ fn into_iter(self) -> std::slice::Iter<'a, Range> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: checkSelection -> check if valid for doc length
|
// TODO: checkSelection -> check if valid for doc length && sorted
|
||||||
|
|
||||||
pub fn keep_matches(
|
pub fn keep_matches(
|
||||||
text: RopeSlice,
|
text: RopeSlice,
|
||||||
@ -387,6 +390,12 @@ pub fn split_on_matches(
|
|||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_new_empty() {
|
||||||
|
let sel = Selection::new(smallvec![], 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_normalizes_and_merges() {
|
fn test_create_normalizes_and_merges() {
|
||||||
let sel = Selection::new(
|
let sel = Selection::new(
|
||||||
|
@ -464,11 +464,13 @@ pub fn change<I>(doc: &Rope, changes: I) -> Self
|
|||||||
I: IntoIterator<Item = Change> + ExactSizeIterator,
|
I: IntoIterator<Item = Change> + ExactSizeIterator,
|
||||||
{
|
{
|
||||||
let len = doc.len_chars();
|
let len = doc.len_chars();
|
||||||
let acc = Vec::with_capacity(2 * changes.len() + 1);
|
let acc = Vec::with_capacity(2 * changes.len() + 1); // rough estimate
|
||||||
let mut changeset = ChangeSet { changes: acc, len };
|
let mut changeset = ChangeSet { changes: acc, len };
|
||||||
|
|
||||||
// TODO: verify ranges are ordered and not overlapping or change will panic.
|
// TODO: verify ranges are ordered and not overlapping or change will panic.
|
||||||
|
|
||||||
|
// TODO: test for (pos, pos, None) to factor out as nothing
|
||||||
|
|
||||||
let mut last = 0;
|
let mut last = 0;
|
||||||
for (from, to, tendril) in changes {
|
for (from, to, tendril) in changes {
|
||||||
// Retain from last "to" to current "from"
|
// Retain from last "to" to current "from"
|
||||||
|
Loading…
Reference in New Issue
Block a user