diff --git a/README.md b/README.md index 391c3f8..da8433d 100644 --- a/README.md +++ b/README.md @@ -66,25 +66,31 @@ require("dapui").setup({ -- Expand lines larger than the window -- Requires >= 0.7 expand_lines = vim.fn.has("nvim-0.7"), - sidebar = { - -- You can change the order of elements in the sidebar - elements = { - -- Provide as ID strings or tables with "id" and "size" keys - { - id = "scopes", - size = 0.25, -- Can be float or integer > 1 + -- Layouts define sections of the screen to place windows. + -- The position can be "left", "right", "top" or "bottom". + -- The size specifies the height/width depending on position. + -- Elements are the elements shown in the layout (in order). + -- Layouts are opened in order so that earlier layouts take priority in window sizing. + layouts = { + { + elements = { + -- Elements can be strings or table with id and size keys. + { id = "scopes", size = 0.25 }, + "breakpoints", + "stacks", + "watches", }, - { id = "breakpoints", size = 0.25 }, - { id = "stacks", size = 0.25 }, - { id = "watches", size = 00.25 }, + size = 40, + position = "left", + }, + { + elements = { + "repl", + "console", + }, + size = 10, + position = "bottom", }, - size = 40, - position = "left", -- Can be "left", "right", "top", "bottom" - }, - tray = { - elements = { "repl", "console" }, - size = 10, - position = "bottom", -- Can be "left", "right", "top", "bottom" }, floating = { max_height = nil, -- These can be integers or a float between 0 and 1. @@ -95,7 +101,7 @@ require("dapui").setup({ }, }, windows = { indent = 1 }, - render = { + render = { max_type_length = nil, -- Can be integer or nil. } }) diff --git a/lua/dapui/config/init.lua b/lua/dapui/config/init.lua index 65ffa73..816185d 100644 --- a/lua/dapui/config/init.lua +++ b/lua/dapui/config/init.lua @@ -35,25 +35,30 @@ local default_config = { [M.actions.TOGGLE] = "t", }, expand_lines = vim.fn.has("nvim-0.7") == 1, - sidebar = { - -- You can change the order of elements in the sidebar - elements = { - -- Provide IDs as strings or tables with "id" and "size" keys - { - id = M.elements.SCOPES, - size = 0.25, -- Can be float or integer > 1 + layouts = { + { + -- You can change the order of elements in the sidebar + elements = { + -- Provide IDs as strings or tables with "id" and "size" keys + { + id = M.elements.SCOPES, + size = 0.25, -- Can be float or integer > 1 + }, + { id = M.elements.BREAKPOINTS, size = 0.25 }, + { id = M.elements.STACKS, size = 0.25 }, + { id = M.elements.WATCHES, size = 0.25 }, }, - { id = M.elements.BREAKPOINTS, size = 0.25 }, - { id = M.elements.STACKS, size = 0.25 }, - { id = M.elements.WATCHES, size = 0.25 }, + size = 40, + position = "left", -- Can be "left" or "right" + }, + { + elements = { + M.elements.REPL, + M.elements.CONSOLE, + }, + size = 10, + position = "bottom", -- Can be "bottom" or "top" }, - size = 40, - position = "left", -- Can be "left" or "right" - }, - tray = { - elements = { M.elements.REPL, M.elements.CONSOLE }, - size = 10, - position = "bottom", -- Can be "bottom" or "top" }, floating = { max_height = nil, -- These can be integers or a float between 0 and 1. @@ -74,6 +79,11 @@ local user_config = {} local function fill_elements(area) area = vim.deepcopy(area) local filled = {} + vim.validate({ + size = { area.size, "number" }, + elements = { area.elements, "table" }, + position = { area.position, "string" }, + }) for i, element in ipairs(area.elements) do if type(element) == "string" then filled[i] = { id = element, size = 1 / #area.elements } @@ -91,7 +101,12 @@ local function dep_warning(message) vim.schedule(function() if not dep_warnings[message] then dep_warnings[message] = true - vim.notify(message, "warn", { title = "nvim-dap-ui" }) + vim.notify(message, "warn", { + title = "nvim-dap-ui", + on_open = function(win) + vim.api.nvim_buf_set_option(vim.api.nvim_win_get_buf(win), "filetype", "markdown") + end, + }) end end) end @@ -105,11 +120,46 @@ local function fill_mappings(mappings) end function M.setup(config) - local filled = vim.tbl_deep_extend("keep", config or {}, default_config) + config = config or {} + local filled = vim.tbl_deep_extend("keep", config, default_config) + + if config.sidebar or config.tray then + dep_warning([[The 'sidebar' and 'tray' options are deprecated. Please use 'layouts' instead. +To replicate previous default behaviour, provide the following +```lua +require('dapui').setup( + layouts = { + { + elements = { + 'scopes', + 'breakpoints', + 'stacks', + 'watches', + }, + size = 40, + position = 'left', + }, + { + elements = { + 'repl', + 'console', + }, + size = 10, + position = 'bottom', + }, + }, +) +```]]) + end + + if config.layouts then + filled.layouts = config.layouts + end filled.mappings = fill_mappings(filled.mappings) filled.floating.mappings = fill_mappings(filled.floating.mappings) - filled.sidebar = fill_elements(filled.sidebar) - filled.tray = fill_elements(filled.tray) + for i, layout in ipairs(filled.layouts) do + filled.layouts[i] = fill_elements(layout) + end user_config = filled require("dapui.config.highlights").setup() @@ -131,6 +181,10 @@ function M.tray() return user_config.tray end +function M.layouts() + return user_config.layouts +end + function M.floating() return user_config.floating end diff --git a/lua/dapui/init.lua b/lua/dapui/init.lua index 866d67c..2df75fa 100644 --- a/lua/dapui/init.lua +++ b/lua/dapui/init.lua @@ -135,63 +135,97 @@ function dapui.setup(user_config) end) end ----Close either or both the tray and sidebar ----@param component string: "tray" or "sidebar" -function dapui.close(component) - windows.tray:update_sizes() - windows.sidebar:update_sizes() - if not component or component == "tray" then - windows.tray:update_sizes() - windows.tray:close() - end - if not component or component == "sidebar" then - windows.sidebar:update_sizes() - windows.sidebar:close() +---Close one or all of the window layouts +---@param layout number|nil: Index of layout in config +function dapui.close(layout) + for _, win_layout in ipairs(windows.layouts) do + win_layout:update_sizes() + end + for i, win_layout in ipairs(windows.layouts) do + if not layout or layout == i then + win_layout:update_sizes() + win_layout:close() + end + end +end + +---@generic T +---@param list T[] +---@return fun(): number, T +local function reverse(list) + local i = #list + 1 + return function() + i = i - 1 + if i <= 0 then + return nil + end + return i, list[i] end end ----Open either or both the tray and sidebar ----@param component string: "tray" or "sidebar" -function dapui.open(component) - windows.tray:update_sizes() - windows.sidebar:update_sizes() - local open_sidebar = false - if component == "tray" and windows.sidebar:is_open() then - windows.sidebar:close() - open_sidebar = true +---Open one or all of the window layouts +---@param layout number|nil: Index of layout in config +function dapui.open(layout) + for _, win_layout in ipairs(windows.layouts) do + win_layout:update_sizes() end - if not component or component == "tray" then - windows.tray:open() + local closed = {} + if layout then + for i = 1, (layout and layout - 1) or #windows.layouts, 1 do + if windows.layouts[i]:is_open() then + closed[#closed + 1] = i + windows.layouts[i]:close() + end + end + end + + for i, win_layout in reverse(windows.layouts) do + if not layout or layout == i then + win_layout:open() + end end - if not component or component == "sidebar" then - windows.sidebar:open() + + if #closed > 0 then + for _, i in ipairs(closed) do + windows.layouts[i]:open() + end end - if open_sidebar then - windows.sidebar:open() + + for _, win_layout in ipairs(windows.layouts) do + win_layout:resize() end - windows.tray:resize() end ----Toggle either or both the tray and sidebar ----@param component string: "tray" or "sidebar" -function dapui.toggle(component) - windows.tray:update_sizes() - windows.sidebar:update_sizes() - local open_sidebar = false - if component == "tray" and windows.sidebar:is_open() then - windows.sidebar:close() - open_sidebar = true +---Toggle one or all of the window layouts. +---@param layout number|nil: Index of layout in config +function dapui.toggle(layout) + for _, win_layout in reverse(windows.layouts) do + win_layout:update_sizes() end - if not component or component == "tray" then - windows.tray:toggle() + + local closed = {} + if layout then + for i = 1, (layout and layout - 1) or #windows.layouts, 1 do + if windows.layouts[i]:is_open() then + closed[#closed + 1] = i + windows.layouts[i]:close() + end + end end - if not component or component == "sidebar" then - windows.sidebar:toggle() + + for i, win_layout in reverse(windows.layouts) do + if not layout or layout == i then + win_layout:toggle() + end end - if open_sidebar then - windows.sidebar:open() + + for _, i in reverse(closed) do + windows.layouts[i]:open() + end + + for _, win_layout in ipairs(windows.layouts) do + win_layout:resize() end - windows.tray:resize() end return dapui diff --git a/lua/dapui/windows/init.lua b/lua/dapui/windows/init.lua index 327f68b..50407ca 100644 --- a/lua/dapui/windows/init.lua +++ b/lua/dapui/windows/init.lua @@ -8,10 +8,8 @@ local WindowLayout = require("dapui.windows.layout") local float_windows = {} ----@type dapui.WindowLayout -M.sidebar = nil ----@type dapui.WindowLayout -M.tray = nil +---@type dapui.WindowLayout[] +M.layouts = {} local function register_elements(elements) local win_configs = {} @@ -27,7 +25,7 @@ local function register_elements(elements) return win_configs end -local function tray_layout(height, position, win_configs) +local function horizontal_layout(height, position, win_configs) local open_cmd = position == "top" and "topleft" or "botright" local function open_tray_win(index) @@ -46,7 +44,7 @@ local function tray_layout(height, position, win_configs) }) end -local function side_layout(width, position, win_configs) +local function vertical_layout(width, position, win_configs) local open_cmd = position == "left" and "topleft" or "botright" local function open_side_win(index) vim.cmd(index == 1 and open_cmd .. " " .. "vsplit" or "split") @@ -68,18 +66,19 @@ local function area_layout(size, position, elements) local win_configs = register_elements(elements) local layout_func if position == "top" or position == "bottom" then - layout_func = tray_layout + layout_func = horizontal_layout else - layout_func = side_layout + layout_func = vertical_layout end return layout_func(size, position, win_configs) end function M.setup() - local tray_config = config.tray() - M.tray = area_layout(tray_config.size, tray_config.position, tray_config.elements) - local sidebar_config = config.sidebar() - M.sidebar = area_layout(sidebar_config.size, sidebar_config.position, sidebar_config.elements) + local layout_configs = config.layouts() + M.layouts = {} + for i, layout in ipairs(layout_configs) do + M.layouts[i] = area_layout(layout.size, layout.position, layout.elements) + end vim.cmd([[ augroup DapuiWindowsSetup au! @@ -89,8 +88,9 @@ function M.setup() end function M._force_buffers() - M.tray:force_buffers() - M.sidebar:force_buffers() + for _, layout in ipairs(M.layouts) do + layout:force_buffers() + end end function M.open_float(element, position, settings) diff --git a/tests/unit/config/init_spec.lua b/tests/unit/config/init_spec.lua index 5f95bfd..56be8dc 100644 --- a/tests/unit/config/init_spec.lua +++ b/tests/unit/config/init_spec.lua @@ -22,15 +22,17 @@ describe("checking setup function", function() end) it("fills elements", function() - config.setup({ sidebar = { elements = { "scopes" } } }) - assert.same({ { id = "scopes", size = 1 } }, config.sidebar().elements) + config.setup({ layouts = { { size = 10, position = "left", elements = { "scopes" } } } }) + assert.same({ { id = "scopes", size = 1 } }, config.layouts()[1].elements) end) it("fills elements with proportional size", function() - config.setup({ sidebar = { elements = { "scopes", "stacks" } } }) + config.setup({ + layouts = { { size = 10, position = "left", elements = { "scopes", "stacks" } } }, + }) assert.same( { { id = "scopes", size = 0.5 }, { id = "stacks", size = 0.5 } }, - config.sidebar().elements + config.layouts()[1].elements ) end) end) diff --git a/tests/unit/windows/layout_spec.lua b/tests/unit/windows/layout_spec.lua index d30cb3d..a14d22b 100644 --- a/tests/unit/windows/layout_spec.lua +++ b/tests/unit/windows/layout_spec.lua @@ -17,8 +17,9 @@ describe("checking window layout", function() config.setup() registered = {} run = {} - local position = config.sidebar().position - local width = config.sidebar().size + local layout_conf = config.layouts()[1] + local position = layout_conf.position + local width = layout_conf.size local open_cmd = position == "left" and "topleft" or "botright" local function open_sidebar_win(index) vim.cmd(index == 1 and open_cmd .. " " .. width .. "vsplit" or "split")