Skip to content

Commit

Permalink
refactor(offsets): use wininfo to calculate offset
Browse files Browse the repository at this point in the history
fixes #789
  • Loading branch information
akinsho committed Aug 2, 2023
1 parent 99f0932 commit aa0b1d7
Showing 1 changed file with 22 additions and 70 deletions.
92 changes: 22 additions & 70 deletions lua/bufferline/offset.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ local api = vim.api
local fn = vim.fn
local padding = constants.padding

local t = {
LEAF = "leaf",
ROW = "row",
COLUMN = "col",
}

local supported_win_types = {
[t.LEAF] = true,
[t.COLUMN] = true,
}

---Format the content of a neighbouring offset's text
---@param size integer
---@param highlight table<string, string>
Expand Down Expand Up @@ -80,57 +69,20 @@ local function guess_window_highlight(win_id, attribute, match)
return match
end

--- This helper checks to see if bufferline supports creating an offset for the given layout
--- Valid window layouts can be
--- * A list of full height splits in a row:
--- `{'row', ['leaf', id], ['leaf', id]}`
--- * A row of splits where one on either edge is not full height but the matching
--- split is on the top:
--- e.g. the vertical tool bar is split in two such as for undo tree
--- `{'row', ['col', ['leaf', id], ['leaf', id]], ['leaf', id]}`
---
---@param windows any[]
---@return boolean, number
local function is_valid_layout(windows)
local win_type, win_id = windows[1], windows[2]
if utils.is_list(win_id) and win_type == t.COLUMN then win_id = win_id[1][2] end
return supported_win_types[win_type] and type(win_id) == "number", win_id
end

--- Test if the windows within a layout row contain the correct panel buffer
--- NOTE: this only tests the first and last windows as those are the only
--- ones that it makes sense to add a panel for
---@param windows any[]
---@param windows {wincol: number, winrow: number, bufnr: number, winid: number}[]
---@param offset table
---@return boolean
---@return number?
---@return boolean?
local function is_offset_section(windows, offset)
local wins = { windows[1] }
if #windows > 1 then wins[#wins + 1] = windows[#windows] end
for idx, win in ipairs(wins) do
local valid_layout, win_id = is_valid_layout(win)
if valid_layout then
local buf = api.nvim_win_get_buf(win_id)
local valid = buf and vim.bo[buf].filetype == offset.filetype
local is_left = idx == 1
if valid then return valid, win_id, is_left end
for _, win in ipairs(windows) do
if win.winrow == 2 and (win.wincol == 1 or win.wincol == #windows) then
local valid = vim.bo[win.bufnr].filetype == offset.filetype
local is_left = win.wincol == 1
if valid then return valid, win.winid, is_left end
end
end
return false, nil, nil
end

--- Iterate over COLUMN layout by always picking the first element.
--- Assuming this is the topmost window, it's the one that should
--- dictate the tabline offset.
---@param layout any[]
---@return any[]
local function iterate_col_layout(layout)
if layout[1] == t.COLUMN then
return iterate_col_layout(layout[2][1])
else
return layout
end
return false
end

---@class OffsetData
Expand All @@ -151,28 +103,28 @@ function M.get()
local total_size = 0
local sep_hl = highlights.hl(hls.offset_separator.hl_group)

if offsets and #offsets > 0 then
local layout = iterate_col_layout(fn.winlayout())
-- wininfo tells us whether or not a window is on the top level or not of the layout
-- if it is on the top level and it is at the end or beginning it is an offset
local wininfo = fn.getwininfo()

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

local hl_name = offset.highlight or guess_window_highlight(win_id) or config.highlights.fill.hl_group
local hl_name = offset.highlight or guess_window_highlight(win_id) or config.highlights.fill.hl_group

local hl = highlights.hl(hl_name)
local component = get_section_text(width, { text = hl, sep = sep_hl }, offset, is_left)
local hl = highlights.hl(hl_name)
local component = get_section_text(width, { text = hl, sep = sep_hl }, offset, is_left)

total_size = total_size + width
total_size = total_size + width

if is_left then
left, left_size = component, left_size + width
else
right, right_size = component, right_size + width
end
if is_left then
left, left_size = component, left_size + width
else
right, right_size = component, right_size + width
end
end
end
Expand Down

0 comments on commit aa0b1d7

Please sign in to comment.