-
-
Notifications
You must be signed in to change notification settings - Fork 205
Cookbook
This page is for various configuration snippets that might be useful.
Some debug adapters support attaching to a running process. If you want to have
a "pick pid" dialog, you can use the pick_process
utils function in your
configuration. For example, in a configuration using the lldb-vscode
debug
adapter, it can be used like this:
dap.configurations.cpp = {
{
-- If you get an "Operation not permitted" error using this, try disabling YAMA:
-- echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
name = "Attach to process",
type = 'cpp', -- Adjust this to match your adapter name (`dap.adapters.<name>`)
request = 'attach',
pid = require('dap.utils').pick_process,
args = {},
},
}
See :help dap-configuration
for more information about nvim-dap configuration.
local dap = require('dap')
local api = vim.api
local keymap_restore = {}
dap.listeners.after['event_initialized']['me'] = function()
for _, buf in pairs(api.nvim_list_bufs()) do
local keymaps = api.nvim_buf_get_keymap(buf, 'n')
for _, keymap in pairs(keymaps) do
if keymap.lhs == "K" then
table.insert(keymap_restore, keymap)
api.nvim_buf_del_keymap(buf, 'n', 'K')
end
end
end
api.nvim_set_keymap(
'n', 'K', '<Cmd>lua require("dap.ui.widgets").hover()<CR>', { silent = true })
end
dap.listeners.after['event_terminated']['me'] = function()
for _, keymap in pairs(keymap_restore) do
api.nvim_buf_set_keymap(
keymap.buffer,
keymap.mode,
keymap.lhs,
keymap.rhs,
{ silent = keymap.silent == 1 }
)
end
keymap_restore = {}
end
If you configure the dap.configurations
table in a Lua module and load that
module via a require
call, the module gets cached. If you then modify the
module with the configurations the changes won't be picked up automatically.
There are two options to force load the changes:
You could add something like autocmd BufWritePost ~/your_dap_config_file :luafile %
in init.vim
.
Assuming the following conditions:
- The code below is in the file
~/.config/nvim/lua/dap_util.lua
-
dap.configurations
is set in~/.config/nvim/lua/dap_config.lua
local M = {}
local dap = require'dap'
function M.reload_continue()
package.loaded['dap_config'] = nil
require('dap_config')
dap.continue()
end
local opts = { noremap=false, silent=true }
-- <Leader>ec to continue
vim.api.nvim_buf_set_keymap( 0, 'n', '<Leader>ec',
'<cmd>lua require"dap".continue()<CR>', opts)
-- <Leader>eC to reload and then continue
vim.api.nvim_buf_set_keymap(0, 'n', '<Leader>eC',
'<cmd>lua require"dap_setup".reload_continue()<CR>', opts)
return M
When debugging .NET projects, you sometimes need to rebuild it. You also don't want to input the path to dll
and/or the path to your proj
file.
TL;DR - replace your config with the config below, it should be intuitive. Otherwise, read a detailed description.
vim.g.dotnet_build_project = function()
local default_path = vim.fn.getcwd() .. '/'
if vim.g['dotnet_last_proj_path'] ~= nil then
default_path = vim.g['dotnet_last_proj_path']
end
local path = vim.fn.input('Path to your *proj file', default_path, 'file')
vim.g['dotnet_last_proj_path'] = path
local cmd = 'dotnet build -c Debug ' .. path .. ' > /dev/null'
print('')
print('Cmd to execute: ' .. cmd)
local f = os.execute(cmd)
if f == 0 then
print('\nBuild: ✔️ ')
else
print('\nBuild: ❌ (code: ' .. f .. ')')
end
end
vim.g.dotnet_get_dll_path = function()
local request = function()
return vim.fn.input('Path to dll', vim.fn.getcwd() .. '/bin/Debug/', 'file')
end
if vim.g['dotnet_last_dll_path'] == nil then
vim.g['dotnet_last_dll_path'] = request()
else
if vim.fn.confirm('Do you want to change the path to dll?\n' .. vim.g['dotnet_last_dll_path'], '&yes\n&no', 2) == 1 then
vim.g['dotnet_last_dll_path'] = request()
end
end
return vim.g['dotnet_last_dll_path']
end
local config = {
{
type = "coreclr",
name = "launch - netcoredbg",
request = "launch",
program = function()
if vim.fn.confirm('Should I recompile first?', '&yes\n&no', 2) == 1 then
vim.g.dotnet_build_project()
end
return vim.g.dotnet_get_dll_path()
end,
},
}
dap.configurations.cs = config
dap.configurations.fsharp = config
So basically, when you start a debug session, the dialog will look like this:
Should I recompile first? y/n
-
y
-
Path to your *proj file
(if you already input once, it will substitute it ; but you still can change it)
-
n
If you didn't specify the dll path yet:
Path to dll
If you did:
-
Do you want to change the path to dll?
(it previews your previous dll path)-
y
Path to dll
n
-
You can bind building the project to some hotkey:
vim.api.nvim_set_keymap('n', '<C-b>', ':lua vim.g.dotnet_build_project()<CR>', { noremap = true, silent = true })
nvim-dap
supports asynchrounous operations using Lua's coroutines. This helps launching telescope
as the selector for choosing an executable to debug.
With variables declared as follows:
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local conf = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
The following code snippet lets you choose an executable through telescope
, passes to nvim-dap
, and launches a C++ debuggin session. (The snippets assume that you have fd
installed, please replace { "fd", "--hidden", "--no-ignore", "--type", "x" }
with a command that fits you)
dap.configurations.cpp = {
{
name = "Launch an executable",
type = "cppdbg",
request = "launch",
cwd = "${workspaceFolder}",
program = function()
return coroutine.create(function(coro)
local opts = {}
pickers
.new(opts, {
prompt_title = "Path to executable",
finder = finders.new_oneshot_job({ "fd", "--hidden", "--no-ignore", "--type", "x" }, {}),
sorter = conf.generic_sorter(opts),
attach_mappings = function(buffer_number)
actions.select_default:replace(function()
actions.close(buffer_number)
coroutine.resume(coro, action_state.get_selected_entry()[1])
end)
return true
end,
})
:find()
end)
end,
},
}
The following creates a user command, named RunScriptWithArgs
that accepts shell expanded arguments, and spawns a DAP session for the process. The configuration uses the type = vim.bo.filetype
- i.e chosen automatically according to your currently edited buffer's &filetype
. The arguments are expanded using expand()
which expands wildcards and environment variables (see :help expand()
).
The keymap defined at the end makes typing that command faster, and also helps you in terms of command line history - in case you run the script you are editing with the same arguments over and over.
vim.api.nvim_create_user_command("RunScriptWithArgs", function(t)
-- :help nvim_create_user_command
args = vim.split(vim.fn.expand(t.args), '\n')
approval = vim.fn.confirm(
"Will try to run:\n " ..
vim.bo.filetype .. " " ..
vim.fn.expand('%') .. " " ..
t.args .. "\n\n" ..
"Do you approve? ",
"&Yes\n&No", 1
)
if approval == 1 then
dap.run({
type = vim.bo.filetype,
request = 'launch',
name = 'Launch file with custom arguments (adhoc)',
program = '${file}',
args = args,
})
end
end, {
complete = 'file',
nargs = '*'
})
vim.keymap.set('n', '<leader>R', ":RunScriptWithArgs ")