Add task docs and default keybindings (#8123)

Also group task source modules together

Release Notes:

- N/A

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This commit is contained in:
Kirill Bulatov 2024-02-21 16:43:56 +02:00 committed by GitHub
parent b9151b9506
commit 0c939e5dfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 84 additions and 64 deletions

View file

@ -381,7 +381,9 @@
"ctrl-k shift-left": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-k shift-right": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-k shift-up": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-k shift-down": ["workspace::SwapPaneInDirection", "Down"]
"ctrl-k shift-down": ["workspace::SwapPaneInDirection", "Down"],
"alt-t": "task::Rerun",
"alt-shift-t": "task::Spawn"
}
},
// Bindings from Sublime Text

View file

@ -423,7 +423,9 @@
"cmd-k shift-left": ["workspace::SwapPaneInDirection", "Left"],
"cmd-k shift-right": ["workspace::SwapPaneInDirection", "Right"],
"cmd-k shift-up": ["workspace::SwapPaneInDirection", "Up"],
"cmd-k shift-down": ["workspace::SwapPaneInDirection", "Down"]
"cmd-k shift-down": ["workspace::SwapPaneInDirection", "Down"],
"alt-t": "task::Rerun",
"alt-shift-t": "task::Spawn"
}
},
// Bindings from Sublime Text

View file

@ -1,10 +1,8 @@
//! Baseline interface of Tasks in Zed: all tasks in Zed are intended to use those for implementing their own logic.
#![deny(missing_docs)]
pub mod oneshot_source;
pub mod static_source;
mod static_task;
pub use static_task::StaticTask;
use collections::HashMap;
use gpui::ModelContext;

View file

