Add gutter action to clear run status (#61375)
# Objective Add a way to manually clear completed run statuses from the gutter. Folow-up to #61095 This follows up on feedback from the previous gutter run status PR. Currently, editing a file clears run statuses automatically, but there was no direct way to clear a completed status without changing the file. ## Solution - Added a `Clear Run Status` entry to the gutter context menu. - Show the entry only when the row has a completed run status. - Clear the stored run status for that runnable when selected. - Keep running statuses unchanged, so this does not behave like task cancellation. ## Testing - Ran `cargo check -p editor`. - Manually ran a test from the gutter and waited for a completed status. - Verified right-clicking the gutter icon shows `Clear Run Status`. - Verified selecting `Clear Run Status` clears the status icon. - Verified the action is not shown for rows without a completed run status. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable [after.webm](https://github.com/user-attachments/assets/1ae284e1-03b1-4842-a63e-9d66c290b325) --- Release Notes: - Improved gutter run statuses by allowing completed statuses to be cleared from the gutter context menu.
This commit is contained in:
1 parent
870ffffcd8
commit
185c6986da
2 files changed
+58
-2
No files matched your search
@@ -4151,6 +4151,7 @@ impl Editor {
|
||||
fn gutter_context_menu(
|
||||
&self,
|
||||
anchor: Anchor,
|
||||
display_row: DisplayRow,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Entity<ContextMenu> {
|
||||
@@ -4213,6 +4214,15 @@ impl Editor {
|
||||
};
|
||||
let has_bookmark = bookmark.as_ref().is_some();
|
||||
|
||||
let clear_runnable_task_status = self
|
||||
.runnable_task_key_for_display_row(display_row, window, cx)
|
||||
.filter(|(buffer_id, buffer_row)| {
|
||||
matches!(
|
||||
self.runnable_task_status(*buffer_id, *buffer_row),
|
||||
Some(RunnableTaskStatus::Passed | RunnableTaskStatus::Failed)
|
||||
)
|
||||
});
|
||||
|
||||
let run_to_cursor = window.is_action_available(&RunToCursor, cx);
|
||||
|
||||
let toggle_state_entry: Option<(&str, Box<dyn Action>)> =
|
||||
@@ -4231,6 +4241,22 @@ impl Editor {
|
||||
ContextMenu::build(window, cx, |menu, _, _cx| {
|
||||
menu.on_blur_subscription(Subscription::new(|| {}))
|
||||
.context(focus_handle)
|
||||
.when_some(
|
||||
clear_runnable_task_status,
|
||||
|this, (buffer_id, buffer_row)| {
|
||||
this.entry("Clear Run Status", None, {
|
||||
let weak_editor = weak_editor.clone();
|
||||
move |_window, cx| {
|
||||
weak_editor
|
||||
.update(cx, |this, cx| {
|
||||
this.clear_runnable_task_status(buffer_id, buffer_row, cx);
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
})
|
||||
.separator()
|
||||
},
|
||||
)
|
||||
.when(run_to_cursor, |this| {
|
||||
let weak_editor = weak_editor.clone();
|
||||
this.entry(
|
||||
@@ -5847,7 +5873,7 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
|
||||
let context_menu = self.gutter_context_menu(anchor, window, cx);
|
||||
let context_menu = self.gutter_context_menu(anchor, display_row, window, cx);
|
||||
|
||||
self.mouse_context_menu = MouseContextMenu::pinned_to_editor(
|
||||
self,
|
||||
|
||||
@@ -18,7 +18,8 @@ use ui::{Clickable as _, Color, IconButton, IconSize, Toggleable as _};
|
||||
|
||||
use crate::{
|
||||
CodeActionSource, Editor, EditorSettings, EditorStyle, RangeToAnchorExt, SpawnNearestTask,
|
||||
ToggleCodeActions, UPDATE_DEBOUNCE, display_map::DisplayRow,
|
||||
ToggleCodeActions, UPDATE_DEBOUNCE,
|
||||
display_map::{DisplayPoint, DisplayRow},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -67,6 +68,10 @@ impl RunnableData {
|
||||
self.task_statuses.insert((buffer_id, buffer_row), status);
|
||||
}
|
||||
|
||||
pub fn clear_task_status(&mut self, (buffer_id, buffer_row): (BufferId, BufferRow)) {
|
||||
self.task_statuses.remove(&(buffer_id, buffer_row));
|
||||
}
|
||||
|
||||
pub fn task_key_for_offset(
|
||||
&self,
|
||||
buffer_id: BufferId,
|
||||
@@ -441,6 +446,31 @@ impl Editor {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(crate) fn clear_runnable_task_status(
|
||||
&mut self,
|
||||
buffer_id: BufferId,
|
||||
buffer_row: BufferRow,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.runnables.clear_task_status((buffer_id, buffer_row));
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub(crate) fn runnable_task_key_for_display_row(
|
||||
&self,
|
||||
display_row: DisplayRow,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<(BufferId, BufferRow)> {
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let multibuffer_row =
|
||||
MultiBufferRow(DisplayPoint::new(display_row, 0).to_point(&snapshot).row);
|
||||
let (buffer_snapshot, range) = snapshot
|
||||
.buffer_snapshot()
|
||||
.buffer_line_for_row(multibuffer_row)?;
|
||||
Some((buffer_snapshot.remote_id(), range.start.row))
|
||||
}
|
||||
|
||||
pub(crate) fn runnable_task_key_for_offset(
|
||||
&self,
|
||||
buffer_id: BufferId,
|
||||
|
||||
Reference in new issue
Block a user