mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-28 20:01:33 +00:00
Experiment with a more general way of pushing editor navigation entries
This commit is contained in:
parent
0cae3e0ac0
commit
16b82d59f1
4 changed files with 66 additions and 2 deletions
|
@ -3297,6 +3297,17 @@ impl Editor {
|
|||
}
|
||||
self.pause_cursor_blinking(cx);
|
||||
|
||||
let prev_newest_selection = self.selections.iter().max_by_key(|s| s.id);
|
||||
let curr_newest_selection = selections.iter().max_by_key(|s| s.id);
|
||||
if let Some((prev_selection, curr_selection)) =
|
||||
prev_newest_selection.zip(curr_newest_selection)
|
||||
{
|
||||
if prev_selection.head().to_offset(&buffer) != curr_selection.head().to_offset(&buffer)
|
||||
{
|
||||
self.push_to_navigation_history(cx);
|
||||
}
|
||||
}
|
||||
|
||||
self.set_selections(
|
||||
Arc::from_iter(selections.into_iter().map(|selection| {
|
||||
let end_bias = if selection.end > selection.start {
|
||||
|
|
|
@ -115,7 +115,9 @@ impl ItemView for Editor {
|
|||
};
|
||||
|
||||
drop(buffer);
|
||||
let navigation = self.navigation.take();
|
||||
self.select_ranges([offset..offset], Some(Autoscroll::Fit), cx);
|
||||
self.navigation = navigation;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
Loading…
Reference in a new issue