Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/bufferline/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ end

---@param position number
local function handle_group_click(position)
groups.toggle_hidden(position)
groups.toggle_hidden({ priority = position })
ui.refresh()
end

Expand Down
65 changes: 43 additions & 22 deletions lua/bufferline/groups.lua
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,10 @@ end
---Execute a command on each buffer of a group
---@param group_name string
---@param callback fun(b: bufferline.Buffer)
local function command(group_name, callback)
local function buf_exec(group_name, callback)
local group = utils.find(function(list) return list.name == group_name end, group_state.components_by_group)

if not group then return end

utils.for_each(callback, group)
utils.for_each(callback, group, function(item) return type(item) == "table" end)
end

---@generic T
Expand Down Expand Up @@ -344,10 +342,9 @@ function M.set_hidden(id, value)
if group then group.hidden = value end
end

---@param priority number?
---@param name string?
function M.toggle_hidden(priority, name)
local group = priority and group_by_priority(priority) or group_by_name(name)
---@param opts {priority: number?, name: string?}
function M.toggle_hidden(opts)
local group = opts.priority and group_by_priority(opts.priority) or group_by_name(opts.name)
if group then group.hidden = not group.hidden end
end

Expand Down Expand Up @@ -453,26 +450,50 @@ end

function M.get_all() return group_state.user_groups end

---@alias group_actions "close" | "toggle"
---@param group_name string
local function close_group(group_name)
buf_exec(group_name, function(b) api.nvim_buf_delete(b.id, { force = true }) end)
if group_name == PINNED_NAME then vim.g[PINNED_KEY] = "" end
for buf, group_id in pairs(group_state.manual_groupings) do
if group_id == group_name then group_state.manual_groupings[buf] = nil end
end
end

---@param args string?
---@param except string[]?
---@return nil
local function handle_close(args, except)
if except then
return utils.for_each(function(group)
if not vim.tbl_contains(except, group.id) then close_group(group.id) end
end, group_state.user_groups)
end

if args then close_group(args) end
end

---@alias bufferline.GroupCLIArgs {except: string[]?}

local arguments = {
except = function(value) return vim.split(value, ",") end,
}

---Execute an action on a group of buffers
---@param name string
---@alias group_actions "close" | "toggle"
---@param args string
---@param action group_actions | fun(b: bufferline.Buffer)
function M.action(name, action)
assert(name, "A name must be passed to execute a group action")
if action == "close" then
command(name, function(b) api.nvim_buf_delete(b.id, { force = true }) end)
ui.refresh()
function M.action(args, action)
assert(args, "arguments must be passed to execute a group action")
local opts = utils.parse_args(args, arguments) ---@type bufferline.GroupCLIArgs

if name == PINNED_NAME then vim.g[PINNED_KEY] = {} end
for buf, group_id in pairs(group_state.manual_groupings) do
if group_id == name then group_state.manual_groupings[buf] = nil end
end
if action == "close" then
handle_close(args, opts.except)
elseif action == "toggle" then
M.toggle_hidden(nil, name)
ui.refresh()
M.toggle_hidden({ name = args })
elseif type(action) == "function" then
command(name, action)
buf_exec(args, action)
end
ui.refresh()
end

function M.toggle_pin()
Expand Down
15 changes: 14 additions & 1 deletion lua/bufferline/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ end
---@param callback fun(item: T)
---@param matcher (fun(item: T):boolean)?
function M.for_each(callback, list, matcher)
for _, item in ipairs(list) do
for _, item in pairs(list) do
if not matcher or matcher(item) then callback(item) end
end
end
Expand Down Expand Up @@ -230,4 +230,17 @@ end
--- Determine which list-check function to use
M.is_list = vim.tbl_isarray or vim.tbl_islist

---parse command line arguments into a table
---@generic T
---@param args string
---@param expected {[string]: fun(arg: string): any}
---@return T:table<string, any>
function M.parse_args(args, expected)
local opts = {}
for arg_name, arg_value in args:gmatch("(%S+)=(%S+)") do
if expected[arg_name] then opts[arg_name] = expected[arg_name](arg_value) end
end
return opts
end

return M