Skip to content

Commit

Permalink
Set the Delve port dynamically for remote debug (#78)
Browse files Browse the repository at this point in the history
* Set the Delve port dynamically

Currently the Delve port can be defined either randomly or hard-coded by
hand.

Hard-coded port allows to know which port to use in debug
configurations, but in practice with many Go projects, it would be
great to set the Delve port in debug configurations.

Luckily `nvim-dap` allows to set an `on_config` callback for an adapter,
which can be used to resolve the adapter settings when a debug session
starts. This PR implements this `nvim-dap` feature, which can be used
with the support of VSCode `launch.json` files to greatly enhance the developer
experience.

This potentially resolves #73

* Fix textlint error

* Fix possible nil table for Go configs

* Complete the documentation

* Validate the VSCode configuration

* Update the doc according to the current version of nvim-dap

* Revert required fields

The extension now decides if it should enable the remote debugging if a
port is defined in the user configuration.
  • Loading branch information
cyb3rd4d authored Aug 6, 2024
1 parent 5030d53 commit 5511788
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 6 deletions.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ An extension for [nvim-dap][1] providing configurations for launching go debugge
- Configuration to attach nvim-dap and Delve into a running process and start a debug session.
- Configuration to start a debug session in the main function.
- Configuration to run tests in a debug session.
- Final Delve configuration is resolved when a debug session starts. This allows to use different addresses and ports for each project or launch configs in a project.

## Pre-reqs

Expand Down Expand Up @@ -67,7 +68,9 @@ lua require('dap-go').setup {
initialize_timeout_sec = 20,
-- a string that defines the port to start delve debugger.
-- default to string "${port}" which instructs nvim-dap
-- to start the process in a random available port
-- to start the process in a random available port.
-- if you set a port in your debug configuration, its value will be
-- assigned dynamically.
port = "${port}",
-- additional args to pass to dlv
args = {},
Expand Down Expand Up @@ -196,6 +199,39 @@ dlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz
nmap <silent> <leader>td :lua require('dap-go').debug_test()<CR>
```

## VSCode launch config

Defining the Go debug configurations for all your projects inside your Neovim configuration can be cumbersome and quite strict.
For more flexibility, `nvim-dap` supports the use of the VSCode launch configurations.

That allows for example to set the Delve port dynamically when you run a debug session. If you create this file in your project (`[root_project]/.vscode/launch.json`):

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Remote debug API server",
"type": "go",
"request": "attach",
"mode": "remote",
"port": 4444,
"host": "127.0.0.1",
"substitutePath": [
{
"from": "${workspaceFolder}", "to": "/usr/src/app"
}
]
}
]
}
```

A debug session `Remote debug API server` will appear in the choices, and the Delve port will be dynamically set to `4444`.
The current version of nvim-dap always loads the file if it exists.

Please see `:h dap-launch.json` for more information.

## Acknowledgement

Thanks to the [nvim-dap-python][6] for the inspiration.
Expand Down
44 changes: 41 additions & 3 deletions doc/nvim-dap-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ CONTENTS *dap-go-toc*
5. Debugging With Command-Line Arguments . |dap-go-debug-cli-args|
6. Debugging With Build Flags ............ |dap-go-debug-cli-args|
7. Debugging With dlv in Headless Mode ... |dap-go-debug-headless|
8. Mappings .............................. |dap-go-mappings|
8. VSCode launch config .................. |dap-go-vscode-launch|
9. Mappings .............................. |dap-go-mappings|

========================================================================
FEATURES *dap-go-features*
Expand All @@ -36,6 +37,10 @@ FEATURES *dap-go-features*

- Configuration to run tests in a debug session.

- Final Delve configuration is resolved when a debug session starts.
This allows to use different addresses and ports for each project or
launch configs in a project.

This plugin makes usage of treesitter to find the nearest test to
debug. Make sure you have the Go treesitter parser installed. If using
|nvim-treesitter| plugin you can install with `:TSInstall go`.
Expand Down Expand Up @@ -80,7 +85,9 @@ The example bellow shows all the possible configurations:
initialize_timeout_sec = 20,
-- a string that defines the port to start delve debugger.
-- default to string "${port}" which instructs nvim-dap
-- to start the process in a random available port
-- to start the process in a random available port.
-- if you set a port in your debug configuration, its value will be
-- assigned dynamically.
port = "${port}",
-- additional args to pass to dlv
args = {},
Expand Down Expand Up @@ -207,6 +214,38 @@ Debugging With dlv in Headless Mode *dap-go-debug-headless*
3. Call `:lua require('dap').continue()` to start debugging.
4. Select the new registered option `Attach remote`.

-----------------------------------------------------------------------
VSCode launch config *dap-go-vscode-launch

1. Create in your Go project a VSCode launch config file (by
default its path must be `.vscode/launch.json` relative to your
project's root directory):
>json
{
"version": "0.2.0",
"configurations": [
{
"name": "Remote debug API server",
"type": "go",
"request": "attach",
"mode": "remote",
"port": 4444,
"host": "127.0.0.1",
"substitutePath": [
{
"from": "${workspaceFolder}", "to": "/usr/src/app"
}
]
}
]
}
<

2. A debug session `Remote debug API server` will appear in the choices,
and the Delve port will be dynamically set to `4444`.

Please see `:h dap-launch.json` for more information.

========================================================================
MAPPINGS *dap-go-mappings*

Expand All @@ -220,5 +259,4 @@ mappings. You can do this by adding the lines bellow to your
vim.keymap.set("n", "<leader>dt", dapgo.debug_test)
vim.keymap.set("n", "<leader>dl", dapgo.debug_last_test)
<

vim:tw=78:et:ft=help:norl:
30 changes: 28 additions & 2 deletions lua/dap-go.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ local function setup_delve_adapter(dap, config)
local args = { "dap", "-l", "127.0.0.1:" .. config.delve.port }
vim.list_extend(args, config.delve.args)

dap.adapters.go = {
local delve_config = {
type = "server",
port = config.delve.port,
executable = {
Expand All @@ -79,10 +79,28 @@ local function setup_delve_adapter(dap, config)
initialize_timeout_sec = config.delve.initialize_timeout_sec,
},
}

dap.adapters.go = function(callback, client_config)
if client_config.port == nil then
callback(delve_config)
return
end

local host = client_config.host
if host == nil then
host = "127.0.0.1"
end

local listener_addr = host .. ":" .. client_config.port
delve_config.port = client_config.port
delve_config.executable.args = { "dap", "-l", listener_addr }

callback(delve_config)
end
end

local function setup_go_configuration(dap, configs)
dap.configurations.go = {
local common_debug_configs = {
{
type = "go",
name = "Debug",
Expand Down Expand Up @@ -139,6 +157,14 @@ local function setup_go_configuration(dap, configs)
},
}

if dap.configurations.go == nil then
dap.configurations.go = {}
end

for _, config in ipairs(common_debug_configs) do
table.insert(dap.configurations.go, config)
end

if configs == nil or configs.dap_configurations == nil then
return
end
Expand Down

0 comments on commit 5511788

Please sign in to comment.