Skip to content
Merged
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.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ local function setup_autocommands(conf)
api.nvim_create_autocmd("SessionLoadPost", {
pattern = "*",
group = BUFFERLINE_GROUP,
callback = function() state.restore_positions() end,
callback = function() state.custom_sort = utils.restore_positions() end,
})
end
if not options.always_show_bufferline then
Expand Down
20 changes: 4 additions & 16 deletions lua/bufferline/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,13 @@ local utils = lazy.require("bufferline.utils") ---@module "bufferline.utils"
local config = lazy.require("bufferline.config") ---@module "bufferline.config"
local groups = lazy.require("bufferline.groups") ---@module "bufferline.groups"
local sorters = lazy.require("bufferline.sorters") ---@module "bufferline.sorters"
local constants = lazy.require("bufferline.constants") ---@module "bufferline.constants"
local pick = lazy.require("bufferline.pick") ---@module "bufferline.pick"

local M = {}

local positions_key = constants.positions_key

local fmt = string.format
local api = vim.api

---@param ids number[]
local function save_positions(ids) vim.g[positions_key] = table.concat(ids, ",") end

--- @param elements bufferline.TabElement[]
--- @return number[]
local function get_ids(elements)
return vim.tbl_map(function(item) return item.id end, elements)
end

--- open the current element
---@param id number
local function open_element(id)
Expand Down Expand Up @@ -170,9 +158,9 @@ function M.move_to(to_index, from_index)
local destination_buf = state.components[next_index]
state.components[next_index] = item
state.components[index] = destination_buf
state.custom_sort = get_ids(state.components)
state.custom_sort = utils.get_ids(state.components)
local opts = config.options
if opts.persist_buffer_sort then save_positions(state.custom_sort) end
if opts.persist_buffer_sort then utils.save_positions(state.custom_sort) end
ui.refresh()
end
end
Expand Down Expand Up @@ -269,9 +257,9 @@ end
function M.sort_by(sort_by)
if next(state.components) == nil then return utils.notify("Unable to find elements to sort, sorry", "warn") end
sorters.sort(state.components, { sort_by = sort_by })
state.custom_sort = get_ids(state.components)
state.custom_sort = utils.get_ids(state.components)
local opts = config.options
if opts.persist_buffer_sort then save_positions(state.custom_sort) end
if opts.persist_buffer_sort then utils.save_positions(state.custom_sort) end
ui.refresh()
end

Expand Down
10 changes: 0 additions & 10 deletions lua/bufferline/state.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
local M = {}

local lazy = require("bufferline.lazy")
local constants = lazy.require("bufferline.constants") ---@module "bufferline.constants"
local utils = lazy.require("bufferline.utils") ---@module "bufferline.utils"

-----------------------------------------------------------------------------//
Expand All @@ -21,15 +20,6 @@ local state = {
right_offset_size = 0,
}

function M.restore_positions()
local str = vim.g[constants.positions_key]
if not str then return str end
-- these are converted to strings when stored
-- so have to be converted back before usage
local ids = vim.split(str, ",")
if ids and #ids > 0 then state.custom_sort = vim.tbl_map(tonumber, ids) end
end

---@param list bufferline.Component[]
---@return bufferline.Component[]
local function filter_invisible(list)
Expand Down
2 changes: 1 addition & 1 deletion lua/bufferline/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@
---@field is_picking boolean
---@field visible_components bufferline.Component[]
---@field __components bufferline.Component[]
---@field custom_sort number[]
---@field custom_sort number[]?
---@field left_offset_size number
---@field right_offset_size number

Expand Down
24 changes: 24 additions & 0 deletions lua/bufferline/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ function M.notify(msg, level, opts)
vim.schedule(function() vim.notify(msg, level, nopts) end)
end

---@return number[]?
function M.restore_positions()
local str = vim.g[constants.positions_key]
local ok, paths = pcall(vim.json.decode, str)
if not ok or type(paths) ~= "table" or #paths == 0 then return nil end
local ids = vim.tbl_map(function(path)
local escaped = vim.fn.fnameescape(path)
return vim.fn.bufnr("^" .. escaped .. "$" --[[@as integer]])
end, paths)
return vim.tbl_filter(function(id) return id ~= -1 end, ids)
end

---@param ids number[]
function M.save_positions(ids)
local paths = vim.tbl_map(function(id) return vim.api.nvim_buf_get_name(id) end, ids)
vim.g[constants.positions_key] = vim.json.encode(paths)
end

--- @param elements bufferline.TabElement[]
--- @return number[]
function M.get_ids(elements)
return vim.tbl_map(function(item) return item.id end, elements)
end

---Get an icon for a filetype using either nvim-web-devicons or vim-devicons
---if using the lua plugin this also returns the icon's highlights
---@param opts bufferline.IconFetcherOpts
Expand Down
47 changes: 47 additions & 0 deletions tests/utils_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,51 @@ describe("Utils tests", function()
local truncated = utils.truncate_name("filename.md.md", 13)
assert.is_equal(truncated, "filename.md" .. constants.ELLIPSIS)
end)

it("should save/restore positions correctly", function()
-- remove existing buffers
vim.cmd("silent %bwipeout!")

local names = { "c.txt", "a.txt", "d.txt", "e.txt", "b.txt" }
local bufs = {}
for _, name in ipairs(names) do
vim.cmd.edit(name)
bufs[name] = api.nvim_get_current_buf()
end

local ids = {
bufs["a.txt"],
bufs["b.txt"],
bufs["c.txt"],
bufs["d.txt"],
bufs["e.txt"],
}

utils.save_positions(ids)

assert.same(utils.restore_positions(), ids)

-- restore_positions should not return invalid bufids

vim.cmd("bwipeout! " .. bufs["c.txt"])

ids = {
bufs["a.txt"],
bufs["b.txt"],
bufs["d.txt"],
bufs["e.txt"],
}
assert.same(utils.restore_positions(), ids)

vim.g[constants.positions_key] = '["INVALID_PATH"]'
assert.same(utils.restore_positions(), {})

-- empty or invalid JSON should return nil

vim.g[constants.positions_key] = "[]"
assert.is_equal(utils.restore_positions(), nil)

vim.g[constants.positions_key] = ""
assert.is_equal(utils.restore_positions(), nil)
end)
end)