@@ -35,23 +35,27 @@ local move_slot = function(direction, slot, delta)
35
35
return slot - delta
36
36
end
37
37
38
+ local function slot_key (direction )
39
+ return (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .RIGHT_LEFT ) and " col"
40
+ or " row"
41
+ end
42
+
43
+ local function space_key (direction )
44
+ return (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .RIGHT_LEFT ) and " width"
45
+ or " height"
46
+ end
47
+
38
48
--- @param windows number[]
39
49
--- @param direction integer
40
50
local function window_intervals (windows , direction , cmp )
41
51
local win_intervals = {}
42
52
for _ , w in pairs (windows ) do
43
53
local exists , existing_conf = util .get_win_config (w )
44
54
if exists then
45
- local slot_key = (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .RIGHT_LEFT )
46
- and " col"
47
- or " row"
48
- local space_key = (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .RIGHT_LEFT )
49
- and " width"
50
- or " height"
51
55
local border_space = existing_conf .border and 2 or 0
52
56
win_intervals [# win_intervals + 1 ] = {
53
- existing_conf [slot_key ],
54
- existing_conf [slot_key ] + existing_conf [space_key ] + border_space ,
57
+ existing_conf [slot_key ( direction ) ],
58
+ existing_conf [slot_key ( direction ) ] + existing_conf [space_key ( direction ) ] + border_space ,
55
59
}
56
60
end
57
61
end
@@ -61,7 +65,7 @@ local function window_intervals(windows, direction, cmp)
61
65
return win_intervals
62
66
end
63
67
64
- local function get_slot_range (direction )
68
+ function M . get_slot_range (direction )
65
69
local top = vim .opt .tabline :get () == " " and 0 or 1
66
70
local bottom = vim .opt .lines :get () - (vim .opt .laststatus :get () > 0 and 2 or 1 )
67
71
local left = 1
@@ -77,6 +81,7 @@ local function get_slot_range(direction)
77
81
end
78
82
error (string.format (" Invalid direction: %s" , direction ))
79
83
end
84
+
80
85
--- @param existing_wins number[] Windows to avoid overlapping
81
86
--- @param required_space number Window height or width including borders
82
87
--- @param direction integer Direction to stack windows , one of M.DIRECTION
@@ -85,7 +90,7 @@ function M.available_slot(existing_wins, required_space, direction)
85
90
local cmp = (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .TOP_DOWN ) and less
86
91
or greater
87
92
88
- local first_slot , last_slot = get_slot_range (direction )
93
+ local first_slot , last_slot = M . get_slot_range (direction )
89
94
90
95
local next_slot = first_slot
91
96
@@ -133,4 +138,51 @@ available_slot(existing_wins, required_space, stages_util.DIRECTION.TOP_DOWN)
133
138
return M .available_slot (wins , required_space , M .DIRECTION .TOP_DOWN )
134
139
end
135
140
141
+ --- Gets the next slow available for the given window while maintaining its position using the given list.
142
+ --- @param win number
143
+ --- @param open_windows
144
+ --- @param direction
145
+ function M .slot_after_previous (win , open_windows , direction )
146
+ local key = slot_key (direction )
147
+ local cmp = (direction == M .DIRECTION .LEFT_RIGHT or direction == M .DIRECTION .TOP_DOWN ) and less
148
+ or greater
149
+ local exists , cur_win_conf = pcall (vim .api .nvim_win_get_config , win )
150
+ if not exists then
151
+ return 0
152
+ end
153
+
154
+ local cur_slot = cur_win_conf [key ][false ]
155
+ local win_confs = {}
156
+ for _ , w in ipairs (open_windows ) do
157
+ local success , conf = pcall (vim .api .nvim_win_get_config , w )
158
+ if success then
159
+ win_confs [w ] = conf
160
+ end
161
+ end
162
+
163
+ local higher_wins = vim .tbl_filter (function (open_win )
164
+ return win_confs [open_win ] and cmp (win_confs [open_win ][key ][false ], cur_slot )
165
+ end , open_windows )
166
+
167
+ if # higher_wins == 0 then
168
+ local first_slot = M .get_slot_range (direction )
169
+ if direction == M .DIRECTION .RIGHT_LEFT or direction == M .DIRECTION .BOTTOM_UP then
170
+ return move_slot (direction , first_slot , cur_win_conf [space_key (direction )] + 2 )
171
+ end
172
+ return first_slot
173
+ end
174
+
175
+ table.sort (higher_wins , function (a , b )
176
+ return cmp (win_confs [a ][key ][false ], win_confs [b ][key ][false ])
177
+ end )
178
+
179
+ local last_win = higher_wins [# higher_wins ]
180
+ local res = move_slot (
181
+ direction ,
182
+ win_confs [last_win ][key ][false ],
183
+ win_confs [last_win ][space_key (direction )] + 2
184
+ )
185
+ return res
186
+ end
187
+
136
188
return M
0 commit comments