@@ -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<dyn Fs>,
+ file: Option<Arc<dyn language::File>>,
+ cx: &App,
+ ) -> gpui::Task<Option<TaskTemplates>> {
+ 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<OsString> {
vec![server_path.into(), "--stdio".into()]
}
@@ -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<LanguageRegistry>, 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());