diff --git a/README.md b/README.md index 51e9425..263179b 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,9 @@ Following options can be given when calling `setup({config})`. Below is the defa -- Disable navigation when tmux is zoomed in disable_on_zoom = false + + -- Moving left on the left-most nvim pane will move to the last pane and vice versa + circular_movement = false } ``` diff --git a/lua/Navigator/navigate.lua b/lua/Navigator/navigate.lua index 9405b5a..84ed4f3 100644 --- a/lua/Navigator/navigate.lua +++ b/lua/Navigator/navigate.lua @@ -25,6 +25,7 @@ function N.setup(opts) N.config = { disable_on_zoom = false, auto_save = nil, + circular_movement = false, } if opts ~= nil then @@ -81,13 +82,32 @@ function N.navigate(direction) wincmd(direction) end - -- After navigation, if the old window and new window matches + -- Check if the old window and new window match after navigation local at_edge = cur_win == A.nvim_get_current_win() + local window_changed = cur_win ~= A.nvim_get_current_win() + -- If only one tmux pane exists, perform + -- 'circular movement' if on an edge + if N.config.circular_movement and at_edge and tmux.single_pane(direction) then + local alt_directions = { h = 'l', j = 'k', k = 'j', l = 'h' } + + local at_alt_edge = false + + while not at_alt_edge do + local new_cur_win = A.nvim_get_current_win() + wincmd(alt_directions[direction]) + at_alt_edge = new_cur_win == A.nvim_get_current_win() + end + + -- If the window has changed, don't change tmux pane + window_changed = cur_win ~= A.nvim_get_current_win() + end + + -- If the old window and new window match -- then we can assume that we hit the edge -- there is tmux pane besided the edge -- So we can navigate to the tmux pane - if N.back_to_tmux(at_edge) then + if N.back_to_tmux(at_edge) and not window_changed then tmux.change_pane(direction) local save = N.config.auto_save diff --git a/lua/Navigator/tmux.lua b/lua/Navigator/tmux.lua index d8f4177..af70f69 100644 --- a/lua/Navigator/tmux.lua +++ b/lua/Navigator/tmux.lua @@ -48,4 +48,26 @@ function T.is_zoomed() return execute("display-message -p '#{window_zoomed_flag}'") == '1' end +---To check whether only one tmux pane exists in a direction +---@param direction string +---@return boolean +function T.single_pane(direction) + -- Check if only one tmux pane exists + if execute("display-message -p '#{window_panes}'") == '1' then + return true + end + + -- Check if tmux pane is zoomed + if T.is_zoomed() and require('Navigator.navigate').config.disable_on_zoom then + return true + end + + -- Compare dimensions of the tmux pane and tmux window in direction + if direction == 'h' or direction == 'l' then + return execute("display-message -p '#{pane_width}'") == execute("display-message -p '#{window_width}'") + elseif direction == 'j' or direction == 'k' then + return execute("display-message -p '#{pane_height}'") == execute("display-message -p '#{window_height}'") + end +end + return T