diff --git a/init.lua b/init.lua index 2af9467..b6f2067 100644 --- a/init.lua +++ b/init.lua @@ -7,3 +7,4 @@ require('colorscheme') require('lsp') require('keybindings') require('diary') +require('layout') diff --git a/lua/keybindings.lua b/lua/keybindings.lua index 6cfc660..cd205a0 100644 --- a/lua/keybindings.lua +++ b/lua/keybindings.lua @@ -61,6 +61,16 @@ local workspaces_fzf_picker = function(opts) end vim.keymap.set('n', 'w', workspaces_fzf_picker, { desc = "Workspaces" }) +------------------------------------------ +-- +-- Window layout save and restore +-- +------------------------------------------ + +local layout = require('layout') +vim.keymap.set('n', 'ss', function() layout.save('default') end, { desc = "Save window layout" }) +vim.keymap.set('n', 'sr', function() layout.restore('default') end, { desc = "Restore window layout" }) + ------------------------------------------ -- -- Word higlighting diff --git a/lua/layout.lua b/lua/layout.lua new file mode 100644 index 0000000..62affa1 --- /dev/null +++ b/lua/layout.lua @@ -0,0 +1,64 @@ +-- save and restore current window layout +-- inspired by: +-- - https://github.com/dedowsdi/.vim/blob/master/autoload/ddd/layout.vim +-- - https://vi.stackexchange.com/a/22545/53081 +local M = {} +local layouts = {} +local resize_cmds = {} + +function M.save(name) + layouts[name] = vim.fn.winlayout() + resize_cmds[name] = vim.fn.winrestcmd() + M.add_buf_to_layout(layouts[name]) +end + +function M.add_buf_to_layout(layout) + if layout[1] == "leaf" then + table.insert(layout, vim.fn.winbufnr(layout[2])) + else + for _, child_layout in ipairs(layout[2]) do + M.add_buf_to_layout(child_layout) + end + end +end + +function M.restore(name) + if not layouts[name] then + return + end + + -- Create clean window + vim.cmd("new") + vim.cmd("wincmd o") + + -- Recursively restore buffers + M.apply_layout(layouts[name]) + + -- Resize + vim.cmd(resize_cmds[name]) +end + +function M.apply_layout(layout) + if layout[1] == "leaf" then + -- Load buffer for leaf + if vim.fn.bufexists(layout[3]) == 1 then + vim.cmd(string.format("b %d", layout[3])) + end + else + -- Split cols or rows, split n-1 times + local split_method = layout[1] == "col" and "rightbelow split" or "rightbelow vsplit" + local wins = { vim.fn.win_getid() } + for i = 2, #layout[2] do + vim.cmd(split_method) + table.insert(wins, vim.fn.win_getid()) + end + + -- Recursive into child windows + for index, win_id in ipairs(wins) do + vim.fn.win_gotoid(win_id) + M.apply_layout(layout[2][index]) + end + end +end + +return M