Detailed changes
@@ -1,5 +1,5 @@
use std::{
- ops::{Deref, DerefMut},
+ ops::{Deref, DerefMut, Range},
path::PathBuf,
};
@@ -145,10 +145,17 @@ impl<'a> NeovimBackedTestContext<'a> {
self.assertion_context.context()
);
- let zed_head = self.update_editor(|editor, cx| editor.selections.newest_display(cx).head());
+ let zed_selection = self.update_editor(|editor, cx| editor.selections.newest_display(cx));
+ let mut zed_selection_range = zed_selection.range();
+ // Zed selections adjust themselves to make the end point visually make sense
+ if zed_selection.reversed {
+ *zed_selection_range.end.column_mut() =
+ zed_selection_range.end.column().saturating_sub(1);
+ }
+ let neovim_selection = self.neovim.selection().await;
assert_eq!(
- self.neovim.head().await,
- zed_head,
+ neovim_selection,
+ zed_selection_range,
"{}",
self.assertion_context.context()
);
@@ -234,7 +241,7 @@ impl<'a> DerefMut for NeovimBackedTestContext<'a> {
#[derive(Serialize, Deserialize)]
pub enum NeovimData {
Text(String),
- Head { row: u32, column: u32 },
+ Selection { start: (u32, u32), end: (u32, u32) },
Mode(Option<Mode>),
}
@@ -267,6 +274,7 @@ impl NeovimConnection {
.await
.expect("Could not attach to ui");
+ // Makes system act a little more like zed in terms of indentation
nvim.set_option("smartindent", nvim_rs::Value::Boolean(true))
.await
.expect("Could not set smartindent on startup");
@@ -319,36 +327,64 @@ impl NeovimConnection {
}
#[cfg(feature = "neovim")]
- pub async fn head(&mut self) -> DisplayPoint {
- let nvim_row: u32 = self
- .nvim
- .command_output("echo line('.')")
- .await
- .unwrap()
- .parse::<u32>()
- .unwrap()
- - 1; // Neovim rows start at 1
- let nvim_column: u32 = self
- .nvim
- .command_output("echo col('.')")
- .await
- .unwrap()
- .parse::<u32>()
- .unwrap()
- - 1; // Neovim columns start at 1
+ pub async fn selection(&mut self) -> Range<DisplayPoint> {
+ let (start, end) = if let Some(Mode::Visual { .. }) = self.mode().await {
+ self.nvim
+ .input("<escape>")
+ .await
+ .expect("Could not exit visual mode");
+ let nvim_buffer = self
+ .nvim
+ .get_current_buf()
+ .await
+ .expect("Could not get neovim buffer");
+ let (start_row, start_col) = nvim_buffer
+ .get_mark("<")
+ .await
+ .expect("Could not get selection start");
+ let (end_row, end_col) = nvim_buffer
+ .get_mark(">")
+ .await
+ .expect("Could not get selection end");
+ self.nvim
+ .input("gv")
+ .await
+ .expect("Could not reselect visual selection");
+
+ (
+ (start_row as u32 - 1, start_col as u32),
+ (end_row as u32 - 1, end_col as u32),
+ )
+ } else {
+ let nvim_row: u32 = self
+ .nvim
+ .command_output("echo line('.')")
+ .await
+ .unwrap()
+ .parse::<u32>()
+ .unwrap()
+ - 1; // Neovim rows start at 1
+ let nvim_column: u32 = self
+ .nvim
+ .command_output("echo col('.')")
+ .await
+ .unwrap()
+ .parse::<u32>()
+ .unwrap()
+ - 1; // Neovim columns start at 1
+
+ ((nvim_row, nvim_column), (nvim_row, nvim_column))
+ };
- self.data.push_back(NeovimData::Head {
- row: nvim_row,
- column: nvim_column,
- });
+ self.data.push_back(NeovimData::Selection { start, end });
- DisplayPoint::new(nvim_row, nvim_column)
+ DisplayPoint::new(start.0, start.1)..DisplayPoint::new(end.0, end.1)
}
#[cfg(not(feature = "neovim"))]
- pub async fn head(&mut self) -> DisplayPoint {
- if let Some(NeovimData::Head { row, column }) = self.data.pop_front() {
- DisplayPoint::new(row, column)
+ pub async fn selection(&mut self) -> Range<DisplayPoint> {
+ if let Some(NeovimData::Selection { start, end }) = self.data.pop_front() {
+ DisplayPoint::new(start.0, start.1)..DisplayPoint::new(end.0, end.1)
} else {
panic!("Invalid test data. Is test deterministic? Try running with '--features neovim' to regenerate");
}
@@ -280,220 +280,92 @@ pub fn paste(_: &mut Workspace, _: &VisualPaste, cx: &mut ViewContext<Workspace>
mod test {
use indoc::indoc;
- use crate::{state::Mode, test_contexts::VimTestContext};
+ use crate::{
+ state::Mode,
+ test_contexts::{NeovimBackedTestContext, VimTestContext},
+ };
#[gpui::test]
async fn test_enter_visual_mode(cx: &mut gpui::TestAppContext) {
- let cx = VimTestContext::new(cx, true).await;
- let mut cx = cx
- .binding(["v", "w", "j"])
- .mode_after(Mode::Visual { line: false });
- cx.assert(
- indoc! {"
+ let mut cx = NeovimBackedTestContext::new(cx)
+ .await
+ .binding(["v", "w", "j"]);
+ cx.assert_all(indoc! {"
The ˇquick brown
- fox jumps over
- the lazy dog"},
- indoc! {"
- The «quick brown
- fox jumps ˇ»over
- the lazy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the ˇlazy dog"},
- indoc! {"
- The quick brown
- fox jumps over
- the «lazy ˇ»dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
fox jumps ˇover
- the lazy dog"},
- indoc! {"
- The quick brown
- fox jumps «over
- ˇ»the lazy dog"},
- );
- let mut cx = cx
- .binding(["v", "b", "k"])
- .mode_after(Mode::Visual { line: false });
- cx.assert(
- indoc! {"
+ the ˇlazy dog"})
+ .await;
+ let mut cx = cx.binding(["v", "b", "k"]);
+ cx.assert_all(indoc! {"
The ˇquick brown
- fox jumps over
- the lazy dog"},
- indoc! {"
- «ˇThe q»uick brown
- fox jumps over
- the lazy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the ˇlazy dog"},
- indoc! {"
- The quick brown
- «ˇfox jumps over
- the l»azy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
fox jumps ˇover
- the lazy dog"},
- indoc! {"
- The «ˇquick brown
- fox jumps o»ver
- the lazy dog"},
- );
+ the ˇlazy dog"})
+ .await;
}
#[gpui::test]
async fn test_visual_delete(cx: &mut gpui::TestAppContext) {
- let cx = VimTestContext::new(cx, true).await;
- let mut cx = cx.binding(["v", "w", "x"]);
- cx.assert("The quick ˇbrown", "The quickˇ ");
+ let mut cx = NeovimBackedTestContext::new(cx)
+ .await
+ .binding(["v", "w", "x"]);
+ cx.assert("The quick ˇbrown").await;
let mut cx = cx.binding(["v", "w", "j", "x"]);
- cx.assert(
- indoc! {"
+ cx.assert(indoc! {"
The ˇquick brown
fox jumps over
- the lazy dog"},
- indoc! {"
- The ˇver
- the lazy dog"},
- );
+ the lazy dog"})
+ .await;
// Test pasting code copied on delete
- cx.simulate_keystrokes(["j", "p"]);
- cx.assert_editor_state(indoc! {"
- The ver
- the lˇquick brown
- fox jumps oazy dog"});
+ cx.simulate_shared_keystrokes(["j", "p"]).await;
+ cx.assert_state_matches().await;
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the ˇlazy dog"},
- indoc! {"
- The quick brown
+ cx.assert_all(indoc! {"
+ The ˇquick brown
fox jumps over
- the ˇog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps ˇover
- the lazy dog"},
- indoc! {"
- The quick brown
- fox jumps ˇhe lazy dog"},
- );
+ the ˇlazy dog"})
+ .await;
let mut cx = cx.binding(["v", "b", "k", "x"]);
- cx.assert(
- indoc! {"
+ cx.assert_all(indoc! {"
The ˇquick brown
- fox jumps over
- the lazy dog"},
- indoc! {"
- ˇuick brown
- fox jumps over
- the lazy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the ˇlazy dog"},
- indoc! {"
- The quick brown
- ˇazy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
fox jumps ˇover
- the lazy dog"},
- indoc! {"
- The ˇver
- the lazy dog"},
- );
+ the ˇlazy dog"})
+ .await;
}
#[gpui::test]
async fn test_visual_line_delete(cx: &mut gpui::TestAppContext) {
- let cx = VimTestContext::new(cx, true).await;
- let mut cx = cx.binding(["shift-v", "x"]);
- cx.assert(
- indoc! {"
+ let mut cx = NeovimBackedTestContext::new(cx)
+ .await
+ .binding(["shift-v", "x"]);
+ cx.assert(indoc! {"
The quˇick brown
fox jumps over
- the lazy dog"},
- indoc! {"
- fox juˇmps over
- the lazy dog"},
- );
+ the lazy dog"})
+ .await;
// Test pasting code copied on delete
- cx.simulate_keystroke("p");
- cx.assert_editor_state(indoc! {"
- fox jumps over
- ˇThe quick brown
- the lazy dog"});
+ cx.simulate_shared_keystroke("p").await;
+ cx.assert_state_matches().await;
- cx.assert(
- indoc! {"
+ cx.assert_all(indoc! {"
The quick brown
fox juˇmps over
- the lazy dog"},
- indoc! {"
- The quick brown
- the laˇzy dog"},
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the laˇzy dog"},
- indoc! {"
- The quick brown
- fox juˇmps over"},
- );
+ the laˇzy dog"})
+ .await;
let mut cx = cx.binding(["shift-v", "j", "x"]);
- cx.assert(
- indoc! {"
+ cx.assert(indoc! {"
The quˇick brown
fox jumps over
- the lazy dog"},
- "the laˇzy dog",
- );
+ the lazy dog"})
+ .await;
// Test pasting code copied on delete
- cx.simulate_keystroke("p");
- cx.assert_editor_state(indoc! {"
- the lazy dog
- ˇThe quick brown
- fox jumps over"});
+ cx.simulate_shared_keystroke("p").await;
+ cx.assert_state_matches().await;
- cx.assert(
- indoc! {"
+ cx.assert_all(indoc! {"
The quick brown
fox juˇmps over
- the lazy dog"},
- "The quˇick brown",
- );
- cx.assert(
- indoc! {"
- The quick brown
- fox jumps over
- the laˇzy dog"},
- indoc! {"
- The quick brown
- fox juˇmps over"},
- );
+ the laˇzy dog"})
+ .await;
}
#[gpui::test]
@@ -1 +1 @@
-[{"Text":""},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"This is a test"},{"Head":{"row":0,"column":13}},{"Mode":"Normal"}]
+[{"Text":""},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"This is a test"},{"Mode":"Normal"},{"Selection":{"start":[0,13],"end":[0,13]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick"},{"Head":{"row":0,"column":6}},{"Mode":"Insert"},{"Text":"The quick"},{"Head":{"row":0,"column":9}},{"Mode":"Insert"}]
+[{"Text":"The quick"},{"Mode":"Insert"},{"Selection":{"start":[0,6],"end":[0,6]}},{"Mode":"Insert"},{"Text":"The quick"},{"Mode":"Insert"},{"Selection":{"start":[0,9],"end":[0,9]}},{"Mode":"Insert"}]
@@ -1 +1 @@
-[{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":4}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"}]
+[{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,4],"end":[0,4]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,8],"end":[0,8]}},{"Mode":"Normal"}]
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -0,0 +1 @@
@@ -1 +1 @@
-[{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":0,"column":5}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":0,"column":5}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"},{"Text":"\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"}]
+[{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,5],"end":[0,5]}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,5],"end":[0,5]}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,8],"end":[0,8]}},{"Mode":"Normal"},{"Text":"\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":4}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":0}},{"Mode":"Normal"}]
+[{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,4],"end":[0,4]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"\nThe quick\nbrown fox "},{"Head":{"row":0,"column":0}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox "},{"Head":{"row":1,"column":9}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox "},{"Head":{"row":2,"column":10}},{"Mode":"Insert"}]
+[{"Text":"\nThe quick\nbrown fox "},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox "},{"Mode":"Insert"},{"Selection":{"start":[1,9],"end":[1,9]}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox "},{"Mode":"Insert"},{"Selection":{"start":[2,10],"end":[2,10]}},{"Mode":"Insert"}]
@@ -1 +1 @@
-[{"Text":"\n"},{"Head":{"row":0,"column":0}},{"Mode":"Insert"},{"Text":"\nThe quick"},{"Head":{"row":0,"column":0}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox\njumps over"},{"Head":{"row":0,"column":0}},{"Mode":"Insert"},{"Text":"The quick\n\nbrown fox\njumps over"},{"Head":{"row":1,"column":0}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\n\njumps over"},{"Head":{"row":2,"column":0}},{"Mode":"Insert"},{"Text":"The quick\n\n\nbrown fox"},{"Head":{"row":1,"column":0}},{"Mode":"Insert"}]
+[{"Text":"\n"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"\nThe quick"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"\nThe quick\nbrown fox\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Insert"},{"Text":"The quick\n\nbrown fox\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"},{"Text":"The quick\nbrown fox\n\njumps over"},{"Mode":"Insert"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Insert"},{"Text":"The quick\n\n\nbrown fox"},{"Mode":"Insert"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Insert"}]
@@ -1 +1 @@
-[{"Text":"The quick brown\nfox jumps"},{"Head":{"row":1,"column":0}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Head":{"row":1,"column":5}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Head":{"row":1,"column":8}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Head":{"row":1,"column":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,5],"end":[1,5]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,8],"end":[1,8]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":3,"column":4}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":3,"column":4}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Head":{"row":3,"column":16}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown"},{"Head":{"row":2,"column":4}},{"Mode":"Normal"},{"Text":"The quick\n\n"},{"Head":{"row":2,"column":0}},{"Mode":"Normal"}]
+[{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[3,4],"end":[3,4]}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[3,4],"end":[3,4]}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown fox jumps\nover the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[3,16],"end":[3,16]}},{"Mode":"Normal"},{"Text":"The quick\n\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[2,4],"end":[2,4]}},{"Mode":"Normal"},{"Text":"The quick\n\n"},{"Mode":"Normal"},{"Selection":{"start":[2,0],"end":[2,0]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":4}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":4}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":0}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick\nbrown fox jumps"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Head":{"row":0,"column":5}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Head":{"row":0,"column":7}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"}]
+[{"Text":"The quick\nbrown fox jumps"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Mode":"Normal"},{"Selection":{"start":[0,5],"end":[0,5]}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Mode":"Normal"},{"Selection":{"start":[0,7],"end":[0,7]}},{"Mode":"Normal"},{"Text":"The quick\nbrown fox jumps"},{"Mode":"Normal"},{"Selection":{"start":[0,8],"end":[0,8]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":1}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":6}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":0,"column":8}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":1}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Head":{"row":1,"column":4}},{"Mode":"Normal"}]
+[{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,1],"end":[0,1]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,6],"end":[0,6]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[0,8],"end":[0,8]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[1,1],"end":[1,1]}},{"Mode":"Normal"},{"Text":"The quick\nbrown"},{"Mode":"Normal"},{"Selection":{"start":[1,4],"end":[1,4]}},{"Mode":"Normal"}]
@@ -1 +1 @@
-[{"Text":"test"},{"Head":{"row":0,"column":0}},{"Mode":"Normal"}]
+[{"Text":"test"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"}]
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -1 +1 @@
@@ -0,0 +1 @@
+[{"Text":"The quick "},{"Mode":"Normal"},{"Selection":{"start":[0,9],"end":[0,9]}},{"Mode":"Normal"},{"Text":"The ver\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,4],"end":[0,4]}},{"Mode":"Normal"},{"Text":"The ver\nthe lquick brown\nfox jumps oazy dog"},{"Mode":"Normal"},{"Selection":{"start":[1,5],"end":[1,5]}},{"Mode":"Normal"},{"Text":"The ver\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,4],"end":[0,4]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps over\nthe og"},{"Mode":"Normal"},{"Selection":{"start":[2,4],"end":[2,4]}},{"Mode":"Normal"},{"Text":"uick brown\nfox jumps over\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,0],"end":[0,0]}},{"Mode":"Normal"},{"Text":"The ver\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,4],"end":[0,4]}},{"Mode":"Normal"},{"Text":"The quick brown\nazy dog"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"}]
@@ -0,0 +1 @@
+[{"Text":"fox jumps over\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,6],"end":[0,6]}},{"Mode":"Normal"},{"Text":"fox jumps over\nThe quick brown\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"},{"Text":"The quick brown\nthe lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[1,6],"end":[1,6]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps over"},{"Mode":"Normal"},{"Selection":{"start":[1,6],"end":[1,6]}},{"Mode":"Normal"},{"Text":"the lazy dog"},{"Mode":"Normal"},{"Selection":{"start":[0,6],"end":[0,6]}},{"Mode":"Normal"},{"Text":"the lazy dog\nThe quick brown\nfox jumps over"},{"Mode":"Normal"},{"Selection":{"start":[1,0],"end":[1,0]}},{"Mode":"Normal"},{"Text":"The quick brown"},{"Mode":"Normal"},{"Selection":{"start":[0,6],"end":[0,6]}},{"Mode":"Normal"},{"Text":"The quick brown\nfox jumps over"},{"Mode":"Normal"},{"Selection":{"start":[1,6],"end":[1,6]}},{"Mode":"Normal"}]
@@ -1 +1 @@