Add clear recent files history command (#42176)

![2025-11-07
181619](https://github.com/user-attachments/assets/a9bef7a6-dc0b-4db2-85e5-2e1df7b21cfa)


Release Notes:

- Added "workspace: clear navigation history" command
This commit is contained in:
Libon
2025-11-11 15:42:00 +02:00
committed by GitHub
parent 58db38722b
commit 9be5e31aca
3 changed files with 128 additions and 0 deletions
@@ -3452,3 +3452,99 @@ async fn test_paths_with_starting_slash(cx: &mut TestAppContext) {
assert_eq!(active_editor.read(cx).title(cx), "file1.txt");
});
}
#[gpui::test]
async fn test_clear_navigation_history(cx: &mut TestAppContext) {
let app_state = init_test(cx);
app_state
.fs
.as_fake()
.insert_tree(
path!("/src"),
json!({
"test": {
"first.rs": "// First file",
"second.rs": "// Second file",
"third.rs": "// Third file",
}
}),
)
.await;
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
workspace.update_in(cx, |_workspace, window, cx| window.focused(cx));
// Open some files to generate navigation history
open_close_queried_buffer("fir", 1, "first.rs", &workspace, cx).await;
open_close_queried_buffer("sec", 1, "second.rs", &workspace, cx).await;
let history_before_clear =
open_close_queried_buffer("thi", 1, "third.rs", &workspace, cx).await;
assert_eq!(
history_before_clear.len(),
2,
"Should have history items before clearing"
);
// Verify that file finder shows history items
let picker = open_file_picker(&workspace, cx);
cx.simulate_input("fir");
picker.update(cx, |finder, _| {
let matches = collect_search_matches(finder);
assert!(
!matches.history.is_empty(),
"File finder should show history items before clearing"
);
});
workspace.update_in(cx, |_, window, cx| {
window.dispatch_action(menu::Cancel.boxed_clone(), cx);
});
// Verify navigation state before clear
workspace.update(cx, |workspace, cx| {
let pane = workspace.active_pane();
pane.read(cx).can_navigate_backward()
});
// Clear navigation history
cx.dispatch_action(workspace::ClearNavigationHistory);
// Verify that navigation is disabled immediately after clear
workspace.update(cx, |workspace, cx| {
let pane = workspace.active_pane();
assert!(
!pane.read(cx).can_navigate_backward(),
"Should not be able to navigate backward after clearing history"
);
assert!(
!pane.read(cx).can_navigate_forward(),
"Should not be able to navigate forward after clearing history"
);
});
// Verify that file finder no longer shows history items
let picker = open_file_picker(&workspace, cx);
cx.simulate_input("fir");
picker.update(cx, |finder, _| {
let matches = collect_search_matches(finder);
assert!(
matches.history.is_empty(),
"File finder should not show history items after clearing"
);
});
workspace.update_in(cx, |_, window, cx| {
window.dispatch_action(menu::Cancel.boxed_clone(), cx);
});
// Verify history is empty by opening a new file
// (this should not show any previous history)
let history_after_clear =
open_close_queried_buffer("sec", 1, "second.rs", &workspace, cx).await;
assert_eq!(
history_after_clear.len(),
0,
"Should have no history items after clearing"
);
}
+19
View File
@@ -4041,6 +4041,25 @@ impl NavHistory {
self.0.lock().mode = NavigationMode::Normal;
}
pub fn clear(&mut self, cx: &mut App) {
let mut state = self.0.lock();
if state.backward_stack.is_empty()
&& state.forward_stack.is_empty()
&& state.closed_stack.is_empty()
&& state.paths_by_item.is_empty()
{
return;
}
state.mode = NavigationMode::Normal;
state.backward_stack.clear();
state.forward_stack.clear();
state.closed_stack.clear();
state.paths_by_item.clear();
state.did_update(cx);
}
pub fn pop(&mut self, mode: NavigationMode, cx: &mut App) -> Option<NavigationEntry> {
let mut state = self.0.lock();
let entry = match mode {
+13
View File
@@ -199,6 +199,8 @@ actions!(
AddFolderToProject,
/// Clears all notifications.
ClearAllNotifications,
/// Clears all navigation history, including forward/backward navigation, recently opened files, and recently closed tabs. **This action is irreversible**.
ClearNavigationHistory,
/// Closes the active dock.
CloseActiveDock,
/// Closes all docks.
@@ -1917,6 +1919,12 @@ impl Workspace {
.collect()
}
pub fn clear_navigation_history(&mut self, _window: &mut Window, cx: &mut Context<Workspace>) {
for pane in &self.panes {
pane.update(cx, |pane, cx| pane.nav_history_mut().clear(cx));
}
}
fn navigate_history(
&mut self,
pane: WeakEntity<Pane>,
@@ -5858,6 +5866,11 @@ impl Workspace {
workspace.clear_all_notifications(cx);
},
))
.on_action(cx.listener(
|workspace: &mut Workspace, _: &ClearNavigationHistory, window, cx| {
workspace.clear_navigation_history(window, cx);
},
))
.on_action(cx.listener(
|workspace: &mut Workspace, _: &SuppressNotification, _, cx| {
if let Some((notification_id, _)) = workspace.notifications.pop() {