@@ -3,7 +3,7 @@ use std::{collections::HashMap, path::PathBuf};
use editor::Editor;
use gpui::{AppContext, ViewContext, WindowContext};
use language::Point;
-use modal::TasksModal;
+use modal::{Spawn, TasksModal};
use project::{Location, WorktreeId};
use task::{Task, TaskContext};
use util::ResultExt;
@@ -15,15 +15,7 @@ pub fn init(cx: &mut AppContext) {
cx.observe_new_views(
|workspace: &mut Workspace, _: &mut ViewContext<Workspace>| {
workspace
- .register_action(|workspace, _: &modal::Spawn, cx| {
- let inventory = workspace.project().read(cx).task_inventory().clone();
- let workspace_handle = workspace.weak_handle();
- let cwd = task_cwd(workspace, cx).log_err().flatten();
- let task_context = task_context(workspace, cwd, cx);
- workspace.toggle_modal(cx, |cx| {
- TasksModal::new(inventory, task_context, workspace_handle, cx)
- })
- })
+ .register_action(spawn_task_or_modal)
.register_action(move |workspace, action: &modal::Rerun, cx| {
if let Some((task, old_context)) =
workspace.project().update(cx, |project, cx| {
@@ -47,6 +39,54 @@ pub fn init(cx: &mut AppContext) {
.detach();
}
+fn spawn_task_or_modal(workspace: &mut Workspace, action: &Spawn, cx: &mut ViewContext<Workspace>) {
+ let inventory = workspace.project().read(cx).task_inventory().clone();
+ let workspace_handle = workspace.weak_handle();
+ let cwd = task_cwd(workspace, cx).log_err().flatten();
+ let task_context = task_context(workspace, cwd, cx);
+ if let Some(name) = action.task_name.clone() {
+ // Do not actually show the modal.
+ spawn_task_with_name(name.clone(), cx);
+ } else {
+ workspace.toggle_modal(cx, |cx| {
+ TasksModal::new(inventory, task_context, workspace_handle, cx)
+ })
+ }
+}
+
+fn spawn_task_with_name(name: String, cx: &mut ViewContext<Workspace>) {
+ cx.spawn(|workspace, mut cx| async move {
+ let did_spawn = workspace
+ .update(&mut cx, |this, cx| {
+ let active_item = this
+ .active_item(cx)
+ .and_then(|item| item.project_path(cx))
+ .map(|path| path.worktree_id);
+ let tasks = this.project().update(cx, |project, cx| {
+ project.task_inventory().update(cx, |inventory, cx| {
+ inventory.list_tasks(None, active_item, false, cx)
+ })
+ });
+ let (_, target_task) = tasks.into_iter().find(|(_, task)| task.name() == name)?;
+ let cwd = task_cwd(this, cx).log_err().flatten();
+ let task_context = task_context(this, cwd, cx);
+ schedule_task(this, target_task.as_ref(), task_context, cx);
+ Some(())
+ })
+ .ok()
+ .flatten()
+ .is_some();
+ if !did_spawn {
+ workspace
+ .update(&mut cx, |workspace, cx| {
+ spawn_task_or_modal(workspace, &Spawn::default(), cx);
+ })
+ .ok();
+ }
+ })
+ .detach();
+}
+
fn task_context(
workspace: &Workspace,
cwd: Option<PathBuf>,
@@ -2,9 +2,9 @@ use std::{path::PathBuf, sync::Arc};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
- actions, impl_actions, rems, AppContext, DismissEvent, EventEmitter, FocusableView,
- InteractiveElement, Model, ParentElement, Render, SharedString, Styled, Subscription, View,
- ViewContext, VisualContext, WeakView,
+ impl_actions, rems, AppContext, DismissEvent, EventEmitter, FocusableView, InteractiveElement,
+ Model, ParentElement, Render, SharedString, Styled, Subscription, View, ViewContext,
+ VisualContext, WeakView,
};
use picker::{
highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
@@ -18,7 +18,16 @@ use workspace::{ModalView, Workspace};
use crate::schedule_task;
use serde::Deserialize;
-actions!(task, [Spawn]);
+
+/// Spawn a task with name or open tasks modal
+#[derive(PartialEq, Clone, Deserialize, Default)]
+pub struct Spawn {
+ #[serde(default)]
+ /// Name of the task to spawn.
+ /// If it is not set, a modal with a list of available tasks is opened instead.
+ /// Defaults to None.
+ pub task_name: Option<String>,
+}
/// Rerun last task
#[derive(PartialEq, Clone, Deserialize, Default)]
@@ -31,7 +40,7 @@ pub struct Rerun {
pub reevaluate_context: bool,
}
-impl_actions!(task, [Rerun]);
+impl_actions!(task, [Rerun, Spawn]);
/// A modal used to spawn new tasks.
pub(crate) struct TasksModalDelegate {
@@ -426,7 +435,7 @@ mod tests {
workspace: &View<Workspace>,
cx: &mut VisualTestContext,
) -> View<Picker<TasksModalDelegate>> {
- cx.dispatch_action(crate::modal::Spawn);
+ cx.dispatch_action(crate::modal::Spawn::default());
workspace.update(cx, |workspace, cx| {
workspace
.active_modal::<TasksModal>(cx)