wip
This commit is contained in:
parent
bef2013c7f
commit
eac33d732e
6 changed files with 73 additions and 109 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue