Allow users to associated tasks with specific languages

Anthony created

This lets users filter tasks shown based on the active location they're
currently in

Change summary

crates/project/src/debugger/locators/go.rs     |  3 ++
crates/project/src/debugger/locators/python.rs |  1 
crates/task/src/task_template.rs               |  6 +++++
crates/tasks_ui/src/modal.rs                   | 23 +++++++++++++++++++
4 files changed, 32 insertions(+), 1 deletion(-)

Detailed changes

crates/project/src/debugger/locators/go.rs 🔗

@@ -264,6 +264,7 @@ mod tests {
             hide: HideStrategy::Never,
             shell: Shell::System,
             tags: vec![],
+            languages: vec![],
             show_summary: true,
             show_command: true,
         };
@@ -291,6 +292,7 @@ mod tests {
             hide: HideStrategy::Never,
             shell: Shell::System,
             tags: vec![],
+            languages: vec![],
             show_summary: true,
             show_command: true,
         };
@@ -429,6 +431,7 @@ mod tests {
             hide: HideStrategy::Never,
             shell: Shell::System,
             tags: vec![],
+            languages: vec![],
             show_summary: true,
             show_command: true,
         };

crates/project/src/debugger/locators/python.rs 🔗

@@ -116,6 +116,7 @@ mod test {
             reveal_target: task::RevealTarget::Dock,
             hide: task::HideStrategy::Never,
             tags: vec!["python-module-main-method".into()],
+            languages: vec![],
             shell: task::Shell::System,
             show_summary: false,
             show_command: false,

crates/task/src/task_template.rs 🔗

@@ -58,6 +58,12 @@ pub struct TaskTemplate {
     /// * `on_success` — hide the terminal tab on task success only, otherwise behaves similar to `always`.
     #[serde(default)]
     pub hide: HideStrategy,
+    /// Languages that this task template is associated with
+    /// When this list is empty, the task will be visible in all langauges.
+    /// Otherwise, the task will be visible only in the specified languages.
+    #[serde(default, deserialize_with = "non_empty_string_vec")]
+    #[schemars(length(min = 1))]
+    pub languages: Vec<String>,
     /// Represents the tags which this template attaches to.
     /// Adding this removes this task from other UI and gives you ability to run it by tag.
     #[serde(default, deserialize_with = "non_empty_string_vec")]

crates/tasks_ui/src/modal.rs 🔗

@@ -200,9 +200,30 @@ impl TasksModal {
             }
         }));
         self.picker.update(cx, |picker, cx| {
+            let language = task_contexts
+                .location()
+                .and_then(|location| location.buffer.read(cx).language())
+                .map(|lang| lang.config().name.clone());
+
             picker.delegate.task_contexts = task_contexts;
+
             picker.delegate.last_used_candidate_index = last_used_candidate_index;
-            picker.delegate.candidates = Some(new_candidates);
+            picker.delegate.candidates = Some(
+                new_candidates
+                    .into_iter()
+                    .filter(|candidate| {
+                        let task_languages = &candidate.1.original_task().languages;
+
+                        task_languages.is_empty()
+                            || language.as_ref().is_none_or(|lang| {
+                                task_languages.iter().any(|task_lang| {
+                                    task_lang.to_ascii_lowercase().as_str()
+                                        == lang.0.to_ascii_lowercase().as_str()
+                                })
+                            })
+                    })
+                    .collect(),
+            );
             picker.refresh(window, cx);
             cx.notify();
         })