Skip to content

Commit 2c7b974

Browse files
committed
feat(stages): slide windows after previous closes
See #105
1 parent 74ba257 commit 2c7b974

File tree

2 files changed

+88
-18
lines changed

2 files changed

+88
-18
lines changed

lua/notify/stages/fade_in_slide_out.lua

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ local stages_util = require("notify.stages.util")
33
return {
44
function(state)
55
local next_height = state.message.height + 2
6-
local next_row = stages_util.available_slot(
7-
state.open_windows,
8-
next_height,
9-
stages_util.DIRECTION.TOP_DOWN
10-
)
6+
local next_row =
7+
stages_util.available_slot(state.open_windows, next_height, stages_util.DIRECTION.TOP_DOWN)
118
if not next_row then
129
return nil
1310
end
@@ -23,19 +20,33 @@ return {
2320
opacity = 0,
2421
}
2522
end,
26-
function()
23+
function(state, win)
2724
return {
2825
opacity = { 100 },
2926
col = { vim.opt.columns:get() },
27+
row = {
28+
stages_util.slot_after_previous(win, state.open_windows, stages_util.DIRECTION.TOP_DOWN),
29+
frequency = 3,
30+
complete = function()
31+
return true
32+
end,
33+
},
3034
}
3135
end,
32-
function()
36+
function(state, win)
3337
return {
3438
col = { vim.opt.columns:get() },
3539
time = true,
40+
row = {
41+
stages_util.slot_after_previous(win, state.open_windows, stages_util.DIRECTION.TOP_DOWN),
42+
frequency = 3,
43+
complete = function()
44+
return true
45+
end,
46+
},
3647
}
3748
end,
38-
function()
49+
function(state, win)
3950
return {
4051
width = {
4152
1,
@@ -53,6 +64,13 @@ return {
5364
end,
5465
},
5566
col = { vim.opt.columns:get() },
67+
row = {
68+
stages_util.slot_after_previous(win, state.open_windows, stages_util.DIRECTION.TOP_DOWN),
69+
frequency = 3,
70+
complete = function()
71+
return true
72+
end,
73+
},
5674
}
5775
end,
5876
}

lua/notify/stages/util.lua

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,27 @@ local move_slot = function(direction, slot, delta)
3535
return slot - delta
3636
end
3737

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+
3848
---@param windows number[]
3949
---@param direction integer
4050
local function window_intervals(windows, direction, cmp)
4151
local win_intervals = {}
4252
for _, w in pairs(windows) do
4353
local exists, existing_conf = util.get_win_config(w)
4454
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"
5155
local border_space = existing_conf.border and 2 or 0
5256
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,
5559
}
5660
end
5761
end
@@ -61,7 +65,7 @@ local function window_intervals(windows, direction, cmp)
6165
return win_intervals
6266
end
6367

64-
local function get_slot_range(direction)
68+
function M.get_slot_range(direction)
6569
local top = vim.opt.tabline:get() == "" and 0 or 1
6670
local bottom = vim.opt.lines:get() - (vim.opt.laststatus:get() > 0 and 2 or 1)
6771
local left = 1
@@ -77,6 +81,7 @@ local function get_slot_range(direction)
7781
end
7882
error(string.format("Invalid direction: %s", direction))
7983
end
84+
8085
---@param existing_wins number[] Windows to avoid overlapping
8186
---@param required_space number Window height or width including borders
8287
---@param direction integer Direction to stack windows, one of M.DIRECTION
@@ -85,7 +90,7 @@ function M.available_slot(existing_wins, required_space, direction)
8590
local cmp = (direction == M.DIRECTION.LEFT_RIGHT or direction == M.DIRECTION.TOP_DOWN) and less
8691
or greater
8792

88-
local first_slot, last_slot = get_slot_range(direction)
93+
local first_slot, last_slot = M.get_slot_range(direction)
8994

9095
local next_slot = first_slot
9196

@@ -133,4 +138,51 @@ available_slot(existing_wins, required_space, stages_util.DIRECTION.TOP_DOWN)
133138
return M.available_slot(wins, required_space, M.DIRECTION.TOP_DOWN)
134139
end
135140

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+
136188
return M

0 commit comments

Comments
 (0)