Add a terminal::RerunTask action (#30288)

Bounded this action to the same defaults `task::Rerun` is bound to.

Unlike the `task::Rerun` which will always rerun the latest task, this
command reruns the current task tab, if focused.
The task is not in scope when the terminal pane is not focused, and
falls back to the regular rerun if invoked on a task-less terminal tab.

This way, we can add a proper tooltip to the terminal tab reruns:

<img width="231" alt="image"
src="https://github.com/user-attachments/assets/2cdd7458-5ba2-4cc7-a10b-3e2db059f1ca"
/>


Release Notes:

- Added `terminal::RerunTask` task action
This commit is contained in:
Kirill Bulatov 2025-05-08 20:39:52 +03:00 committed by GitHub
parent 9268308543
commit c64dc82e21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 13 deletions

View file

@ -951,7 +951,10 @@
"shift-down": "terminal::ScrollLineDown", "shift-down": "terminal::ScrollLineDown",
"shift-home": "terminal::ScrollToTop", "shift-home": "terminal::ScrollToTop",
"shift-end": "terminal::ScrollToBottom", "shift-end": "terminal::ScrollToBottom",
"ctrl-shift-space": "terminal::ToggleViMode" "ctrl-shift-space": "terminal::ToggleViMode",
"ctrl-shift-r": "terminal::RerunTask",
"ctrl-alt-r": "terminal::RerunTask",
"alt-t": "terminal::RerunTask"
} }
}, },
{ {

View file

@ -1037,7 +1037,8 @@
"ctrl-alt-up": "pane::SplitUp", "ctrl-alt-up": "pane::SplitUp",
"ctrl-alt-down": "pane::SplitDown", "ctrl-alt-down": "pane::SplitDown",
"ctrl-alt-left": "pane::SplitLeft", "ctrl-alt-left": "pane::SplitLeft",
"ctrl-alt-right": "pane::SplitRight" "ctrl-alt-right": "pane::SplitRight",
"cmd-alt-r": "terminal::RerunTask"
} }
}, },
{ {

View file

@ -8,12 +8,14 @@ use editor::{Editor, EditorSettings, actions::SelectAll, scroll::ScrollbarAutoHi
use gpui::{ use gpui::{
AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, KeyContext, AnyElement, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, KeyContext,
KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render, ScrollWheelEvent, KeyDownEvent, Keystroke, MouseButton, MouseDownEvent, Pixels, Render, ScrollWheelEvent,
Stateful, Styled, Subscription, Task, WeakEntity, anchored, deferred, div, impl_actions, Stateful, Styled, Subscription, Task, WeakEntity, actions, anchored, deferred, div,
impl_actions,
}; };
use itertools::Itertools; use itertools::Itertools;
use persistence::TERMINAL_DB; use persistence::TERMINAL_DB;
use project::{Entry, Metadata, Project, search::SearchQuery, terminals::TerminalKind}; use project::{Entry, Metadata, Project, search::SearchQuery, terminals::TerminalKind};
use schemars::JsonSchema; use schemars::JsonSchema;
use task::TaskId;
use terminal::{ use terminal::{
Clear, Copy, Event, HoveredWord, MaybeNavigationTarget, Paste, ScrollLineDown, ScrollLineUp, Clear, Copy, Event, HoveredWord, MaybeNavigationTarget, Paste, ScrollLineDown, ScrollLineUp,
ScrollPageDown, ScrollPageUp, ScrollToBottom, ScrollToTop, ShowCharacterPalette, TaskState, ScrollPageDown, ScrollPageUp, ScrollToBottom, ScrollToTop, ShowCharacterPalette, TaskState,
@ -71,6 +73,8 @@ pub struct SendText(String);
#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)] #[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq)]
pub struct SendKeystroke(String); pub struct SendKeystroke(String);
actions!(terminal, [RerunTask]);
impl_actions!(terminal, [SendText, SendKeystroke]); impl_actions!(terminal, [SendText, SendKeystroke]);
pub fn init(cx: &mut App) { pub fn init(cx: &mut App) {
@ -334,6 +338,18 @@ impl TerminalView {
cx.notify(); cx.notify();
} }
fn rerun_task(&mut self, _: &RerunTask, window: &mut Window, cx: &mut Context<Self>) {
let task = self
.terminal
.update(cx, |terminal, _| {
terminal
.task()
.map(|task| terminal_rerun_override(&task.id))
})
.unwrap_or_default();
window.dispatch_action(Box::new(task), cx);
}
fn clear(&mut self, _: &Clear, _: &mut Window, cx: &mut Context<Self>) { fn clear(&mut self, _: &Clear, _: &mut Window, cx: &mut Context<Self>) {
self.scroll_top = px(0.); self.scroll_top = px(0.);
self.terminal.update(cx, |term, _| term.clear()); self.terminal.update(cx, |term, _| term.clear());
@ -826,22 +842,25 @@ impl TerminalView {
.size(ButtonSize::Compact) .size(ButtonSize::Compact)
.icon_color(Color::Default) .icon_color(Color::Default)
.shape(ui::IconButtonShape::Square) .shape(ui::IconButtonShape::Square)
.tooltip(Tooltip::text("Rerun task")) .tooltip(move |window, cx| {
Tooltip::for_action("Rerun task", &RerunTask, window, cx)
})
.on_click(move |_, window, cx| { .on_click(move |_, window, cx| {
window.dispatch_action( window.dispatch_action(Box::new(terminal_rerun_override(&task_id)), cx);
Box::new(zed_actions::Rerun {
task_id: Some(task_id.0.clone()),
allow_concurrent_runs: Some(true),
use_new_terminal: Some(false),
reevaluate_context: false,
}),
cx,
);
}), }),
) )
} }
} }
fn terminal_rerun_override(task: &TaskId) -> zed_actions::Rerun {
zed_actions::Rerun {
task_id: Some(task.0.clone()),
allow_concurrent_runs: Some(true),
use_new_terminal: Some(false),
reevaluate_context: false,
}
}
fn subscribe_for_terminal_events( fn subscribe_for_terminal_events(
terminal: &Entity<Terminal>, terminal: &Entity<Terminal>,
workspace: WeakEntity<Workspace>, workspace: WeakEntity<Workspace>,
@ -1360,6 +1379,7 @@ impl Render for TerminalView {
.on_action(cx.listener(TerminalView::toggle_vi_mode)) .on_action(cx.listener(TerminalView::toggle_vi_mode))
.on_action(cx.listener(TerminalView::show_character_palette)) .on_action(cx.listener(TerminalView::show_character_palette))
.on_action(cx.listener(TerminalView::select_all)) .on_action(cx.listener(TerminalView::select_all))
.on_action(cx.listener(TerminalView::rerun_task))
.on_key_down(cx.listener(Self::key_down)) .on_key_down(cx.listener(Self::key_down))
.on_mouse_down( .on_mouse_down(
MouseButton::Right, MouseButton::Right,