Skip to content

Commit 13a959d

Browse files
committed
refactor(offsets): use wininfo to calculate offset
fixes #789
1 parent 99f0932 commit 13a959d

1 file changed

Lines changed: 28 additions & 73 deletions

File tree

lua/bufferline/offset.lua

Lines changed: 28 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,6 @@ local api = vim.api
1010
local fn = vim.fn
1111
local padding = constants.padding
1212

13-
local t = {
14-
LEAF = "leaf",
15-
ROW = "row",
16-
COLUMN = "col",
17-
}
18-
19-
local supported_win_types = {
20-
[t.LEAF] = true,
21-
[t.COLUMN] = true,
22-
}
23-
2413
---Format the content of a neighbouring offset's text
2514
---@param size integer
2615
---@param highlight table<string, string>
@@ -80,57 +69,23 @@ local function guess_window_highlight(win_id, attribute, match)
8069
return match
8170
end
8271

83-
--- This helper checks to see if bufferline supports creating an offset for the given layout
84-
--- Valid window layouts can be
85-
--- * A list of full height splits in a row:
86-
--- `{'row', ['leaf', id], ['leaf', id]}`
87-
--- * A row of splits where one on either edge is not full height but the matching
88-
--- split is on the top:
89-
--- e.g. the vertical tool bar is split in two such as for undo tree
90-
--- `{'row', ['col', ['leaf', id], ['leaf', id]], ['leaf', id]}`
91-
---
92-
---@param windows any[]
93-
---@return boolean, number
94-
local function is_valid_layout(windows)
95-
local win_type, win_id = windows[1], windows[2]
96-
if utils.is_list(win_id) and win_type == t.COLUMN then win_id = win_id[1][2] end
97-
return supported_win_types[win_type] and type(win_id) == "number", win_id
98-
end
99-
100-
--- Test if the windows within a layout row contain the correct panel buffer
101-
--- NOTE: this only tests the first and last windows as those are the only
102-
--- ones that it makes sense to add a panel for
103-
---@param windows any[]
72+
---@param windows {wincol: number, winrow: number, bufnr: number, winid: number, width: number}[]
10473
---@param offset table
105-
---@return boolean
106-
---@return number?
107-
---@return boolean?
74+
---@return boolean valid
75+
---@return number? win_id
76+
---@return boolean? is_left
10877
local function is_offset_section(windows, offset)
109-
local wins = { windows[1] }
110-
if #windows > 1 then wins[#wins + 1] = windows[#windows] end
111-
for idx, win in ipairs(wins) do
112-
local valid_layout, win_id = is_valid_layout(win)
113-
if valid_layout then
114-
local buf = api.nvim_win_get_buf(win_id)
115-
local valid = buf and vim.bo[buf].filetype == offset.filetype
116-
local is_left = idx == 1
117-
if valid then return valid, win_id, is_left end
78+
local last = windows[1]
79+
for _, win in ipairs(windows) do
80+
if win.winrow == 2 then
81+
if vim.bo[win.bufnr].filetype == offset.filetype then
82+
if win.wincol > last.wincol then last = win end
83+
if win.wincol == 1 then return true, win.winid, true end
84+
end
11885
end
11986
end
120-
return false, nil, nil
121-
end
122-
123-
--- Iterate over COLUMN layout by always picking the first element.
124-
--- Assuming this is the topmost window, it's the one that should
125-
--- dictate the tabline offset.
126-
---@param layout any[]
127-
---@return any[]
128-
local function iterate_col_layout(layout)
129-
if layout[1] == t.COLUMN then
130-
return iterate_col_layout(layout[2][1])
131-
else
132-
return layout
133-
end
87+
if last.wincol > 1 then return true, last.winid, false end
88+
return false
13489
end
13590

13691
---@class OffsetData
@@ -151,28 +106,28 @@ function M.get()
151106
local total_size = 0
152107
local sep_hl = highlights.hl(hls.offset_separator.hl_group)
153108

154-
if offsets and #offsets > 0 then
155-
local layout = iterate_col_layout(fn.winlayout())
109+
-- wininfo tells us whether or not a window is on the top level or not of the layout
110+
-- if it is on the top level and it is at the end or beginning it is an offset
111+
local wininfo = vim.tbl_filter(function(win) return fn.win_gettype(win.winnr) == "" end, fn.getwininfo())
156112

113+
if offsets and #offsets > 0 then
157114
for _, offset in ipairs(offsets) do
158115
-- don't bother proceeding if there are no vertical splits
159-
if layout[1] == t.ROW then
160-
local is_valid, win_id, is_left = is_offset_section(layout[2], offset)
161-
if is_valid and win_id then
162-
local width = api.nvim_win_get_width(win_id) + (offset.padding or 0)
116+
local is_valid, win_id, is_left = is_offset_section(wininfo, offset)
117+
if is_valid and win_id then
118+
local width = api.nvim_win_get_width(win_id) + (offset.padding or 0)
163119

164-
local hl_name = offset.highlight or guess_window_highlight(win_id) or config.highlights.fill.hl_group
120+
local hl_name = offset.highlight or guess_window_highlight(win_id) or config.highlights.fill.hl_group
165121

166-
local hl = highlights.hl(hl_name)
167-
local component = get_section_text(width, { text = hl, sep = sep_hl }, offset, is_left)
122+
local hl = highlights.hl(hl_name)
123+
local component = get_section_text(width, { text = hl, sep = sep_hl }, offset, is_left)
168124

169-
total_size = total_size + width
125+
total_size = total_size + width
170126

171-
if is_left then
172-
left, left_size = component, left_size + width
173-
else
174-
right, right_size = component, right_size + width
175-
end
127+
if is_left then
128+
left, left_size = component, left_size + width
129+
else
130+
right, right_size = component, right_size + width
176131
end
177132
end
178133
end

0 commit comments

Comments
 (0)