@ -1,9 +1,11 @@
//! A source of tasks, based on ad-hoc user command prompt input.
use std::sync::Arc;
use gpui::{AppContext, Model};
use task::{Source, SpawnInTerminal, Task, TaskId};
use ui::Context;
use crate::{Source, SpawnInTerminal, Task, TaskId};
use gpui::{AppContext, Context, Model};
/// A storage and source of tasks generated out of user command prompt inputs.
pub struct OneshotSource {
tasks: Vec<Arc<dyn Task>>,
}
@ -51,10 +53,12 @@ impl Task for OneshotTask {
}
impl OneshotSource {
/// Initializes the oneshot source, preparing to store user prompts.
pub fn new(cx: &mut AppContext) -> Model<Box<dyn Source>> {
cx.new_model(|_| Box::new(Self { tasks: Vec::new() }) as Box<dyn Source>)
}
/// Spawns a certain task based on the user prompt.
pub fn spawn(&mut self, prompt: String) -> Arc<dyn Task> {
let ret = Arc::new(OneshotTask::new(prompt));
self.tasks.push(ret.clone());

View file

@ -12,9 +12,53 @@ use schemars::{gen::SchemaSettings, JsonSchema};
use serde::{Deserialize, Serialize};
use util::ResultExt;
use crate::{Source, StaticTask, Task};
use crate::{Source, SpawnInTerminal, Task, TaskId};
use futures::channel::mpsc::UnboundedReceiver;
/// A single config file entry with the deserialized task definition.
#[derive(Clone, Debug, PartialEq)]
struct StaticTask {
id: TaskId,
definition: Definition,
}
impl StaticTask {
pub(super) fn new(id: usize, task_definition: Definition) -> Self {
Self {
id: TaskId(format!("static_{}_{}", task_definition.label, id)),
definition: task_definition,
}
}
}
impl Task for StaticTask {
fn exec(&self, cwd: Option<PathBuf>) -> Option<SpawnInTerminal> {
Some(SpawnInTerminal {
id: self.id.clone(),
cwd,
use_new_terminal: self.definition.use_new_terminal,
allow_concurrent_runs: self.definition.allow_concurrent_runs,
label: self.definition.label.clone(),
command: self.definition.command.clone(),
args: self.definition.args.clone(),
env: self.definition.env.clone(),
separate_shell: false,
})
}
fn name(&self) -> &str {
&self.definition.label
}
fn id(&self) -> &TaskId {
&self.id
}
fn cwd(&self) -> Option<&Path> {
self.definition.cwd.as_deref()
}
}
/// The source of tasks defined in a tasks config file.
pub struct StaticSource {
tasks: Vec<StaticTask>,

View file

@ -1,49 +0,0 @@
//! Definitions of tasks with a static file config definition, not dependent on the application state.
use std::path::{Path, PathBuf};
use crate::{static_source::Definition, SpawnInTerminal, Task, TaskId};
/// A single config file entry with the deserialized task definition.
#[derive(Clone, Debug, PartialEq)]
pub struct StaticTask {
id: TaskId,
definition: Definition,
}
impl StaticTask {
pub(super) fn new(id: usize, task_definition: Definition) -> Self {
Self {
id: TaskId(format!("static_{}_{}", task_definition.label, id)),
definition: task_definition,
}
}
}
impl Task for StaticTask {
fn exec(&self, cwd: Option<PathBuf>) -> Option<SpawnInTerminal> {
Some(SpawnInTerminal {
id: self.id.clone(),
cwd,
use_new_terminal: self.definition.use_new_terminal,
allow_concurrent_runs: self.definition.allow_concurrent_runs,
label: self.definition.label.clone(),
command: self.definition.command.clone(),
args: self.definition.args.clone(),
env: self.definition.env.clone(),
separate_shell: false,
})
}
fn name(&self) -> &str {
&self.definition.label
}
fn id(&self) -> &TaskId {
&self.id
}
fn cwd(&self) -> Option<&Path> {
self.definition.cwd.as_deref()
}
}

View file

@ -2,13 +2,11 @@ use std::path::PathBuf;
use gpui::{AppContext, ViewContext, WindowContext};
use modal::TasksModal;
pub use oneshot_source::OneshotSource;
use task::Task;
use util::ResultExt;
use workspace::Workspace;
mod modal;
mod oneshot_source;
pub fn init(cx: &mut AppContext) {
cx.observe_new_views(

View file

@ -8,12 +8,12 @@ use gpui::{
};
use picker::{Picker, PickerDelegate};
use project::Inventory;
use task::Task;
use task::{oneshot_source::OneshotSource, Task};
use ui::{v_flex, HighlightedLabel, ListItem, ListItemSpacing, Selectable};
use util::ResultExt;
use workspace::{ModalView, Workspace};
use crate::{schedule_task, OneshotSource};
use crate::schedule_task;
actions!(task, [Spawn, Rerun]);

View file

@ -28,8 +28,7 @@ use settings::{
DEFAULT_KEYMAP_PATH,
};
use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc};
use task::static_source::StaticSource;
use tasks_ui::OneshotSource;
use task::{oneshot_source::OneshotSource, static_source::StaticSource};
use terminal_view::terminal_panel::{self, TerminalPanel};
use util::{
asset_str,

View file

@ -14,6 +14,7 @@
- [Workflows]()
- [Collaboration]()
- [Using AI]()
- [Tasks](./tasks.md)
# Contributing to Zed

21
docs/src/tasks.md Normal file
View file

@ -0,0 +1,21 @@
# Tasks
Zed supports ways to spawn (and rerun) commands using its integrated terminal to output the results.
Currently, two kinds of tasks are supported, but more will be added in the future.
## Static tasks
Tasks, defined in a config file (`tasks.json` in the Zed config directory) that do not depend on the current editor or its content.
Config file can be opened with `zed::OpenTasks` action ("zed: open tasks" in the command palette), it will have a configuration example with all options commented.
Every task from that file can be spawned via the task modal, that is opened with `task::Spawn` action ("tasks: spawn" in the command pane).
Last task spawned via that modal can be rerun with `task::Rerun` ("tasks: rerun" in the command palette) command.
## Oneshot tasks
Same task modal opened via `task::Spawn` supports arbitrary bash-like command execution: type a command inside the modal, and use `cmd-enter` to spawn it.
Task modal will persist list of those command for current Zed session, `task::Rerun` will also rerun such tasks if they were the last ones spawned.