json: Register tasks on Rust side and not via tasks.json (#12345)

Piotr Osiewicz created

/cc @RemcoSmitsDev new task indicators weren't showing for me in JSON
files.
`tasks.json` of native grammars is not being read by anything by
default, so we tend to register tasks as Rust structs, foregoing the
deserialization step. This doesn't apply to tasks registered in
extensions, which have to have tasks.json.

Release Notes:

- N/A

Change summary

crates/languages/src/json.rs         | 21 +++++++++++++++++++++
crates/languages/src/json/tasks.json | 14 --------------
crates/languages/src/lib.rs          |  4 +++-
3 files changed, 24 insertions(+), 15 deletions(-)

Detailed changes

crates/languages/src/json.rs 🔗

@@ -7,6 +7,7 @@ use gpui::{AppContext, AsyncAppContext};
 use language::{LanguageRegistry, LanguageServerName, LspAdapter, LspAdapterDelegate};
 use lsp::LanguageServerBinary;
 use node_runtime::NodeRuntime;
+use project::ContextProviderWithTasks;
 use serde_json::{json, Value};
 use settings::{KeymapFile, SettingsJsonSchemaParams, SettingsStore};
 use smol::fs;
@@ -16,10 +17,30 @@ use std::{
     path::{Path, PathBuf},
     sync::{Arc, OnceLock},
 };
+use task::{TaskTemplate, TaskTemplates, VariableName};
 use util::{maybe, paths, ResultExt};
 
 const SERVER_PATH: &str = "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver";
 
+pub(super) fn json_task_context() -> ContextProviderWithTasks {
+    ContextProviderWithTasks::new(TaskTemplates(vec![
+        TaskTemplate {
+            label: "package script $ZED_CUSTOM_script".to_owned(),
+            command: "npm 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".to_owned(),
+            args: vec![VariableName::Custom("script".into()).template_value()],
+            tags: vec!["composer-script".into()],
+            ..TaskTemplate::default()
+        },
+    ]))
+}
+
 fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
     vec![server_path.into(), "--stdio".into()]
 }

crates/languages/src/json/tasks.json 🔗

@@ -1,14 +0,0 @@
-[
-  {
-    "label": "package script $ZED_CUSTOM_script",
-    "command": "npm run",
-    "args": ["$ZED_CUSTOM_script"],
-    "tags": ["package-script"]
-  },
-  {
-    "label": "composer script $ZED_CUSTOM_script",
-    "command": "composer",
-    "args": ["$ZED_CUSTOM_script"],
-    "tags": ["composer-script"]
-  }
-]

crates/languages/src/lib.rs 🔗

@@ -1,5 +1,6 @@
 use anyhow::Context;
 use gpui::{AppContext, UpdateGlobal};
+use json::json_task_context;
 pub use language::*;
 use node_runtime::NodeRuntime;
 use rust_embed::RustEmbed;
@@ -119,7 +120,8 @@ pub fn init(
         vec![Arc::new(json::JsonLspAdapter::new(
             node_runtime.clone(),
             languages.clone(),
-        ))]
+        ))],
+        json_task_context()
     );
     language!("markdown");
     language!(