From a67f28dba24b8ce3ed29fc32a57eb775752f8151 Mon Sep 17 00:00:00 2001 From: Anthony Eid Date: Thu, 27 Jun 2024 11:00:33 -0400 Subject: [PATCH] Get Start Debugger action to open task menu --- .gitignore | 1 + Cargo.lock | 2 ++ crates/debugger_ui/Cargo.toml | 2 ++ crates/debugger_ui/src/lib.rs | 2 +- crates/paths/src/paths.rs | 2 +- crates/project/src/project.rs | 35 ++++++++++++++++---------------- crates/task/src/debug_format.rs | 24 ++++++++++++++++++++++ crates/task/src/lib.rs | 2 +- crates/task/src/task_template.rs | 16 ++++++++++++++- crates/tasks_ui/src/lib.rs | 13 ++++++++---- crates/tasks_ui/src/modal.rs | 9 ++++++-- 11 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 crates/task/src/debug_format.rs diff --git a/.gitignore b/.gitignore index e0dfc13d37..3d5187ca4e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ DerivedData/ .vscode .wrangler .flatpak-builder +.zed/debug.json diff --git a/Cargo.lock b/Cargo.lock index e14a4720c2..08809fe056 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3282,6 +3282,8 @@ dependencies = [ "project", "serde", "serde_derive", + "task", + "tasks_ui", "ui", "workspace", ] diff --git a/crates/debugger_ui/Cargo.toml b/crates/debugger_ui/Cargo.toml index 2ad433f813..0f333d0325 100644 --- a/crates/debugger_ui/Cargo.toml +++ b/crates/debugger_ui/Cargo.toml @@ -22,6 +22,8 @@ serde.workspace = true serde_derive.workspace = true ui.workspace = true workspace.workspace = true +tasks_ui.workspace = true +task.workspace = true [dev-dependencies] editor = { workspace = true, features = ["test-support"] } diff --git a/crates/debugger_ui/src/lib.rs b/crates/debugger_ui/src/lib.rs index cb4a816845..cf77096378 100644 --- a/crates/debugger_ui/src/lib.rs +++ b/crates/debugger_ui/src/lib.rs @@ -17,7 +17,7 @@ pub fn init(cx: &mut AppContext) { |workspace: &mut Workspace, action: &StartDebugger, cx: &mut ViewContext<'_, Workspace>| { - select_debugger(workspace, action, cx).detach(); + tasks_ui::toggle_modal(workspace, cx, task::TaskType::Debug).detach(); }, ); }, diff --git a/crates/paths/src/paths.rs b/crates/paths/src/paths.rs index 08a4bfe910..a832a2df26 100644 --- a/crates/paths/src/paths.rs +++ b/crates/paths/src/paths.rs @@ -249,7 +249,7 @@ pub fn local_vscode_tasks_file_relative_path() -> &'static Path { } /// Returns the relative path to a `launch.json` file within a project. -pub fn local_launch_file_relative_path() -> &'static Path { +pub fn local_debug_file_relative_path() -> &'static Path { static LOCAL_LAUNCH_FILE_RELATIVE_PATH: OnceLock<&Path> = OnceLock::new(); LOCAL_LAUNCH_FILE_RELATIVE_PATH.get_or_init(|| Path::new(".zed/debug.json")) } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 4dd8020072..edf6475533 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -74,7 +74,7 @@ use lsp_command::*; use node_runtime::NodeRuntime; use parking_lot::{Mutex, RwLock}; use paths::{ - local_launch_file_relative_path, local_settings_file_relative_path, + local_debug_file_relative_path, local_settings_file_relative_path, local_tasks_file_relative_path, local_vscode_launch_file_relative_path, local_vscode_tasks_file_relative_path, }; @@ -1085,12 +1085,14 @@ impl Project { "/Users/remcosmits/Documents/code/symfony_demo".into(), &mut cx, move |event, cx| { - this2.update(cx, |_, cx| { - cx.emit(Event::DebugClientEvent { - client_id: id, - event, + this2 + .update(cx, |_, cx| { + cx.emit(Event::DebugClientEvent { + client_id: id, + event, + }) }) - }).log_err(); + .log_err(); }, ) .await @@ -8425,28 +8427,24 @@ impl Project { ); } }) - } else if abs_path.ends_with(local_launch_file_relative_path()) { + } else if abs_path.ends_with(local_debug_file_relative_path()) { // TODO: handle local launch file (.zed/debug.json) - self.debugger_configs().update(cx, |debugger_configs, cx| { + self.task_inventory().update(cx, |task_inventory, cx| { if removed { - debugger_configs.remove_source(&abs_path); + task_inventory.remove_local_static_source(&abs_path); } else { let fs = self.fs.clone(); - let debugger_configs_file_rx = + let debug_task_file_rx = watch_config_file(&cx.background_executor(), fs, abs_path.clone()); - debugger_configs.add_source( - DebuggerConfigSourceKind::Worktree { - id: remote_worktree_id.to_usize(), + task_inventory.add_source( + TaskSourceKind::Worktree { + id: remote_worktree_id, abs_path, id_base: "local_debug_File_for_worktree".into(), }, |tx, cx| { - debugger_inventory::StaticSource::new(TrackedFile::new( - debugger_configs_file_rx, - tx, - cx, - )) + StaticSource::new(TrackedFile::new(debug_task_file_rx, tx, cx)) }, cx, ); @@ -11139,6 +11137,7 @@ impl Project { allow_concurrent_runs: proto_template.allow_concurrent_runs, reveal, tags: proto_template.tags, + ..Default::default() }; Some((task_source_kind, task_template)) }) diff --git a/crates/task/src/debug_format.rs b/crates/task/src/debug_format.rs new file mode 100644 index 0000000000..7f3a49ac51 --- /dev/null +++ b/crates/task/src/debug_format.rs @@ -0,0 +1,24 @@ +use anyhow::bail; +use collections::HashMap; +use serde::Deserialize; +use util::ResultExt; + +use crate::{TaskTemplate, TaskTemplates, VariableName}; + +struct ZedDebugTaskFile {} + +impl ZedDebugTaskFile { + fn to_zed_format(self) -> anyhow::Result {} +} +impl TryFrom for TaskTemplates { + type Error = anyhow::Error; + + fn try_from(value: ZedDebugTaskFile) -> Result { + let templates = value + .tasks + .into_iter() + .filter_map(|debug_task_file| debug_task_file.to_zed_format(&replacer).log_err()) + .collect(); + Ok(Self(templates)) + } +} diff --git a/crates/task/src/lib.rs b/crates/task/src/lib.rs index 10b9b050a4..dcc252c287 100644 --- a/crates/task/src/lib.rs +++ b/crates/task/src/lib.rs @@ -12,7 +12,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::{borrow::Cow, path::Path}; -pub use task_template::{RevealStrategy, TaskTemplate, TaskTemplates}; +pub use task_template::{RevealStrategy, TaskTemplate, TaskTemplates, TaskType}; pub use vscode_format::VsCodeTaskFile; /// Task identifier, unique within the application. diff --git a/crates/task/src/task_template.rs b/crates/task/src/task_template.rs index fda245b4c5..831e8bebdb 100644 --- a/crates/task/src/task_template.rs +++ b/crates/task/src/task_template.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{default, path::PathBuf}; use anyhow::{bail, Context}; use collections::{HashMap, HashSet}; @@ -45,12 +45,26 @@ pub struct TaskTemplate { /// * `never` — avoid changing current terminal pane focus, but still add/reuse the task's tab there #[serde(default)] pub reveal: RevealStrategy, + /// If this task should start a debugger or not + #[serde(default)] + pub task_type: TaskType, /// Represents the tags which this template attaches to. Adding this removes this task from other UI. #[serde(default)] pub tags: Vec, } +/// Represents the type of task that is being ran +#[derive(Default, Deserialize, Serialize, PartialEq, Eq, JsonSchema, Copy, Clone, Debug)] +#[serde(rename_all = "snake_case")] +pub enum TaskType { + /// Act like a typically task that runs commands + #[default] + Script, + /// This task starts the debugger for a language + Debug, +} + /// What to do with the terminal pane and tab, after the command was started. #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] diff --git a/crates/tasks_ui/src/lib.rs b/crates/tasks_ui/src/lib.rs index 2106cbe831..d7dab3c19b 100644 --- a/crates/tasks_ui/src/lib.rs +++ b/crates/tasks_ui/src/lib.rs @@ -3,6 +3,7 @@ use editor::{tasks::task_context, Editor}; use gpui::{AppContext, Task as AsyncTask, ViewContext, WindowContext}; use modal::TasksModal; use project::{Location, WorktreeId}; +use task::TaskType; use workspace::tasks::schedule_task; use workspace::{tasks::schedule_resolved_task, Workspace}; @@ -70,7 +71,7 @@ pub fn init(cx: &mut AppContext) { ); } } else { - toggle_modal(workspace, cx).detach(); + toggle_modal(workspace, cx, TaskType::Script).detach(); }; }); }, @@ -81,11 +82,15 @@ pub fn init(cx: &mut AppContext) { fn spawn_task_or_modal(workspace: &mut Workspace, action: &Spawn, cx: &mut ViewContext) { match &action.task_name { Some(name) => spawn_task_with_name(name.clone(), cx).detach_and_log_err(cx), - None => toggle_modal(workspace, cx).detach(), + None => toggle_modal(workspace, cx, task::TaskType::Script).detach(), } } -fn toggle_modal(workspace: &mut Workspace, cx: &mut ViewContext<'_, Workspace>) -> AsyncTask<()> { +pub fn toggle_modal( + workspace: &mut Workspace, + cx: &mut ViewContext<'_, Workspace>, + task_type: TaskType, +) -> AsyncTask<()> { let project = workspace.project().clone(); let workspace_handle = workspace.weak_handle(); let context_task = task_context(workspace, cx); @@ -97,7 +102,7 @@ fn toggle_modal(workspace: &mut Workspace, cx: &mut ViewContext<'_, Workspace>) project.is_local() || project.ssh_connection_string(cx).is_some() }) { workspace.toggle_modal(cx, |cx| { - TasksModal::new(project, task_context, workspace_handle, cx) + TasksModal::new(project, task_context, workspace_handle, cx, task_type) }) } }) diff --git a/crates/tasks_ui/src/modal.rs b/crates/tasks_ui/src/modal.rs index 34c1c127d6..f3e93c277f 100644 --- a/crates/tasks_ui/src/modal.rs +++ b/crates/tasks_ui/src/modal.rs @@ -9,7 +9,7 @@ use gpui::{ }; use picker::{highlighted_match_with_paths::HighlightedText, Picker, PickerDelegate}; use project::{Project, TaskSourceKind}; -use task::{ResolvedTask, TaskContext, TaskId, TaskTemplate}; +use task::{ResolvedTask, TaskContext, TaskId, TaskTemplate, TaskType}; use ui::{ div, h_flex, v_flex, ActiveTheme, Button, ButtonCommon, ButtonSize, Clickable, Color, FluentBuilder as _, Icon, IconButton, IconButtonShape, IconName, IconSize, IntoElement, @@ -73,6 +73,8 @@ pub(crate) struct TasksModalDelegate { prompt: String, task_context: TaskContext, placeholder_text: Arc, + /// If this delegate is responsible for running a scripting task or a debugger + task_type: TaskType, } impl TasksModalDelegate { @@ -80,6 +82,7 @@ impl TasksModalDelegate { project: Model, task_context: TaskContext, workspace: WeakView, + task_type: TaskType, ) -> Self { Self { project, @@ -92,6 +95,7 @@ impl TasksModalDelegate { prompt: String::default(), task_context, placeholder_text: Arc::from("Find a task, or run a command"), + task_type, } } @@ -143,10 +147,11 @@ impl TasksModal { task_context: TaskContext, workspace: WeakView, cx: &mut ViewContext, + task_type: TaskType, ) -> Self { let picker = cx.new_view(|cx| { Picker::uniform_list( - TasksModalDelegate::new(project, task_context, workspace), + TasksModalDelegate::new(project, task_context, workspace, task_type), cx, ) });