From 5511788255c92bdd845f8d9690f88e2e0f0ff9f2 Mon Sep 17 00:00:00 2001 From: cyb3rd4d <300826+cyb3rd4d@users.noreply.github.com> Date: Tue, 6 Aug 2024 03:38:04 +0200 Subject: [PATCH] Set the Delve port dynamically for remote debug (#78) * 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 https://github.com/leoluz/nvim-dap-go/issues/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. --- README.md | 38 +++++++++++++++++++++++++++++++++++++- doc/nvim-dap-go.txt | 44 +++++++++++++++++++++++++++++++++++++++++--- lua/dap-go.lua | 30 ++++++++++++++++++++++++++++-- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 06d05b7..38974d2 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 = {}, @@ -196,6 +199,39 @@ dlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz nmap td :lua require('dap-go').debug_test() ``` +## 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. diff --git a/doc/nvim-dap-go.txt b/doc/nvim-dap-go.txt index f62e0ae..3252561 100644 --- a/doc/nvim-dap-go.txt +++ b/doc/nvim-dap-go.txt @@ -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* @@ -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`. @@ -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 = {}, @@ -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* @@ -220,5 +259,4 @@ mappings. You can do this by adding the lines bellow to your vim.keymap.set("n", "dt", dapgo.debug_test) vim.keymap.set("n", "dl", dapgo.debug_last_test) < - vim:tw=78:et:ft=help:norl: diff --git a/lua/dap-go.lua b/lua/dap-go.lua index cfded30..6e125a9 100644 --- a/lua/dap-go.lua +++ b/lua/dap-go.lua @@ -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 = { @@ -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", @@ -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