[WIP] Start work on a simple windows swapping feature, much like how tiling window managers work

This commit is contained in:
Martin Larsson 2024-06-03 00:07:14 +02:00
parent 4875e0fc9f
commit c34d0afa71

View file

@ -33,3 +33,105 @@ require("terminal").setup()
-- See ":help vim.highlight.on_yank()"
setup_yank_highlight()
-- Extract to plugin later
local function is_floating_window(window)
return vim.api.nvim_win_get_config(window).relative ~= ""
end
local function is_window_resizable(window)
local config = vim.api.nvim_win_get_config(window)
return not config.winfixwidth and not config.winfixheight
end
local function get_total_num_windows_open()
return #vim.api.nvim_tabpage_list_wins(0)
end
local function get_adjacent_window(dir_char)
assert(dir_char == "h" or dir_char == "j" or dir_char == "k" or dir_char == "l", "Invalid direction character")
local current_window = vim.api.nvim_get_current_win()
assert(current_window, "Current window is nil")
vim.cmd("wincmd " .. dir_char)
local new_window = vim.api.nvim_get_current_win()
vim.api.nvim_set_current_win(current_window)
assert(vim.api.nvim_get_current_win() == current_window, "Cursor moved to a different window")
return new_window
end
local function is_current_window_at_edge(dir_char)
return vim.api.nvim_get_current_win() == get_adjacent_window(dir_char)
end
local function swap_buffer_between_windows(window_a, window_b)
assert(window_a and window_b, "Invalid window")
local buffer_a = vim.api.nvim_win_get_buf(window_a)
local buffer_b = vim.api.nvim_win_get_buf(window_b)
vim.api.nvim_win_set_buf(window_a, buffer_b)
vim.api.nvim_win_set_buf(window_b, buffer_a)
assert(vim.api.nvim_win_get_buf(window_a) == buffer_b and vim.api.nvim_win_get_buf(window_b) == buffer_a,
"Failed to swap buffers")
end
local function swap_window(dir_char)
assert(dir_char == "h" or dir_char == "j" or dir_char == "k" or dir_char == "l", "Invalid direction character")
local current_window = vim.api.nvim_get_current_win()
assert(current_window, "Current window is nil")
local required_num_windows = 2
if get_total_num_windows_open() < required_num_windows then
return
end
if is_floating_window(current_window) then
return
end
if is_current_window_at_edge(dir_char) then
return
end
if not is_window_resizable(current_window) then
return
end
local adjacent_window = get_adjacent_window(dir_char)
if not is_window_resizable(adjacent_window) then
return
end
swap_buffer_between_windows(current_window, adjacent_window)
end
require("utils").add_keymaps({
n = {
-- ["<C-S>Left"] = {
["h"] = {
cmd = function()
swap_window("h")
end
},
-- ["<C-S>Down"] = {
["j"] = {
cmd = function()
swap_window("j")
end
},
-- ["<C-S>Up"] = {
["k"] = {
cmd = function()
swap_window("k")
end
},
-- ["<C-S>Right"] = {
["l"] = {
cmd = function()
swap_window("l")
end
},
},
})