Let dap toggle terminal/repl.

main
Joshua Potter 2024-03-04 19:55:49 -07:00
parent f9beed8b30
commit 6f15bd3695
2 changed files with 134 additions and 42 deletions

View File

@ -61,35 +61,24 @@ local function select_config_and_run()
) )
end end
local function sidebar_new(widget)
return dap_ui_widgets.sidebar(widget, { width = 40 }, '')
end
local function sidebar_is_open(sidebar)
return sidebar.win and vim.api.nvim_win_is_valid(sidebar.win)
end
-- Setup buffer-local DAP mappings. This function is expected to be called in -- Setup buffer-local DAP mappings. This function is expected to be called in
-- a filetype plugin, e.g. `nvim/after/ftplugin/c.lua`. -- a filetype plugin, e.g. `nvim/after/ftplugin/c.lua`.
function M.buffer_map() function M.buffer_map()
local function set_nnoremap(key, func) local function sidebar_new(widget)
vim.keymap.set( return dap_ui_widgets.sidebar(widget, { width = 32 }, '')
'n',
string.format('<localleader>%s', key),
func,
{ buffer = true }
)
end end
local sidebars = { local sidebars = {
expression = sidebar_new(dap_ui_widgets.expression),
frames = sidebar_new(dap_ui_widgets.frames), frames = sidebar_new(dap_ui_widgets.frames),
scopes = sidebar_new(dap_ui_widgets.scopes), scopes = sidebar_new(dap_ui_widgets.scopes),
sessions = sidebar_new(dap_ui_widgets.sessions),
threads = sidebar_new(dap_ui_widgets.threads), threads = sidebar_new(dap_ui_widgets.threads),
} }
local function any_sidebar_open() local function sidebar_is_open(sb)
return sb.win and vim.api.nvim_win_is_valid(sb.win)
end
local function sidebar_any_open()
for _, sb in pairs(sidebars) do for _, sb in pairs(sidebars) do
if sidebar_is_open(sb) then if sidebar_is_open(sb) then
return true return true
@ -98,22 +87,119 @@ function M.buffer_map()
return false return false
end end
local function toggle_sidebar(sidebar) local function sidebar_toggle(sidebar)
if sidebar_is_open(sidebar) then if sidebar_is_open(sidebar) then
sidebar.close({ mode = 'toggle' }) sidebar.close({ mode = 'toggle' })
else else
local win_id = vim.fn.win_getid() local win_id = vim.fn.win_getid()
vim.cmd.wincmd('t') -- Move to topleft-most window. vim.cmd.wincmd('t') -- Move to topleft-most window.
vim.cmd(any_sidebar_open() and 'leftabove split' or 'vertical topleft split') vim.cmd(sidebar_any_open() and 'leftabove split' or 'vertical topleft split')
sidebar.open() sidebar.open()
vim.fn.win_gotoid(win_id) vim.fn.win_gotoid(win_id)
-- Update state of windows. -- Update state of windows.
vim.api.nvim_win_set_option(sidebar.win, 'colorcolumn', '') vim.api.nvim_win_set_option(sidebar.win, 'colorcolumn', '')
vim.api.nvim_win_set_option(sidebar.win, 'list', false) vim.api.nvim_win_set_option(sidebar.win, 'list', false)
vim.api.nvim_win_set_option(sidebar.win, 'wrap', false) vim.api.nvim_win_set_option(sidebar.win, 'wrap', false)
vim.api.nvim_win_set_option(sidebar.win, 'winfixwidth', true)
end end
end end
local function sidebar_only(sidebar)
for _, sb in pairs(sidebars) do
if sb ~= sidebar and sidebar_is_open(sb) then
sb.close({ mode = 'toggle' })
end
end
if not sidebar_is_open(sidebar) then
sidebar_toggle(sidebar)
end
end
local function find_bufnr_by_pattern(pattern)
for _, bufnr in pairs(vim.api.nvim_list_bufs()) do
if vim.fn.bufname(bufnr):match(pattern) then
return bufnr
end
end
return nil
end
local function is_bufnr_open(bufnr)
if not bufnr then
return false
end
local windows = vim.fn.win_findbuf(bufnr)
for _, _ in pairs(windows) do
return true
end
return false
end
local function repl_is_open()
return is_bufnr_open(find_bufnr_by_pattern("^%[dap%-repl]"))
end
local function term_is_open()
return is_bufnr_open(find_bufnr_by_pattern("^%[dap%-terminal]"))
end
local function repl_open(opts)
if repl_is_open() then
return
end
local height = opts.height or 10
local win_id = vim.fn.win_getid()
vim.cmd.wincmd('b') -- Move to bottomright-most window.
dap.repl.open({}, term_is_open() and
'vertical rightbelow split' or
string.format('rightbelow %dsplit', height))
vim.api.nvim_win_set_option(0, 'winfixheight', true)
vim.fn.win_gotoid(win_id)
end
local function term_open(opts)
if term_is_open() then
return
end
local height = opts.height or 10
local win_id = vim.fn.win_getid()
vim.cmd.wincmd('b') -- Move to bottomright-most window.
vim.cmd(repl_is_open() and
'vertical rightbelow split' or
string.format('rightbelow %dsplit', height))
vim.api.nvim_win_set_option(0, 'winfixheight', true)
vim.api.nvim_win_set_buf(0, find_bufnr_by_pattern("^%[dap%-terminal]"))
vim.fn.win_gotoid(win_id)
end
local function repl_close()
dap.repl.close()
end
local function term_close()
if not term_is_open() then
return
end
local bufnr = find_bufnr_by_pattern("^%[dap%-terminal]")
local windows = vim.fn.win_findbuf(bufnr)
for _, win in pairs(windows) do
vim.api.nvim_win_close(win, --[[force=]] true)
end
end
local function repl_toggle(opts)
if repl_is_open() then repl_close() else repl_open(opts) end
end
local function term_toggle(opts)
if term_is_open() then term_close() else term_open(opts) end
end
local function set_nnoremap(key, func)
local input = string.format('<localleader>%s', key)
vim.keymap.set('n', input, func, { buffer = true })
end
set_nnoremap('<localleader>', select_config_and_run) set_nnoremap('<localleader>', select_config_and_run)
set_nnoremap('b', dap.toggle_breakpoint) set_nnoremap('b', dap.toggle_breakpoint)
set_nnoremap('c', function() set_nnoremap('c', function()
@ -123,6 +209,7 @@ function M.buffer_map()
end end
dap.continue() dap.continue()
end) end)
set_nnoremap('d', dap.down) set_nnoremap('d', dap.down)
set_nnoremap('i', dap.step_into) set_nnoremap('i', dap.step_into)
set_nnoremap('n', dap.step_over) set_nnoremap('n', dap.step_over)
@ -131,23 +218,23 @@ function M.buffer_map()
set_nnoremap('r', dap.run_to_cursor) set_nnoremap('r', dap.run_to_cursor)
set_nnoremap('u', dap.up) set_nnoremap('u', dap.up)
set_nnoremap('x', dap.clear_breakpoints) set_nnoremap('x', dap.clear_breakpoints)
set_nnoremap('we', function()
toggle_sidebar(sidebars.expression) set_nnoremap('wf', function() sidebar_toggle(sidebars.frames) end)
set_nnoremap('wh', function() sidebar_toggle(sidebars.threads) end)
set_nnoremap('wr', function() repl_toggle({ height = 10 }) end)
set_nnoremap('ws', function() sidebar_toggle(sidebars.scopes) end)
set_nnoremap('wt', function() term_toggle({ height = 10 }) end)
set_nnoremap('wF', function() sidebar_only(sidebars.frames) end)
set_nnoremap('wH', function() sidebar_only(sidebars.threads) end)
set_nnoremap('wR', function()
term_close()
repl_open({ height = 10 })
end) end)
set_nnoremap('wf', function() set_nnoremap('wS', function() sidebar_only(sidebars.scopes) end)
toggle_sidebar(sidebars.frames) set_nnoremap('wT', function()
end) repl_close()
set_nnoremap('wc', function() term_open({ height = 10 })
toggle_sidebar(sidebars.scopes)
end)
set_nnoremap('wr', function()
dap.repl.toggle({ height = 10 })
end)
set_nnoremap('ws', function()
toggle_sidebar(sidebars.sessions)
end)
set_nnoremap('wt', function()
toggle_sidebar(sidebars.threads)
end) end)
end end

View File

@ -47,10 +47,15 @@ let
nvim-dap = { nvim-dap = {
plugin = utils.pluginGit plugin = utils.pluginGit
"e154fdb6d70b3765d71f296e718b29d8b7026a63" "fc880e82059eb21c0fa896be60146e5f17680648"
"mfussenegger/nvim-dap"; "mfussenegger/nvim-dap";
config = '' config = ''
require('dap').defaults.fallback.terminal_win_cmd = 'below 10split new' require("dap").defaults.fallback.terminal_win_cmd = function()
return vim.api.nvim_create_buf(
true, -- listed
true -- scratch
)
end
${config.programs.neovim.nvim-dap} ${config.programs.neovim.nvim-dap}
''; '';
}; };