@@ -11,7 +11,13 @@ use gpui::{
};
use postage::watch;
use project::ProjectPath;
-use std::{any::Any, cell::RefCell, cmp, mem, rc::Rc};
+use std::{
+ any::Any,
+ cell::RefCell,
+ cmp, mem,
+ rc::Rc,
+ time::{Duration, Instant},
+};
use util::ResultExt;
action!(Split, SplitDirection);
@@ -104,6 +110,7 @@ impl Default for NavigationMode {
struct NavigationEntry {
item_view: Box<dyn WeakItemViewHandle>,
data: Option<Box<dyn Any>>,
+ insertion_time: Option<Instant>,
}
impl Pane {
@@ -551,9 +558,20 @@ impl Navigation {
let mut state = self.0.borrow_mut();
match state.mode {
NavigationMode::Normal => {
+ let mut insertion_time = Instant::now();
+ if let Some(prev_insertion_time) =
+ state.backward_stack.last().and_then(|e| e.insertion_time)
+ {
+ if insertion_time.duration_since(prev_insertion_time) <= Duration::from_secs(2)
+ {
+ state.backward_stack.pop();
+ insertion_time = prev_insertion_time;
+ }
+ }
state.backward_stack.push(NavigationEntry {
item_view: Box::new(cx.weak_handle()),
data: data.map(|data| Box::new(data) as Box<dyn Any>),
+ insertion_time: Some(insertion_time),
});
state.forward_stack.clear();
}
@@ -561,12 +579,14 @@ impl Navigation {
state.forward_stack.push(NavigationEntry {
item_view: Box::new(cx.weak_handle()),
data: data.map(|data| Box::new(data) as Box<dyn Any>),
+ insertion_time: None,
});
}
NavigationMode::GoingForward => {
state.backward_stack.push(NavigationEntry {
item_view: Box::new(cx.weak_handle()),
data: data.map(|data| Box::new(data) as Box<dyn Any>),
+ insertion_time: None,
});
}
}
@@ -755,6 +755,14 @@ mod tests {
(file3.clone(), DisplayPoint::new(0, 2))
);
+ workspace
+ .update(&mut cx, |w, cx| Pane::go_back(w, cx))
+ .await;
+ assert_eq!(
+ active_location(&workspace, &mut cx),
+ (file3.clone(), DisplayPoint::new(0, 0))
+ );
+
workspace
.update(&mut cx, |w, cx| Pane::go_back(w, cx))
.await;
@@ -771,10 +779,26 @@ mod tests {
(file1.clone(), DisplayPoint::new(0, 1))
);
+ workspace
+ .update(&mut cx, |w, cx| Pane::go_back(w, cx))
+ .await;
+ assert_eq!(
+ active_location(&workspace, &mut cx),
+ (file1.clone(), DisplayPoint::new(0, 0))
+ );
+
// Go back one more time and ensure we don't navigate past the first item in the history.
workspace
.update(&mut cx, |w, cx| Pane::go_back(w, cx))
.await;
+ assert_eq!(
+ active_location(&workspace, &mut cx),
+ (file1.clone(), DisplayPoint::new(0, 0))
+ );
+
+ workspace
+ .update(&mut cx, |w, cx| Pane::go_forward(w, cx))
+ .await;
assert_eq!(
active_location(&workspace, &mut cx),
(file1.clone(), DisplayPoint::new(0, 1))
@@ -801,7 +825,7 @@ mod tests {
.await;
assert_eq!(
active_location(&workspace, &mut cx),
- (file3.clone(), DisplayPoint::new(0, 2))
+ (file3.clone(), DisplayPoint::new(0, 0))
);
// Go back to an item that has been closed and removed from disk, ensuring it gets skipped.
@@ -822,6 +846,13 @@ mod tests {
active_location(&workspace, &mut cx),
(file1.clone(), DisplayPoint::new(0, 1))
);
+ workspace
+ .update(&mut cx, |w, cx| Pane::go_forward(w, cx))
+ .await;
+ assert_eq!(
+ active_location(&workspace, &mut cx),
+ (file3.clone(), DisplayPoint::new(0, 0))
+ );
fn active_location(
workspace: &ViewHandle<Workspace>,