From 012c5fe97eccf5e00feedb6b3e228a819fde7edb Mon Sep 17 00:00:00 2001 From: AThePeanut4 <49614525+AThePeanut4@users.noreply.github.com> Date: Fri, 23 Jun 2023 02:32:21 +0200 Subject: [PATCH 1/3] fix: store paths in g:BufferlinePositions --- lua/bufferline/commands.lua | 7 ++++--- lua/bufferline/state.lua | 13 ++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lua/bufferline/commands.lua b/lua/bufferline/commands.lua index 7bea9f95..e105307a 100644 --- a/lua/bufferline/commands.lua +++ b/lua/bufferline/commands.lua @@ -13,13 +13,14 @@ 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 +local function 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[] diff --git a/lua/bufferline/state.lua b/lua/bufferline/state.lua index 90f23dbf..0ee284ca 100644 --- a/lua/bufferline/state.lua +++ b/lua/bufferline/state.lua @@ -23,11 +23,14 @@ local state = { 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 + local ok, paths = pcall(vim.json.decode, str) + if not ok or type(paths) ~= "table" or #paths == 0 then return end + local ids = vim.tbl_map(function(path) + local escaped = vim.fn.fnameescape(path) + return vim.fn.bufnr("^" .. escaped .. "$" --[[@as integer]]) + end, paths) + ids = vim.tbl_filter(function(id) return id ~= -1 end, ids) + state.custom_sort = ids end ---@param list bufferline.Component[] From 84ad560697b6435e334711d805616c2fc804f736 Mon Sep 17 00:00:00 2001 From: AThePeanut4 <49614525+AThePeanut4@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:46:21 +0200 Subject: [PATCH 2/3] refactor: move restore_positions, save_positions and get_ids into utils --- lua/bufferline.lua | 2 +- lua/bufferline/commands.lua | 21 ++++----------------- lua/bufferline/state.lua | 13 ------------- lua/bufferline/types.lua | 2 +- lua/bufferline/utils/init.lua | 24 ++++++++++++++++++++++++ 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lua/bufferline.lua b/lua/bufferline.lua index 7bc28950..6e68aa9b 100644 --- a/lua/bufferline.lua +++ b/lua/bufferline.lua @@ -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 diff --git a/lua/bufferline/commands.lua b/lua/bufferline/commands.lua index e105307a..8b8c1283 100644 --- a/lua/bufferline/commands.lua +++ b/lua/bufferline/commands.lua @@ -8,7 +8,6 @@ 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 = {} @@ -16,18 +15,6 @@ local M = {} local fmt = string.format local api = vim.api ----@param ids number[] -local function 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[] -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) @@ -171,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 @@ -270,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 diff --git a/lua/bufferline/state.lua b/lua/bufferline/state.lua index 0ee284ca..c45f91a2 100644 --- a/lua/bufferline/state.lua +++ b/lua/bufferline/state.lua @@ -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" -----------------------------------------------------------------------------// @@ -21,18 +20,6 @@ local state = { right_offset_size = 0, } -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 end - local ids = vim.tbl_map(function(path) - local escaped = vim.fn.fnameescape(path) - return vim.fn.bufnr("^" .. escaped .. "$" --[[@as integer]]) - end, paths) - ids = vim.tbl_filter(function(id) return id ~= -1 end, ids) - state.custom_sort = ids -end - ---@param list bufferline.Component[] ---@return bufferline.Component[] local function filter_invisible(list) diff --git a/lua/bufferline/types.lua b/lua/bufferline/types.lua index f7aeb4eb..0dba6e76 100644 --- a/lua/bufferline/types.lua +++ b/lua/bufferline/types.lua @@ -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 diff --git a/lua/bufferline/utils/init.lua b/lua/bufferline/utils/init.lua index 4c06c08c..726ba7f2 100644 --- a/lua/bufferline/utils/init.lua +++ b/lua/bufferline/utils/init.lua @@ -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 From 7cde1a16f94e67efd2a262ce04f13a363fa24eb3 Mon Sep 17 00:00:00 2001 From: AThePeanut4 <49614525+AThePeanut4@users.noreply.github.com> Date: Tue, 27 Jun 2023 18:44:18 +0200 Subject: [PATCH 3/3] test: add save/restore tests --- tests/utils_spec.lua | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/utils_spec.lua b/tests/utils_spec.lua index ccdf8a48..39923825 100644 --- a/tests/utils_spec.lua +++ b/tests/utils_spec.lua @@ -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)