More vim fixes and move some more things out of app.rs

This commit is contained in:
Kay Simmons 2023-02-10 14:41:22 -08:00
parent c1812ddc27
commit 3d53336916
19 changed files with 595 additions and 473 deletions

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use editor::{
char_kind,
display_map::{DisplaySnapshot, ToDisplayPoint},
@ -15,7 +17,7 @@ use crate::{
Vim,
};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Motion {
Left,
Backspace,
@ -32,8 +34,8 @@ pub enum Motion {
StartOfDocument,
EndOfDocument,
Matching,
FindForward { before: bool, character: char },
FindBackward { after: bool, character: char },
FindForward { before: bool, text: Arc<str> },
FindBackward { after: bool, text: Arc<str> },
}
#[derive(Clone, Deserialize, PartialEq)]
@ -134,7 +136,7 @@ pub(crate) fn motion(motion: Motion, cx: &mut MutableAppContext) {
// Motion handling is specified here:
// https://github.com/vim/vim/blob/master/runtime/doc/motion.txt
impl Motion {
pub fn linewise(self) -> bool {
pub fn linewise(&self) -> bool {
use Motion::*;
matches!(
self,
@ -142,12 +144,12 @@ impl Motion {
)
}
pub fn infallible(self) -> bool {
pub fn infallible(&self) -> bool {
use Motion::*;
matches!(self, StartOfDocument | CurrentLine | EndOfDocument)
}
pub fn inclusive(self) -> bool {
pub fn inclusive(&self) -> bool {
use Motion::*;
match self {
Down
@ -171,13 +173,14 @@ impl Motion {
}
pub fn move_point(
self,
&self,
map: &DisplaySnapshot,
point: DisplayPoint,
goal: SelectionGoal,
times: usize,
) -> Option<(DisplayPoint, SelectionGoal)> {
use Motion::*;
let infallible = self.infallible();
let (new_point, goal) = match self {
Left => (left(map, point, times), SelectionGoal::None),
Backspace => (backspace(map, point, times), SelectionGoal::None),
@ -185,15 +188,15 @@ impl Motion {
Up => up(map, point, goal, times),
Right => (right(map, point, times), SelectionGoal::None),
NextWordStart { ignore_punctuation } => (
next_word_start(map, point, ignore_punctuation, times),
next_word_start(map, point, *ignore_punctuation, times),
SelectionGoal::None,
),
NextWordEnd { ignore_punctuation } => (
next_word_end(map, point, ignore_punctuation, times),
next_word_end(map, point, *ignore_punctuation, times),
SelectionGoal::None,
),
PreviousWordStart { ignore_punctuation } => (
previous_word_start(map, point, ignore_punctuation, times),
previous_word_start(map, point, *ignore_punctuation, times),
SelectionGoal::None,
),
FirstNonWhitespace => (first_non_whitespace(map, point), SelectionGoal::None),
@ -203,22 +206,22 @@ impl Motion {
StartOfDocument => (start_of_document(map, point, times), SelectionGoal::None),
EndOfDocument => (end_of_document(map, point, times), SelectionGoal::None),
Matching => (matching(map, point), SelectionGoal::None),
FindForward { before, character } => (
find_forward(map, point, before, character, times),
FindForward { before, text } => (
find_forward(map, point, *before, text.clone(), times),
SelectionGoal::None,
),
FindBackward { after, character } => (
find_backward(map, point, after, character, times),
FindBackward { after, text } => (
find_backward(map, point, *after, text.clone(), times),
SelectionGoal::None,
),
};
(new_point != point || self.infallible()).then_some((new_point, goal))
(new_point != point || infallible).then_some((new_point, goal))
}
// Expands a selection using self motion for an operator
pub fn expand_selection(
self,
&self,
map: &DisplaySnapshot,
selection: &mut Selection<DisplayPoint>,
times: usize,
@ -254,7 +257,7 @@ impl Motion {
// but "d}" will not include that line.
let mut inclusive = self.inclusive();
if !inclusive
&& self != Motion::Backspace
&& self != &Motion::Backspace
&& selection.end.row() > selection.start.row()
&& selection.end.column() == 0
{
@ -466,45 +469,42 @@ fn find_forward(
map: &DisplaySnapshot,
from: DisplayPoint,
before: bool,
target: char,
mut times: usize,
target: Arc<str>,
times: usize,
) -> DisplayPoint {
let mut previous_point = from;
for (ch, point) in map.chars_at(from) {
if ch == target && point != from {
times -= 1;
if times == 0 {
return if before { previous_point } else { point };
map.find_while(from, target.as_ref(), |ch, _| ch != '\n')
.skip_while(|found_at| found_at == &from)
.nth(times - 1)
.map(|mut found| {
if before {
*found.column_mut() -= 1;
found = map.clip_point(found, Bias::Right);
found
} else {
found
}
} else if ch == '\n' {
break;
}
previous_point = point;
}
from
})
.unwrap_or(from)
}
fn find_backward(
map: &DisplaySnapshot,
from: DisplayPoint,
after: bool,
target: char,
mut times: usize,
target: Arc<str>,
times: usize,
) -> DisplayPoint {
let mut previous_point = from;
for (ch, point) in map.reverse_chars_at(from) {
if ch == target && point != from {
times -= 1;
if times == 0 {
return if after { previous_point } else { point };
map.reverse_find_while(from, target.as_ref(), |ch, _| ch != '\n')
.skip_while(|found_at| found_at == &from)
.nth(times - 1)
.map(|mut found| {
if after {
*found.column_mut() += 1;
found = map.clip_point(found, Bias::Left);
found
} else {
found
}
} else if ch == '\n' {
break;
}
previous_point = point;
}
from
})
.unwrap_or(from)
}