Task::spawn now takes an optional task name as an argument.
If it is not set, we fall back to opening a modal. This allows user to spawn tasks via keybind.
This commit is contained in:
parent
fa5dfe19f8
commit
bf295eac90
2 changed files with 65 additions and 16 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue