rust: Add support for doctest runnables (#24806)

Coenen Benjamin created

Screenshot:


![image](https://github.com/user-attachments/assets/0ac88029-76c1-4135-bef2-373636e3587d)

I would be happy to add tests if you point me to the right place to do
it please.

Release Notes:

- Added support for doc test in tasks for Rust

---------

Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com>

Change summary

crates/languages/src/rust.rs            | 20 ++++++++++++
crates/languages/src/rust/runnables.scm | 42 ++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)

Detailed changes

crates/languages/src/rust.rs 🔗

@@ -577,6 +577,26 @@ impl ContextProvider for RustContextProvider {
                 cwd: Some("$ZED_DIRNAME".to_owned()),
                 ..TaskTemplate::default()
             },
+            TaskTemplate {
+                label: format!(
+                    "DocTest '{}' (package: {})",
+                    VariableName::Symbol.template_value(),
+                    RUST_PACKAGE_TASK_VARIABLE.template_value(),
+                ),
+                command: "cargo".into(),
+                args: vec![
+                    "test".into(),
+                    "--doc".into(),
+                    "-p".into(),
+                    RUST_PACKAGE_TASK_VARIABLE.template_value(),
+                    VariableName::Symbol.template_value(),
+                    "--".into(),
+                    "--nocapture".into(),
+                ],
+                tags: vec!["rust-doc-test".to_owned()],
+                cwd: Some("$ZED_DIRNAME".to_owned()),
+                ..TaskTemplate::default()
+            },
             TaskTemplate {
                 label: format!(
                     "Test '{}' (package: {})",

crates/languages/src/rust/runnables.scm 🔗

@@ -1,4 +1,4 @@
-
+; Rust mod test
 (
     (mod_item
         name: (_) @run
@@ -7,6 +7,7 @@
     (#set! tag rust-mod-test)
 )
 
+; Rust test
 (
     (
         (attribute_item (attribute
@@ -28,6 +29,45 @@
     (#set! tag rust-test)
 )
 
+; Rust doc test
+(
+    (
+        (line_comment) *
+        (line_comment
+            doc: (_) @_comment_content
+        ) @start
+        (#match? @_comment_content "```")
+        (line_comment) *
+        (line_comment
+            doc: (_) @_end_comment_content
+        ) @_end_code_block
+        (#match? @_end_comment_content "```")
+        .
+        (attribute_item) *
+        .
+        [(line_comment) (block_comment)] *
+        .
+        [(function_item
+            name: (_) @run
+            body: _
+        ) (function_signature_item
+            name: (_) @run
+        ) (struct_item
+            name: (_) @run
+        ) (enum_item
+            name: (_) @run
+            body: _
+        ) (
+            (attribute_item) ?
+            (macro_definition
+                name: (_) @run)
+        ) (mod_item
+            name: (_) @run
+        )] @_end
+    )
+    (#set! tag rust-doc-test)
+)
+
 ; Rust main function
 (
     (