[
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 180\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 30\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: Lint\non:\n  pull_request: ~\n  push:\n    branches:\n      - master\njobs:\n  stylua:\n    name: Stylua\n    runs-on: ubuntu-20.04\n    steps:\n      - uses: actions/checkout@v2\n      - uses: JohnnyMorganz/stylua-action@v2\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          # CLI arguments\n          args: --color always --check lua/\n\n  super-linter:\n    name: Super Linter\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Code\n        uses: actions/checkout@v2\n      - name: Lint Code Base\n        uses: github/super-linter/slim@v4\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          VALIDATE_JSCPD: false\n          VALIDATE_PYTHON_BLACK: false\n"
  },
  {
    "path": ".gitignore",
    "content": "doc/tags\n.luarc.json\n"
  },
  {
    "path": ".luacheckrc",
    "content": "globals = {\n  \"vim\",\n}\nread_globals = {\n  \"describe\",\n  \"it\",\n  \"before_each\",\n  \"after_each\",\n  \"assert\"\n}\n"
  },
  {
    "path": ".stylua.toml",
    "content": "column_width = 120\nline_endings = \"Unix\"\nindent_type = \"Spaces\"\nindent_width = 2\nquote_style = \"AutoPreferDouble\"\ncall_parentheses = \"Always\"\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Leonardo Luz Almeida\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# nvim-dap-go\n\nAn extension for [nvim-dap][1] providing configurations for launching go debugger (delve) and debugging individual tests.\n\n## Features\n\n- Auto launch Delve. No configuration needed. You just have to have `dlv` in your path.\n- 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.\n- Configuration to attach nvim-dap and Delve into a running process and start a debug session.\n- Configuration to start a debug session in the main function.\n- Configuration to run tests in a debug session.\n- 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.\n\n## Pre-reqs\n\n- Neovim >= 0.9.0\n- [nvim-dap][1]\n- [delve][2] >= 1.7.0\n\nThis plugin extension make usage of treesitter to find the nearest test to debug.\nMake sure you have the Go treesitter parser installed.\nIf using [nvim-treesitter][3] plugin you can install with `:TSInstall go`.\n\n## Installation\n\n- Install like any other neovim plugin:\n  - If using [vim-plug][4]: `Plug 'leoluz/nvim-dap-go'`\n  - If using [packer.nvim][5]: `use 'leoluz/nvim-dap-go'`\n\n## Usage\n\n### Register the plugin\n\nCall the setup function in your `init.vim` to register the go adapter and the configurations to debug go tests:\n\n```vimL\nlua require('dap-go').setup()\n```\n\n### Configuring\n\nIt is possible to customize nvim-dap-go by passing a config table in the setup function.\n\nThe example below shows all the possible configurations:\n\n```lua\nlua require('dap-go').setup {\n  -- Additional dap configurations can be added.\n  -- dap_configurations accepts a list of tables where each entry\n  -- represents a dap configuration. For more details do:\n  -- :help dap-configuration\n  dap_configurations = {\n    {\n      -- Must be \"go\" or it will be ignored by the plugin\n      type = \"go\",\n      name = \"Attach remote\",\n      mode = \"remote\",\n      request = \"attach\",\n    },\n  },\n  -- delve configurations\n  delve = {\n    -- the path to the executable dlv which will be used for debugging.\n    -- by default, this is the \"dlv\" executable on your PATH.\n    path = \"dlv\",\n    -- time to wait for delve to initialize the debug session.\n    -- default to 20 seconds\n    initialize_timeout_sec = 20,\n    -- a string that defines the port to start delve debugger.\n    -- default to string \"${port}\" which instructs nvim-dap\n    -- to start the process in a random available port.\n    -- if you set a port in your debug configuration, its value will be\n    -- assigned dynamically.\n    port = \"${port}\",\n    -- additional args to pass to dlv\n    args = {},\n    -- the build flags that are passed to delve.\n    -- defaults to empty string, but can be used to provide flags\n    -- such as \"-tags=unit\" to make sure the test suite is\n    -- compiled during debugging, for example.\n    -- passing build flags using args is ineffective, as those are\n    -- ignored by delve in dap mode.\n    -- avaliable ui interactive function to prompt for arguments get_arguments\n    build_flags = {},\n    -- whether the dlv process to be created detached or not. there is\n    -- an issue on delve versions < 1.24.0 for Windows where this needs to be\n    -- set to false, otherwise the dlv server creation will fail.\n    -- avaliable ui interactive function to prompt for build flags: get_build_flags\n    detached = vim.fn.has(\"win32\") == 0,\n    -- the current working directory to run dlv from, if other than\n    -- the current working directory.\n    cwd = nil,\n  },\n  -- options related to running closest test\n  tests = {\n    -- enables verbosity when running the test.\n    verbose = false,\n  },\n}\n```\n\n### Use nvim-dap as usual\n\n- Call `:lua require('dap').continue()` to start debugging.\n- All pre-configured debuggers will be displayed for you to choose from.\n- See `:help dap-mappings` and `:help dap-api`.\n\n### Debugging individual tests\n\nTo debug the closest method above the cursor use you can run:\n\n- `:lua require('dap-go').debug_test()`\n\nOnce a test was run, you can simply run it again from anywhere:\n\n- `:lua require('dap-go').debug_last_test()`\n\nIt is better to define a mapping to invoke this command. See the mapping section below.\n\n### Debugging with command-line arguments\n\n1. Select the option `Debug (Arguments)`\n1. Enter each argument separated by a space (i.e. `option1 option2 option3`)\n1. Press enter\n\n![Start Debug Session with Arguments](./images/image1.png \"Start Debug Session with Arguments\")\n![Enter Arguments](./images/image2.png \"Enter Arguments\")\n![Begin Debugging](./images/image3.png \"Being Debugging\")\n\n### Debugging with build flags\n\n1. Register a new option to debug with build flags:\n\n```lua\nrequire('dap-go').setup ({\n  dap_configurations = {\n    {\n      type = \"go\",\n      name = \"Debug (Build Flags)\",\n      request = \"launch\",\n      program = \"${file}\",\n      buildFlags = require(\"dap-go\").get_build_flags,\n    },\n  },\n})\n```\n\n2. To prompt for both build flags and arguments register the following:\n\n```lua\nrequire(\"dap-go\").setup({\n    dap_configurations = {\n        {\n            type = \"go\",\n            name = \"Debug (Build Flags & Arguments)\",\n            request = \"launch\",\n            program = \"${file}\",\n            args = require(\"dap-go\").get_arguments,\n            buildFlags = require(\"dap-go\").get_build_flags,\n        },\n    }\n})\n```\n\n3. To create a custom debugging configuration that requires an interactive prompt the following functions can be\n   attached to the args and buildFlags fields of dap_configurations.\n   - `require('dap-go').get_arguments`\n   - `require('dap-go').get_buid_flags`\n\n### Debugging with dlv in headless mode\n\n1. Register a new option to attach to a remote debugger:\n\n```lua\nlua require('dap-go').setup {\n  dap_configurations = {\n    {\n      type = \"go\",\n      name = \"Attach remote\",\n      mode = \"remote\",\n      request = \"attach\",\n    },\n  },\n}\n```\n\n1. Start `dlv` in headless mode. You can specify subcommands and flags after `--`, e.g.,\n\n```sh\ndlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz\n```\n\n1. Call `:lua require('dap').continue()` to start debugging.\n1. Select the new registered option `Attach remote`.\n\n## Mappings\n\n```vimL\nnmap <silent> <leader>td :lua require('dap-go').debug_test()<CR>\n```\n\n## VSCode launch config\n\nDefining the Go debug configurations for all your projects inside your Neovim configuration can be cumbersome and quite strict.\nFor more flexibility, `nvim-dap` supports the use of the VSCode launch configurations.\n\nThat 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`):\n\n```json\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Remote debug API server\",\n            \"type\": \"go\",\n            \"request\": \"attach\",\n            \"mode\": \"remote\",\n            \"port\": 4444,\n            \"host\": \"127.0.0.1\",\n            \"substitutePath\": [\n                {\n                    \"from\": \"${workspaceFolder}\", \"to\": \"/usr/src/app\"\n                }\n            ]\n        }\n    ]\n}\n```\n\nA debug session `Remote debug API server` will appear in the choices, and the Delve port will be dynamically set to `4444`.\nThe current version of nvim-dap always loads the file if it exists.\n\nPlease see `:h dap-launch.json` for more information.\n\n## Acknowledgement\n\nThanks to the [nvim-dap-python][6] for the inspiration.\n\n[1]: https://github.com/mfussenegger/nvim-dap\n[2]: https://github.com/go-delve/delve\n[3]: https://github.com/nvim-treesitter/nvim-treesitter\n[4]: https://github.com/junegunn/vim-plug\n[5]: https://github.com/wbthomason/packer.nvim\n[6]: https://github.com/mfussenegger/nvim-dap-python\n"
  },
  {
    "path": "doc/nvim-dap-go.txt",
    "content": "========================================================================\nINTRODUCTION                                                  *dap-go*\n\nnvim-dap-go is an extension for nvim-dap (see |dap.txt|) providing\nconfigurations for launching go debugger (delve) and debugging\nindividual tests. As such, it requires nvim-dap go to be installed.\nFor more details see\nhttps://github.com/mfussenegger/nvim-dap#installation\n\n========================================================================\nCONTENTS                                                  *dap-go-toc*\n\n    1. Features .............................. |dap-go-features|\n    2. Configuration ......................... |dap-go-configuration|\n    3. Usage ................................. |dap-go-usage|\n    4. Debugging Individual Tests ............ |dap-go-debug-test|\n    5. Debugging With Command-Line Arguments . |dap-go-debug-cli-args|\n    6. Debugging With Build Flags ............ |dap-go-debug-cli-args|\n    7. Debugging With dlv in Headless Mode ... |dap-go-debug-headless|\n    8. VSCode launch config .................. |dap-go-vscode-launch|\n    9. Mappings .............................. |dap-go-mappings|\n\n========================================================================\nFEATURES                                             *dap-go-features*\n\n- Auto launch Delve. No configuration needed. You just have to have\n  `dlv` in your path.\n\n- Run just the closest test from the cursor in debug mode (uses\n  |treesitter|). See [debugging individual\n  tests](#debugging-individual-tests) section bellow for more details.\n\n- Configuration to attach nvim-dap and Delve into a running process\n  and start a debug session.\n\n- Configuration to start a debug session in the main function.\n\n- Configuration to run tests in a debug session.\n\n- Final Delve configuration is resolved when a debug session starts.\n  This allows to use different addresses and ports for each project or\n  launch configs in a project.\n\nThis plugin makes usage of treesitter to find the nearest test to\ndebug. Make sure you have the Go treesitter parser installed. If using\n|nvim-treesitter| plugin you can install with `:TSInstall go`.\n\n========================================================================\nCONFIGURATION                                   *dap-go-configuration*\n\nRegister the plugin by calling the setup function in your `init.lua`:\n\n>lua\n    require('dap-go').setup()\n<\n\nThis will apply all default configurations which is all you need for\nnormal use-cases. It is possible to customize nvim-dap-go by passing a\nconfig table in the setup function.\n\nThe example bellow shows all the possible configurations:\n\n>lua\n    require('dap-go').setup {\n      -- Additional dap configurations can be added.\n      -- dap_configurations accepts a list of tables where each entry\n      -- represents a dap configuration. For more details see:\n      -- |dap-configuration|\n      dap_configurations = {\n        {\n          -- Must be \"go\" or it will be ignored by the plugin\n          type = \"go\",\n          name = \"Attach remote\",\n          mode = \"remote\",\n          request = \"attach\",\n        },\n      },\n      -- delve configurations\n      delve = {\n        -- the path to the executable dlv which will be used for debugging.\n        -- by default, this is the \"dlv\" executable on your PATH.\n        path = \"dlv\",\n        -- time to wait for delve to initialize the debug session.\n        -- default to 20 seconds\n        initialize_timeout_sec = 20,\n        -- a string that defines the port to start delve debugger.\n        -- default to string \"${port}\" which instructs nvim-dap\n        -- to start the process in a random available port.\n        -- if you set a port in your debug configuration, its value will be\n        -- assigned dynamically.\n        port = \"${port}\",\n        -- additional args to pass to dlv\n        args = {},\n        -- the build flags that are passed to delve.\n        -- defaults to empty string, but can be used to provide flags\n        -- such as \"-tags=unit\" to make sure the test suite is\n        -- compiled during debugging, for example.\n        -- passing build flags using args is ineffective, as those are\n        -- ignored by delve in dap mode.\n        build_flags = \"\",\n        -- whether the dlv process to be created detached or not. there is\n        -- an issue on delve versions < 1.24.0 for Windows where this needs to be\n        -- set to false, otherwise the dlv server creation will fail.\n        detached = vim.fn.has(\"win32\") == 0,\n      },\n      -- options related to running closest test\n      tests = {\n        -- enables verbosity when running the test.\n        verbose = false,\n      },\n    }\n<\n\n========================================================================\nUSAGE                                                   *dap-go-usage*\n\nOnce the plugin is registered, use nvim-dap as usual:\n\n- Call `:lua require('dap').continue()` to start debugging.\n- All pre-configured debuggers will be displayed for you to choose\n  from.\n- See |dap-mappings| and |dap-api|.\n\n-----------------------------------------------------------------------\nDebugging Individual Tests                        *dap-go-debug-test*\n\nTo debug the closest method above the cursor use you can run:\n>\n    :lua require('dap-go').debug_test()`\n<\n\nThe |dap-configuration| in use can be customized by passing an optional\ntable argument to `debug-test`. For example, you can override default\nbuild flags as follows:\n>lua\n    require(\"dap-go\").debug_test({\n      buildFlags = \"-tags=integration\",\n    })\n<\n\nOnce a test runs, you can simply run it again from anywhere:\n>\n    :lua require('dap-go').debug_last_test()`\n<\n\nIt is better to define mappings to invoke these commands. See the\n|dap-go-mappings| section bellow.\n\n-----------------------------------------------------------------------\nDebugging With Command-Line Arguments         *dap-go-debug-cli-args*\n\n    1. Select the option `Debug (Arguments)`.\n    2. Enter each argument separated by a space (i.e. `option1 option2\n    option3`).\n    3. Press enter.\n\n-----------------------------------------------------------------------\nDebugging With Build Flags                  *dap-go-debug-build-flags*\n\n    1. Register a new option to debug with build flags:\n>lua\n    require('dap-go').setup {\n      dap_configurations = {\n        {\n            type = \"go\",\n            name = \"Debug (Build Flags)\",\n            request = \"launch\",\n            program = \"${file}\",\n            buildFlags = require(\"dap-go\").get_build_flags,\n        },\n      },\n    })\n<\n\n    2. To prompt for both build flags and arguments register the \n    following:\n>lua\n    require(\"dap-go\").setup({\n        dap_configurations = {\n            {\n                type = \"go\",\n                name = \"Debug (Build Flags & Arguments)\",\n                request = \"launch\",\n                program = \"${file}\",\n                args = require(\"dap-go\").get_arguments,\n                buildFlags = require(\"dap-go\").get_build_flags,\n            },\n        }\n    })\n<\n\n    3. To create a custom debugging configuration that requires an \n    interactive prompt the following functions can be attached to \n    the args and buildFlags fields of dap_configurations.\n    \n    `require('dap-go').get_arguments`\n    `require('dap-go').get_buid_flags`\n\n-----------------------------------------------------------------------\nDebugging With dlv in Headless Mode           *dap-go-debug-headless*\n\n    1. Register a new option to attach to a remote debugger:\n>lua\n    require('dap-go').setup {\n      dap_configurations = {\n        {\n          type = \"go\",\n          name = \"Attach remote\",\n          mode = \"remote\",\n          request = \"attach\",\n        },\n      },\n    }\n<\n\n    2. Start `dlv` in headless mode. You can specify subcommands and\n    flags after `--`, e.g.,\n\n>sh\n    dlv debug -l 127.0.0.1:38697 --headless ./main.go -- subcommand --myflag=xyz\n<\n\n    3. Call `:lua require('dap').continue()` to start debugging.\n    4. Select the new registered option `Attach remote`.\n\n-----------------------------------------------------------------------\nVSCode launch config                           *dap-go-vscode-launch\n\n    1. Create in your Go project a VSCode launch config file (by\n    default its path must be `.vscode/launch.json` relative to your\n    project's root directory):\n>json\n    {\n        \"version\": \"0.2.0\",\n        \"configurations\": [\n            {\n                \"name\": \"Remote debug API server\",\n                \"type\": \"go\",\n                \"request\": \"attach\",\n                \"mode\": \"remote\",\n                \"port\": 4444,\n                \"host\": \"127.0.0.1\",\n                \"substitutePath\": [\n                    {\n                        \"from\": \"${workspaceFolder}\", \"to\": \"/usr/src/app\"\n                    }\n                ]\n            }\n        ]\n    }\n<\n\n    2. A debug session `Remote debug API server` will appear in the choices,\n    and the Delve port will be dynamically set to `4444`.\n\nPlease see `:h dap-launch.json` for more information.\n\n========================================================================\nMAPPINGS                                             *dap-go-mappings*\n\nnvim-dap-go doesn't provide any pre-configured keymaps. It does\nprovide lua functions that you can easly use to define your own\nmappings. You can do this by adding the lines bellow to your\n`init.lua`:\n\n>lua\n    local dapgo = require('dap-go')\n    vim.keymap.set(\"n\", \"<leader>dt\", dapgo.debug_test)\n    vim.keymap.set(\"n\", \"<leader>dl\", dapgo.debug_last_test)\n<\nvim:tw=78:et:ft=help:norl:\n"
  },
  {
    "path": "lua/dap-go-ts.lua",
    "content": "local M = {}\n\nlocal tests_query = [[\n(function_declaration\n  name: (identifier) @testname\n  parameters: (parameter_list\n    . (parameter_declaration\n      type: (pointer_type) @type) .)\n  (#match? @type \"*testing.(T|M)\")\n  (#match? @testname \"^Test.+$\")) @parent\n]]\n\nlocal subtests_query = [[\n(call_expression\n  function: (selector_expression\n    operand: (identifier)\n    field: (field_identifier) @run)\n  arguments: (argument_list\n    (interpreted_string_literal) @testname\n    [\n     (func_literal)\n     (identifier)\n    ])\n  (#eq? @run \"Run\")) @parent\n]]\n\nlocal function format_subtest(testcase, test_tree)\n  local parent\n  if testcase.parent then\n    for _, curr in pairs(test_tree) do\n      if curr.name == testcase.parent then\n        parent = curr\n        break\n      end\n    end\n    return string.format(\"%s/%s\", format_subtest(parent, test_tree), testcase.name)\n  else\n    return testcase.name\n  end\nend\n\nlocal function get_closest_above_cursor(test_tree)\n  local result\n  for _, curr in pairs(test_tree) do\n    if not result then\n      result = curr\n    else\n      local node_row1, _, _, _ = curr.node:range()\n      local result_row1, _, _, _ = result.node:range()\n      if node_row1 > result_row1 then\n        result = curr\n      end\n    end\n  end\n  if result then\n    return format_subtest(result, test_tree)\n  end\n  return nil\nend\n\nlocal function is_parent(dest, source)\n  if not (dest and source) then\n    return false\n  end\n  if dest == source then\n    return false\n  end\n\n  local current = source\n  while current ~= nil do\n    if current == dest then\n      return true\n    end\n\n    current = current:parent()\n  end\n\n  return false\nend\n\nlocal function get_closest_test()\n  local stop_row = vim.api.nvim_win_get_cursor(0)[1]\n  local ft = vim.api.nvim_buf_get_option(0, \"filetype\")\n  assert(ft == \"go\", \"can only find test in go files, not \" .. ft)\n  local parser = vim.treesitter.get_parser(0)\n  local root = (parser:parse()[1]):root()\n\n  local test_tree = {}\n\n  local test_query = vim.treesitter.query.parse(ft, tests_query)\n  assert(test_query, \"could not parse test query\")\n  for _, match, _ in test_query:iter_matches(root, 0, 0, stop_row, { all = true }) do\n    local test_match = {}\n    for id, nodes in pairs(match) do\n      for _, node in ipairs(nodes) do\n        local capture = test_query.captures[id]\n        if capture == \"testname\" then\n          local name = vim.treesitter.get_node_text(node, 0)\n          test_match.name = name\n        end\n        if capture == \"parent\" then\n          test_match.node = node\n        end\n      end\n    end\n    table.insert(test_tree, test_match)\n  end\n\n  local subtest_query = vim.treesitter.query.parse(ft, subtests_query)\n  assert(subtest_query, \"could not parse test query\")\n  for _, match, _ in subtest_query:iter_matches(root, 0, 0, stop_row, { all = true }) do\n    local test_match = {}\n    for id, nodes in pairs(match) do\n      for _, node in ipairs(nodes) do\n        local capture = subtest_query.captures[id]\n        if capture == \"testname\" then\n          local name = vim.treesitter.get_node_text(node, 0)\n          test_match.name = string.gsub(string.gsub(name, \" \", \"_\"), '\"', \"\")\n        end\n        if capture == \"parent\" then\n          test_match.node = node\n        end\n      end\n    end\n    table.insert(test_tree, test_match)\n  end\n\n  table.sort(test_tree, function(a, b)\n    return is_parent(a.node, b.node)\n  end)\n\n  for _, parent in ipairs(test_tree) do\n    for _, child in ipairs(test_tree) do\n      if is_parent(parent.node, child.node) then\n        child.parent = parent.name\n      end\n    end\n  end\n\n  return get_closest_above_cursor(test_tree)\nend\n\nlocal function get_package_name()\n  local test_dir = vim.fn.fnamemodify(vim.fn.expand(\"%:.:h\"), \":r\")\n  return \"./\" .. test_dir\nend\n\nM.closest_test = function()\n  local package_name = get_package_name()\n  local test_case = get_closest_test()\n  local test_scope\n  if test_case then\n    test_scope = \"testcase\"\n  else\n    test_scope = \"package\"\n  end\n  return {\n    package = package_name,\n    name = test_case,\n    scope = test_scope,\n  }\nend\n\nM.get_root_dir = function()\n  local id, client = next(vim.lsp.buf_get_clients())\n  if id == nil then\n    error({ error_msg = \"lsp client not attached\" })\n  end\n  if not client.config.root_dir then\n    error({ error_msg = \"lsp root_dir not defined\" })\n  end\n  return client.config.root_dir\nend\n\nreturn M\n"
  },
  {
    "path": "lua/dap-go.lua",
    "content": "local ts = require(\"dap-go-ts\")\n\nlocal M = {\n  last_testname = \"\",\n  last_testpath = \"\",\n  test_buildflags = \"\",\n  test_verbose = false,\n}\n\nlocal default_config = {\n  delve = {\n    path = \"dlv\",\n    initialize_timeout_sec = 20,\n    port = \"${port}\",\n    args = {},\n    build_flags = \"\",\n    -- Automatically handle the issue on delve Windows versions < 1.24.0\n    -- where delve needs to be run in attched mode or it will fail (actually crashes).\n    detached = vim.fn.has(\"win32\") == 0,\n    output_mode = \"remote\",\n  },\n  tests = {\n    verbose = false,\n  },\n}\n\nlocal internal_global_config = {}\n\nlocal function load_module(module_name)\n  local ok, module = pcall(require, module_name)\n  assert(ok, string.format(\"dap-go dependency error: %s not installed\", module_name))\n  return module\nend\n\nlocal function get_arguments()\n  return coroutine.create(function(dap_run_co)\n    local args = {}\n    vim.ui.input({ prompt = \"Args: \" }, function(input)\n      args = vim.split(input or \"\", \" \")\n      coroutine.resume(dap_run_co, args)\n    end)\n  end)\nend\n\nlocal function get_build_flags(config)\n  return coroutine.create(function(dap_run_co)\n    local build_flags = config.build_flags\n    vim.ui.input({ prompt = \"Build Flags: \" }, function(input)\n      build_flags = vim.split(input or \"\", \" \")\n      coroutine.resume(dap_run_co, build_flags)\n    end)\n  end)\nend\n\nlocal function filtered_pick_process()\n  local opts = {}\n  vim.ui.input(\n    { prompt = \"Search by process name (lua pattern), or hit enter to select from the process list: \" },\n    function(input)\n      opts[\"filter\"] = input or \"\"\n    end\n  )\n  return require(\"dap.utils\").pick_process(opts)\nend\n\nlocal function setup_delve_adapter(dap, config)\n  local args = { \"dap\", \"-l\", \"127.0.0.1:\" .. config.delve.port }\n  vim.list_extend(args, config.delve.args)\n\n  local delve_config = {\n    type = \"server\",\n    port = config.delve.port,\n    executable = {\n      command = config.delve.path,\n      args = args,\n      detached = config.delve.detached,\n      cwd = config.delve.cwd,\n    },\n    options = {\n      initialize_timeout_sec = config.delve.initialize_timeout_sec,\n    },\n  }\n\n  dap.adapters.go = function(callback, client_config)\n    if client_config.port == nil then\n      callback(delve_config)\n      return\n    end\n\n    local host = client_config.host\n    if host == nil then\n      host = \"127.0.0.1\"\n    end\n\n    local listener_addr = host .. \":\" .. client_config.port\n    delve_config.port = client_config.port\n    delve_config.executable.args = { \"dap\", \"-l\", listener_addr }\n\n    callback(delve_config)\n  end\nend\n\nlocal function setup_go_configuration(dap, configs)\n  local common_debug_configs = {\n    {\n      type = \"go\",\n      name = \"Debug\",\n      request = \"launch\",\n      program = \"${file}\",\n      buildFlags = configs.delve.build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n    {\n      type = \"go\",\n      name = \"Debug (Arguments)\",\n      request = \"launch\",\n      program = \"${file}\",\n      args = get_arguments,\n      buildFlags = configs.delve.build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n    {\n      type = \"go\",\n      name = \"Debug (Arguments & Build Flags)\",\n      request = \"launch\",\n      program = \"${file}\",\n      args = get_arguments,\n      buildFlags = get_build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n    {\n      type = \"go\",\n      name = \"Debug Package\",\n      request = \"launch\",\n      program = \"${fileDirname}\",\n      buildFlags = configs.delve.build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n    {\n      type = \"go\",\n      name = \"Attach\",\n      mode = \"local\",\n      request = \"attach\",\n      processId = filtered_pick_process,\n      buildFlags = configs.delve.build_flags,\n    },\n    {\n      type = \"go\",\n      name = \"Debug test\",\n      request = \"launch\",\n      mode = \"test\",\n      program = \"${file}\",\n      buildFlags = configs.delve.build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n    {\n      type = \"go\",\n      name = \"Debug test (go.mod)\",\n      request = \"launch\",\n      mode = \"test\",\n      program = \"./${relativeFileDirname}\",\n      buildFlags = configs.delve.build_flags,\n      outputMode = configs.delve.output_mode,\n    },\n  }\n\n  if dap.configurations.go == nil then\n    dap.configurations.go = {}\n  end\n\n  for _, config in ipairs(common_debug_configs) do\n    table.insert(dap.configurations.go, config)\n  end\n\n  if configs == nil or configs.dap_configurations == nil then\n    return\n  end\n\n  for _, config in ipairs(configs.dap_configurations) do\n    if config.type == \"go\" then\n      table.insert(dap.configurations.go, config)\n    end\n  end\nend\n\nfunction M.setup(opts)\n  internal_global_config = vim.tbl_deep_extend(\"force\", default_config, opts or {})\n  M.test_buildflags = internal_global_config.delve.build_flags\n  M.test_verbose = internal_global_config.tests.verbose\n\n  local dap = load_module(\"dap\")\n  setup_delve_adapter(dap, internal_global_config)\n  setup_go_configuration(dap, internal_global_config)\nend\n\nlocal function debug_test(testname, testpath, build_flags, extra_args, custom_config)\n  local dap = load_module(\"dap\")\n\n  local config = {\n    type = \"go\",\n    name = testname,\n    request = \"launch\",\n    mode = \"test\",\n    program = testpath,\n    args = { \"-test.run\", \"^\" .. testname .. \"$\" },\n    buildFlags = build_flags,\n    outputMode = \"remote\",\n  }\n  config = vim.tbl_deep_extend(\"force\", config, custom_config or {})\n\n  if not vim.tbl_isempty(extra_args) then\n    table.move(extra_args, 1, #extra_args, #config.args + 1, config.args)\n  end\n\n  dap.run(config)\nend\n\nfunction M.debug_test(custom_config)\n  local test = ts.closest_test()\n\n  if test.name == \"\" or test.name == nil then\n    vim.notify(\"no test found\")\n    return false\n  end\n\n  M.last_testname = test.name\n  M.last_testpath = test.package\n\n  local msg = string.format(\"starting debug session '%s : %s'...\", test.package, test.name)\n  vim.notify(msg)\n\n  local extra_args = {}\n  if M.test_verbose then\n    extra_args = { \"-test.v\" }\n  end\n\n  debug_test(test.name, test.package, M.test_buildflags, extra_args, custom_config)\n\n  return true\nend\n\nfunction M.debug_last_test()\n  local testname = M.last_testname\n  local testpath = M.last_testpath\n\n  if testname == \"\" then\n    vim.notify(\"no last run test found\")\n    return false\n  end\n\n  local msg = string.format(\"starting debug session '%s : %s'...\", testpath, testname)\n  vim.notify(msg)\n\n  local extra_args = {}\n  if M.test_verbose then\n    extra_args = { \"-test.v\" }\n  end\n\n  debug_test(testname, testpath, M.test_buildflags, extra_args)\n\n  return true\nend\n\nfunction M.get_build_flags()\n  return get_build_flags(internal_global_config)\nend\n\nfunction M.get_arguments()\n  return get_arguments()\nend\n\nreturn M\n"
  },
  {
    "path": "tests/go.mod",
    "content": "module github.com/leoluz/nvim-dap-go\n\ngo 1.22.2\n"
  },
  {
    "path": "tests/subtest_bar_test.go",
    "content": "package tests\n\nimport (\n\t\"testing\"\n)\n\n// https://github.com/leoluz/nvim-dap-go/pull/82\nfunc TestWithSubTests(t *testing.T) {\n\tt.Run(\"subtest with function literal\", func(t *testing.T) { t.Fail() })\n\tmyFunc := func(t *testing.T) { t.FailNow() }\n\tt.Run(\"subtest with identifier\", myFunc)\n}\n"
  }
]