Cargo.lock 🔗
@@ -11423,6 +11423,7 @@ dependencies = [
"theme_selector2",
"ui2",
"util",
+ "vim2",
"workspace2",
]
Conrad Irwin created
- Uncomment editor event tests
- Uncomment vim search tests
Just command left
Release Notes:
- N/A
Cargo.lock | 1
crates/editor2/src/editor.rs | 1
crates/vim/src/editor_events.rs | 47 +++---
crates/vim2/src/editor_events.rs | 61 ++++---
crates/vim2/src/normal/search.rs | 260 +++++++++++++++++-----------------
crates/welcome2/Cargo.toml | 2
crates/welcome2/src/welcome.rs | 26 +-
7 files changed, 200 insertions(+), 198 deletions(-)
@@ -11423,6 +11423,7 @@ dependencies = [
"theme_selector2",
"ui2",
"util",
+ "vim2",
"workspace2",
]
@@ -2171,7 +2171,6 @@ impl Editor {
self.blink_manager.update(cx, BlinkManager::pause_blinking);
cx.emit(EditorEvent::SelectionsChanged { local });
- cx.emit(SearchEvent::MatchesInvalidated);
if self.selections.disjoint_anchors().len() == 1 {
cx.emit(SearchEvent::ActiveMatchChanged)
@@ -63,31 +63,30 @@ fn released(EditorReleased(editor): &EditorReleased, cx: &mut AppContext) {
});
}
-// #[cfg(test)]
-// mod test {
-// use crate::{test::VimTestContext, Vim};
-// use editor::Editor;
-// use gpui::View;
-// use language::Buffer;
+#[cfg(test)]
+mod test {
+ use crate::{test::VimTestContext, Vim};
+ use editor::Editor;
+ use gpui::View;
+ use language::Buffer;
-// // regression test for blur called with a different active editor
-// #[gpui::test]
-// async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
-// let mut cx = VimTestContext::new(cx, true).await;
+ // regression test for blur called with a different active editor
+ #[gpui::test]
+ async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
-// let buffer = cx.add_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
-// let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
-// let editor2 = cx.read(|cx| window2.root(cx)).unwrap();
+ let buffer = cx.add_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
+ let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
+ let editor2 = cx.read(|cx| window2.root(cx)).unwrap();
-// cx.update(|cx| {
-// let vim = Vim::read(cx);
-// assert_eq!(vim.active_editor.unwrap().id(), editor2.id())
-// });
+ cx.update(|cx| {
+ let vim = Vim::read(cx);
+ assert_eq!(vim.active_editor.unwrap().id(), editor2.id())
+ });
-// // no panic when blurring an editor in a different window.
-// cx.update_editor(|editor1, cx| {
-// todo!()
-// // editor1.focus_out(cx.handle().into_any(), cx);
-// });
-// }
-// }
+ // no panic when blurring an editor in a different window.
+ cx.update_editor(|editor1, cx| {
+ editor1.focus_out(cx.handle().into_any(), cx);
+ });
+ }
+}
@@ -65,35 +65,40 @@ fn released(entity_id: EntityId, cx: &mut WindowContext) {
});
}
-// #[cfg(test)]
-// mod test {
-// use crate::{test::VimTestContext, Vim};
-// use editor::Editor;
-// use gpui::{Context, Entity};
-// use language::Buffer;
+#[cfg(test)]
+mod test {
+ use crate::{test::VimTestContext, Vim};
+ use editor::Editor;
+ use gpui::{Context, Entity};
+ use language::Buffer;
-// // regression test for blur called with a different active editor
-// #[gpui::test]
-// async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
-// let mut cx = VimTestContext::new(cx, true).await;
+ // regression test for blur called with a different active editor
+ #[gpui::test]
+ async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
-// let buffer = cx.build_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
-// let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
-// let editor2 = cx
-// .update(|cx| window2.update(cx, |editor, cx| cx.view()))
-// .unwrap();
+ let buffer = cx.build_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
+ let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
+ let editor2 = cx
+ .update(|cx| {
+ window2.update(cx, |_, cx| {
+ cx.focus_self();
+ cx.view().clone()
+ })
+ })
+ .unwrap();
-// cx.update(|cx| {
-// let vim = Vim::read(cx);
-// assert_eq!(
-// vim.active_editor.unwrap().entity_id().unwrap(),
-// editor2.entity_id()
-// )
-// });
+ cx.update(|cx| {
+ let vim = Vim::read(cx);
+ assert_eq!(
+ vim.active_editor.as_ref().unwrap().entity_id(),
+ editor2.entity_id(),
+ )
+ });
-// // no panic when blurring an editor in a different window.
-// cx.update_editor(|editor1, cx| {
-// editor1.focus_out(cx.handle().into_any(), cx);
-// });
-// }
-// }
+ // no panic when blurring an editor in a different window.
+ cx.update_editor(|editor1, cx| {
+ editor1.handle_blur(cx);
+ });
+ }
+}
@@ -345,133 +345,133 @@ fn parse_replace_all(query: &str) -> Replacement {
replacement
}
-// #[cfg(test)]
-// mod test {
-// use editor::DisplayPoint;
-// use search::BufferSearchBar;
-
-// use crate::{state::Mode, test::VimTestContext};
-
-// #[gpui::test]
-// async fn test_move_to_next(cx: &mut gpui::TestAppContext) {
-// let mut cx = VimTestContext::new(cx, true).await;
-// cx.set_state("ˇhi\nhigh\nhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["*"]);
-// cx.run_until_parked();
-// cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["*"]);
-// cx.run_until_parked();
-// cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["#"]);
-// cx.run_until_parked();
-// cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["#"]);
-// cx.run_until_parked();
-// cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["2", "*"]);
-// cx.run_until_parked();
-// cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["g", "*"]);
-// cx.run_until_parked();
-// cx.assert_state("hi\nˇhigh\nhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["n"]);
-// cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
-
-// cx.simulate_keystrokes(["g", "#"]);
-// cx.run_until_parked();
-// cx.assert_state("hi\nˇhigh\nhi\n", Mode::Normal);
-// }
-
-// #[gpui::test]
-// async fn test_search(cx: &mut gpui::TestAppContext) {
-// let mut cx = VimTestContext::new(cx, true).await;
-
-// cx.set_state("aa\nbˇb\ncc\ncc\ncc\n", Mode::Normal);
-// cx.simulate_keystrokes(["/", "c", "c"]);
-
-// let search_bar = cx.workspace(|workspace, cx| {
-// workspace
-// .active_pane()
-// .read(cx)
-// .toolbar()
-// .read(cx)
-// .item_of_type::<BufferSearchBar>()
-// .expect("Buffer search bar should be deployed")
-// });
-
-// cx.update_view(search_bar, |bar, cx| {
-// assert_eq!(bar.query(cx), "cc");
-// });
-
-// cx.run_until_parked();
-
-// cx.update_editor(|editor, cx| {
-// let highlights = editor.all_text_background_highlights(cx);
-// assert_eq!(3, highlights.len());
-// assert_eq!(
-// DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),
-// highlights[0].0
-// )
-// });
-
-// cx.simulate_keystrokes(["enter"]);
-// cx.assert_state("aa\nbb\nˇcc\ncc\ncc\n", Mode::Normal);
-
-// // n to go to next/N to go to previous
-// cx.simulate_keystrokes(["n"]);
-// cx.assert_state("aa\nbb\ncc\nˇcc\ncc\n", Mode::Normal);
-// cx.simulate_keystrokes(["shift-n"]);
-// cx.assert_state("aa\nbb\nˇcc\ncc\ncc\n", Mode::Normal);
-
-// // ?<enter> to go to previous
-// cx.simulate_keystrokes(["?", "enter"]);
-// cx.assert_state("aa\nbb\ncc\ncc\nˇcc\n", Mode::Normal);
-// cx.simulate_keystrokes(["?", "enter"]);
-// cx.assert_state("aa\nbb\ncc\nˇcc\ncc\n", Mode::Normal);
-
-// // /<enter> to go to next
-// cx.simulate_keystrokes(["/", "enter"]);
-// cx.assert_state("aa\nbb\ncc\ncc\nˇcc\n", Mode::Normal);
-
-// // ?{search}<enter> to search backwards
-// cx.simulate_keystrokes(["?", "b", "enter"]);
-// cx.assert_state("aa\nbˇb\ncc\ncc\ncc\n", Mode::Normal);
-
-// // works with counts
-// cx.simulate_keystrokes(["4", "/", "c"]);
-// cx.simulate_keystrokes(["enter"]);
-// cx.assert_state("aa\nbb\ncc\ncˇc\ncc\n", Mode::Normal);
-
-// // check that searching resumes from cursor, not previous match
-// cx.set_state("ˇaa\nbb\ndd\ncc\nbb\n", Mode::Normal);
-// cx.simulate_keystrokes(["/", "d"]);
-// cx.simulate_keystrokes(["enter"]);
-// cx.assert_state("aa\nbb\nˇdd\ncc\nbb\n", Mode::Normal);
-// cx.update_editor(|editor, cx| editor.move_to_beginning(&Default::default(), cx));
-// cx.assert_state("ˇaa\nbb\ndd\ncc\nbb\n", Mode::Normal);
-// cx.simulate_keystrokes(["/", "b"]);
-// cx.simulate_keystrokes(["enter"]);
-// cx.assert_state("aa\nˇbb\ndd\ncc\nbb\n", Mode::Normal);
-// }
-
-// #[gpui::test]
-// async fn test_non_vim_search(cx: &mut gpui::TestAppContext) {
-// let mut cx = VimTestContext::new(cx, false).await;
-// cx.set_state("ˇone one one one", Mode::Normal);
-// cx.simulate_keystrokes(["cmd-f"]);
-// cx.run_until_parked();
-
-// cx.assert_editor_state("«oneˇ» one one one");
-// cx.simulate_keystrokes(["enter"]);
-// cx.assert_editor_state("one «oneˇ» one one");
-// cx.simulate_keystrokes(["shift-enter"]);
-// cx.assert_editor_state("«oneˇ» one one one");
-// }
-// }
+#[cfg(test)]
+mod test {
+ use editor::DisplayPoint;
+ use search::BufferSearchBar;
+
+ use crate::{state::Mode, test::VimTestContext};
+
+ #[gpui::test]
+ async fn test_move_to_next(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
+ cx.set_state("ˇhi\nhigh\nhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["*"]);
+ cx.run_until_parked();
+ cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["*"]);
+ cx.run_until_parked();
+ cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["#"]);
+ cx.run_until_parked();
+ cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["#"]);
+ cx.run_until_parked();
+ cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["2", "*"]);
+ cx.run_until_parked();
+ cx.assert_state("ˇhi\nhigh\nhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["g", "*"]);
+ cx.run_until_parked();
+ cx.assert_state("hi\nˇhigh\nhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["n"]);
+ cx.assert_state("hi\nhigh\nˇhi\n", Mode::Normal);
+
+ cx.simulate_keystrokes(["g", "#"]);
+ cx.run_until_parked();
+ cx.assert_state("hi\nˇhigh\nhi\n", Mode::Normal);
+ }
+
+ #[gpui::test]
+ async fn test_search(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
+
+ cx.set_state("aa\nbˇb\ncc\ncc\ncc\n", Mode::Normal);
+ cx.simulate_keystrokes(["/", "c", "c"]);
+
+ let search_bar = cx.workspace(|workspace, cx| {
+ workspace
+ .active_pane()
+ .read(cx)
+ .toolbar()
+ .read(cx)
+ .item_of_type::<BufferSearchBar>()
+ .expect("Buffer search bar should be deployed")
+ });
+
+ cx.update_view(search_bar, |bar, cx| {
+ assert_eq!(bar.query(cx), "cc");
+ });
+
+ cx.run_until_parked();
+
+ cx.update_editor(|editor, cx| {
+ let highlights = editor.all_text_background_highlights(cx);
+ assert_eq!(3, highlights.len());
+ assert_eq!(
+ DisplayPoint::new(2, 0)..DisplayPoint::new(2, 2),
+ highlights[0].0
+ )
+ });
+
+ cx.simulate_keystrokes(["enter"]);
+ cx.assert_state("aa\nbb\nˇcc\ncc\ncc\n", Mode::Normal);
+
+ // n to go to next/N to go to previous
+ cx.simulate_keystrokes(["n"]);
+ cx.assert_state("aa\nbb\ncc\nˇcc\ncc\n", Mode::Normal);
+ cx.simulate_keystrokes(["shift-n"]);
+ cx.assert_state("aa\nbb\nˇcc\ncc\ncc\n", Mode::Normal);
+
+ // ?<enter> to go to previous
+ cx.simulate_keystrokes(["?", "enter"]);
+ cx.assert_state("aa\nbb\ncc\ncc\nˇcc\n", Mode::Normal);
+ cx.simulate_keystrokes(["?", "enter"]);
+ cx.assert_state("aa\nbb\ncc\nˇcc\ncc\n", Mode::Normal);
+
+ // /<enter> to go to next
+ cx.simulate_keystrokes(["/", "enter"]);
+ cx.assert_state("aa\nbb\ncc\ncc\nˇcc\n", Mode::Normal);
+
+ // ?{search}<enter> to search backwards
+ cx.simulate_keystrokes(["?", "b", "enter"]);
+ cx.assert_state("aa\nbˇb\ncc\ncc\ncc\n", Mode::Normal);
+
+ // works with counts
+ cx.simulate_keystrokes(["4", "/", "c"]);
+ cx.simulate_keystrokes(["enter"]);
+ cx.assert_state("aa\nbb\ncc\ncˇc\ncc\n", Mode::Normal);
+
+ // check that searching resumes from cursor, not previous match
+ cx.set_state("ˇaa\nbb\ndd\ncc\nbb\n", Mode::Normal);
+ cx.simulate_keystrokes(["/", "d"]);
+ cx.simulate_keystrokes(["enter"]);
+ cx.assert_state("aa\nbb\nˇdd\ncc\nbb\n", Mode::Normal);
+ cx.update_editor(|editor, cx| editor.move_to_beginning(&Default::default(), cx));
+ cx.assert_state("ˇaa\nbb\ndd\ncc\nbb\n", Mode::Normal);
+ cx.simulate_keystrokes(["/", "b"]);
+ cx.simulate_keystrokes(["enter"]);
+ cx.assert_state("aa\nˇbb\ndd\ncc\nbb\n", Mode::Normal);
+ }
+
+ #[gpui::test]
+ async fn test_non_vim_search(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, false).await;
+ cx.set_state("ˇone one one one", Mode::Normal);
+ cx.simulate_keystrokes(["cmd-f"]);
+ cx.run_until_parked();
+
+ cx.assert_editor_state("«oneˇ» one one one");
+ cx.simulate_keystrokes(["enter"]);
+ cx.assert_editor_state("one «oneˇ» one one");
+ cx.simulate_keystrokes(["shift-enter"]);
+ cx.assert_editor_state("«oneˇ» one one one");
+ }
+}
@@ -26,7 +26,7 @@ theme_selector = { package = "theme_selector2", path = "../theme_selector2" }
util = { path = "../util" }
picker = { package = "picker2", path = "../picker2" }
workspace = { package = "workspace2", path = "../workspace2" }
-# vim = { package = "vim2", path = "../vim2" }
+vim = { package = "vim2", path = "../vim2" }
anyhow.workspace = true
log.workspace = true
@@ -11,6 +11,7 @@ use gpui::{
use settings::{Settings, SettingsStore};
use std::sync::Arc;
use ui::{prelude::*, Checkbox};
+use vim::VimModeSetting;
use workspace::{
dock::DockPosition,
item::{Item, ItemEvent},
@@ -128,29 +129,26 @@ impl Render for WelcomePage {
.border_color(cx.theme().colors().border)
.rounded_md()
.child(
- // todo!("vim setting")
h_stack()
.gap_2()
.child(
Checkbox::new(
"enable-vim",
- if false
- /* VimSettings::get_global(cx).enabled */
- {
+ if VimModeSetting::get_global(cx).0 {
ui::Selection::Selected
} else {
ui::Selection::Unselected
},
- ),
- // .on_click(cx.listener(
- // move |this, selection, cx| {
- // this.update_settings::<VimSettings>(
- // selection,
- // cx,
- // |settings, value| settings.enabled = value,
- // );
- // },
- // )),
+ )
+ .on_click(cx.listener(
+ move |this, selection, cx| {
+ this.update_settings::<VimModeSetting>(
+ selection,
+ cx,
+ |setting, value| *setting = Some(value),
+ );
+ },
+ )),
)
.child(Label::new("Enable vim mode")),
)