diff --git a/crates/languages/src/json.rs b/crates/languages/src/json.rs index f208ae004a14271b9ff9de7b2887f53e669ea6cd..fefc517e2bcce1bdb462f870e33275220a74d596 100644 --- a/crates/languages/src/json.rs +++ b/crates/languages/src/json.rs @@ -5,12 +5,14 @@ use async_trait::async_trait; use collections::HashMap; use dap::DapRegistry; use futures::StreamExt; -use gpui::{App, AsyncApp}; +use gpui::{App, AsyncApp, Task}; use http_client::github::{GitHubLspBinaryVersion, latest_github_release}; -use language::{LanguageRegistry, LanguageToolchainStore, LspAdapter, LspAdapterDelegate}; +use language::{ + ContextProvider, LanguageRegistry, LanguageToolchainStore, LspAdapter, LspAdapterDelegate, +}; use lsp::{LanguageServerBinary, LanguageServerName}; use node_runtime::NodeRuntime; -use project::{ContextProviderWithTasks, Fs, lsp_store::language_server_settings}; +use project::{Fs, lsp_store::language_server_settings}; use serde_json::{Value, json}; use settings::{KeymapFile, SettingsJsonSchemaParams, SettingsStore}; use smol::{ @@ -36,25 +38,77 @@ const SERVER_PATH: &str = const TSCONFIG_SCHEMA: &str = include_str!("json/schemas/tsconfig.json"); const PACKAGE_JSON_SCHEMA: &str = include_str!("json/schemas/package.json"); -pub(super) fn json_task_context() -> ContextProviderWithTasks { - ContextProviderWithTasks::new(TaskTemplates(vec![ - TaskTemplate { - label: "package script $ZED_CUSTOM_script".to_owned(), - command: "npm --prefix $ZED_DIRNAME run".to_owned(), - args: vec![VariableName::Custom("script".into()).template_value()], - tags: vec!["package-script".into()], - ..TaskTemplate::default() - }, - TaskTemplate { - label: "composer script $ZED_CUSTOM_script".to_owned(), - command: "composer -d $ZED_DIRNAME".to_owned(), - args: vec![VariableName::Custom("script".into()).template_value()], - tags: vec!["composer-script".into()], - ..TaskTemplate::default() - }, - ])) -} +pub(crate) struct JsonTaskProvider; +impl ContextProvider for JsonTaskProvider { + fn associated_tasks( + &self, + _: Arc, + file: Option>, + cx: &App, + ) -> gpui::Task> { + let Some(file) = project::File::from_dyn(file.as_ref()) + .filter(|file| file.path.file_name() == Some("package.json".as_ref())) + .cloned() + else { + return Task::ready(None); + }; + + cx.spawn(async move |cx| { + let contents = file + .worktree + .update(cx, |this, cx| this.load_file(&file.path, cx)) + .ok()? + .await + .ok()?; + + let as_json = serde_json_lenient::Value::from_str(&contents.text).ok()?; + let gutter_tasks = [ + TaskTemplate { + label: "package script $ZED_CUSTOM_script".to_owned(), + command: "npm".to_owned(), + args: vec![ + "--prefix".into(), + "$ZED_DIRNAME".into(), + "run".into(), + VariableName::Custom("script".into()).template_value(), + ], + tags: vec!["package-script".into()], + ..TaskTemplate::default() + }, + TaskTemplate { + label: "composer script $ZED_CUSTOM_script".to_owned(), + command: "composer".to_owned(), + args: vec![ + "-d".into(), + "$ZED_DIRNAME".into(), + VariableName::Custom("script".into()).template_value(), + ], + tags: vec!["composer-script".into()], + ..TaskTemplate::default() + }, + ]; + let tasks = as_json + .get("scripts")? + .as_object()? + .keys() + .map(|key| TaskTemplate { + label: format!("run {key}"), + command: "npm".to_owned(), + args: vec![ + "--prefix".into(), + "$ZED_DIRNAME".into(), + "run".into(), + key.into(), + ], + ..TaskTemplate::default() + }) + .chain(gutter_tasks) + .collect(); + Some(TaskTemplates(tasks)) + }) + } +} fn server_binary_arguments(server_path: &Path) -> Vec { vec![server_path.into(), "--stdio".into()] } diff --git a/crates/languages/src/json/config.toml b/crates/languages/src/json/config.toml index d20d471c30f63027be551cfccc9a15fc31fae573..1cf815704cd1d0ecd25c25e00d5925c13ff0cf35 100644 --- a/crates/languages/src/json/config.toml +++ b/crates/languages/src/json/config.toml @@ -10,6 +10,6 @@ brackets = [ ] tab_size = 2 prettier_parser_name = "json" - +debuggers = ["JavaScript"] [overrides.string] completion_query_characters = [":", " "] diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index 71ab3f095900df6bb472ed8372cfbdf7ad1ea618..5469ed522bd48d110ab1d59a4290ca30302bc5b0 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -1,6 +1,5 @@ use anyhow::Context as _; use gpui::{App, UpdateGlobal}; -use json::json_task_context; use node_runtime::NodeRuntime; use python::PyprojectTomlManifestProvider; use rust::CargoManifestProvider; @@ -12,6 +11,8 @@ use util::{ResultExt, asset_str}; pub use language::*; +use crate::json::JsonTaskProvider; + mod bash; mod c; mod css; @@ -78,7 +79,7 @@ pub fn init(languages: Arc, node: NodeRuntime, cx: &mut App) { let eslint_adapter = Arc::new(typescript::EsLintLspAdapter::new(node.clone())); let go_context_provider = Arc::new(go::GoContextProvider); let go_lsp_adapter = Arc::new(go::GoLspAdapter); - let json_context_provider = Arc::new(json_task_context()); + let json_context_provider = Arc::new(JsonTaskProvider); let json_lsp_adapter = Arc::new(json::JsonLspAdapter::new(node.clone(), languages.clone())); let node_version_lsp_adapter = Arc::new(json::NodeVersionAdapter); let py_lsp_adapter = Arc::new(python::PyLspAdapter::new()); diff --git a/crates/project/src/debugger/locators/node.rs b/crates/project/src/debugger/locators/node.rs index 7599c66a975a42b91e2a37c852c11d76fa8a69c1..32f56011a5f240c5e1dc78251466976ef342aeee 100644 --- a/crates/project/src/debugger/locators/node.rs +++ b/crates/project/src/debugger/locators/node.rs @@ -28,7 +28,10 @@ impl DapLocator for NodeLocator { if adapter.0.as_ref() != "JavaScript" { return None; } - if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() { + if build_config.command != TYPESCRIPT_RUNNER_VARIABLE.template_value() + && build_config.command != "composer" + && build_config.command != "npm" + { return None; }