From 76b4fbc078d52a0cc460b4572f04cd31e22f83e3 Mon Sep 17 00:00:00 2001 From: Markus Koller Date: Sun, 26 May 2024 22:30:35 +0200 Subject: [PATCH] feat: make floating window behavior configurable --- README.md | 4 +++ lua/smart-splits/api.lua | 58 ++++++++++++++++++++----------------- lua/smart-splits/config.lua | 2 ++ lua/smart-splits/types.lua | 6 ++++ 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 66c4739..9dc446f 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,10 @@ require('smart-splits').setup({ -- NOTE: `at_edge = 'wrap'` is not supported on Kitty terminal -- multiplexer, as there is no way to determine layout via the CLI at_edge = 'wrap', + -- Desired behavior when the current window is floating: + -- 'previous' => Focus previous Vim window and perform action + -- 'mux' => Always forward action to multiplexer + float_win_behavior = 'previous', -- when moving cursor between splits left or right, -- place the cursor on the same row of the *screen* -- regardless of line numbers. False by default. diff --git a/lua/smart-splits/api.lua b/lua/smart-splits/api.lua index e77ebeb..5641634 100644 --- a/lua/smart-splits/api.lua +++ b/lua/smart-splits/api.lua @@ -6,6 +6,7 @@ local mux_utils = require('smart-splits.mux.utils') local types = require('smart-splits.types') local Direction = types.Direction local AtEdgeBehavior = types.AtEdgeBehavior +local FloatWinBehavior = types.FloatWinBehavior local M = {} @@ -194,20 +195,37 @@ local function compute_direction_horizontal(direction) return result end +---@param mux_callback fun()|nil +---@return boolean +local function handle_floating_window(mux_callback) + if utils.is_floating_window() then + if config.float_win_behavior == FloatWinBehavior.previous then + -- focus the last accessed window. + -- if it's also floating, do not attempt to perform the action. + local prev_win = vim.fn.win_getid(vim.fn.winnr('#')) + if utils.is_floating_window(prev_win) then + return true + end + + vim.api.nvim_set_current_win(prev_win) + return false + elseif config.float_win_behavior == FloatWinBehavior.mux then + -- always forward the action to the multiplexer + if mux_callback then + mux_callback() + end + return true + end + end +end + ---@param direction SmartSplitsDirection ---@param amount number local function resize(direction, amount) amount = amount or config.default_amount - -- ignore currently focused floating windows by focusing the last accessed window - -- if the last accessed window is also floating, do not attempt to resize it - if utils.is_floating_window() then - local prev_win = vim.fn.win_getid(vim.fn.winnr('#')) - if utils.is_floating_window(prev_win) then - return - end - - vim.api.nvim_set_current_win(prev_win) + if handle_floating_window(function() mux.resize_pane(direction, amount) end) then + return end -- if a full width window and horizontall resize check if we can resize with multiplexer @@ -336,15 +354,8 @@ local function move_cursor(direction, opts) end end - -- ignore currently focused floating windows by focusing the last accessed window - -- if the last accessed window is also floating, do not attempt to move the cursor - if utils.is_floating_window() then - local prev_win = vim.fn.win_getid(vim.fn.winnr('#')) - if utils.is_floating_window(prev_win) then - return - end - - vim.api.nvim_set_current_win(prev_win) + if handle_floating_window(function() mux.move_pane(direction, true, at_edge) end) then + return end local offset = vim.fn.winline() + vim.api.nvim_win_get_position(0)[1] @@ -421,15 +432,8 @@ end local function swap_bufs(direction, opts) opts = opts or {} - -- ignore currently focused floating windows by focusing the last accessed window - -- if the last accessed window is also floating, do not attempt to swap buffers - if utils.is_floating_window() then - local prev_win = vim.fn.win_getid(vim.fn.winnr('#')) - if utils.is_floating_window(prev_win) then - return - end - - vim.api.nvim_set_current_win(prev_win) + if handle_floating_window() then + return end local buf_1 = vim.api.nvim_get_current_buf() diff --git a/lua/smart-splits/config.lua b/lua/smart-splits/config.lua index e6c0d43..b9ca204 100644 --- a/lua/smart-splits/config.lua +++ b/lua/smart-splits/config.lua @@ -20,6 +20,7 @@ local mux_utils = require('smart-splits.mux.utils') ---@field ignored_filetypes string[] ---@field default_amount number ---@field at_edge SmartSplitsAtEdgeBehavior +---@field float_win_behavior SmartSplitsFloatWinBehavior ---@field move_cursor_same_row boolean ---@field cursor_follows_swapped_bufs boolean ---@field resize_mode SmartResizeModeConfig @@ -45,6 +46,7 @@ local config = { ---@diagnostic disable-line:missing-fields }, default_amount = 3, at_edge = AtEdgeBehavior.wrap, + float_win_behavior = 'previous', move_cursor_same_row = false, cursor_follows_swapped_bufs = false, resize_mode = { diff --git a/lua/smart-splits/types.lua b/lua/smart-splits/types.lua index 7649489..4f5afe9 100644 --- a/lua/smart-splits/types.lua +++ b/lua/smart-splits/types.lua @@ -40,6 +40,12 @@ local M = { ---@type SmartSplitsAtEdgeBehavior stop = 'stop', }, + FloatWinBehavior = { + ---@type SmartSplitsFloatWinBehavior + previous = 'previous', + ---@type SmartSplitsFloatWinBehavior + mux = 'mux', + }, Multiplexer = { ---@type SmartSplitsMultiplexerType tmux = 'tmux',