diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 6b6bc68f509f78cb6569dbf861e7896de9e34f0b..b1c41f393d24057a56881a9510a103153bb0d4f3 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4156,6 +4156,63 @@ mod tests { }); } + #[gpui::test] + fn test_navigation_history(cx: &mut gpui::MutableAppContext) { + cx.add_window(Default::default(), |cx| { + use workspace::ItemView; + let navigation = Rc::new(workspace::Navigation::default()); + let settings = EditorSettings::test(&cx); + let buffer = MultiBuffer::build_simple(&sample_text(30, 5, 'a'), cx); + let mut editor = build_editor(buffer.clone(), settings, cx); + editor.navigation = Some(navigation.clone()); + + // Move the cursor a small distance. + // Nothing is added to the navigation history. + editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx); + editor.select_display_ranges(&[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)], cx); + assert!(navigation.pop_backward().is_none()); + + // Move the cursor a large distance. + // The history can jump back to the previous position. + editor.select_display_ranges(&[DisplayPoint::new(13, 0)..DisplayPoint::new(13, 3)], cx); + let nav_entry = navigation.pop_backward().unwrap(); + editor.navigate(nav_entry.data.unwrap(), cx); + assert_eq!(nav_entry.item_view.id(), cx.view_id()); + assert_eq!( + editor.selected_display_ranges(cx), + &[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)] + ); + + // Move the cursor a small distance via the mouse. + // Nothing is added to the navigation history. + editor.begin_selection(DisplayPoint::new(5, 0), false, 1, cx); + editor.end_selection(cx); + assert_eq!( + editor.selected_display_ranges(cx), + &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] + ); + assert!(navigation.pop_backward().is_none()); + + // Move the cursor a large distance via the mouse. + // The history can jump back to the previous position. + editor.begin_selection(DisplayPoint::new(15, 0), false, 1, cx); + editor.end_selection(cx); + assert_eq!( + editor.selected_display_ranges(cx), + &[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)] + ); + let nav_entry = navigation.pop_backward().unwrap(); + editor.navigate(nav_entry.data.unwrap(), cx); + assert_eq!(nav_entry.item_view.id(), cx.view_id()); + assert_eq!( + editor.selected_display_ranges(cx), + &[DisplayPoint::new(5, 0)..DisplayPoint::new(5, 0)] + ); + + editor + }); + } + #[gpui::test] fn test_cancel(cx: &mut gpui::MutableAppContext) { let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx); diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index a93ebde051cf9d198cf46a0a6fc27d0f13bd3c5f..0a1cbdc1dac1d7dd034e2c442ab95a3540355354 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -101,9 +101,9 @@ impl Default for NavigationMode { } } -struct NavigationEntry { - item_view: Box, - data: Option>, +pub struct NavigationEntry { + pub item_view: Box, + pub data: Option>, } impl Pane { @@ -535,11 +535,19 @@ impl View for Pane { } impl Navigation { + pub fn pop_backward(&self) -> Option { + self.0.borrow_mut().backward_stack.pop() + } + + pub fn pop_forward(&self) -> Option { + self.0.borrow_mut().forward_stack.pop() + } + fn pop(&self, mode: NavigationMode) -> Option { match mode { NavigationMode::Normal => None, - NavigationMode::GoingBack => self.0.borrow_mut().backward_stack.pop(), - NavigationMode::GoingForward => self.0.borrow_mut().forward_stack.pop(), + NavigationMode::GoingBack => self.pop_backward(), + NavigationMode::GoingForward => self.pop_forward(), } }