diff --git a/crates/languages/src/rust.rs b/crates/languages/src/rust.rs index 8b2e48ff1595e2f8e1f1b185eeb4d760b74bbfea..fa13957d1d1645fd1b8d7918fd5defa6ba2cde54 100644 --- a/crates/languages/src/rust.rs +++ b/crates/languages/src/rust.rs @@ -389,6 +389,22 @@ impl ContextProvider for RustContextProvider { tags: vec!["rust-test".to_owned()], ..TaskTemplate::default() }, + TaskTemplate { + label: format!( + "cargo test -p {} {}", + RUST_PACKAGE_TASK_VARIABLE.template_value(), + VariableName::Stem.template_value(), + ), + command: "cargo".into(), + args: vec![ + "test".into(), + "-p".into(), + RUST_PACKAGE_TASK_VARIABLE.template_value(), + VariableName::Stem.template_value(), + ], + tags: vec!["rust-mod-test".to_owned()], + ..TaskTemplate::default() + }, TaskTemplate { label: format!( "cargo test -p {}", diff --git a/crates/languages/src/rust/runnables.scm b/crates/languages/src/rust/runnables.scm index a0409623b873a0a2c324df72129f523b1841dd4d..f722fb00d70b66a43c5d9c477bdb753290584a17 100644 --- a/crates/languages/src/rust/runnables.scm +++ b/crates/languages/src/rust/runnables.scm @@ -1,3 +1,8 @@ +(mod_item + name: (_) @run + (#eq? @run "tests") +) @rust-mod-test + ( (attribute_item (attribute [((identifier) @_attribute) diff --git a/crates/project/src/task_inventory.rs b/crates/project/src/task_inventory.rs index 9f16de1f92717e964350c4f1dddfe6521e837b59..fbed35e3828525701f23bd3f5e3bef5e0f90df1c 100644 --- a/crates/project/src/task_inventory.rs +++ b/crates/project/src/task_inventory.rs @@ -550,7 +550,17 @@ impl ContextProvider for BasicContextProvider { task_variables.insert(VariableName::SelectedText, selected_text); } if let Some(path) = current_file { - task_variables.insert(VariableName::File, path); + task_variables.insert(VariableName::File, path.clone()); + + let path = Path::new(&path); + + if let Some(filename) = path.file_name().and_then(|f| f.to_str()) { + task_variables.insert(VariableName::Filename, String::from(filename)); + } + + if let Some(stem) = path.file_stem().and_then(|s| s.to_str()) { + task_variables.insert(VariableName::Stem, String::from(stem)); + } } let worktree_abs_path = buffer diff --git a/crates/task/src/lib.rs b/crates/task/src/lib.rs index d1c9aa22ccdb29b54952d2a7188dc847e6267749..3d7a4e3a5b4083da4ffef0cf2f05f3c6770ca822 100644 --- a/crates/task/src/lib.rs +++ b/crates/task/src/lib.rs @@ -124,6 +124,10 @@ impl ResolvedTask { pub enum VariableName { /// An absolute path of the currently opened file. File, + /// the currently opened filename. + Filename, + /// stem (filename without extension) of the currently opened file. + Stem, /// An absolute path of the currently opened worktree, that contains the file. WorktreeRoot, /// A symbol text, that contains latest cursor/selection position. @@ -160,6 +164,8 @@ impl std::fmt::Display for VariableName { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Self::File => write!(f, "{ZED_VARIABLE_NAME_PREFIX}FILE"), + Self::Filename => write!(f, "{ZED_VARIABLE_NAME_PREFIX}FILENAME"), + Self::Stem => write!(f, "{ZED_VARIABLE_NAME_PREFIX}STEM"), Self::WorktreeRoot => write!(f, "{ZED_VARIABLE_NAME_PREFIX}WORKTREE_ROOT"), Self::Symbol => write!(f, "{ZED_VARIABLE_NAME_PREFIX}SYMBOL"), Self::Row => write!(f, "{ZED_VARIABLE_NAME_PREFIX}ROW"), diff --git a/crates/tasks_ui/src/lib.rs b/crates/tasks_ui/src/lib.rs index 8b91ccd26860109182ac2ecc02cb2005ba4eb43b..bbc3161cd7c73bd5253c776704f92002c29214ff 100644 --- a/crates/tasks_ui/src/lib.rs +++ b/crates/tasks_ui/src/lib.rs @@ -260,6 +260,8 @@ mod tests { cwd: Some("/dir".into()), task_variables: TaskVariables::from_iter([ (VariableName::File, "/dir/rust/b.rs".into()), + (VariableName::Filename, "b.rs".into()), + (VariableName::Stem, "b".into()), (VariableName::WorktreeRoot, "/dir".into()), (VariableName::Row, "1".into()), (VariableName::Column, "1".into()), @@ -276,6 +278,8 @@ mod tests { cwd: Some("/dir".into()), task_variables: TaskVariables::from_iter([ (VariableName::File, "/dir/rust/b.rs".into()), + (VariableName::Filename, "b.rs".into()), + (VariableName::Stem, "b".into()), (VariableName::WorktreeRoot, "/dir".into()), (VariableName::Row, "1".into()), (VariableName::Column, "15".into()), @@ -293,6 +297,8 @@ mod tests { cwd: Some("/dir".into()), task_variables: TaskVariables::from_iter([ (VariableName::File, "/dir/a.ts".into()), + (VariableName::Filename, "a.ts".into()), + (VariableName::Stem, "a".into()), (VariableName::WorktreeRoot, "/dir".into()), (VariableName::Row, "1".into()), (VariableName::Column, "1".into()), diff --git a/docs/src/tasks.md b/docs/src/tasks.md index 5a9a81adc5f88a91b0a46b07d7d7c4ec2b0d03f6..a89f5e9436dfb557fd36c064f47725453d9fda22 100644 --- a/docs/src/tasks.md +++ b/docs/src/tasks.md @@ -43,10 +43,12 @@ These variables allow you to pull information from the current editor and use it - `ZED_COLUMN`: current line column - `ZED_ROW`: current line row -- `ZED_FILE`: absolute path to the file +- `ZED_FILE`: absolute path of the currently opened file (e.g. `/Users/my-user/path/to/project/src/main.rs`) +- `ZED_FILENAME`: filename of the currently opened file (e.g. `main.rs`) +- `ZED_STEM`: stem (filename without extension) of the currently opened file (e.g. `main`) - `ZED_SYMBOL`: currently selected symbol; should match the last symbol shown in a symbol breadcrumb (e.g. `mod tests > fn test_task_contexts`) - `ZED_SELECTED_TEXT`: currently selected text -- `ZED_WORKTREE_ROOT`: absolute path to the root of the current worktree. +- `ZED_WORKTREE_ROOT`: absolute path to the root of the current worktree. (e.g. `/Users/my-user/path/to/project`) - `ZED_CUSTOM_RUST_PACKAGE`: (Rust-specific) name of the parent package of $ZED_FILE source file. To use a variable in a task, prefix it with a dollar sign (`$`):