minimalistic nvim-dap-ui alternative
https://github.com/user-attachments/assets/01c461f7-b77b-4232-bed5-4630f3e7c039
[!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)
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 5 "views" that share the same window (so there's clutter)
<CR>
<CR>
subtle
(hidden) frames with t
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 either completely hide it (if it's not being used at all) or hide it only during session initialization.
return {
winbar = {
show = true,
sections = { "watches", "exceptions", "breakpoints", "threads", "repl" },
-- Must be one of the sections declared above
default_section = "watches",
},
windows = {
height = 12,
terminal = {
-- 'left'|'right'|'above'|'below': Terminal position in layout
position = "left",
-- List of debug adapters for which the terminal should be ALWAYS hidden
hide = {},
-- Hide the terminal when starting a new session
start_hidden = false,
},
},
}
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 expressionThough, 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. The threads view has 2 mappings:
<CR>
jumps to a location in the call stackt
toggles subtle framesWhen 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
Additionally, you can use DapViewClose!
and DapViewToggle!
to also hide the
terminal window, if you prefer a tidy view.
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").close(true) -- Same as `DapViewClose!`
require("dap-view").toggle()
require("dap-view").toggle(true) -- Same as `DapViewToggle!`
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" })
If you find yourself constantly toggling nvim-dap-view
once a session starts and then closing on session end, you might want to add the following snippet to your configuration:
local dap, dv = require("dap"), require("dap-view")
dap.listeners.before.attach["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.launch["dap-view-config"] = function()
dv.open()
end
dap.listeners.before.event_terminated["dap-view-config"] = function()
dv.close()
end
dap.listeners.before.event_exited["dap-view-config"] = function()
dv.close()
end
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
-- `go` is known to not use the terminal.
hide = { "go", "some-other-adapter" },
},
},
}
When setting windows.terminal.position
to right
the views window may be used
to display the current breakpoint because nvim-dap
defaults to the global
switchbuf
setting. A common solution is to set switchbuf
to "useopen":
require("dap").defaults.fallback.switchbuf = "useopen"
If you are using an adapter that does not natively support the nvim-dap
integrated
terminal, but you want to use the nvim-dap-view
terminal anyway, you can get
the winnr
and bufnr
of the nvim-dap-view
terminal via dap-view.state
and
use vim.fn.jobstart
to start your debug adapter in the nvim-dap-view
terminal!
An example can be found here
nvim-dap-view
defines 10 highlight groups:
NvimDapViewMissingData
NvimDapViewWatchText
NvimDapViewWatchTextChanged
NvimDapViewExceptionFilterEnabled
NvimDapViewExceptionFilterDisabled
NvimDapViewFileName
NvimDapViewLineNumber
NvimDapViewSeparator
NvimDapViewThread
NvimDapViewThreadStopped
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
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,
})
Missing something? Create an issue with a feature request!
Implement every feature from nvim-dap-ui. More specifically,
nvim-dap
already provides a very nice UI for that, using widgets (see :h dap-widgets
). The TLDR is that you can uselocal widgets = require("dap.ui.widgets")
widgets.centered_float(widgets.scopes, { border = "rounded" })
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).
nvim-dap
's widgets. You can userequire("dap.ui.widgets").hover(nil, { border = "rounded" })
to create a nice floating window to display the variable under the cursor.
nvim-dap
. We
could use a workaround, but a new API is
plannedquicker.nvim
;nvim-dap
:nvim-dap
.'winbar'
to handle multiple views.[^1]: Filters depend on the debug adapter's capabilities [^2]: From treesitter and extmarks (e.g., semantic highlighting from LSP)