Repository: leoluz/nvim-dap-go Branch: main Commit: b4421153ead5 Files: 12 Total size: 30.9 KB Directory structure: gitextract_bycjcokq/ ├── .github/ │ ├── stale.yml │ └── workflows/ │ └── lint.yml ├── .gitignore ├── .luacheckrc ├── .stylua.toml ├── LICENSE ├── README.md ├── doc/ │ └── nvim-dap-go.txt ├── lua/ │ ├── dap-go-ts.lua │ └── dap-go.lua └── tests/ ├── go.mod └── subtest_bar_test.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 180 # Number of days of inactivity before a stale issue is closed daysUntilClose: 30 # Issues with these labels will never be considered stale exemptLabels: - pinned - security # Label to use when marking an issue as stale staleLabel: wontfix # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false ================================================ FILE: .github/workflows/lint.yml ================================================ name: Lint on: pull_request: ~ push: branches: - master jobs: stylua: name: Stylua runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: JohnnyMorganz/stylua-action@v2 with: token: ${{ secrets.GITHUB_TOKEN }} # CLI arguments args: --color always --check lua/ super-linter: name: Super Linter runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Lint Code Base uses: github/super-linter/slim@v4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VALIDATE_JSCPD: false VALIDATE_PYTHON_BLACK: false ================================================ FILE: .gitignore ================================================ doc/tags .luarc.json ================================================ FILE: .luacheckrc ================================================ globals = { "vim", } read_globals = { "describe", "it", "before_each", "after_each", "assert" } ================================================ FILE: .stylua.toml ================================================ column_width = 120 line_endings = "Unix" indent_type = "Spaces" indent_width = 2 quote_style = "AutoPreferDouble" call_parentheses = "Always" ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2023 Leonardo Luz Almeida Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # nvim-dap-go An extension for [nvim-dap][1] providing configurations for launching go debugger (delve) and debugging individual tests. ## Features - Auto launch Delve. No configuration needed. You just have to have `dlv` in your path. - Run just the closest test from the cursor in debug mode (uses treesitter). See [debugging individual tests](#debugging-individual-tests) section below for more details. - 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 - Neovim >= 0.9.0 - [nvim-dap][1] - [delve][2] >= 1.7.0 This plugin extension make usage of treesitter to find the nearest test to debug. Make sure you have the Go treesitter parser installed. If using [nvim-treesitter][3] plugin you can install with `:TSInstall go`. ## Installation - Install like any other neovim plugin: - If using [vim-plug][4]: `Plug 'leoluz/nvim-dap-go'` - If using [packer.nvim][5]: `use 'leoluz/nvim-dap-go'` ## Usage ### Register the plugin Call the setup function in your `init.vim` to register the go adapter and the configurations to debug go tests: ```vimL lua require('dap-go').setup() ``` ### Configuring It is possible to customize nvim-dap-go by passing a config table in the setup function. The example below shows all the possible configurations: ```lua lua require('dap-go').setup { -- Additional dap configurations can be added. -- dap_configurations accepts a list of tables where each entry -- represents a dap configuration. For more details do: -- :help dap-configuration dap_configurations = { { -- Must be "go" or it will be ignored by the plugin type = "go", name = "Attach remote", mode = "remote", request = "attach", }, }, -- delve configurations delve = { -- the path to the executable dlv which will be used for debugging. -- by default, this is the "dlv" executable on your PATH. path = "dlv", -- time to wait for delve to initialize the debug session. -- default to 20 seconds 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. -- if you set a port in your debug configuration, its value will be -- assigned dynamically. port = "${port}", -- additional args to pass to dlv args = {}, -- the build flags that are passed to delve. -- defaults to empty string, but can be used to provide flags -- such as "-tags=unit" to make sure the test suite is -- compiled during debugging, for example. -- passing build flags using args is ineffective, as those are -- ignored by delve in dap mode. -- avaliable ui interactive function to prompt for arguments get_arguments build_flags = {}, -- whether the dlv process to be created detached or not. there is -- an issue on delve versions < 1.24.0 for Windows where this needs to be -- set to false, otherwise the dlv server creation will fail. -- avaliable ui interactive function to prompt for build flags: get_build_flags detached = vim.fn.has("win32") == 0, -- the current working directory to run dlv from, if other than -- the current working directory. cwd = nil, }, -- options related to running closest test tests = { -- enables verbosity when running the test. verbose = false, }, } ``` ### Use nvim-dap as usual - Call `:lua require('dap').continue()` to start debugging. - All pre-configured debuggers will be displayed for you to choose from. - See `:help dap-mappings` and `:help dap-api`. ### Debugging individual tests To debug the closest method above the cursor use you can run: - `:lua require('dap-go').debug_test()` Once a test was run, you can simply run it again from anywhere: - `:lua require('dap-go').debug_last_test()` It is better to define a mapping to invoke this command. See the mapping section below. ### Debugging with command-line arguments 1. Select the option `Debug (Arguments)` 1. Enter each argument separated by a space (i.e. `option1 option2 option3`) 1. Press enter ![Start Debug Session with Arguments](./images/image1.png "Start Debug Session with Arguments") ![Enter Arguments](./images/image2.png "Enter Arguments") ![Begin Debugging](./images/image3.png "Being Debugging") ### Debugging with build flags 1. Register a new option to debug with build flags: ```lua require('dap-go').setup ({ dap_configurations = { { type = "go", name = "Debug (Build Flags)", request = "launch", program = "${file}", buildFlags = require("dap-go").get_build_flags, }, }, }) ``` 2. To prompt for both build flags and arguments register the following: ```lua require("dap-go").setup({ dap_configurations = { { type = "go", name = "Debug (Build Flags & Arguments)", request = "launch", program = "${file}", args = require("dap-go").get_arguments, buildFlags = require("dap-go").get_build_flags, }, } }) ``` 3. To create a custom debugging configuration that requires an interactive prompt the following functions can be attached to the args and buildFlags fields of dap_configurations. - `require('dap-go').get_arguments` - `require('dap-go').get_buid_flags` ### Debugging with dlv in headless mode 1. Register a new option to attach to a remote debugger: ```lua lua require('dap-go').setup { dap_configurations = { { type = "go", name = "Attach remote", mode = "remote", request = "attach", }, }, } ``` 1. Start `dlv` in headless mode. You can specify subcommands and flags after `--`, e.g., ```sh dlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz ``` 1. Call `:lua require('dap').continue()` to start debugging. 1. Select the new registered option `Attach remote`. ## Mappings ```vimL 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. [1]: https://github.com/mfussenegger/nvim-dap [2]: https://github.com/go-delve/delve [3]: https://github.com/nvim-treesitter/nvim-treesitter [4]: https://github.com/junegunn/vim-plug [5]: https://github.com/wbthomason/packer.nvim [6]: https://github.com/mfussenegger/nvim-dap-python ================================================ FILE: doc/nvim-dap-go.txt ================================================ ======================================================================== INTRODUCTION *dap-go* nvim-dap-go is an extension for nvim-dap (see |dap.txt|) providing configurations for launching go debugger (delve) and debugging individual tests. As such, it requires nvim-dap go to be installed. For more details see https://github.com/mfussenegger/nvim-dap#installation ======================================================================== CONTENTS *dap-go-toc* 1. Features .............................. |dap-go-features| 2. Configuration ......................... |dap-go-configuration| 3. Usage ................................. |dap-go-usage| 4. Debugging Individual Tests ............ |dap-go-debug-test| 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. VSCode launch config .................. |dap-go-vscode-launch| 9. Mappings .............................. |dap-go-mappings| ======================================================================== FEATURES *dap-go-features* - Auto launch Delve. No configuration needed. You just have to have `dlv` in your path. - Run just the closest test from the cursor in debug mode (uses |treesitter|). See [debugging individual tests](#debugging-individual-tests) section bellow for more details. - 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. 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`. ======================================================================== CONFIGURATION *dap-go-configuration* Register the plugin by calling the setup function in your `init.lua`: >lua require('dap-go').setup() < This will apply all default configurations which is all you need for normal use-cases. It is possible to customize nvim-dap-go by passing a config table in the setup function. The example bellow shows all the possible configurations: >lua require('dap-go').setup { -- Additional dap configurations can be added. -- dap_configurations accepts a list of tables where each entry -- represents a dap configuration. For more details see: -- |dap-configuration| dap_configurations = { { -- Must be "go" or it will be ignored by the plugin type = "go", name = "Attach remote", mode = "remote", request = "attach", }, }, -- delve configurations delve = { -- the path to the executable dlv which will be used for debugging. -- by default, this is the "dlv" executable on your PATH. path = "dlv", -- time to wait for delve to initialize the debug session. -- default to 20 seconds 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. -- if you set a port in your debug configuration, its value will be -- assigned dynamically. port = "${port}", -- additional args to pass to dlv args = {}, -- the build flags that are passed to delve. -- defaults to empty string, but can be used to provide flags -- such as "-tags=unit" to make sure the test suite is -- compiled during debugging, for example. -- passing build flags using args is ineffective, as those are -- ignored by delve in dap mode. build_flags = "", -- whether the dlv process to be created detached or not. there is -- an issue on delve versions < 1.24.0 for Windows where this needs to be -- set to false, otherwise the dlv server creation will fail. detached = vim.fn.has("win32") == 0, }, -- options related to running closest test tests = { -- enables verbosity when running the test. verbose = false, }, } < ======================================================================== USAGE *dap-go-usage* Once the plugin is registered, use nvim-dap as usual: - Call `:lua require('dap').continue()` to start debugging. - All pre-configured debuggers will be displayed for you to choose from. - See |dap-mappings| and |dap-api|. ----------------------------------------------------------------------- Debugging Individual Tests *dap-go-debug-test* To debug the closest method above the cursor use you can run: > :lua require('dap-go').debug_test()` < The |dap-configuration| in use can be customized by passing an optional table argument to `debug-test`. For example, you can override default build flags as follows: >lua require("dap-go").debug_test({ buildFlags = "-tags=integration", }) < Once a test runs, you can simply run it again from anywhere: > :lua require('dap-go').debug_last_test()` < It is better to define mappings to invoke these commands. See the |dap-go-mappings| section bellow. ----------------------------------------------------------------------- Debugging With Command-Line Arguments *dap-go-debug-cli-args* 1. Select the option `Debug (Arguments)`. 2. Enter each argument separated by a space (i.e. `option1 option2 option3`). 3. Press enter. ----------------------------------------------------------------------- Debugging With Build Flags *dap-go-debug-build-flags* 1. Register a new option to debug with build flags: >lua require('dap-go').setup { dap_configurations = { { type = "go", name = "Debug (Build Flags)", request = "launch", program = "${file}", buildFlags = require("dap-go").get_build_flags, }, }, }) < 2. To prompt for both build flags and arguments register the following: >lua require("dap-go").setup({ dap_configurations = { { type = "go", name = "Debug (Build Flags & Arguments)", request = "launch", program = "${file}", args = require("dap-go").get_arguments, buildFlags = require("dap-go").get_build_flags, }, } }) < 3. To create a custom debugging configuration that requires an interactive prompt the following functions can be attached to the args and buildFlags fields of dap_configurations. `require('dap-go').get_arguments` `require('dap-go').get_buid_flags` ----------------------------------------------------------------------- Debugging With dlv in Headless Mode *dap-go-debug-headless* 1. Register a new option to attach to a remote debugger: >lua require('dap-go').setup { dap_configurations = { { type = "go", name = "Attach remote", mode = "remote", request = "attach", }, }, } < 2. Start `dlv` in headless mode. You can specify subcommands and flags after `--`, e.g., >sh dlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz < 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* nvim-dap-go doesn't provide any pre-configured keymaps. It does provide lua functions that you can easly use to define your own mappings. You can do this by adding the lines bellow to your `init.lua`: >lua local dapgo = require('dap-go') vim.keymap.set("n", "dt", dapgo.debug_test) vim.keymap.set("n", "dl", dapgo.debug_last_test) < vim:tw=78:et:ft=help:norl: ================================================ FILE: lua/dap-go-ts.lua ================================================ local M = {} local tests_query = [[ (function_declaration name: (identifier) @testname parameters: (parameter_list . (parameter_declaration type: (pointer_type) @type) .) (#match? @type "*testing.(T|M)") (#match? @testname "^Test.+$")) @parent ]] local subtests_query = [[ (call_expression function: (selector_expression operand: (identifier) field: (field_identifier) @run) arguments: (argument_list (interpreted_string_literal) @testname [ (func_literal) (identifier) ]) (#eq? @run "Run")) @parent ]] local function format_subtest(testcase, test_tree) local parent if testcase.parent then for _, curr in pairs(test_tree) do if curr.name == testcase.parent then parent = curr break end end return string.format("%s/%s", format_subtest(parent, test_tree), testcase.name) else return testcase.name end end local function get_closest_above_cursor(test_tree) local result for _, curr in pairs(test_tree) do if not result then result = curr else local node_row1, _, _, _ = curr.node:range() local result_row1, _, _, _ = result.node:range() if node_row1 > result_row1 then result = curr end end end if result then return format_subtest(result, test_tree) end return nil end local function is_parent(dest, source) if not (dest and source) then return false end if dest == source then return false end local current = source while current ~= nil do if current == dest then return true end current = current:parent() end return false end local function get_closest_test() local stop_row = vim.api.nvim_win_get_cursor(0)[1] local ft = vim.api.nvim_buf_get_option(0, "filetype") assert(ft == "go", "can only find test in go files, not " .. ft) local parser = vim.treesitter.get_parser(0) local root = (parser:parse()[1]):root() local test_tree = {} local test_query = vim.treesitter.query.parse(ft, tests_query) assert(test_query, "could not parse test query") for _, match, _ in test_query:iter_matches(root, 0, 0, stop_row, { all = true }) do local test_match = {} for id, nodes in pairs(match) do for _, node in ipairs(nodes) do local capture = test_query.captures[id] if capture == "testname" then local name = vim.treesitter.get_node_text(node, 0) test_match.name = name end if capture == "parent" then test_match.node = node end end end table.insert(test_tree, test_match) end local subtest_query = vim.treesitter.query.parse(ft, subtests_query) assert(subtest_query, "could not parse test query") for _, match, _ in subtest_query:iter_matches(root, 0, 0, stop_row, { all = true }) do local test_match = {} for id, nodes in pairs(match) do for _, node in ipairs(nodes) do local capture = subtest_query.captures[id] if capture == "testname" then local name = vim.treesitter.get_node_text(node, 0) test_match.name = string.gsub(string.gsub(name, " ", "_"), '"', "") end if capture == "parent" then test_match.node = node end end end table.insert(test_tree, test_match) end table.sort(test_tree, function(a, b) return is_parent(a.node, b.node) end) for _, parent in ipairs(test_tree) do for _, child in ipairs(test_tree) do if is_parent(parent.node, child.node) then child.parent = parent.name end end end return get_closest_above_cursor(test_tree) end local function get_package_name() local test_dir = vim.fn.fnamemodify(vim.fn.expand("%:.:h"), ":r") return "./" .. test_dir end M.closest_test = function() local package_name = get_package_name() local test_case = get_closest_test() local test_scope if test_case then test_scope = "testcase" else test_scope = "package" end return { package = package_name, name = test_case, scope = test_scope, } end M.get_root_dir = function() local id, client = next(vim.lsp.buf_get_clients()) if id == nil then error({ error_msg = "lsp client not attached" }) end if not client.config.root_dir then error({ error_msg = "lsp root_dir not defined" }) end return client.config.root_dir end return M ================================================ FILE: lua/dap-go.lua ================================================ local ts = require("dap-go-ts") local M = { last_testname = "", last_testpath = "", test_buildflags = "", test_verbose = false, } local default_config = { delve = { path = "dlv", initialize_timeout_sec = 20, port = "${port}", args = {}, build_flags = "", -- Automatically handle the issue on delve Windows versions < 1.24.0 -- where delve needs to be run in attched mode or it will fail (actually crashes). detached = vim.fn.has("win32") == 0, output_mode = "remote", }, tests = { verbose = false, }, } local internal_global_config = {} local function load_module(module_name) local ok, module = pcall(require, module_name) assert(ok, string.format("dap-go dependency error: %s not installed", module_name)) return module end local function get_arguments() return coroutine.create(function(dap_run_co) local args = {} vim.ui.input({ prompt = "Args: " }, function(input) args = vim.split(input or "", " ") coroutine.resume(dap_run_co, args) end) end) end local function get_build_flags(config) return coroutine.create(function(dap_run_co) local build_flags = config.build_flags vim.ui.input({ prompt = "Build Flags: " }, function(input) build_flags = vim.split(input or "", " ") coroutine.resume(dap_run_co, build_flags) end) end) end local function filtered_pick_process() local opts = {} vim.ui.input( { prompt = "Search by process name (lua pattern), or hit enter to select from the process list: " }, function(input) opts["filter"] = input or "" end ) return require("dap.utils").pick_process(opts) end 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) local delve_config = { type = "server", port = config.delve.port, executable = { command = config.delve.path, args = args, detached = config.delve.detached, cwd = config.delve.cwd, }, options = { 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) local common_debug_configs = { { type = "go", name = "Debug", request = "launch", program = "${file}", buildFlags = configs.delve.build_flags, outputMode = configs.delve.output_mode, }, { type = "go", name = "Debug (Arguments)", request = "launch", program = "${file}", args = get_arguments, buildFlags = configs.delve.build_flags, outputMode = configs.delve.output_mode, }, { type = "go", name = "Debug (Arguments & Build Flags)", request = "launch", program = "${file}", args = get_arguments, buildFlags = get_build_flags, outputMode = configs.delve.output_mode, }, { type = "go", name = "Debug Package", request = "launch", program = "${fileDirname}", buildFlags = configs.delve.build_flags, outputMode = configs.delve.output_mode, }, { type = "go", name = "Attach", mode = "local", request = "attach", processId = filtered_pick_process, buildFlags = configs.delve.build_flags, }, { type = "go", name = "Debug test", request = "launch", mode = "test", program = "${file}", buildFlags = configs.delve.build_flags, outputMode = configs.delve.output_mode, }, { type = "go", name = "Debug test (go.mod)", request = "launch", mode = "test", program = "./${relativeFileDirname}", buildFlags = configs.delve.build_flags, outputMode = configs.delve.output_mode, }, } 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 for _, config in ipairs(configs.dap_configurations) do if config.type == "go" then table.insert(dap.configurations.go, config) end end end function M.setup(opts) internal_global_config = vim.tbl_deep_extend("force", default_config, opts or {}) M.test_buildflags = internal_global_config.delve.build_flags M.test_verbose = internal_global_config.tests.verbose local dap = load_module("dap") setup_delve_adapter(dap, internal_global_config) setup_go_configuration(dap, internal_global_config) end local function debug_test(testname, testpath, build_flags, extra_args, custom_config) local dap = load_module("dap") local config = { type = "go", name = testname, request = "launch", mode = "test", program = testpath, args = { "-test.run", "^" .. testname .. "$" }, buildFlags = build_flags, outputMode = "remote", } config = vim.tbl_deep_extend("force", config, custom_config or {}) if not vim.tbl_isempty(extra_args) then table.move(extra_args, 1, #extra_args, #config.args + 1, config.args) end dap.run(config) end function M.debug_test(custom_config) local test = ts.closest_test() if test.name == "" or test.name == nil then vim.notify("no test found") return false end M.last_testname = test.name M.last_testpath = test.package local msg = string.format("starting debug session '%s : %s'...", test.package, test.name) vim.notify(msg) local extra_args = {} if M.test_verbose then extra_args = { "-test.v" } end debug_test(test.name, test.package, M.test_buildflags, extra_args, custom_config) return true end function M.debug_last_test() local testname = M.last_testname local testpath = M.last_testpath if testname == "" then vim.notify("no last run test found") return false end local msg = string.format("starting debug session '%s : %s'...", testpath, testname) vim.notify(msg) local extra_args = {} if M.test_verbose then extra_args = { "-test.v" } end debug_test(testname, testpath, M.test_buildflags, extra_args) return true end function M.get_build_flags() return get_build_flags(internal_global_config) end function M.get_arguments() return get_arguments() end return M ================================================ FILE: tests/go.mod ================================================ module github.com/leoluz/nvim-dap-go go 1.22.2 ================================================ FILE: tests/subtest_bar_test.go ================================================ package tests import ( "testing" ) // https://github.com/leoluz/nvim-dap-go/pull/82 func TestWithSubTests(t *testing.T) { t.Run("subtest with function literal", func(t *testing.T) { t.Fail() }) myFunc := func(t *testing.T) { t.FailNow() } t.Run("subtest with identifier", myFunc) }