mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-07 00:06:24 +03:00
go: Add runnables (#12110)
This adds support for runnables to Go. It adds the following tasks: - `go test $ZED_GO_PACKAGE -run $ZED_SYMBOL` - `go test $ZED_GO_PACKAGE` - `go test ./...` - `go run $ZED_GO_PACKAGE` if it has a `main` function Release Notes: - Added built-in Go runnables and tasks that allow users to run Go test functions, test packages, or run `main` functions. Demo: https://github.com/zed-industries/zed/assets/1185253/a6271d80-faf4-466a-bf63-efbec8fe6c35 https://github.com/zed-industries/zed/assets/1185253/92f2b616-7501-463d-b613-1ec1084ae0cd
This commit is contained in:
parent
e5b9e2044e
commit
8168ec2a28
@ -13,15 +13,17 @@ use settings::Settings;
|
||||
use smol::{fs, process};
|
||||
use std::{
|
||||
any::Any,
|
||||
borrow::Cow,
|
||||
ffi::{OsStr, OsString},
|
||||
ops::Range,
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
str,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering::SeqCst},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use task::{TaskTemplate, TaskTemplates, TaskVariables, VariableName};
|
||||
use util::{fs::remove_matching, maybe, ResultExt};
|
||||
|
||||
fn server_binary_arguments() -> Vec<OsString> {
|
||||
@ -438,6 +440,93 @@ fn adjust_runs(
|
||||
runs
|
||||
}
|
||||
|
||||
pub(crate) struct GoContextProvider;
|
||||
|
||||
const GO_PACKAGE_TASK_VARIABLE: VariableName = VariableName::Custom(Cow::Borrowed("GO_PACKAGE"));
|
||||
|
||||
impl ContextProvider for GoContextProvider {
|
||||
fn build_context(
|
||||
&self,
|
||||
worktree_abs_path: Option<&Path>,
|
||||
location: &Location,
|
||||
cx: &mut gpui::AppContext,
|
||||
) -> Result<TaskVariables> {
|
||||
let local_abs_path = location
|
||||
.buffer
|
||||
.read(cx)
|
||||
.file()
|
||||
.and_then(|file| Some(file.as_local()?.abs_path(cx)));
|
||||
|
||||
Ok(
|
||||
if let Some(buffer_dir) = local_abs_path
|
||||
.as_deref()
|
||||
.and_then(|local_abs_path| local_abs_path.parent())
|
||||
{
|
||||
// Prefer the relative form `./my-nested-package/is-here` over
|
||||
// absolute path, because it's more readable in the modal, but
|
||||
// the absolute path also works.
|
||||
let package_name = worktree_abs_path
|
||||
.and_then(|worktree_abs_path| buffer_dir.strip_prefix(worktree_abs_path).ok())
|
||||
.map(|relative_pkg_dir| {
|
||||
if relative_pkg_dir.as_os_str().is_empty() {
|
||||
".".into()
|
||||
} else {
|
||||
format!("./{}", relative_pkg_dir.to_string_lossy())
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| format!("{}", buffer_dir.to_string_lossy()));
|
||||
|
||||
TaskVariables::from_iter(Some((
|
||||
GO_PACKAGE_TASK_VARIABLE.clone(),
|
||||
package_name.to_string(),
|
||||
)))
|
||||
} else {
|
||||
TaskVariables::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn associated_tasks(&self) -> Option<TaskTemplates> {
|
||||
Some(TaskTemplates(vec![
|
||||
TaskTemplate {
|
||||
label: format!(
|
||||
"go test {} -run {}",
|
||||
GO_PACKAGE_TASK_VARIABLE.template_value(),
|
||||
VariableName::Symbol.template_value(),
|
||||
),
|
||||
command: "go".into(),
|
||||
args: vec![
|
||||
"test".into(),
|
||||
GO_PACKAGE_TASK_VARIABLE.template_value(),
|
||||
"-run".into(),
|
||||
VariableName::Symbol.template_value(),
|
||||
],
|
||||
tags: vec!["go-test".to_owned()],
|
||||
..TaskTemplate::default()
|
||||
},
|
||||
TaskTemplate {
|
||||
label: format!("go test {}", GO_PACKAGE_TASK_VARIABLE.template_value()),
|
||||
command: "go".into(),
|
||||
args: vec!["test".into(), GO_PACKAGE_TASK_VARIABLE.template_value()],
|
||||
..TaskTemplate::default()
|
||||
},
|
||||
TaskTemplate {
|
||||
label: "go test ./...".into(),
|
||||
command: "go".into(),
|
||||
args: vec!["test".into(), "./...".into()],
|
||||
..TaskTemplate::default()
|
||||
},
|
||||
TaskTemplate {
|
||||
label: format!("go run {}", GO_PACKAGE_TASK_VARIABLE.template_value(),),
|
||||
command: "go".into(),
|
||||
args: vec!["run".into(), GO_PACKAGE_TASK_VARIABLE.template_value()],
|
||||
tags: vec!["go-main".to_owned()],
|
||||
..TaskTemplate::default()
|
||||
},
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
9
crates/languages/src/go/runnables.scm
Normal file
9
crates/languages/src/go/runnables.scm
Normal file
@ -0,0 +1,9 @@
|
||||
(
|
||||
(function_declaration name: (_) @run
|
||||
(#match? @run "^Test.*"))
|
||||
) @go-test
|
||||
|
||||
(
|
||||
(function_declaration name: (_) @run
|
||||
(#eq? @run "main"))
|
||||
) @go-main
|
@ -8,7 +8,10 @@ use smol::stream::StreamExt;
|
||||
use std::{str, sync::Arc};
|
||||
use util::{asset_str, ResultExt};
|
||||
|
||||
use crate::{bash::bash_task_context, python::python_task_context, rust::RustContextProvider};
|
||||
use crate::{
|
||||
bash::bash_task_context, go::GoContextProvider, python::python_task_context,
|
||||
rust::RustContextProvider,
|
||||
};
|
||||
|
||||
mod bash;
|
||||
mod c;
|
||||
@ -103,7 +106,7 @@ pub fn init(
|
||||
"css",
|
||||
vec![Arc::new(css::CssLspAdapter::new(node_runtime.clone())),]
|
||||
);
|
||||
language!("go", vec![Arc::new(go::GoLspAdapter)]);
|
||||
language!("go", vec![Arc::new(go::GoLspAdapter)], GoContextProvider);
|
||||
language!("gomod");
|
||||
language!("gowork");
|
||||
language!(
|
||||
|
Loading…
Reference in New Issue
Block a user