vim2 compiling (but mostly commented out)
This commit is contained in:
parent
7a9f764aa0
commit
32837d67be
146 changed files with 22013 additions and 10 deletions
502
crates/vim2/src/normal/change.rs
Normal file
502
crates/vim2/src/normal/change.rs
Normal file
|
@ -0,0 +1,502 @@
|
|||
use crate::{motion::Motion, object::Object, state::Mode, utils::copy_selections_content, Vim};
|
||||
use editor::{
|
||||
char_kind,
|
||||
display_map::DisplaySnapshot,
|
||||
movement::{self, FindRange, TextLayoutDetails},
|
||||
scroll::autoscroll::Autoscroll,
|
||||
CharKind, DisplayPoint,
|
||||
};
|
||||
use gpui::WindowContext;
|
||||
use language::Selection;
|
||||
|
||||
pub fn change_motion(vim: &mut Vim, motion: Motion, times: Option<usize>, cx: &mut WindowContext) {
|
||||
// Some motions ignore failure when switching to normal mode
|
||||
let mut motion_succeeded = matches!(
|
||||
motion,
|
||||
Motion::Left
|
||||
| Motion::Right
|
||||
| Motion::EndOfLine { .. }
|
||||
| Motion::Backspace
|
||||
| Motion::StartOfLine { .. }
|
||||
);
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
let text_layout_details = editor.text_layout_details(cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
// We are swapping to insert mode anyway. Just set the line end clipping behavior now
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
motion_succeeded |= if let Motion::NextWordStart { ignore_punctuation } = motion
|
||||
{
|
||||
expand_changed_word_selection(
|
||||
map,
|
||||
selection,
|
||||
times,
|
||||
ignore_punctuation,
|
||||
&text_layout_details,
|
||||
)
|
||||
} else {
|
||||
motion.expand_selection(map, selection, times, false, &text_layout_details)
|
||||
};
|
||||
});
|
||||
});
|
||||
copy_selections_content(editor, motion.linewise(), cx);
|
||||
editor.insert("", cx);
|
||||
});
|
||||
});
|
||||
|
||||
if motion_succeeded {
|
||||
vim.switch_mode(Mode::Insert, false, cx)
|
||||
} else {
|
||||
vim.switch_mode(Mode::Normal, false, cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_object(vim: &mut Vim, object: Object, around: bool, cx: &mut WindowContext) {
|
||||
let mut objects_found = false;
|
||||
vim.update_active_editor(cx, |editor, cx| {
|
||||
// We are swapping to insert mode anyway. Just set the line end clipping behavior now
|
||||
editor.set_clip_at_line_ends(false, cx);
|
||||
editor.transact(cx, |editor, cx| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_with(|map, selection| {
|
||||
objects_found |= object.expand_selection(map, selection, around);
|
||||
});
|
||||
});
|
||||
if objects_found {
|
||||
copy_selections_content(editor, false, cx);
|
||||
editor.insert("", cx);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if objects_found {
|
||||
vim.switch_mode(Mode::Insert, false, cx);
|
||||
} else {
|
||||
vim.switch_mode(Mode::Normal, false, cx);
|
||||
}
|
||||
}
|
||||
|
||||
// From the docs https://vimdoc.sourceforge.net/htmldoc/motion.html
|
||||
// Special case: "cw" and "cW" are treated like "ce" and "cE" if the cursor is
|
||||
// on a non-blank. This is because "cw" is interpreted as change-word, and a
|
||||
// word does not include the following white space. {Vi: "cw" when on a blank
|
||||
// followed by other blanks changes only the first blank; this is probably a
|
||||
// bug, because "dw" deletes all the blanks}
|
||||
fn expand_changed_word_selection(
|
||||
map: &DisplaySnapshot,
|
||||
selection: &mut Selection<DisplayPoint>,
|
||||
times: Option<usize>,
|
||||
ignore_punctuation: bool,
|
||||
text_layout_details: &TextLayoutDetails,
|
||||
) -> bool {
|
||||
if times.is_none() || times.unwrap() == 1 {
|
||||
let scope = map
|
||||
.buffer_snapshot
|
||||
.language_scope_at(selection.start.to_point(map));
|
||||
let in_word = map
|
||||
.chars_at(selection.head())
|
||||
.next()
|
||||
.map(|(c, _)| char_kind(&scope, c) != CharKind::Whitespace)
|
||||
.unwrap_or_default();
|
||||
|
||||
if in_word {
|
||||
selection.end =
|
||||
movement::find_boundary(map, selection.end, FindRange::MultiLine, |left, right| {
|
||||
let left_kind = char_kind(&scope, left).coerce_punctuation(ignore_punctuation);
|
||||
let right_kind =
|
||||
char_kind(&scope, right).coerce_punctuation(ignore_punctuation);
|
||||
|
||||
left_kind != right_kind && left_kind != CharKind::Whitespace
|
||||
});
|
||||
true
|
||||
} else {
|
||||
Motion::NextWordStart { ignore_punctuation }.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
None,
|
||||
false,
|
||||
&text_layout_details,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Motion::NextWordStart { ignore_punctuation }.expand_selection(
|
||||
map,
|
||||
selection,
|
||||
times,
|
||||
false,
|
||||
&text_layout_details,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
// use indoc::indoc;
|
||||
|
||||
// use crate::test::NeovimBackedTestContext;
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_h(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "h"]);
|
||||
// cx.assert("Teˇst").await;
|
||||
// cx.assert("Tˇest").await;
|
||||
// cx.assert("ˇTest").await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test
|
||||
// ˇtest"})
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_backspace(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx)
|
||||
// .await
|
||||
// .binding(["c", "backspace"]);
|
||||
// cx.assert("Teˇst").await;
|
||||
// cx.assert("Tˇest").await;
|
||||
// cx.assert("ˇTest").await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test
|
||||
// ˇtest"})
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_l(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "l"]);
|
||||
// cx.assert("Teˇst").await;
|
||||
// cx.assert("Tesˇt").await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_w(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "w"]);
|
||||
// cx.assert("Teˇst").await;
|
||||
// cx.assert("Tˇest test").await;
|
||||
// cx.assert("Testˇ test").await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test teˇst
|
||||
// test"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test tesˇt
|
||||
// test"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test test
|
||||
// ˇ
|
||||
// test"})
|
||||
// .await;
|
||||
|
||||
// let mut cx = cx.binding(["c", "shift-w"]);
|
||||
// cx.assert("Test teˇst-test test").await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_e(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "e"]);
|
||||
// cx.assert("Teˇst Test").await;
|
||||
// cx.assert("Tˇest test").await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test teˇst
|
||||
// test"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test tesˇt
|
||||
// test"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test test
|
||||
// ˇ
|
||||
// test"})
|
||||
// .await;
|
||||
|
||||
// let mut cx = cx.binding(["c", "shift-e"]);
|
||||
// cx.assert("Test teˇst-test test").await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_b(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "b"]);
|
||||
// cx.assert("Teˇst Test").await;
|
||||
// cx.assert("Test ˇtest").await;
|
||||
// cx.assert("Test1 test2 ˇtest3").await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test test
|
||||
// ˇtest"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// Test test
|
||||
// ˇ
|
||||
// test"})
|
||||
// .await;
|
||||
|
||||
// let mut cx = cx.binding(["c", "shift-b"]);
|
||||
// cx.assert("Test test-test ˇtest").await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_end_of_line(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await.binding(["c", "$"]);
|
||||
// cx.assert(indoc! {"
|
||||
// The qˇuick
|
||||
// brown fox"})
|
||||
// .await;
|
||||
// cx.assert(indoc! {"
|
||||
// The quick
|
||||
// ˇ
|
||||
// brown fox"})
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_0(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The qˇuick
|
||||
// brown fox"},
|
||||
// ["c", "0"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// ˇ
|
||||
// brown fox"},
|
||||
// ["c", "0"],
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_k(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown ˇfox
|
||||
// jumps over"},
|
||||
// ["c", "k"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// jumps ˇover"},
|
||||
// ["c", "k"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The qˇuick
|
||||
// brown fox
|
||||
// jumps over"},
|
||||
// ["c", "k"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// ˇ
|
||||
// brown fox
|
||||
// jumps over"},
|
||||
// ["c", "k"],
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_j(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown ˇfox
|
||||
// jumps over"},
|
||||
// ["c", "j"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// jumps ˇover"},
|
||||
// ["c", "j"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The qˇuick
|
||||
// brown fox
|
||||
// jumps over"},
|
||||
// ["c", "j"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// ˇ"},
|
||||
// ["c", "j"],
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_end_of_document(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brownˇ fox
|
||||
// jumps over
|
||||
// the lazy"},
|
||||
// ["c", "shift-g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brownˇ fox
|
||||
// jumps over
|
||||
// the lazy"},
|
||||
// ["c", "shift-g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// jumps over
|
||||
// the lˇazy"},
|
||||
// ["c", "shift-g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// jumps over
|
||||
// ˇ"},
|
||||
// ["c", "shift-g"],
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_change_gg(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brownˇ fox
|
||||
// jumps over
|
||||
// the lazy"},
|
||||
// ["c", "g", "g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The quick
|
||||
// brown fox
|
||||
// jumps over
|
||||
// the lˇazy"},
|
||||
// ["c", "g", "g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// The qˇuick
|
||||
// brown fox
|
||||
// jumps over
|
||||
// the lazy"},
|
||||
// ["c", "g", "g"],
|
||||
// )
|
||||
// .await;
|
||||
// cx.assert_neovim_compatible(
|
||||
// indoc! {"
|
||||
// ˇ
|
||||
// brown fox
|
||||
// jumps over
|
||||
// the lazy"},
|
||||
// ["c", "g", "g"],
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_repeated_cj(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// for count in 1..=5 {
|
||||
// cx.assert_binding_matches_all(
|
||||
// ["c", &count.to_string(), "j"],
|
||||
// indoc! {"
|
||||
// ˇThe quˇickˇ browˇn
|
||||
// ˇ
|
||||
// ˇfox ˇjumpsˇ-ˇoˇver
|
||||
// ˇthe lazy dog
|
||||
// "},
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_repeated_cl(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// for count in 1..=5 {
|
||||
// cx.assert_binding_matches_all(
|
||||
// ["c", &count.to_string(), "l"],
|
||||
// indoc! {"
|
||||
// ˇThe quˇickˇ browˇn
|
||||
// ˇ
|
||||
// ˇfox ˇjumpsˇ-ˇoˇver
|
||||
// ˇthe lazy dog
|
||||
// "},
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_repeated_cb(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// for count in 1..=5 {
|
||||
// for marked_text in cx.each_marked_position(indoc! {"
|
||||
// ˇThe quˇickˇ browˇn
|
||||
// ˇ
|
||||
// ˇfox ˇjumpsˇ-ˇoˇver
|
||||
// ˇthe lazy dog
|
||||
// "})
|
||||
// {
|
||||
// cx.assert_neovim_compatible(&marked_text, ["c", &count.to_string(), "b"])
|
||||
// .await;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_repeated_ce(cx: &mut gpui::TestAppContext) {
|
||||
// let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
||||
// for count in 1..=5 {
|
||||
// cx.assert_binding_matches_all(
|
||||
// ["c", &count.to_string(), "e"],
|
||||
// indoc! {"
|
||||
// ˇThe quˇickˇ browˇn
|
||||
// ˇ
|
||||
// ˇfox ˇjumpsˇ-ˇoˇver
|
||||
// ˇthe lazy dog
|
||||
// "},
|
||||
// )
|
||||
// .await;
|
||||
// }
|
||||
// }
|
||||
// }
|
Loading…
Add table
Add a link
Reference in a new issue