Add some tests for portions of visual text objects. Note: they are slightly broken currently as described in the tests

This commit is contained in:
K Simmons 2022-10-10 15:32:12 -07:00
parent d2494822b0
commit 6a237deb21
14 changed files with 111 additions and 61 deletions

View file

@ -44,7 +44,7 @@ fn object(object: Object, cx: &mut MutableAppContext) {
}
impl Object {
pub fn object_range(
pub fn range(
self,
map: &DisplaySnapshot,
relative_to: DisplayPoint,
@ -68,7 +68,7 @@ impl Object {
selection: &mut Selection<DisplayPoint>,
around: bool,
) {
let range = self.object_range(map, selection.head(), around);
let range = self.range(map, selection.head(), around);
selection.start = range.start;
selection.end = range.end;
}
@ -328,43 +328,58 @@ mod test {
"};
#[gpui::test]
async fn test_change_in_word(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["c", "i", "w"]);
cx.assert_all(WORD_LOCATIONS).await;
let mut cx = cx.consume().binding(["c", "i", "shift-w"]);
cx.assert_all(WORD_LOCATIONS).await;
async fn test_change_word_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.assert_binding_matches_all(["c", "i", "w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["c", "i", "shift-w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["c", "a", "w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["c", "a", "shift-w"], WORD_LOCATIONS)
.await;
}
#[gpui::test]
async fn test_delete_in_word(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["d", "i", "w"]);
cx.assert_all(WORD_LOCATIONS).await;
let mut cx = cx.consume().binding(["d", "i", "shift-w"]);
cx.assert_all(WORD_LOCATIONS).await;
async fn test_delete_word_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.assert_binding_matches_all(["d", "i", "w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["d", "i", "shift-w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["d", "a", "w"], WORD_LOCATIONS)
.await;
cx.assert_binding_matches_all(["d", "a", "shift-w"], WORD_LOCATIONS)
.await;
}
#[gpui::test]
async fn test_change_around_word(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["c", "a", "w"]);
cx.assert_all(WORD_LOCATIONS).await;
let mut cx = cx.consume().binding(["c", "a", "shift-w"]);
cx.assert_all(WORD_LOCATIONS).await;
}
async fn test_visual_word_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
#[gpui::test]
async fn test_delete_around_word(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["d", "a", "w"]);
cx.assert_all(WORD_LOCATIONS).await;
let mut cx = cx.consume().binding(["d", "a", "shift-w"]);
cx.assert_all(WORD_LOCATIONS).await;
cx.assert_binding_matches_all(["v", "i", "w"], WORD_LOCATIONS)
.await;
// Visual text objects are slightly broken when used with non empty selections
// cx.assert_binding_matches_all(["v", "h", "i", "w"], WORD_LOCATIONS)
// .await;
// cx.assert_binding_matches_all(["v", "l", "i", "w"], WORD_LOCATIONS)
// .await;
cx.assert_binding_matches_all(["v", "i", "shift-w"], WORD_LOCATIONS)
.await;
// Visual text objects are slightly broken when used with non empty selections
// cx.assert_binding_matches_all(["v", "i", "h", "shift-w"], WORD_LOCATIONS)
// .await;
// cx.assert_binding_matches_all(["v", "i", "l", "shift-w"], WORD_LOCATIONS)
// .await;
// Visual around words is somewhat broken right now when it comes to newlines
// cx.assert_binding_matches_all(["v", "a", "w"], WORD_LOCATIONS)
// .await;
// cx.assert_binding_matches_all(["v", "a", "shift-w"], WORD_LOCATIONS)
// .await;
}
const SENTENCE_EXAMPLES: &[&'static str] = &[
@ -390,32 +405,35 @@ mod test {
];
#[gpui::test]
async fn test_change_in_sentence(cx: &mut gpui::TestAppContext) {
async fn test_change_sentence_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["c", "i", "s"]);
for sentence_example in SENTENCE_EXAMPLES {
cx.assert_all(sentence_example).await;
}
let mut cx = cx.binding(["c", "a", "s"]);
// Resulting position is slightly incorrect for unintuitive reasons.
cx.add_initial_state_exemption("The quick brown?ˇ Fox Jumps! Over the lazy.");
// Changing around the sentence at the end of the line doesn't remove whitespace.'
cx.add_initial_state_exemption("The quick brown.)]\'\" Brown fox jumps.ˇ ");
for sentence_example in SENTENCE_EXAMPLES {
cx.assert_all(sentence_example).await;
}
}
#[gpui::test]
async fn test_delete_in_sentence(cx: &mut gpui::TestAppContext) {
async fn test_delete_sentence_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["d", "i", "s"]);
for sentence_example in SENTENCE_EXAMPLES {
cx.assert_all(sentence_example).await;
}
}
#[gpui::test]
async fn test_change_around_sentence(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["c", "a", "s"]);
let mut cx = cx.binding(["d", "a", "s"]);
// Resulting position is slightly incorrect for unintuitive reasons.
cx.add_initial_state_exemption("The quick brown?ˇ Fox Jumps! Over the lazy.");
// Changing around the sentence at the end of the line doesn't remove whitespace.'
@ -427,18 +445,18 @@ mod test {
}
#[gpui::test]
async fn test_delete_around_sentence(cx: &mut gpui::TestAppContext) {
async fn test_visual_sentence_object(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx)
.await
.binding(["d", "a", "s"]);
// Resulting position is slightly incorrect for unintuitive reasons.
cx.add_initial_state_exemption("The quick brown?ˇ Fox Jumps! Over the lazy.");
// Changing around the sentence at the end of the line doesn't remove whitespace.'
cx.add_initial_state_exemption("The quick brown.)]\'\" Brown fox jumps.ˇ ");
.binding(["v", "i", "s"]);
for sentence_example in SENTENCE_EXAMPLES {
cx.assert_all(sentence_example).await;
}
// Visual around sentences is somewhat broken right now when it comes to newlines
// let mut cx = cx.binding(["d", "a", "s"]);
// for sentence_example in SENTENCE_EXAMPLES {
// cx.assert_all(sentence_example).await;
// }
}
}

View file

@ -26,6 +26,7 @@ async fn test_neovim(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.simulate_shared_keystroke("i").await;
cx.assert_state_matches().await;
cx.simulate_shared_keystrokes([
"shift-T", "e", "s", "t", " ", "t", "e", "s", "t", "escape", "0", "d", "w",
])

View file

@ -6,7 +6,13 @@ use gpui::{actions, MutableAppContext, ViewContext};
use language::{AutoindentMode, SelectionGoal};
use workspace::Workspace;
use crate::{motion::Motion, object::Object, state::Mode, utils::copy_selections_content, Vim};
use crate::{
motion::Motion,
object::Object,
state::{Mode, Operator},
utils::copy_selections_content,
Vim,
};
actions!(vim, [VisualDelete, VisualChange, VisualYank, VisualPaste]);
@ -47,7 +53,34 @@ pub fn visual_motion(motion: Motion, times: usize, cx: &mut MutableAppContext) {
});
}
pub fn visual_object(_object: Object, _cx: &mut MutableAppContext) {}
pub fn visual_object(object: Object, cx: &mut MutableAppContext) {
Vim::update(cx, |vim, cx| {
if let Operator::Object { around } = vim.pop_operator(cx) {
vim.update_active_editor(cx, |editor, cx| {
editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
s.move_with(|map, selection| {
let head = selection.head();
let mut range = object.range(map, head, around);
if !range.is_empty() {
if let Some((_, end)) = map.reverse_chars_at(range.end).next() {
range.end = end;
}
if selection.is_empty() {
selection.start = range.start;
selection.end = range.end;
} else if selection.reversed {
selection.start = range.start;
} else {
selection.end = range.end;
}
}
})
});
});
}
});
}
pub fn change(_: &mut Workspace, _: &VisualChange, cx: &mut ViewContext<Workspace>) {
Vim::update(cx, |vim, cx| {

View file

@ -1 +0,0 @@
[{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Insert"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Insert"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Insert"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Insert"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Insert"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Insert"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Insert"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Insert"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Insert"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Insert"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Insert"},{"Selection":{"start":[0,27],"end":[0,27]}},{"Mode":"Insert"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Insert"},{"Selection":{"start":[2,13],"end":[2,13]}},{"Mode":"Insert"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Insert"},{"Selection":{"start":[2,13],"end":[2,13]}},{"Mode":"Insert"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Insert"},{"Selection":{"start":[2,13],"end":[2,13]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"Brown fox jumps. "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick brown.)]'\" "},{"Mode":"Insert"},{"Selection":{"start":[0,21],"end":[0,21]}},{"Mode":"Insert"},{"Text":"The quick brown.)]'\" "},{"Mode":"Insert"},{"Selection":{"start":[0,21],"end":[0,21]}},{"Mode":"Insert"}]

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
[{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Fox Jumps! Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Normal"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Normal"},{"Text":"The quick brown? Over the lazy."},{"Mode":"Normal"},{"Selection":{"start":[0,17],"end":[0,17]}},{"Mode":"Normal"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Normal"},{"Selection":{"start":[0,26],"end":[0,26]}},{"Mode":"Normal"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Normal"},{"Selection":{"start":[0,26],"end":[0,26]}},{"Mode":"Normal"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Normal"},{"Selection":{"start":[0,26],"end":[0,26]}},{"Mode":"Normal"},{"Text":"The quick brown? Fox Jumps!"},{"Mode":"Normal"},{"Selection":{"start":[0,26],"end":[0,26]}},{"Mode":"Normal"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick \nbrown fox jumps over\n"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Normal"},{"Selection":{"start":[2,12],"end":[2,12]}},{"Mode":"Normal"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Normal"},{"Selection":{"start":[2,12],"end":[2,12]}},{"Mode":"Normal"},{"Text":"The quick brown \nfox jumps over\nthe lazy dog.\n"},{"Mode":"Normal"},{"Selection":{"start":[2,12],"end":[2,12]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"Brown fox jumps. "},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick brown.)]'\" "},{"Mode":"Normal"},{"Selection":{"start":[0,20],"end":[0,20]}},{"Mode":"Normal"},{"Text":"The quick brown.)]'\" "},{"Mode":"Normal"},{"Selection":{"start":[0,20],"end":[0,20]}},{"Mode":"Normal"}]

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
[{"Text":"test"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"}]
[{"Text":""},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"test"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long