This commit is contained in:
Kay Simmons 2023-02-16 12:23:45 -08:00
parent bef2013c7f
commit eac33d732e
6 changed files with 73 additions and 109 deletions

View file

@ -385,9 +385,13 @@ impl MultiBuffer {
_ => Default::default(), _ => Default::default(),
}; };
#[allow(clippy::type_complexity)] struct BufferEdit {
let mut buffer_edits: HashMap<usize, Vec<(Range<usize>, Arc<str>, bool, u32)>> = range: Range<usize>,
Default::default(); new_text: Arc<str>,
is_insertion: bool,
original_indent_column: u32,
}
let mut buffer_edits: HashMap<usize, Vec<BufferEdit>> = Default::default();
let mut cursor = snapshot.excerpts.cursor::<usize>(); let mut cursor = snapshot.excerpts.cursor::<usize>();
for (ix, (range, new_text)) in edits.enumerate() { for (ix, (range, new_text)) in edits.enumerate() {
let new_text: Arc<str> = new_text.into(); let new_text: Arc<str> = new_text.into();
@ -422,12 +426,12 @@ impl MultiBuffer {
buffer_edits buffer_edits
.entry(start_excerpt.buffer_id) .entry(start_excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
.push(( .push(BufferEdit {
buffer_start..buffer_end, range: buffer_start..buffer_end,
new_text, new_text,
true, is_insertion: true,
original_indent_column, original_indent_column,
)); });
} else { } else {
let start_excerpt_range = buffer_start let start_excerpt_range = buffer_start
..start_excerpt ..start_excerpt
@ -444,21 +448,21 @@ impl MultiBuffer {
buffer_edits buffer_edits
.entry(start_excerpt.buffer_id) .entry(start_excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
.push(( .push(BufferEdit {
start_excerpt_range, range: start_excerpt_range,
new_text.clone(), new_text: new_text.clone(),
true, is_insertion: true,
original_indent_column, original_indent_column,
)); });
buffer_edits buffer_edits
.entry(end_excerpt.buffer_id) .entry(end_excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
.push(( .push(BufferEdit {
end_excerpt_range, range: end_excerpt_range,
new_text.clone(), new_text: new_text.clone(),
false, is_insertion: false,
original_indent_column, original_indent_column,
)); });
cursor.seek(&range.start, Bias::Right, &()); cursor.seek(&range.start, Bias::Right, &());
cursor.next(&()); cursor.next(&());
@ -469,19 +473,19 @@ impl MultiBuffer {
buffer_edits buffer_edits
.entry(excerpt.buffer_id) .entry(excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
.push(( .push(BufferEdit {
excerpt.range.context.to_offset(&excerpt.buffer), range: excerpt.range.context.to_offset(&excerpt.buffer),
new_text.clone(), new_text: new_text.clone(),
false, is_insertion: false,
original_indent_column, original_indent_column,
)); });
cursor.next(&()); cursor.next(&());
} }
} }
} }
for (buffer_id, mut edits) in buffer_edits { for (buffer_id, mut edits) in buffer_edits {
edits.sort_unstable_by_key(|(range, _, _, _)| range.start); edits.sort_unstable_by_key(|edit| edit.range.start);
self.buffers.borrow()[&buffer_id] self.buffers.borrow()[&buffer_id]
.buffer .buffer
.update(cx, |buffer, cx| { .update(cx, |buffer, cx| {
@ -490,14 +494,19 @@ impl MultiBuffer {
let mut original_indent_columns = Vec::new(); let mut original_indent_columns = Vec::new();
let mut deletions = Vec::new(); let mut deletions = Vec::new();
let empty_str: Arc<str> = "".into(); let empty_str: Arc<str> = "".into();
while let Some(( while let Some(BufferEdit {
mut range, mut range,
new_text, new_text,
mut is_insertion, mut is_insertion,
original_indent_column, original_indent_column,
)) = edits.next() }) = edits.next()
{ {
while let Some((next_range, _, next_is_insertion, _)) = edits.peek() { while let Some(BufferEdit {
range: next_range,
is_insertion: next_is_insertion,
..
}) = edits.peek()
{
if range.end >= next_range.start { if range.end >= next_range.start {
range.end = cmp::max(next_range.end, range.end); range.end = cmp::max(next_range.end, range.end);
is_insertion |= *next_is_insertion; is_insertion |= *next_is_insertion;

View file

@ -122,7 +122,26 @@ impl<'a> EditorLspTestContext<'a> {
..Default::default() ..Default::default()
}, },
Some(tree_sitter_rust::language()), Some(tree_sitter_rust::language()),
); )
.with_queries(LanguageQueries {
indents: Some(Cow::from(indoc! {r#"
[
((where_clause) _ @end)
(field_expression)
(call_expression)
(assignment_expression)
(let_declaration)
(let_chain)
(await_expression)
] @indent
(_ "[" "]" @end) @indent
(_ "<" ">" @end) @indent
(_ "{" "}" @end) @indent
(_ "(" ")" @end) @indent"#})),
..Default::default()
})
.expect("Could not parse queries");
Self::new(language, capabilities, cx).await Self::new(language, capabilities, cx).await
} }
@ -148,7 +167,7 @@ impl<'a> EditorLspTestContext<'a> {
("\"" @open "\"" @close)"#})), ("\"" @open "\"" @close)"#})),
..Default::default() ..Default::default()
}) })
.expect("Could not parse brackets"); .expect("Could not parse queries");
Self::new(language, capabilities, cx).await Self::new(language, capabilities, cx).await
} }

View file

@ -1389,12 +1389,12 @@ impl Buffer {
.enumerate() .enumerate()
.zip(&edit_operation.as_edit().unwrap().new_text) .zip(&edit_operation.as_edit().unwrap().new_text)
.map(|((ix, (range, _)), new_text)| { .map(|((ix, (range, _)), new_text)| {
let new_text_len = new_text.len(); let new_text_length = new_text.len();
let old_start = range.start.to_point(&before_edit); let old_start = range.start.to_point(&before_edit);
let new_start = (delta + range.start as isize) as usize; let new_start = (delta + range.start as isize) as usize;
delta += new_text_len as isize - (range.end as isize - range.start as isize); delta += new_text_length as isize - (range.end as isize - range.start as isize);
let mut range_of_insertion_to_indent = 0..new_text_len; let mut range_of_insertion_to_indent = 0..new_text_length;
let mut first_line_is_new = false; let mut first_line_is_new = false;
let mut original_indent_column = None; let mut original_indent_column = None;

View file

@ -857,13 +857,15 @@ mod test {
// Our indentation is smarter than vims. So we don't match here // Our indentation is smarter than vims. So we don't match here
cx.assert_manual( cx.assert_manual(
indoc! {" indoc! {"
fn test() fn test() {
println!(ˇ);"}, println!(ˇ);
}"},
Mode::Normal, Mode::Normal,
indoc! {" indoc! {"
fn test() fn test() {
ˇ ˇ
println!();"}, println!();
}"},
Mode::Insert, Mode::Insert,
); );
cx.assert_manual( cx.assert_manual(

View file

@ -3,10 +3,8 @@ use std::ops::{Deref, DerefMut};
use editor::test::{ use editor::test::{
editor_lsp_test_context::EditorLspTestContext, editor_test_context::EditorTestContext, editor_lsp_test_context::EditorLspTestContext, editor_test_context::EditorTestContext,
}; };
use gpui::{json::json, AppContext, ContextHandle, ViewHandle}; use gpui::{AppContext, ContextHandle};
use project::Project;
use search::{BufferSearchBar, ProjectSearchBar}; use search::{BufferSearchBar, ProjectSearchBar};
use workspace::{pane, AppState, WorkspaceHandle};
use crate::{state::Operator, *}; use crate::{state::Operator, *};
@ -14,56 +12,29 @@ use super::VimBindingTestContext;
pub struct VimTestContext<'a> { pub struct VimTestContext<'a> {
cx: EditorLspTestContext<'a>, cx: EditorLspTestContext<'a>,
workspace: ViewHandle<Workspace>,
} }
impl<'a> VimTestContext<'a> { impl<'a> VimTestContext<'a> {
pub async fn new(cx: &'a mut gpui::TestAppContext, enabled: bool) -> VimTestContext<'a> { pub async fn new(cx: &'a mut gpui::TestAppContext, enabled: bool) -> VimTestContext<'a> {
cx.update(|cx| { cx.update(|cx| {
editor::init(cx);
pane::init(cx);
search::init(cx); search::init(cx);
crate::init(cx); crate::init(cx);
settings::KeymapFileContent::load("keymaps/vim.json", cx).unwrap(); settings::KeymapFileContent::load("keymaps/vim.json", cx).unwrap();
}); });
let mut cx = EditorLspTestContext::new_rust(Default::default(), cx).await;
cx.update(|cx| { cx.update(|cx| {
cx.update_global(|settings: &mut Settings, _| { cx.update_global(|settings: &mut Settings, _| {
settings.vim_mode = enabled; settings.vim_mode = enabled;
}); });
}); });
let params = cx.update(AppState::test); let window_id = cx.window_id;
let file_name = "test.rs";
let mut fake_servers = language
.set_fake_lsp_adapter(Arc::new(FakeLspAdapter {
..Default::default()
}))
.await;
let project = Project::test(params.fs.clone(), [], cx).await;
project.update(cx, |project, _| project.languages().add(Arc::new(language)));
params
.fs
.as_fake()
.insert_tree("/root", json!({ "dir": { "test.rs": "" } }))
.await;
let (window_id, workspace) = cx.add_window(|cx| {
Workspace::new(
Default::default(),
0,
project.clone(),
|_, _| unimplemented!(),
cx,
)
});
// Setup search toolbars and keypress hook // Setup search toolbars and keypress hook
workspace.update(cx, |workspace, cx| { cx.update_workspace(|workspace, cx| {
observe_keystrokes(window_id, cx); observe_keystrokes(window_id, cx);
workspace.active_pane().update(cx, |pane, cx| { workspace.active_pane().update(cx, |pane, cx| {
pane.toolbar().update(cx, |toolbar, cx| { pane.toolbar().update(cx, |toolbar, cx| {
@ -75,51 +46,14 @@ impl<'a> VimTestContext<'a> {
}); });
}); });
project Self { cx }
.update(cx, |project, cx| {
project.find_or_create_local_worktree("/root", true, cx)
})
.await
.unwrap();
cx.read(|cx| workspace.read(cx).worktree_scans_complete(cx))
.await;
let file = cx.read(|cx| workspace.file_project_paths(cx)[0].clone());
let item = workspace
.update(cx, |workspace, cx| {
workspace.open_path(file, None, true, cx)
})
.await
.expect("Could not open test file");
let editor = cx.update(|cx| {
item.act_as::<Editor>(cx)
.expect("Opened test file wasn't an editor")
});
editor.update(cx, |_, cx| cx.focus_self());
let lsp = fake_servers.next().await.unwrap();
Self {
cx: EditorLspTestContext {
cx: EditorTestContext {
cx,
window_id,
editor,
},
lsp,
workspace,
buffer_lsp_url: lsp::Url::from_file_path("/root/dir/file.rs").unwrap(),
},
workspace,
}
} }
pub fn workspace<F, T>(&mut self, read: F) -> T pub fn workspace<F, T>(&mut self, read: F) -> T
where where
F: FnOnce(&Workspace, &AppContext) -> T, F: FnOnce(&Workspace, &AppContext) -> T,
{ {
self.workspace.read_with(self.cx.cx.cx, read) self.cx.workspace.read_with(self.cx.cx.cx, read)
} }
pub fn enable_vim(&mut self) { pub fn enable_vim(&mut self) {

View file

@ -650,7 +650,7 @@ mod test {
The quick brown The quick brown
the the
ˇfox jumps over ˇfox jumps over
dog"}, dog"},
Mode::Normal, Mode::Normal,
); );
} }