@@ -1,4 +1,4 @@
-use anyhow::{Context as _, anyhow};
+use anyhow::{Context as _, anyhow, bail};
use dap::{
StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest,
adapters::DebugTaskDefinition,
@@ -7,6 +7,7 @@ use dap::{
use gpui::{AsyncApp, SharedString};
use language::LanguageName;
use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
+use util;
use crate::*;
@@ -15,6 +16,7 @@ pub(crate) struct GoDebugAdapter;
impl GoDebugAdapter {
const ADAPTER_NAME: &'static str = "Delve";
+ const DEFAULT_TIMEOUT_MS: u64 = 60000;
}
#[async_trait(?Send)]
@@ -338,19 +340,75 @@ impl DebugAdapter for GoDebugAdapter {
_user_installed_path: Option<PathBuf>,
_cx: &mut AsyncApp,
) -> Result<DebugAdapterBinary> {
- let delve_path = delegate
- .which(OsStr::new("dlv"))
- .await
- .and_then(|p| p.to_str().map(|p| p.to_string()))
- .context("Dlv not found in path")?;
+ let adapter_path = paths::debug_adapters_dir().join(&Self::ADAPTER_NAME);
+ let dlv_path = adapter_path.join("dlv");
+
+ let delve_path = if let Some(path) = delegate.which(OsStr::new("dlv")).await {
+ path.to_string_lossy().to_string()
+ } else if delegate.fs().is_file(&dlv_path).await {
+ dlv_path.to_string_lossy().to_string()
+ } else {
+ let go = delegate
+ .which(OsStr::new("go"))
+ .await
+ .context("Go not found in path. Please install Go first, then Dlv will be installed automatically.")?;
+
+ let adapter_path = paths::debug_adapters_dir().join(&Self::ADAPTER_NAME);
+
+ let install_output = util::command::new_smol_command(&go)
+ .env("GO111MODULE", "on")
+ .env("GOBIN", &adapter_path)
+ .args(&["install", "github.com/go-delve/delve/cmd/dlv@latest"])
+ .output()
+ .await?;
+
+ if !install_output.status.success() {
+ bail!(
+ "failed to install dlv via `go install`. stdout: {:?}, stderr: {:?}\n Please try installing it manually using 'go install github.com/go-delve/delve/cmd/dlv@latest'",
+ String::from_utf8_lossy(&install_output.stdout),
+ String::from_utf8_lossy(&install_output.stderr)
+ );
+ }
+
+ adapter_path.join("dlv").to_string_lossy().to_string()
+ };
+
+ let mut tcp_connection = task_definition.tcp_connection.clone().unwrap_or_default();
+
+ if tcp_connection.timeout.is_none()
+ || tcp_connection.timeout.unwrap_or(0) < Self::DEFAULT_TIMEOUT_MS
+ {
+ tcp_connection.timeout = Some(Self::DEFAULT_TIMEOUT_MS);
+ }
- let tcp_connection = task_definition.tcp_connection.clone().unwrap_or_default();
let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
+ let cwd = task_definition
+ .config
+ .get("cwd")
+ .and_then(|s| s.as_str())
+ .map(PathBuf::from)
+ .unwrap_or_else(|| delegate.worktree_root_path().to_path_buf());
+
+ let arguments = if cfg!(windows) {
+ vec![
+ "dap".into(),
+ "--listen".into(),
+ format!("{}:{}", host, port),
+ "--headless".into(),
+ ]
+ } else {
+ vec![
+ "dap".into(),
+ "--listen".into(),
+ format!("{}:{}", host, port),
+ ]
+ };
+
Ok(DebugAdapterBinary {
command: delve_path,
- arguments: vec!["dap".into(), "--listen".into(), format!("{host}:{port}")],
- cwd: Some(delegate.worktree_root_path().to_path_buf()),
+ arguments,
+ cwd: Some(cwd),
envs: HashMap::default(),
connection: Some(adapters::TcpArguments {
host,
@@ -28,15 +28,15 @@ These adapters enable Zed to provide a consistent debugging experience across mu
## Getting Started
-For basic debugging you can set up a new configuration by opening up the `New Session Modal` either by the `debugger: start` (default: f4) or clicking the plus icon at the top right of the debug panel. Once the `New Session Modal` is open you can click custom on the bottom left to open a view that allows you to create a custom debug configuration. Once you have created a configuration you can save it to your workspace's `.zed/debug.json` by clicking on the save button on the bottom left.
+For basic debugging you can set up a new configuration by opening the `New Session Modal` either via the `debugger: start` (default: f4) or clicking the plus icon at the top right of the debug panel.
-For more advance use cases you can create debug configurations by directly editing the `.zed/debug.json` file in your project root directory. Once you fill out the adapter and label fields completions will show you the available options of the selected debug adapter.
+For more advanced use cases you can create debug configurations by directly editing the `.zed/debug.json` file in your project root directory.
You can then use the `New Session Modal` to select a configuration then start debugging.
### Configuration
-While configuration fields are debug adapter dependent, most adapters support the follow fields.
+While configuration fields are debug adapter dependent, most adapters support the following fields.
```json
[
@@ -71,7 +71,7 @@ Zed currently supports these types of breakpoints
- Conditional Breakpoints: Stop at the breakpoint when it's hit if the condition is met
- Hit Breakpoints: Stop at the breakpoint when it's hit a certain number of times
-Standard breakpoints can be toggled by left clicking on the editor gutter or using the Toggle Breakpoint action. Right clicking on a breakpoint, right clicking on a code runner symbol brings up the breakpoint context menu. That has options for toggling breakpoints and editing log breakpoints.
+Standard breakpoints can be toggled by left clicking on the editor gutter or using the Toggle Breakpoint action. Right clicking on a breakpoint or on a code runner symbol brings up the breakpoint context menu. This has options for toggling breakpoints and editing log breakpoints.
Other kinds of breakpoints can be toggled/edited by right clicking on the breakpoint icon in the gutter and selecting the desired option.
@@ -216,10 +216,10 @@ Other kinds of breakpoints can be toggled/edited by right clicking on the breakp
## Theme
-The Debugger supports the following theme options
+The Debugger supports the following theme options:
- /// Color used to accent some of the debuggers elements
- /// Only accent breakpoint & breakpoint related symbols right now
+ /// Color used to accent some of the debugger's elements
+ /// Only accents breakpoint & breakpoint related symbols right now
**debugger.accent**: Color used to accent breakpoint & breakpoint related symbols
**editor.debugger_active_line.background**: Background color of active debug line