Full Code of leoluz/nvim-dap-go for AI

main b4421153ead5 cached
12 files
30.9 KB
8.0k tokens
1 symbols
1 requests
Download .txt
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 <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.

[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", "<leader>dt", dapgo.debug_test)
    vim.keymap.set("n", "<leader>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)
}
Download .txt
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
Download .txt
SYMBOL INDEX (1 symbols across 1 files)

FILE: tests/subtest_bar_test.go
  function TestWithSubTests (line 8) | func TestWithSubTests(t *testing.T) {
Condensed preview — 12 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (34K chars).
[
  {
    "path": ".github/stale.yml",
    "chars": 686,
    "preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 180\n# Number of days of inactivity before a"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 695,
    "preview": "name: Lint\non:\n  pull_request: ~\n  push:\n    branches:\n      - master\njobs:\n  stylua:\n    name: Stylua\n    runs-on: ubun"
  },
  {
    "path": ".gitignore",
    "chars": 21,
    "preview": "doc/tags\n.luarc.json\n"
  },
  {
    "path": ".luacheckrc",
    "chars": 108,
    "preview": "globals = {\n  \"vim\",\n}\nread_globals = {\n  \"describe\",\n  \"it\",\n  \"before_each\",\n  \"after_each\",\n  \"assert\"\n}\n"
  },
  {
    "path": ".stylua.toml",
    "chars": 142,
    "preview": "column_width = 120\nline_endings = \"Unix\"\nindent_type = \"Spaces\"\nindent_width = 2\nquote_style = \"AutoPreferDouble\"\ncall_p"
  },
  {
    "path": "LICENSE",
    "chars": 1077,
    "preview": "MIT License\n\nCopyright (c) 2023 Leonardo Luz Almeida\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "README.md",
    "chars": 7812,
    "preview": "# nvim-dap-go\n\nAn extension for [nvim-dap][1] providing configurations for launching go debugger (delve) and debugging i"
  },
  {
    "path": "doc/nvim-dap-go.txt",
    "chars": 9606,
    "preview": "========================================================================\nINTRODUCTION                                   "
  },
  {
    "path": "lua/dap-go-ts.lua",
    "chars": 4388,
    "preview": "local M = {}\n\nlocal tests_query = [[\n(function_declaration\n  name: (identifier) @testname\n  parameters: (parameter_list\n"
  },
  {
    "path": "lua/dap-go.lua",
    "chars": 6753,
    "preview": "local ts = require(\"dap-go-ts\")\n\nlocal M = {\n  last_testname = \"\",\n  last_testpath = \"\",\n  test_buildflags = \"\",\n  test_"
  },
  {
    "path": "tests/go.mod",
    "chars": 48,
    "preview": "module github.com/leoluz/nvim-dap-go\n\ngo 1.22.2\n"
  },
  {
    "path": "tests/subtest_bar_test.go",
    "chars": 288,
    "preview": "package tests\n\nimport (\n\t\"testing\"\n)\n\n// https://github.com/leoluz/nvim-dap-go/pull/82\nfunc TestWithSubTests(t *testing."
  }
]

About this extraction

This page contains the full source code of the leoluz/nvim-dap-go GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 12 files (30.9 KB), approximately 8.0k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!