Skip to content

Commit

Permalink
Introduce nvim-dap (Debugger Adapter Protocol) to my NVim
Browse files Browse the repository at this point in the history
I want to be able to debug Node apps (Specially NextJS) app on backend
side. nvim-dap use DAP protocol from Microsoft which is the one used by
VSCode on their debugging experience. This is the same in Nvim.

To be honest this has been fucking painful for several reasons.
1. First Next.js latest version has fucked their debugging experience.
   So I had to simplify the problem and first understand how node
   `--inspect` flag works on a simple Node server. Then I look into
   existing issues on Next.js and I discoverd that their debugging
   experience is broken in latest version. A [fix is comming in this PR](vercel/next.js#51467)
2. Second. After setting the `nvim-dap` plugin with the VSCode / JS
   debugging experience I spent a shameful amount of time hitting
   `node-terminal` debug mode when in reality was `pwa-node`. Yes, `pwa`
   is ultra weird and that took me time to figure out. [Issue here about
   it](microsoft/vscode#151910)

FUCK! This was hard 😂
  • Loading branch information
andresgutgon committed Jun 25, 2023
1 parent 7e367c2 commit 86735b1
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 0 deletions.
1 change: 1 addition & 0 deletions nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ require "user.lualine"
require "user.trouble"
require "user.prettier"
require "user.spectre"
require "user.dap"
18 changes: 18 additions & 0 deletions nvim/lua/user/dap/dap_ui.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
local ok_dap, dap = pcall(require, "dap")
local ok_dapui, dapui = pcall(require, "dapui")

if not (ok_dap and ok_dapui) then
return
end

dapui.setup()

dap.listeners.after.event_initialized["dapui_config"] = function(session, body)
dapui.open()
end
dap.listeners.before.event_terminated["dapui_config"] = function()
dapui.close()
end
dap.listeners.before.event_exited["dapui_config"] = function()
dapui.close()
end
8 changes: 8 additions & 0 deletions nvim/lua/user/dap/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- DAP components
require("user.dap.telescope")
require("user.dap.keymaps")
require("user.dap.line_signs")
require("user.dap.dap_ui")

-- DAP language debuggers
require("user.dap.languages.javascript")
78 changes: 78 additions & 0 deletions nvim/lua/user/dap/keymaps.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
local keymap = vim.api.nvim_set_keymap
local opts = { noremap = true, silent = true }

-- This list all possible ways of debugging
-- If the app have a `./.vscode/launch.json` file it will
-- appear here
keymap("n", "<leader>dl", "<CMD>Telescope dap configurations<CR>", opts)

-- Continue. This launch the debugger
keymap(
"n",
"<leader>dr",
":lua require(\"dap\").repl.open()<CR>",
opts
)

-- Set breakboint
keymap(
"n",
"<leader>di",
":lua require(\"dap\").toggle_breakpoint()<CR>",
opts
)

-- Continue. This launch the debugger
keymap(
"n",
"<leader>dc",
":lua require(\"dap\").continue()<CR>",
opts
)

-- Next line
keymap(
"n",
"<leader>dn",
":lua require(\"dap\").step_over()<CR>",
opts
)

-- Prev line
keymap(
"n",
"<leader>dN",
":lua require(\"dap\").step_into()<CR>",
opts
)

-- Go out of method
keymap(
"n",
"<leader>do",
":lua require(\"dap\").step_out()<CR>",
opts
)

keymap(
"n",
"<leader>dl",
":lua require(\"dap\").run_to_cursor()<CR>",
opts
)

-- Disconnect. End debugging session
keymap(
"n",
"<leader>dS",
":lua require(\"dap\").disconnect()<CR>",
opts
)

-- Dap UI. Toggle
keymap(
"n",
"<leader>dww",
":lua require(\"dapui\").toggle()<CR>",
opts
)
38 changes: 38 additions & 0 deletions nvim/lua/user/dap/languages/javascript.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
local ok_dap, dap = pcall(require, "dap")
local ok_dap_vscode, dap_vscode = pcall(require, "dap-vscode-js")
local ok_dap_launch_vscode, dap_launch_vscode = pcall(require, "dap.ext.vscode")

if not (ok_dap and ok_dap_vscode) then
return
end

local home = os.getenv('HOME')
local node_path = home .. '/.nvm/versions/node/v19.7.0/bin/node'
local debugger_path = home .. "/.local/share/nvim/site/pack/packer/opt/vscode-js-debug"

dap_vscode.setup({
node_path = node_path,
debugger_path = debugger_path,
log_file_level = vim.log.levels.DEBUG,
log_console_level = vim.log.levels.ERROR,
log_file_path = "/tmp/dap_vscode_js.log",
adapters = {
"pwa-node",
"pwa-chrome",
"pwa-msedge",
"node-terminal",
"pwa-extensionHost"
}
})


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

-- ## DAP `launch.json`
dap_launch_vscode.load_launchjs(nil, {
["pwa-node"] = languages,
["node-terminal"] = languages
})
56 changes: 56 additions & 0 deletions nvim/lua/user/dap/line_signs.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
-- VSCode theme visual line selection color
local theme_line_color = '#264F78'
vim.api.nvim_set_hl(0, 'DapLine', { ctermbg = 0, fg = nil, bg = theme_line_color })
vim.api.nvim_set_hl(0, 'DapBreakpoint', { ctermbg = 0, fg = '#993939', bg = theme_line_color })
vim.api.nvim_set_hl(0, 'DapLogPoint', { ctermbg = 0, fg = '#61afef', bg = theme_line_color })
vim.api.nvim_set_hl(0, 'DapStopped', { ctermbg = 0, fg = '#98c379', bg = theme_line_color })


-- # Line Signs
vim.fn.sign_define(
'DapBreakpoint',
{
text = '',
texthl = 'DapBreakpoint',
linehl = 'DapLine',
numhl = 'DapLine'
}
)
vim.fn.sign_define(
'DapBreakpointCondition',
{
text = '',
texthl = 'DapBreakpoint',
linehl = 'DapLine',
numhl = 'DapLine'
}
)

vim.fn.sign_define(
'DapBreakpointRejected',
{
text = '',
texthl = 'DapBreakpoint',
linehl = 'DapLine',
numhl = 'DapLine'
}
)

vim.fn.sign_define(
'DapLogPoint',
{
text = '',
texthl = 'DapLogPoint',
linehl = 'DapLine',
numhl = 'DapLine'
}
)
vim.fn.sign_define(
'DapStopped',
{
text = '',
texthl = 'DapStopped',
linehl = 'DapLine',
numhl = 'DapLine'
}
)
7 changes: 7 additions & 0 deletions nvim/lua/user/dap/telescope.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
local ok_telescope, telescope = pcall(require, "telescope")

if not (ok_telescope) then
return
end

telescope.load_extension('dap')
17 changes: 17 additions & 0 deletions nvim/lua/user/plugins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@ local plugins = function(use)
use({ "williamboman/mason.nvim" }) -- An LSP installer
use({ "williamboman/mason-lspconfig.nvim" }) -- Bridge between lspconfig and mason

-- Debug DAP
use "mfussenegger/nvim-dap"
use {
"rcarriga/nvim-dap-ui",
requires = { "mfussenegger/nvim-dap" }
}
use "nvim-telescope/telescope-dap.nvim"
use {
"mxsdev/nvim-dap-vscode-js",
requires = { "mfussenegger/nvim-dap" }
}
use {
"microsoft/vscode-js-debug",
opt = true,
run = "npm install --legacy-peer-deps && npx gulp vsDebugServerBundle && mv dist out"
}

-- A collection of common configurations for Neovim's built-in language server client.
use({
"neovim/nvim-lspconfig",
Expand Down

0 comments on commit 86735b1

Please sign in to comment.