aboutsummaryrefslogtreecommitdiffstats
path: root/neovim/.config/nvim/lua/config/dap_node.lua
blob: 0fb6890f6eab792a6357268854d4a66b10e96661 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
-- JavaScript/TypeScript launch configs, wired to the js-debug-adapter
-- (Microsoft's vscode-js-debug, bundled by Mason as a standalone
-- multi-session DAP server) that dap.lua's mason-nvim-dap ensure_installed
-- installs.
--
-- There's no nvim-dap-python equivalent for this: the one community plugin
-- for it (mxsdev/nvim-dap-vscode-js) hardcodes the older
-- `out/src/vsDebugServer.js` vscode-js-debug build layout, which doesn't
-- match what Mason's js-debug-adapter package actually installs
-- (`js-debug/src/dapDebugServer.js`) - so this resolves the Mason path
-- directly instead, same approach as dap-python.lua's debugpy_path.
--
-- Lives under lua/config/ rather than lua/plugins/ (and is required
-- eagerly from dap.lua's config()) because it isn't an installable plugin
-- itself, just adapter/config wiring - same reason project_run.lua lives
-- here instead of there.
--
-- js-debug-adapter is a multi-session server: debugging a script that
-- spawns a worker thread arrives as a `startDebugging` reverse request
-- rather than a second top-level session. nvim-dap's core (dap/session.lua)
-- already handles that natively, so no extra plugin is needed for it either.
local M = {}

local function configurations()
  return {
    {
      type = "pwa-node",
      request = "launch",
      name = "Launch file",
      program = "${file}",
      cwd = "${workspaceFolder}",
    },
    {
      type = "pwa-node",
      request = "attach",
      name = "Attach to process",
      processId = require("dap.utils").pick_process,
      cwd = "${workspaceFolder}",
    },
  }
end

function M.setup()
  local registry = require("mason-registry")
  local pkg = registry.get_package("js-debug-adapter")

  local function register()
    local entrypoint = pkg:get_install_path() .. "/js-debug/src/dapDebugServer.js"

    require("dap").adapters["pwa-node"] = {
      type = "server",
      host = "localhost",
      port = "${port}",
      executable = {
        command = "node",
        args = { entrypoint, "${port}" },
      },
    }

    local dap = require("dap")
    for _, filetype in ipairs({ "javascript", "typescript", "javascriptreact", "typescriptreact" }) do
      dap.configurations[filetype] = configurations()
    end
  end

  if pkg:is_installed() then
    register()
  else
    -- Same reasoning as dap-python.lua: dap.lua's mason-nvim-dap
    -- ensure_installed triggers the install, but that's async - on a fresh
    -- machine (or before it finishes) the entrypoint doesn't exist on disk
    -- yet, so wire up the adapter once the install actually completes
    -- instead of pointing it at a path that isn't there yet.
    vim.notify(
      "js-debug-adapter not installed yet - dap.lua's ensure_installed should be"
        .. " installing it now (check :Mason); run :MasonInstall js-debug-adapter"
        .. " if it doesn't show up there. Debugging will work once it's done.",
      vim.log.levels.WARN
    )
    registry:on("package:install:success", function(installed_pkg)
      if installed_pkg.name == "js-debug-adapter" then
        register()
      end
    end)
  end
end

return M