mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Add test for go-to hunk and fix discovered bugs
This commit is contained in:
parent
ae2021e073
commit
8361b4d47a
8 changed files with 145 additions and 72 deletions
|
@ -5258,6 +5258,7 @@ impl Editor {
|
|||
this: &mut Editor,
|
||||
snapshot: &DisplaySnapshot,
|
||||
initial_point: Point,
|
||||
is_wrapped: bool,
|
||||
direction: Direction,
|
||||
cx: &mut ViewContext<Editor>,
|
||||
) -> bool {
|
||||
|
@ -5274,12 +5275,18 @@ impl Editor {
|
|||
let display_point = initial_point.to_display_point(snapshot);
|
||||
let mut hunks = hunks
|
||||
.map(|hunk| diff_hunk_to_display(hunk, &snapshot))
|
||||
.skip_while(|hunk| hunk.display_row_range().contains(&display_point.row()))
|
||||
.skip_while(|hunk| {
|
||||
if is_wrapped {
|
||||
false
|
||||
} else {
|
||||
hunk.contains_display_row(display_point.row())
|
||||
}
|
||||
})
|
||||
.dedup();
|
||||
|
||||
if let Some(hunk) = hunks.next() {
|
||||
this.change_selections(Some(Autoscroll::Center), cx, |s| {
|
||||
let row = hunk.display_row_range().start;
|
||||
let row = hunk.start_display_row();
|
||||
let point = DisplayPoint::new(row, 0);
|
||||
s.select_display_ranges([point..point]);
|
||||
});
|
||||
|
@ -5290,12 +5297,12 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
if !seek_in_direction(self, &snapshot, selection.head(), direction, cx) {
|
||||
if !seek_in_direction(self, &snapshot, selection.head(), false, direction, cx) {
|
||||
let wrapped_point = match direction {
|
||||
Direction::Next => Point::zero(),
|
||||
Direction::Prev => snapshot.buffer_snapshot.max_point(),
|
||||
};
|
||||
seek_in_direction(self, &snapshot, wrapped_point, direction, cx);
|
||||
seek_in_direction(self, &snapshot, wrapped_point, true, direction, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ use unindent::Unindent;
|
|||
|
||||
use super::*;
|
||||
use crate::test::{
|
||||
assert_text_with_selections, build_editor, editor_git_test_context::EditorGitTestContext,
|
||||
editor_lsp_test_context::EditorLspTestContext, editor_test_context::EditorTestContext,
|
||||
select_ranges,
|
||||
assert_text_with_selections, build_editor, editor_lsp_test_context::EditorLspTestContext,
|
||||
editor_test_context::EditorTestContext, select_ranges,
|
||||
};
|
||||
use gpui::{
|
||||
executor::Deterministic,
|
||||
geometry::rect::RectF,
|
||||
platform::{WindowBounds, WindowOptions},
|
||||
};
|
||||
|
@ -5081,8 +5081,108 @@ fn test_combine_syntax_and_fuzzy_match_highlights() {
|
|||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn go_to_hunk(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorGitTestContext::new(cx);
|
||||
async fn go_to_hunk(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = EditorTestContext::new(cx);
|
||||
|
||||
let diff_base = r#"
|
||||
use some::mod;
|
||||
|
||||
const A: u32 = 42;
|
||||
|
||||
fn main() {
|
||||
println!("hello");
|
||||
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent();
|
||||
|
||||
// Edits are modified, removed, modified, added
|
||||
cx.set_state(
|
||||
&r#"
|
||||
use some::modified;
|
||||
|
||||
ˇ
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.set_diff_base(Some(&diff_base));
|
||||
deterministic.run_until_parked();
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
//Wrap around the bottom of the buffer
|
||||
for _ in 0..3 {
|
||||
editor.go_to_hunk(&GoToHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
ˇuse some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
//Wrap around the top of the buffer
|
||||
for _ in 0..2 {
|
||||
editor.go_to_prev_hunk(&GoToPrevHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
use some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
ˇ println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, cx| {
|
||||
editor.fold(&Fold, cx);
|
||||
|
||||
//Make sure that the fold only gets one hunk
|
||||
for _ in 0..4 {
|
||||
editor.go_to_hunk(&GoToHunk, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.assert_editor_state(
|
||||
&r#"
|
||||
ˇuse some::modified;
|
||||
|
||||
|
||||
fn main() {
|
||||
println!("hello there");
|
||||
|
||||
println!("around the");
|
||||
println!("world");
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||
|
|
|
@ -21,14 +21,32 @@ pub enum DisplayDiffHunk {
|
|||
}
|
||||
|
||||
impl DisplayDiffHunk {
|
||||
pub fn display_row_range(&self) -> Range<u32> {
|
||||
pub fn start_display_row(&self) -> u32 {
|
||||
match self {
|
||||
&DisplayDiffHunk::Folded { display_row } => display_row..display_row + 1,
|
||||
&DisplayDiffHunk::Folded { display_row } => display_row,
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range, ..
|
||||
} => display_row_range.clone(),
|
||||
} => display_row_range.start,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_display_row(&self, display_row: u32) -> bool {
|
||||
let range = match self {
|
||||
&DisplayDiffHunk::Folded { display_row } => display_row..=display_row,
|
||||
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range, ..
|
||||
} => {
|
||||
if display_row_range.len() == 0 {
|
||||
display_row_range.start..=display_row_range.end
|
||||
} else {
|
||||
display_row_range.start..=display_row_range.end - 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
range.contains(&display_row)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn diff_hunk_to_display(hunk: DiffHunk<u32>, snapshot: &DisplaySnapshot) -> DisplayDiffHunk {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
pub mod editor_git_test_context;
|
||||
pub mod editor_lsp_test_context;
|
||||
pub mod editor_test_context;
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use gpui::ModelHandle;
|
||||
use language::Buffer;
|
||||
use settings::Settings;
|
||||
|
||||
use crate::MultiBuffer;
|
||||
|
||||
use super::{build_editor, editor_test_context::EditorTestContext};
|
||||
|
||||
pub struct EditorGitTestContext<'a> {
|
||||
pub cx: EditorTestContext<'a>,
|
||||
pub buffer: ModelHandle<Buffer>,
|
||||
}
|
||||
|
||||
impl<'a> EditorGitTestContext<'a> {
|
||||
pub async fn new(cx: &'a mut gpui::TestAppContext) -> EditorGitTestContext<'a> {
|
||||
let (window_id, buffer, editor) = cx.update(|cx| {
|
||||
cx.set_global(Settings::test(cx));
|
||||
crate::init(cx);
|
||||
|
||||
let buffer = cx.add_model(|cx| Buffer::new(0, "", cx));
|
||||
let multibuffer = cx.add_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
||||
|
||||
let (window_id, editor) =
|
||||
cx.add_window(Default::default(), |cx| build_editor(multibuffer, cx));
|
||||
|
||||
editor.update(cx, |_, cx| cx.focus_self());
|
||||
|
||||
(window_id, buffer, editor)
|
||||
});
|
||||
|
||||
Self {
|
||||
cx: EditorTestContext {
|
||||
cx,
|
||||
window_id,
|
||||
editor,
|
||||
},
|
||||
buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for EditorGitTestContext<'a> {
|
||||
type Target = EditorTestContext<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.cx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut for EditorGitTestContext<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.cx
|
||||
}
|
||||
}
|
|
@ -151,6 +151,11 @@ impl<'a> EditorTestContext<'a> {
|
|||
snapshot.anchor_before(ranges[0].start)..snapshot.anchor_after(ranges[0].end)
|
||||
}
|
||||
|
||||
pub fn set_diff_base(&mut self, diff_base: Option<&str>) {
|
||||
let diff_base = diff_base.map(String::from);
|
||||
self.update_buffer(|buffer, cx| buffer.set_diff_base(diff_base, cx));
|
||||
}
|
||||
|
||||
/// Change the editor's text and selections using a string containing
|
||||
/// embedded range markers that represent the ranges and directions of
|
||||
/// each selection.
|
||||
|
|
|
@ -681,7 +681,7 @@ impl Buffer {
|
|||
self.diff_base.as_deref()
|
||||
}
|
||||
|
||||
pub fn update_diff_base(&mut self, diff_base: Option<String>, cx: &mut ModelContext<Self>) {
|
||||
pub fn set_diff_base(&mut self, diff_base: Option<String>, cx: &mut ModelContext<Self>) {
|
||||
self.diff_base = diff_base;
|
||||
self.git_diff_recalc(cx);
|
||||
}
|
||||
|
|
|
@ -4410,7 +4410,7 @@ impl Project {
|
|||
.await;
|
||||
|
||||
let buffer_id = buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.update_diff_base(diff_base.clone(), cx);
|
||||
buffer.set_diff_base(diff_base.clone(), cx);
|
||||
buffer.remote_id()
|
||||
});
|
||||
|
||||
|
@ -4968,7 +4968,7 @@ impl Project {
|
|||
.and_then(|b| b.upgrade(cx))
|
||||
.ok_or_else(|| anyhow!("No such buffer {}", buffer_id))?;
|
||||
|
||||
buffer.update(cx, |buffer, cx| buffer.update_diff_base(diff_base, cx));
|
||||
buffer.update(cx, |buffer, cx| buffer.set_diff_base(diff_base, cx));
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue