minimalistic nvim-dap-ui alternative
dap-view-demo2.mp4
Warning
Currently requires a neovim nightly (0.11+)
return {
{
"igorlfs/nvim-dap-view",
opts = {},
},
}
For a better experience, consider adding nvim-dap-view
as a dependency for
nvim-dap
(instead of declaring it as a standalone plugin)
Why?
By default, when launching a session, nvim-dap
's terminal window takes half
the screen. As a saner default, nvim-dap-view
hijacks the terminal window
(even if not invoked), making the split take only 12 (configurable) lines.
-- Your nvim-dap config
return {
{
"mfussenegger/nvim-dap",
dependencies = {
{ "igorlfs/nvim-dap-view", opts = {} },
...,
},
...,
},
}
The plugin provides 4 "views" that share the same window (so there's clutter)
- Watches view
- Shows a list of (user defined) expressions, that are evaluated by the debug adapter
- Add, edit and delete expressions from the watch list
- Including adding the variable under the cursor
- Exceptions view
- Control when the debugger should stop, outside of breakpoints (e.g., whenever an exception is thrown, or when an exception is caught1).
- Toggle filter with
<CR>
- Breakpoints view
- List all breakpoints
- Uses syntax highlighting2
- Shows filename and number line
- Jump to a breakpoint with
<CR>
- List all breakpoints
- REPL view
- Use REPL provided by nvim-dap
You can also interact with the console provided by nvim-dap
(though, arguably, that's not a feature from nvim-dap-view
). The console has its own window. However, its default size (height) is resized to match your nvim-dap-view
configuration. You can also completely hide it, if it's not being used.
Default options
return {
winbar = {
show = true,
sections = { "watches", "exceptions", "breakpoints", "repl" },
-- Must be one of the sections declared above
default_section = "watches",
},
windows = {
height = 12,
terminal = {
-- List of adapters for which the terminal should be hidden
hide = {},
},
},
}
Start a regular debugging session. When desired, you can use :DapViewOpen
to
start the plugin. You can switch to a view (section) using the letter outlined
in the 'winbar'
(e.g., B
for the breakpoints view).
Both the breakpoints view and the exceptions view have only 1 mapping: <CR>
.
It jumps to a breakpoint and toggles an exception filter, respectively. The
watches view comes with 3 mappings:
i
to insert a new expressione
to edit an expressiond
to delete an expression
Though, the preferred way of adding a new expression is using the
:DapViewWatch
command. In normal mode, it adds the variable under the cursor
to the watch list.
When you finish your session, you can use :DapViewClose
to close the
nvim-dap-view
window.
In total, there are 4 commands:
DapViewOpen
DapViewClose
DapViewToggle
DapViewWatch
If you prefer using lua functions, I got you covered! The following provide the same functionality as above:
require("dap-view").open()
require("dap-view").close()
require("dap-view").toggle()
require("dap-view").add_expr()
nvim-dap-view
doesn't define any keybindings (outside its own buffer, of
course). An example for the toggle functionality, using the lua API:
vim.keymap.set("n", "<leader>v", function()
require("dap-view").toggle()
end, { desc = "Toggle nvim-dap-view" })
Some debug adapters don't use the integrated terminal (console). To avoid having a useless window lying around, you can completely hide the terminal for them. To achieve that, add the following snippet to your nvim-dap-view
setup:
-- Goes into your opts table (if using lazy.nvim), otherwise goes into the setup function
-- No need to include the "return" statement (or the outer curly braces)
return {
windows = {
terminal = {
-- NOTE Don't copy paste this snippet
-- Use the actual names for the adapters you want to hide
-- `delve` is known to not use the terminal
hide = { "delve", "some-other-adapter" },
},
},
}
nvim-dap-view
defines 8 highlight groups:
NvimDapViewMissingData
NvimDapViewWatchText
NvimDapViewWatchTextChanged
NvimDapViewExceptionFilterEnabled
NvimDapViewExceptionFilterDisabled
NvimDapViewBreakpointFileName
NvimDapViewBreakpointLineNumber
NvimDapViewBreakpointSeparator
They are linked to (somewhat) reasonable defaults, but they may look odd with your colorscheme. Consider contributing to your colorscheme by sending a PR to add support to nvim-dap-view
.
nvim-dap-view
sets buffer filetypes for the following Views
Window | Filetype |
---|---|
watches, exceptions, breakpoints | dap-view |
terminal | dap-view-term |
These filetypes can be used to override buffer and window options set by nvim-dap-view
Example autocommand
Map q to quit in nvim-dap-view
filetypes:
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = { "dap-view", "dap-view-term", "dap-repl" }, -- dap-repl is set by `nvim-dap`
callback = function(evt)
vim.keymap.set("n", "q", "<C-w>q", { silent = true, buffer = evt.buf })
end,
})
- Watches
- Actions
- Expanding variables
- Yank expression's value
- Actions
- Threads and Stacks view
Missing something? Create an issue with a feature request!
Implement every feature from nvim-dap-ui. More specifically,
- There will be no "scopes" view (i.e., list all variables in scope). The rationale is that
nvim-dap
already provides a very nice UI for that, using widgets (see:h dap-widgets
). The TLDR is that you can use
function()
local widgets = require("dap.ui.widgets")
widgets.centered_float(widgets.scopes, { border = "rounded" })
end
to create a nice, centered floating window, where you can navigate and explore variables. A major advantage from this approach is that you're not limited to a small window at the bottom of your screen (which can be troublesome in noisy environments or languages).
- Likewise, there will be no "hover" view, since it's also perfectly handled by
nvim-dap
's widgets. You can use
function() require("dap.ui.widgets").hover(nil, { border = "rounded" }) end
- Breakpoints view doesn't show breakpoint conditions
- That's a limitation with the current breakpoints API from
nvim-dap
. We could use a workaround, but a new API is planned
- That's a limitation with the current breakpoints API from
- Code to inject treesitter highlights into line is taken from
quicker.nvim
; - Some snippets are directly extracted from
nvim-dap
:- Currently, there's no API to extract breakpoint information (see issue), so we resort to using nvim-dap internal mechanism, that tracks extmarks;
- The magic to extract expressions from visual mode is also a courtesy of
nvim-dap
.
- lucaSartore for the inspiration for handling breakpoint exceptions;
- Kulala for the creative usage
of neovim's
'winbar'
to handle multiple views. - blink.cmp for the config validation (which is partialy taken from a PR to indent-blankline)