Fix enter in normal mode acting incorrectly

This commit is contained in:
Kay Simmons 2023-02-23 13:40:31 -08:00
parent efafd1d8d3
commit 2276d25bdf
4 changed files with 57 additions and 16 deletions

View File

@ -27,6 +27,7 @@
"h": "vim::Left", "h": "vim::Left",
"backspace": "vim::Backspace", "backspace": "vim::Backspace",
"j": "vim::Down", "j": "vim::Down",
"enter": "vim::NextLineStart",
"k": "vim::Up", "k": "vim::Up",
"l": "vim::Right", "l": "vim::Right",
"$": "vim::EndOfLine", "$": "vim::EndOfLine",

View File

@ -36,6 +36,7 @@ pub enum Motion {
Matching, Matching,
FindForward { before: bool, text: Arc<str> }, FindForward { before: bool, text: Arc<str> },
FindBackward { after: bool, text: Arc<str> }, FindBackward { after: bool, text: Arc<str> },
NextLineStart,
} }
#[derive(Clone, Deserialize, PartialEq)] #[derive(Clone, Deserialize, PartialEq)]
@ -74,6 +75,7 @@ actions!(
StartOfDocument, StartOfDocument,
EndOfDocument, EndOfDocument,
Matching, Matching,
NextLineStart,
] ]
); );
impl_actions!(vim, [NextWordStart, NextWordEnd, PreviousWordStart]); impl_actions!(vim, [NextWordStart, NextWordEnd, PreviousWordStart]);
@ -111,6 +113,7 @@ pub fn init(cx: &mut MutableAppContext) {
&PreviousWordStart { ignore_punctuation }: &PreviousWordStart, &PreviousWordStart { ignore_punctuation }: &PreviousWordStart,
cx: _| { motion(Motion::PreviousWordStart { ignore_punctuation }, cx) }, cx: _| { motion(Motion::PreviousWordStart { ignore_punctuation }, cx) },
); );
cx.add_action(|_: &mut Workspace, &NextLineStart, cx: _| motion(Motion::NextLineStart, cx))
} }
pub(crate) fn motion(motion: Motion, cx: &mut MutableAppContext) { pub(crate) fn motion(motion: Motion, cx: &mut MutableAppContext) {
@ -138,15 +141,43 @@ pub(crate) fn motion(motion: Motion, cx: &mut MutableAppContext) {
impl Motion { impl Motion {
pub fn linewise(&self) -> bool { pub fn linewise(&self) -> bool {
use Motion::*; use Motion::*;
matches!( match self {
self, Down | Up | StartOfDocument | EndOfDocument | CurrentLine | NextLineStart => true,
Down | Up | StartOfDocument | EndOfDocument | CurrentLine EndOfLine
) | NextWordEnd { .. }
| Matching
| FindForward { .. }
| Left
| Backspace
| Right
| StartOfLine
| NextWordStart { .. }
| PreviousWordStart { .. }
| FirstNonWhitespace
| FindBackward { .. } => false,
}
} }
pub fn infallible(&self) -> bool { pub fn infallible(&self) -> bool {
use Motion::*; use Motion::*;
matches!(self, StartOfDocument | CurrentLine | EndOfDocument) match self {
StartOfDocument | EndOfDocument | CurrentLine => true,
Down
| Up
| EndOfLine
| NextWordEnd { .. }
| Matching
| FindForward { .. }
| Left
| Backspace
| Right
| StartOfLine
| NextWordStart { .. }
| PreviousWordStart { .. }
| FirstNonWhitespace
| FindBackward { .. }
| NextLineStart => false,
}
} }
pub fn inclusive(&self) -> bool { pub fn inclusive(&self) -> bool {
@ -160,7 +191,8 @@ impl Motion {
| EndOfLine | EndOfLine
| NextWordEnd { .. } | NextWordEnd { .. }
| Matching | Matching
| FindForward { .. } => true, | FindForward { .. }
| NextLineStart => true,
Left Left
| Backspace | Backspace
| Right | Right
@ -214,6 +246,7 @@ impl Motion {
find_backward(map, point, *after, text.clone(), times), find_backward(map, point, *after, text.clone(), times),
SelectionGoal::None, SelectionGoal::None,
), ),
NextLineStart => (next_line_start(map, point, times), SelectionGoal::None),
}; };
(new_point != point || infallible).then_some((new_point, goal)) (new_point != point || infallible).then_some((new_point, goal))
@ -543,3 +576,8 @@ fn find_backward(
}) })
.unwrap_or(from) .unwrap_or(from)
} }
fn next_line_start(map: &DisplaySnapshot, point: DisplayPoint, times: usize) -> DisplayPoint {
let new_row = (point.row() + times as u32).min(map.max_buffer_row());
map.clip_point(DisplayPoint::new(new_row, 0), Bias::Left)
}

View File

@ -473,6 +473,7 @@ pub(crate) fn normal_replace(text: Arc<str>, cx: &mut MutableAppContext) {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use gpui::TestAppContext;
use indoc::indoc; use indoc::indoc;
use crate::{ use crate::{
@ -515,15 +516,15 @@ mod test {
.await; .await;
} }
// #[gpui::test] #[gpui::test]
// async fn test_enter(cx: &mut gpui::TestAppContext) { async fn test_enter(cx: &mut gpui::TestAppContext) {
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["enter"]); let mut cx = NeovimBackedTestContext::new(cx).await.binding(["enter"]);
// cx.assert_all(indoc! {" cx.assert_all(indoc! {"
// ˇThe qˇuick broˇwn ˇThe qˇuick broˇwn
// ˇfox jumps" ˇfox jumps"
// }) })
// .await; .await;
// } }
#[gpui::test] #[gpui::test]
async fn test_k(cx: &mut gpui::TestAppContext) { async fn test_k(cx: &mut gpui::TestAppContext) {
@ -1030,7 +1031,7 @@ mod test {
} }
#[gpui::test] #[gpui::test]
async fn test_percent(cx: &mut gpui::TestAppContext) { async fn test_percent(cx: &mut TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await.binding(["%"]); let mut cx = NeovimBackedTestContext::new(cx).await.binding(["%"]);
cx.assert_all("ˇconsole.logˇ(ˇvaˇrˇ)ˇ;").await; cx.assert_all("ˇconsole.logˇ(ˇvaˇrˇ)ˇ;").await;
cx.assert_all("ˇconsole.logˇ(ˇ'var', ˇ[ˇ1, ˇ2, 3ˇ]ˇ)ˇ;") cx.assert_all("ˇconsole.logˇ(ˇ'var', ˇ[ˇ1, ˇ2, 3ˇ]ˇ)ˇ;")

View File

@ -0,0 +1 @@
[{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"}]