···11local M = {}
2233+local state = require("yankbank.state")
44+35--- get a table containg a single yankbank entry by index
46---@param i integer
57---@return table
68function M.get_entry(i)
79 return {
88- yank_text = YB_YANKS[i],
99- reg_type = YB_REG_TYPES[i],
1010+ yank_text = state.get_yanks()[i],
1111+ reg_type = state.get_reg_types()[i],
1012 }
1113end
1214···1416---@return table
1517function M.get_all()
1618 local out = {}
1717- for i, v in ipairs(YB_YANKS) do
1919+ local yanks = state.get_yanks()
2020+ local reg_types = state.get_reg_types()
2121+ for i, v in ipairs(yanks) do
1822 table.insert(out, {
1923 yank_text = v,
2020- reg_type = YB_REG_TYPES[i],
2424+ reg_type = reg_types[i],
2125 })
2226 end
2327 return out
···3438--- remove entry from yankbank by index
3539---@param i integer index to remove
3640function M.remove_entry(i)
3737- local yank_text = table.remove(YB_YANKS, i)
3838- local reg_type = table.remove(YB_REG_TYPES, i)
3939- if YB_OPTS.persist_type == "sqlite" then
4141+ local yanks = state.get_yanks()
4242+ local reg_types = state.get_reg_types()
4343+ local yank_text = table.remove(yanks, i)
4444+ local reg_type = table.remove(reg_types, i)
4545+ state.set_yanks(yanks)
4646+ state.set_reg_types(reg_types)
4747+4848+ local opts = state.get_opts()
4949+ if opts.persist_type == "sqlite" then
4050 require("yankbank.persistence.sql")
4151 .data()
4252 .remove_match(yank_text, reg_type)
···4757---
4858---@param i integer index to pin
4959function M.pin_entry(i)
5050- if i > #YB_PINS then
6060+ local pins = state.get_pins()
6161+ if i > #pins then
5162 return
5263 end
53645465 -- TODO: show pins differently in popup (could use different hl_groups for pinned entries?)
5555- YB_PINS[i] = 1
6666+ pins[i] = 1
6767+ state.set_pins(pins)
56685757- if YB_OPTS.persist_type == "sqlite" then
6969+ local opts = state.get_opts()
7070+ if opts.persist_type == "sqlite" then
5871 return require("yankbank.persistence.sql")
5972 .data()
6060- .pin(YB_YANKS[i], YB_REG_TYPES[i])
7373+ .pin(state.get_yanks()[i], state.get_reg_types()[i])
6174 end
6275end
6376···6578---
6679---@param i integer index to unpin
6780function M.unpin_entry(i)
6868- if i > #YB_PINS then
8181+ local pins = state.get_pins()
8282+ if i > #pins then
6983 return
7084 end
71857286 -- TODO: update popup pin highlight
7373- YB_PINS[i] = 0
8787+ pins[i] = 0
8888+ state.set_pins(pins)
74897575- if YB_OPTS.persist_type == "sqlite" then
9090+ local opts = state.get_opts()
9191+ if opts.persist_type == "sqlite" then
7692 return require("yankbank.persistence.sql")
7793 .data()
7878- .unpin(YB_YANKS[i], YB_REG_TYPES[i])
9494+ .unpin(state.get_yanks()[i], state.get_reg_types()[i])
7995 end
8096end
8197
+42-13
lua/yankbank/clipboard.lua
···11local M = {}
2233+local state = require("yankbank.state")
44+55+--- get the last zero entry in a table
66+---
77+---@param t table
88+---@return integer?
99+local function last_zero_entry(t)
1010+ for i = #t, 1, -1 do
1111+ if t[i] == 0 then
1212+ return i
1313+ end
1414+ end
1515+ return nil
1616+end
1717+318--- Function to add yanked text to table
419---@param text string
520---@param reg_type string
···1126 end
12271328 local is_pinned = 0
2929+ local yanks = state.get_yanks()
3030+ local reg_types = state.get_reg_types()
3131+ local pins = state.get_pins()
14321533 -- check for duplicate values already inserted
1616- for i, entry in ipairs(YB_YANKS) do
3434+ for i, entry in ipairs(yanks) do
1735 if entry == text then
1836 -- remove matched entry so it can be inserted at 1st position
1919- table.remove(YB_YANKS, i)
2020- table.remove(YB_REG_TYPES, i)
2121- is_pinned = table.remove(YB_PINS, i)
3737+ table.remove(yanks, i)
3838+ table.remove(reg_types, i)
3939+ is_pinned = table.remove(pins, i)
2240 break
2341 end
2442 end
···2947 or is_pinned
30483149 -- add entry to bank
3232- table.insert(YB_YANKS, 1, text)
3333- table.insert(YB_REG_TYPES, 1, reg_type)
3434- table.insert(YB_PINS, 1, is_pinned)
5050+ table.insert(yanks, 1, text)
5151+ table.insert(reg_types, 1, reg_type)
5252+ table.insert(pins, 1, is_pinned)
35533654 -- trim table size if necessary
3737- if #YB_YANKS > YB_OPTS.max_entries then
3838- local i = require("yankbank.utils").last_zero_entry(YB_PINS)
5555+ local opts = state.get_opts()
5656+ if #yanks > opts.max_entries then
5757+ local i = last_zero_entry(pins)
39584059 if not i or i == 1 then
4160 -- WARN: undefined behavior
···4463 )
4564 else
4665 -- remove last non-pinned entry
4747- table.remove(YB_YANKS, i)
4848- table.remove(YB_REG_TYPES, i)
4949- table.remove(YB_PINS, i)
6666+ table.remove(yanks, i)
6767+ table.remove(reg_types, i)
6868+ table.remove(pins, i)
5069 end
5170 end
7171+7272+ -- update state
7373+ state.set_yanks(yanks)
7474+ state.set_reg_types(reg_types)
7575+ state.set_pins(pins)
52765377 -- add entry to persistent store
5478 require("yankbank.persistence").add_entry(text, reg_type, pin)
···7498 return
7599 end
76100101101+ -- lazy load initialization when first yank happens
102102+ require("yankbank").ensure_initialized()
77103 M.add_yank(yank_text, reg_type)
78104 end
79105 end,
80106 })
8110782108 -- poll registers when vim is focused (check for new clipboard activity)
8383- if YB_OPTS.focus_gain_poll == true then
109109+ local opts = state.get_opts()
110110+ if opts.focus_gain_poll == true then
84111 vim.api.nvim_create_autocmd("FocusGained", {
85112 callback = function()
86113 -- get register information
···95122 return
96123 end
97124125125+ -- lazy load initialization when first focus gain happens
126126+ require("yankbank").ensure_initialized()
98127 M.add_yank(yank_text, reg_type)
99128 end,
100129 })
-66
lua/yankbank/data.lua
···11-local M = {}
22-33---- reformat yanks table for popup
44----@return table, table
55-function M.get_display_lines()
66- local display_lines = {}
77- local line_yank_map = {}
88- local yank_num = 0
99-1010- -- calculate the maximum width needed for the yank numbers
1111- local max_digits = #tostring(#YB_YANKS)
1212-1313- -- assumes yanks is table of strings
1414- for i, yank in ipairs(YB_YANKS) do
1515- yank_num = yank_num + 1
1616-1717- local yank_lines = yank
1818- if type(yank) == "string" then
1919- -- remove trailing newlines
2020- yank = yank:gsub("\n$", "")
2121- yank_lines = vim.split(yank, "\n", { plain = true })
2222- end
2323-2424- local leading_space, leading_space_length
2525-2626- -- determine the number of leading whitespaces on the first line
2727- if #yank_lines > 0 then
2828- leading_space = yank_lines[1]:match("^(%s*)")
2929- leading_space_length = #leading_space
3030- end
3131-3232- for j, line in ipairs(yank_lines) do
3333- if j == 1 then
3434- -- Format the line number with uniform spacing
3535- local lineNumber =
3636- string.format("%" .. max_digits .. "d: ", yank_num)
3737- line = line:sub(leading_space_length + 1)
3838- table.insert(display_lines, lineNumber .. line)
3939- else
4040- -- Remove the same amount of leading whitespace as on the first line
4141- line = line:sub(leading_space_length + 1)
4242- -- Use spaces equal to the line number's reserved space to align subsequent lines
4343- table.insert(
4444- display_lines,
4545- string.rep(" ", max_digits + 2) .. line
4646- )
4747- end
4848- table.insert(line_yank_map, i)
4949- end
5050-5151- if i < #YB_YANKS then
5252- -- Add a visual separator between yanks, aligned with the yank content
5353- if YB_OPTS.sep ~= "" then
5454- table.insert(
5555- display_lines,
5656- string.rep(" ", max_digits + 2) .. YB_OPTS.sep
5757- )
5858- end
5959- table.insert(line_yank_map, false)
6060- end
6161- end
6262-6363- return display_lines, line_yank_map
6464-end
6565-6666-return M
+58-43
lua/yankbank/init.lua
···11local M = {}
2233+local initialized = false
44+55+function M.ensure_initialized()
66+ if initialized then
77+ return
88+ end
99+1010+ local state = require("yankbank.state")
1111+ local persistence = require("yankbank.persistence")
1212+1313+ -- enable persistence based on opts (needs to be called before autocmd setup)
1414+ local yanks, reg_types, pins = persistence.setup()
1515+ state.init(yanks, reg_types, pins, state.get_opts())
1616+1717+ initialized = true
1818+end
1919+2020+--- wrapper function for main plugin functionality
2121+local function show_yank_bank()
2222+ M.ensure_initialized()
2323+2424+ local state = require("yankbank.state")
2525+ local menu = require("yankbank.menu")
2626+2727+ -- set up menu keybinds from defaults and state.get_opts().keymaps
2828+ menu.setup()
2929+3030+ local persistence = require("yankbank.persistence")
3131+ local yanks = persistence.get_yanks() or state.get_yanks()
3232+ state.set_yanks(yanks)
3333+3434+ -- initialize buffer and populate bank
3535+ local buf_data = menu.create_and_fill_buffer()
3636+ if not buf_data then
3737+ return
3838+ end
3939+4040+ -- open popup window
4141+ buf_data.win_id = menu.open_window(buf_data)
4242+4343+ -- set popup keybinds
4444+ menu.set_keymaps(buf_data)
4545+end
4646+347-- plugin setup
448---@param opts? table
549function M.setup(opts)
66- -- define global variables
77- YB_YANKS = {}
88- YB_REG_TYPES = {}
99- YB_PINS = {}
1010- YB_OPTS = {}
1111-1212- -- local imports
1313- local clipboard = require("yankbank.clipboard")
1414- local persistence = require("yankbank.persistence")
1515-1650 -- default plugin options
1751 local default_opts = {
1852 max_entries = 10,
···2761 db_path = nil,
2862 bind_indices = nil,
2963 }
3030-3131- --- wrapper function for main plugin functionality
3232- local function show_yank_bank()
3333- local menu = require("yankbank.menu")
3434-3535- -- set up menu keybinds from defaults and YB_OPTS.keymaps
3636- menu.setup()
3737-3838- YB_YANKS = persistence.get_yanks() or YB_YANKS
3939-4040- -- initialize buffer and populate bank
4141- local buf_data = menu.create_and_fill_buffer()
4242- if not buf_data then
4343- return
4444- end
4545-4646- -- open popup window
4747- buf_data.win_id = menu.open_window(buf_data)
4848-4949- -- set popup keybinds
5050- menu.set_keymaps(buf_data)
5151- end
52645365 -- merge opts with default options table
5454- YB_OPTS = vim.tbl_deep_extend("keep", opts or {}, default_opts)
6666+ local merged_opts = vim.tbl_deep_extend("keep", opts or {}, default_opts)
55675656- -- enable persistence based on opts (needs to be called before autocmd setup)
5757- YB_YANKS, YB_REG_TYPES, YB_PINS = persistence.setup()
5858-5959- -- create clipboard autocmds
6060- clipboard.setup_yank_autocmd()
6868+ -- store config in state module (lazy loaded when needed)
6969+ local state = require("yankbank.state")
7070+ state.set_opts(merged_opts)
61716272 -- create user command
6373 vim.api.nvim_create_user_command("YankBank", function()
6474 show_yank_bank()
6575 end, { desc = "Show Recent Yanks" })
7676+7777+ -- create clipboard autocmds
7878+ require("yankbank.clipboard").setup_yank_autocmd()
66796780 -- Bind 1-n if `bind_indices` is set to a string
6868- if YB_OPTS.bind_indices then
6969- for i = 1, YB_OPTS.max_entries do
7070- vim.keymap.set("n", YB_OPTS.bind_indices .. i, function()
8181+ if merged_opts.bind_indices then
8282+ for i = 1, merged_opts.max_entries do
8383+ vim.keymap.set("n", merged_opts.bind_indices .. i, function()
8484+ M.ensure_initialized()
8585+ local state = require("yankbank.state")
7186 require("yankbank.helpers").smart_paste(
7272- YB_YANKS[i],
7373- YB_REG_TYPES[i],
8787+ state.get_yanks()[i],
8888+ state.get_reg_types()[i],
7489 true
7590 )
7691 end, {
+101-27
lua/yankbank/menu.lua
···11local M = {}
2233-local data = require("yankbank.data")
44-local helpers = require("yankbank.helpers")
33+local state = require("yankbank.state")
5465-- default plugin keymaps
76local default_keymaps = {
···1817 yank_register = "+",
1918}
20192121--- local YB_OPTS.keymaps = {}
2222-2320function M.setup()
2121+ local opts = state.get_opts()
2422 -- merge default and options keymap tables
2525- YB_OPTS.keymaps =
2626- vim.tbl_deep_extend("force", default_keymaps, YB_OPTS.keymaps or {})
2323+ opts.keymaps =
2424+ vim.tbl_deep_extend("force", default_keymaps, opts.keymaps or {})
2725 -- merge default and options register tables
2828- YB_OPTS.registers =
2929- vim.tbl_deep_extend("force", default_registers, YB_OPTS.registers or {})
2626+ opts.registers =
2727+ vim.tbl_deep_extend("force", default_registers, opts.registers or {})
30283129 -- check table for number behavior option (prefix or jump, default to prefix)
3232- YB_OPTS.num_behavior = YB_OPTS.num_behavior or "prefix"
3030+ opts.num_behavior = opts.num_behavior or "prefix"
3131+3232+ state.set_opts(opts)
3333+end
3434+3535+--- reformat yanks table for popup
3636+---@return table, table
3737+local function get_display_lines()
3838+ local display_lines = {}
3939+ local line_yank_map = {}
4040+ local yank_num = 0
4141+4242+ local yanks = state.get_yanks()
4343+ local opts = state.get_opts()
4444+4545+ -- calculate the maximum width needed for the yank numbers
4646+ local max_digits = #tostring(#yanks)
4747+4848+ -- assumes yanks is table of strings
4949+ for i, yank in ipairs(yanks) do
5050+ yank_num = yank_num + 1
5151+5252+ local yank_lines = yank
5353+ if type(yank) == "string" then
5454+ -- remove trailing newlines
5555+ yank = yank:gsub("\n$", "")
5656+ yank_lines = vim.split(yank, "\n", { plain = true })
5757+ end
5858+5959+ local leading_space, leading_space_length
6060+6161+ -- determine the number of leading whitespaces on the first line
6262+ if #yank_lines > 0 then
6363+ leading_space = yank_lines[1]:match("^(%s*)")
6464+ leading_space_length = #leading_space
6565+ end
6666+6767+ for j, line in ipairs(yank_lines) do
6868+ if j == 1 then
6969+ -- Format the line number with uniform spacing
7070+ local lineNumber =
7171+ string.format("%" .. max_digits .. "d: ", yank_num)
7272+ line = line:sub(leading_space_length + 1)
7373+ table.insert(display_lines, lineNumber .. line)
7474+ else
7575+ -- Remove the same amount of leading whitespace as on the first line
7676+ line = line:sub(leading_space_length + 1)
7777+ -- Use spaces equal to the line number's reserved space to align subsequent lines
7878+ table.insert(
7979+ display_lines,
8080+ string.rep(" ", max_digits + 2) .. line
8181+ )
8282+ end
8383+ table.insert(line_yank_map, i)
8484+ end
8585+8686+ if i < #yanks then
8787+ -- Add a visual separator between yanks, aligned with the yank content
8888+ if opts.sep ~= "" then
8989+ table.insert(
9090+ display_lines,
9191+ string.rep(" ", max_digits + 2) .. opts.sep
9292+ )
9393+ end
9494+ table.insert(line_yank_map, false)
9595+ end
9696+ end
9797+9898+ return display_lines, line_yank_map
3399end
3410035101--- Container class for YankBank buffer related variables
···43109---@return YankBankBufData?
44110function M.create_and_fill_buffer()
45111 -- stop if yanks or register types table is empty
4646- if #YB_YANKS == 0 or #YB_REG_TYPES == 0 then
112112+ local yanks = state.get_yanks()
113113+ local reg_types = state.get_reg_types()
114114+ if #yanks == 0 or #reg_types == 0 then
47115 print("No yanks to show.")
48116 return nil
49117 end
···55123 local current_filetype = vim.bo.filetype
56124 vim.api.nvim_set_option_value("filetype", current_filetype, { buf = bufnr })
571255858- local display_lines, line_yank_map = data.get_display_lines()
126126+ local display_lines, line_yank_map = get_display_lines()
5912760128 -- replace current buffer contents with updated table
61129 vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, display_lines)
···119187function M.set_keymaps(b)
120188 -- key mappings for selection and closing the popup
121189 local map_opts = { noremap = true, silent = true, buffer = b.bufnr }
190190+ local opts = state.get_opts()
191191+192192+ local helpers = require("yankbank.helpers")
122193123194 -- popup buffer navigation binds
124124- if YB_OPTS.num_behavior == "prefix" then
125125- vim.keymap.set("n", YB_OPTS.keymaps.navigation_next, function()
195195+ if opts.num_behavior == "prefix" then
196196+ vim.keymap.set("n", opts.keymaps.navigation_next, function()
126197 local count = vim.v.count1 > 0 and vim.v.count1 or 1
127198 helpers.next_numbered_item(count)
128199 return ""
129200 end, { noremap = true, silent = true, buffer = b.bufnr })
130130- vim.keymap.set("n", YB_OPTS.keymaps.navigation_prev, function()
201201+ vim.keymap.set("n", opts.keymaps.navigation_prev, function()
131202 local count = vim.v.count1 > 0 and vim.v.count1 or 1
132203 helpers.prev_numbered_item(count)
133204 return ""
···135206 else
136207 vim.keymap.set(
137208 "n",
138138- YB_OPTS.keymaps.navigation_next,
209209+ opts.keymaps.navigation_next,
139210 helpers.next_numbered_item,
140211 map_opts
141212 )
142213 vim.keymap.set(
143214 "n",
144144- YB_OPTS.keymaps.navigation_prev,
215215+ opts.keymaps.navigation_prev,
145216 helpers.prev_numbered_item,
146217 map_opts
147218 )
148219 end
149220150221 -- map number keys to jump to entry if num_behavior is 'jump'
151151- if YB_OPTS.num_behavior == "jump" then
152152- for i = 1, YB_OPTS.max_entries do
222222+ if opts.num_behavior == "jump" then
223223+ for i = 1, opts.max_entries do
153224 vim.keymap.set("n", tostring(i), function()
154225 local target_line = nil
155226 for line_num, yank_num in pairs(b.line_yank_map) do
···166237 end
167238168239 -- bind paste behavior
169169- vim.keymap.set("n", YB_OPTS.keymaps.paste, function()
240240+ vim.keymap.set("n", opts.keymaps.paste, function()
170241 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
171242 -- use the mapping to find the original yank
172243 local yankIndex = b.line_yank_map[cursor]
···174245 -- close window upon selection
175246 vim.api.nvim_win_close(b.win_id, true)
176247 helpers.smart_paste(
177177- YB_YANKS[yankIndex],
178178- YB_REG_TYPES[yankIndex],
248248+ state.get_yanks()[yankIndex],
249249+ state.get_reg_types()[yankIndex],
179250 true
180251 )
181252 else
···183254 end
184255 end, map_opts)
185256 -- paste backwards
186186- vim.keymap.set("n", YB_OPTS.keymaps.paste_back, function()
257257+ vim.keymap.set("n", opts.keymaps.paste_back, function()
187258 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
188259 -- use the mapping to find the original yank
189260 local yankIndex = b.line_yank_map[cursor]
···191262 -- close window upon selection
192263 vim.api.nvim_win_close(b.win_id, true)
193264 helpers.smart_paste(
194194- YB_YANKS[yankIndex],
195195- YB_REG_TYPES[yankIndex],
265265+ state.get_yanks()[yankIndex],
266266+ state.get_reg_types()[yankIndex],
196267 false
197268 )
198269 else
···201272 end, map_opts)
202273203274 -- bind yank behavior
204204- vim.keymap.set("n", YB_OPTS.keymaps.yank, function()
275275+ vim.keymap.set("n", opts.keymaps.yank, function()
205276 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
206277 local yankIndex = b.line_yank_map[cursor]
207278 if yankIndex then
208208- vim.fn.setreg(YB_OPTS.registers.yank_register, YB_YANKS[yankIndex])
279279+ vim.fn.setreg(
280280+ opts.registers.yank_register,
281281+ state.get_yanks()[yankIndex]
282282+ )
209283 vim.api.nvim_win_close(b.win_id, true)
210284 end
211285 end, map_opts)
212286213287 -- close popup keybinds
214288 -- REFACTOR: check if close keybind is string, handle differently
215215- for _, map in ipairs(YB_OPTS.keymaps.close) do
289289+ for _, map in ipairs(opts.keymaps.close) do
216290 vim.keymap.set("n", map, function()
217291 vim.api.nvim_win_close(b.win_id, true)
218292 end, map_opts)
+8-4
lua/yankbank/persistence.lua
···11local M = {}
2233+local state = require("yankbank.state")
34local persistence = {}
4556---add entry from bank to
···78---@param reg_type string
89---@param pin integer|boolean?
910function M.add_entry(entry, reg_type, pin)
1010- if YB_OPTS.persist_type == "sqlite" then
1111+ local opts = state.get_opts()
1212+ if opts.persist_type == "sqlite" then
1113 persistence:insert_yank(entry, reg_type, pin)
1214 end
1315end
14161517--- get current state of yanks in persistent storage
1618function M.get_yanks()
1717- if YB_OPTS.persist_type == "sqlite" then
1919+ local opts = state.get_opts()
2020+ if opts.persist_type == "sqlite" then
1821 return persistence:get_bank()
1922 end
2023end
···2427---@return table
2528---@return table
2629function M.setup()
2727- if not YB_OPTS.persist_type then
3030+ local opts = state.get_opts()
3131+ if not opts.persist_type then
2832 return {}, {}, {}
2929- elseif YB_OPTS.persist_type == "sqlite" then
3333+ elseif opts.persist_type == "sqlite" then
3034 persistence = require("yankbank.persistence.sql").setup()
3135 return persistence:get_bank()
3236 else
+14-9
lua/yankbank/persistence/sql.lua
···11local M = {}
2233local sqlite = require("sqlite")
44+local state = require("yankbank.state")
4555-local dbdir = YB_OPTS.db_path
66- or debug.getinfo(1).source:sub(2):match("(.*/).*/.*/.*/")
77- or "./"
88--- or vim.fn.stdpath("data")
66+local function get_db_path()
77+ local opts = state.get_opts()
88+ return opts.db_path
99+ or debug.getinfo(1).source:sub(2):match("(.*/).*/.*/.*/")
1010+ or "./"
1111+end
1212+913local max_entries = 10
10141115---@class YankBankDB:sqlite_db
1216---@field bank sqlite_tbl
1317---@field bank sqlite_tbl
1418local db = sqlite({
1515- uri = dbdir .. "/yankbank.db",
1919+ uri = get_db_path() .. "/yankbank.db",
1620 bank = {
1721 -- yanked text should be unique and be primary key
1822 yank_text = { "text", unique = true, primary = true, required = true },
···178182--- set up database persistence
179183---@return sqlite_tbl data
180184function M.setup()
181181- max_entries = YB_OPTS.max_entries
185185+ local opts = state.get_opts()
186186+ max_entries = opts.max_entries
182187183188 vim.api.nvim_create_user_command("YankBankClearDB", function()
184189 data:drop()
185185- YB_YANKS = {}
186186- YB_REG_TYPES = {}
190190+ state.set_yanks({})
191191+ state.set_reg_types({})
187192 end, {})
188193189189- if YB_OPTS.debug == true then
194194+ if opts.debug == true then
190195 vim.api.nvim_create_user_command("YankBankViewDB", function()
191196 print(vim.inspect(data:get()))
192197 end, {})
···11-local M = {}
22-33---- get the last zero entry in a table
44----
55----@param t table
66----@return integer?
77-function M.last_zero_entry(t)
88- for i = #t, 1, -1 do
99- if t[i] == 0 then
1010- return i
1111- end
1212- end
1313- return nil
1414-end
1515-1616-return M