···1local M = {}
2003--- get a table containg a single yankbank entry by index
4---@param i integer
5---@return table
6function M.get_entry(i)
7 return {
8- yank_text = YB_YANKS[i],
9- reg_type = YB_REG_TYPES[i],
10 }
11end
12···14---@return table
15function M.get_all()
16 local out = {}
17- for i, v in ipairs(YB_YANKS) do
0018 table.insert(out, {
19 yank_text = v,
20- reg_type = YB_REG_TYPES[i],
21 })
22 end
23 return out
···34--- remove entry from yankbank by index
35---@param i integer index to remove
36function M.remove_entry(i)
37- local yank_text = table.remove(YB_YANKS, i)
38- local reg_type = table.remove(YB_REG_TYPES, i)
39- if YB_OPTS.persist_type == "sqlite" then
00000040 require("yankbank.persistence.sql")
41 .data()
42 .remove_match(yank_text, reg_type)
···47---
48---@param i integer index to pin
49function M.pin_entry(i)
50- if i > #YB_PINS then
051 return
52 end
5354 -- TODO: show pins differently in popup (could use different hl_groups for pinned entries?)
55- YB_PINS[i] = 1
05657- if YB_OPTS.persist_type == "sqlite" then
058 return require("yankbank.persistence.sql")
59 .data()
60- .pin(YB_YANKS[i], YB_REG_TYPES[i])
61 end
62end
63···65---
66---@param i integer index to unpin
67function M.unpin_entry(i)
68- if i > #YB_PINS then
069 return
70 end
7172 -- TODO: update popup pin highlight
73- YB_PINS[i] = 0
07475- if YB_OPTS.persist_type == "sqlite" then
076 return require("yankbank.persistence.sql")
77 .data()
78- .unpin(YB_YANKS[i], YB_REG_TYPES[i])
79 end
80end
81
···1local M = {}
23+local state = require("yankbank.state")
4+5--- get a table containg a single yankbank entry by index
6---@param i integer
7---@return table
8function M.get_entry(i)
9 return {
10+ yank_text = state.get_yanks()[i],
11+ reg_type = state.get_reg_types()[i],
12 }
13end
14···16---@return table
17function M.get_all()
18 local out = {}
19+ local yanks = state.get_yanks()
20+ local reg_types = state.get_reg_types()
21+ for i, v in ipairs(yanks) do
22 table.insert(out, {
23 yank_text = v,
24+ reg_type = reg_types[i],
25 })
26 end
27 return out
···38--- remove entry from yankbank by index
39---@param i integer index to remove
40function M.remove_entry(i)
41+ local yanks = state.get_yanks()
42+ local reg_types = state.get_reg_types()
43+ local yank_text = table.remove(yanks, i)
44+ local reg_type = table.remove(reg_types, i)
45+ state.set_yanks(yanks)
46+ state.set_reg_types(reg_types)
47+48+ local opts = state.get_opts()
49+ if opts.persist_type == "sqlite" then
50 require("yankbank.persistence.sql")
51 .data()
52 .remove_match(yank_text, reg_type)
···57---
58---@param i integer index to pin
59function M.pin_entry(i)
60+ local pins = state.get_pins()
61+ if i > #pins then
62 return
63 end
6465 -- TODO: show pins differently in popup (could use different hl_groups for pinned entries?)
66+ pins[i] = 1
67+ state.set_pins(pins)
6869+ local opts = state.get_opts()
70+ if opts.persist_type == "sqlite" then
71 return require("yankbank.persistence.sql")
72 .data()
73+ .pin(state.get_yanks()[i], state.get_reg_types()[i])
74 end
75end
76···78---
79---@param i integer index to unpin
80function M.unpin_entry(i)
81+ local pins = state.get_pins()
82+ if i > #pins then
83 return
84 end
8586 -- TODO: update popup pin highlight
87+ pins[i] = 0
88+ state.set_pins(pins)
8990+ local opts = state.get_opts()
91+ if opts.persist_type == "sqlite" then
92 return require("yankbank.persistence.sql")
93 .data()
94+ .unpin(state.get_yanks()[i], state.get_reg_types()[i])
95 end
96end
97
+42-13
lua/yankbank/clipboard.lua
···1local M = {}
20000000000000003--- Function to add yanked text to table
4---@param text string
5---@param reg_type string
···11 end
1213 local is_pinned = 0
0001415 -- check for duplicate values already inserted
16- for i, entry in ipairs(YB_YANKS) do
17 if entry == text then
18 -- remove matched entry so it can be inserted at 1st position
19- table.remove(YB_YANKS, i)
20- table.remove(YB_REG_TYPES, i)
21- is_pinned = table.remove(YB_PINS, i)
22 break
23 end
24 end
···29 or is_pinned
3031 -- add entry to bank
32- table.insert(YB_YANKS, 1, text)
33- table.insert(YB_REG_TYPES, 1, reg_type)
34- table.insert(YB_PINS, 1, is_pinned)
3536 -- trim table size if necessary
37- if #YB_YANKS > YB_OPTS.max_entries then
38- local i = require("yankbank.utils").last_zero_entry(YB_PINS)
03940 if not i or i == 1 then
41 -- WARN: undefined behavior
···44 )
45 else
46 -- remove last non-pinned entry
47- table.remove(YB_YANKS, i)
48- table.remove(YB_REG_TYPES, i)
49- table.remove(YB_PINS, i)
50 end
51 end
000005253 -- add entry to persistent store
54 require("yankbank.persistence").add_entry(text, reg_type, pin)
···74 return
75 end
760077 M.add_yank(yank_text, reg_type)
78 end
79 end,
80 })
8182 -- poll registers when vim is focused (check for new clipboard activity)
83- if YB_OPTS.focus_gain_poll == true then
084 vim.api.nvim_create_autocmd("FocusGained", {
85 callback = function()
86 -- get register information
···95 return
96 end
970098 M.add_yank(yank_text, reg_type)
99 end,
100 })
···1local M = {}
23+local state = require("yankbank.state")
4+5+--- get the last zero entry in a table
6+---
7+---@param t table
8+---@return integer?
9+local function last_zero_entry(t)
10+ for i = #t, 1, -1 do
11+ if t[i] == 0 then
12+ return i
13+ end
14+ end
15+ return nil
16+end
17+18--- Function to add yanked text to table
19---@param text string
20---@param reg_type string
···26 end
2728 local is_pinned = 0
29+ local yanks = state.get_yanks()
30+ local reg_types = state.get_reg_types()
31+ local pins = state.get_pins()
3233 -- check for duplicate values already inserted
34+ for i, entry in ipairs(yanks) do
35 if entry == text then
36 -- remove matched entry so it can be inserted at 1st position
37+ table.remove(yanks, i)
38+ table.remove(reg_types, i)
39+ is_pinned = table.remove(pins, i)
40 break
41 end
42 end
···47 or is_pinned
4849 -- add entry to bank
50+ table.insert(yanks, 1, text)
51+ table.insert(reg_types, 1, reg_type)
52+ table.insert(pins, 1, is_pinned)
5354 -- trim table size if necessary
55+ local opts = state.get_opts()
56+ if #yanks > opts.max_entries then
57+ local i = last_zero_entry(pins)
5859 if not i or i == 1 then
60 -- WARN: undefined behavior
···63 )
64 else
65 -- remove last non-pinned entry
66+ table.remove(yanks, i)
67+ table.remove(reg_types, i)
68+ table.remove(pins, i)
69 end
70 end
71+72+ -- update state
73+ state.set_yanks(yanks)
74+ state.set_reg_types(reg_types)
75+ state.set_pins(pins)
7677 -- add entry to persistent store
78 require("yankbank.persistence").add_entry(text, reg_type, pin)
···98 return
99 end
100101+ -- lazy load initialization when first yank happens
102+ require("yankbank").ensure_initialized()
103 M.add_yank(yank_text, reg_type)
104 end
105 end,
106 })
107108 -- poll registers when vim is focused (check for new clipboard activity)
109+ local opts = state.get_opts()
110+ if opts.focus_gain_poll == true then
111 vim.api.nvim_create_autocmd("FocusGained", {
112 callback = function()
113 -- get register information
···122 return
123 end
124125+ -- lazy load initialization when first focus gain happens
126+ require("yankbank").ensure_initialized()
127 M.add_yank(yank_text, reg_type)
128 end,
129 })
-66
lua/yankbank/data.lua
···1-local M = {}
2-3---- reformat yanks table for popup
4----@return table, table
5-function M.get_display_lines()
6- local display_lines = {}
7- local line_yank_map = {}
8- local yank_num = 0
9-10- -- calculate the maximum width needed for the yank numbers
11- local max_digits = #tostring(#YB_YANKS)
12-13- -- assumes yanks is table of strings
14- for i, yank in ipairs(YB_YANKS) do
15- yank_num = yank_num + 1
16-17- local yank_lines = yank
18- if type(yank) == "string" then
19- -- remove trailing newlines
20- yank = yank:gsub("\n$", "")
21- yank_lines = vim.split(yank, "\n", { plain = true })
22- end
23-24- local leading_space, leading_space_length
25-26- -- determine the number of leading whitespaces on the first line
27- if #yank_lines > 0 then
28- leading_space = yank_lines[1]:match("^(%s*)")
29- leading_space_length = #leading_space
30- end
31-32- for j, line in ipairs(yank_lines) do
33- if j == 1 then
34- -- Format the line number with uniform spacing
35- local lineNumber =
36- string.format("%" .. max_digits .. "d: ", yank_num)
37- line = line:sub(leading_space_length + 1)
38- table.insert(display_lines, lineNumber .. line)
39- else
40- -- Remove the same amount of leading whitespace as on the first line
41- line = line:sub(leading_space_length + 1)
42- -- Use spaces equal to the line number's reserved space to align subsequent lines
43- table.insert(
44- display_lines,
45- string.rep(" ", max_digits + 2) .. line
46- )
47- end
48- table.insert(line_yank_map, i)
49- end
50-51- if i < #YB_YANKS then
52- -- Add a visual separator between yanks, aligned with the yank content
53- if YB_OPTS.sep ~= "" then
54- table.insert(
55- display_lines,
56- string.rep(" ", max_digits + 2) .. YB_OPTS.sep
57- )
58- end
59- table.insert(line_yank_map, false)
60- end
61- end
62-63- return display_lines, line_yank_map
64-end
65-66-return M
···1local M = {}
2000000000000000000000000000000000000000000003-- plugin setup
4---@param opts? table
5function M.setup(opts)
6- -- define global variables
7- YB_YANKS = {}
8- YB_REG_TYPES = {}
9- YB_PINS = {}
10- YB_OPTS = {}
11-12- -- local imports
13- local clipboard = require("yankbank.clipboard")
14- local persistence = require("yankbank.persistence")
15-16 -- default plugin options
17 local default_opts = {
18 max_entries = 10,
···27 db_path = nil,
28 bind_indices = nil,
29 }
30-31- --- wrapper function for main plugin functionality
32- local function show_yank_bank()
33- local menu = require("yankbank.menu")
34-35- -- set up menu keybinds from defaults and YB_OPTS.keymaps
36- menu.setup()
37-38- YB_YANKS = persistence.get_yanks() or YB_YANKS
39-40- -- initialize buffer and populate bank
41- local buf_data = menu.create_and_fill_buffer()
42- if not buf_data then
43- return
44- end
45-46- -- open popup window
47- buf_data.win_id = menu.open_window(buf_data)
48-49- -- set popup keybinds
50- menu.set_keymaps(buf_data)
51- end
5253 -- merge opts with default options table
54- YB_OPTS = vim.tbl_deep_extend("keep", opts or {}, default_opts)
5556- -- enable persistence based on opts (needs to be called before autocmd setup)
57- YB_YANKS, YB_REG_TYPES, YB_PINS = persistence.setup()
58-59- -- create clipboard autocmds
60- clipboard.setup_yank_autocmd()
6162 -- create user command
63 vim.api.nvim_create_user_command("YankBank", function()
64 show_yank_bank()
65 end, { desc = "Show Recent Yanks" })
0006667 -- Bind 1-n if `bind_indices` is set to a string
68- if YB_OPTS.bind_indices then
69- for i = 1, YB_OPTS.max_entries do
70- vim.keymap.set("n", YB_OPTS.bind_indices .. i, function()
0071 require("yankbank.helpers").smart_paste(
72- YB_YANKS[i],
73- YB_REG_TYPES[i],
74 true
75 )
76 end, {
···1local M = {}
23+local initialized = false
4+5+function M.ensure_initialized()
6+ if initialized then
7+ return
8+ end
9+10+ local state = require("yankbank.state")
11+ local persistence = require("yankbank.persistence")
12+13+ -- enable persistence based on opts (needs to be called before autocmd setup)
14+ local yanks, reg_types, pins = persistence.setup()
15+ state.init(yanks, reg_types, pins, state.get_opts())
16+17+ initialized = true
18+end
19+20+--- wrapper function for main plugin functionality
21+local function show_yank_bank()
22+ M.ensure_initialized()
23+24+ local state = require("yankbank.state")
25+ local menu = require("yankbank.menu")
26+27+ -- set up menu keybinds from defaults and state.get_opts().keymaps
28+ menu.setup()
29+30+ local persistence = require("yankbank.persistence")
31+ local yanks = persistence.get_yanks() or state.get_yanks()
32+ state.set_yanks(yanks)
33+34+ -- initialize buffer and populate bank
35+ local buf_data = menu.create_and_fill_buffer()
36+ if not buf_data then
37+ return
38+ end
39+40+ -- open popup window
41+ buf_data.win_id = menu.open_window(buf_data)
42+43+ -- set popup keybinds
44+ menu.set_keymaps(buf_data)
45+end
46+47-- plugin setup
48---@param opts? table
49function M.setup(opts)
000000000050 -- default plugin options
51 local default_opts = {
52 max_entries = 10,
···61 db_path = nil,
62 bind_indices = nil,
63 }
00000000000000000000006465 -- merge opts with default options table
66+ local merged_opts = vim.tbl_deep_extend("keep", opts or {}, default_opts)
6768+ -- store config in state module (lazy loaded when needed)
69+ local state = require("yankbank.state")
70+ state.set_opts(merged_opts)
007172 -- create user command
73 vim.api.nvim_create_user_command("YankBank", function()
74 show_yank_bank()
75 end, { desc = "Show Recent Yanks" })
76+77+ -- create clipboard autocmds
78+ require("yankbank.clipboard").setup_yank_autocmd()
7980 -- Bind 1-n if `bind_indices` is set to a string
81+ if merged_opts.bind_indices then
82+ for i = 1, merged_opts.max_entries do
83+ vim.keymap.set("n", merged_opts.bind_indices .. i, function()
84+ M.ensure_initialized()
85+ local state = require("yankbank.state")
86 require("yankbank.helpers").smart_paste(
87+ state.get_yanks()[i],
88+ state.get_reg_types()[i],
89 true
90 )
91 end, {
+101-27
lua/yankbank/menu.lua
···1local M = {}
23-local data = require("yankbank.data")
4-local helpers = require("yankbank.helpers")
56-- default plugin keymaps
7local default_keymaps = {
···18 yank_register = "+",
19}
2021--- local YB_OPTS.keymaps = {}
22-23function M.setup()
024 -- merge default and options keymap tables
25- YB_OPTS.keymaps =
26- vim.tbl_deep_extend("force", default_keymaps, YB_OPTS.keymaps or {})
27 -- merge default and options register tables
28- YB_OPTS.registers =
29- vim.tbl_deep_extend("force", default_registers, YB_OPTS.registers or {})
3031 -- check table for number behavior option (prefix or jump, default to prefix)
32- YB_OPTS.num_behavior = YB_OPTS.num_behavior or "prefix"
0000000000000000000000000000000000000000000000000000000000000000000033end
3435--- Container class for YankBank buffer related variables
···43---@return YankBankBufData?
44function M.create_and_fill_buffer()
45 -- stop if yanks or register types table is empty
46- if #YB_YANKS == 0 or #YB_REG_TYPES == 0 then
0047 print("No yanks to show.")
48 return nil
49 end
···55 local current_filetype = vim.bo.filetype
56 vim.api.nvim_set_option_value("filetype", current_filetype, { buf = bufnr })
5758- local display_lines, line_yank_map = data.get_display_lines()
5960 -- replace current buffer contents with updated table
61 vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, display_lines)
···119function M.set_keymaps(b)
120 -- key mappings for selection and closing the popup
121 local map_opts = { noremap = true, silent = true, buffer = b.bufnr }
000122123 -- popup buffer navigation binds
124- if YB_OPTS.num_behavior == "prefix" then
125- vim.keymap.set("n", YB_OPTS.keymaps.navigation_next, function()
126 local count = vim.v.count1 > 0 and vim.v.count1 or 1
127 helpers.next_numbered_item(count)
128 return ""
129 end, { noremap = true, silent = true, buffer = b.bufnr })
130- vim.keymap.set("n", YB_OPTS.keymaps.navigation_prev, function()
131 local count = vim.v.count1 > 0 and vim.v.count1 or 1
132 helpers.prev_numbered_item(count)
133 return ""
···135 else
136 vim.keymap.set(
137 "n",
138- YB_OPTS.keymaps.navigation_next,
139 helpers.next_numbered_item,
140 map_opts
141 )
142 vim.keymap.set(
143 "n",
144- YB_OPTS.keymaps.navigation_prev,
145 helpers.prev_numbered_item,
146 map_opts
147 )
148 end
149150 -- map number keys to jump to entry if num_behavior is 'jump'
151- if YB_OPTS.num_behavior == "jump" then
152- for i = 1, YB_OPTS.max_entries do
153 vim.keymap.set("n", tostring(i), function()
154 local target_line = nil
155 for line_num, yank_num in pairs(b.line_yank_map) do
···166 end
167168 -- bind paste behavior
169- vim.keymap.set("n", YB_OPTS.keymaps.paste, function()
170 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
171 -- use the mapping to find the original yank
172 local yankIndex = b.line_yank_map[cursor]
···174 -- close window upon selection
175 vim.api.nvim_win_close(b.win_id, true)
176 helpers.smart_paste(
177- YB_YANKS[yankIndex],
178- YB_REG_TYPES[yankIndex],
179 true
180 )
181 else
···183 end
184 end, map_opts)
185 -- paste backwards
186- vim.keymap.set("n", YB_OPTS.keymaps.paste_back, function()
187 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
188 -- use the mapping to find the original yank
189 local yankIndex = b.line_yank_map[cursor]
···191 -- close window upon selection
192 vim.api.nvim_win_close(b.win_id, true)
193 helpers.smart_paste(
194- YB_YANKS[yankIndex],
195- YB_REG_TYPES[yankIndex],
196 false
197 )
198 else
···201 end, map_opts)
202203 -- bind yank behavior
204- vim.keymap.set("n", YB_OPTS.keymaps.yank, function()
205 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
206 local yankIndex = b.line_yank_map[cursor]
207 if yankIndex then
208- vim.fn.setreg(YB_OPTS.registers.yank_register, YB_YANKS[yankIndex])
000209 vim.api.nvim_win_close(b.win_id, true)
210 end
211 end, map_opts)
212213 -- close popup keybinds
214 -- REFACTOR: check if close keybind is string, handle differently
215- for _, map in ipairs(YB_OPTS.keymaps.close) do
216 vim.keymap.set("n", map, function()
217 vim.api.nvim_win_close(b.win_id, true)
218 end, map_opts)
···1local M = {}
23+local state = require("yankbank.state")
045-- default plugin keymaps
6local default_keymaps = {
···17 yank_register = "+",
18}
190020function M.setup()
21+ local opts = state.get_opts()
22 -- merge default and options keymap tables
23+ opts.keymaps =
24+ vim.tbl_deep_extend("force", default_keymaps, opts.keymaps or {})
25 -- merge default and options register tables
26+ opts.registers =
27+ vim.tbl_deep_extend("force", default_registers, opts.registers or {})
2829 -- check table for number behavior option (prefix or jump, default to prefix)
30+ opts.num_behavior = opts.num_behavior or "prefix"
31+32+ state.set_opts(opts)
33+end
34+35+--- reformat yanks table for popup
36+---@return table, table
37+local function get_display_lines()
38+ local display_lines = {}
39+ local line_yank_map = {}
40+ local yank_num = 0
41+42+ local yanks = state.get_yanks()
43+ local opts = state.get_opts()
44+45+ -- calculate the maximum width needed for the yank numbers
46+ local max_digits = #tostring(#yanks)
47+48+ -- assumes yanks is table of strings
49+ for i, yank in ipairs(yanks) do
50+ yank_num = yank_num + 1
51+52+ local yank_lines = yank
53+ if type(yank) == "string" then
54+ -- remove trailing newlines
55+ yank = yank:gsub("\n$", "")
56+ yank_lines = vim.split(yank, "\n", { plain = true })
57+ end
58+59+ local leading_space, leading_space_length
60+61+ -- determine the number of leading whitespaces on the first line
62+ if #yank_lines > 0 then
63+ leading_space = yank_lines[1]:match("^(%s*)")
64+ leading_space_length = #leading_space
65+ end
66+67+ for j, line in ipairs(yank_lines) do
68+ if j == 1 then
69+ -- Format the line number with uniform spacing
70+ local lineNumber =
71+ string.format("%" .. max_digits .. "d: ", yank_num)
72+ line = line:sub(leading_space_length + 1)
73+ table.insert(display_lines, lineNumber .. line)
74+ else
75+ -- Remove the same amount of leading whitespace as on the first line
76+ line = line:sub(leading_space_length + 1)
77+ -- Use spaces equal to the line number's reserved space to align subsequent lines
78+ table.insert(
79+ display_lines,
80+ string.rep(" ", max_digits + 2) .. line
81+ )
82+ end
83+ table.insert(line_yank_map, i)
84+ end
85+86+ if i < #yanks then
87+ -- Add a visual separator between yanks, aligned with the yank content
88+ if opts.sep ~= "" then
89+ table.insert(
90+ display_lines,
91+ string.rep(" ", max_digits + 2) .. opts.sep
92+ )
93+ end
94+ table.insert(line_yank_map, false)
95+ end
96+ end
97+98+ return display_lines, line_yank_map
99end
100101--- Container class for YankBank buffer related variables
···109---@return YankBankBufData?
110function M.create_and_fill_buffer()
111 -- stop if yanks or register types table is empty
112+ local yanks = state.get_yanks()
113+ local reg_types = state.get_reg_types()
114+ if #yanks == 0 or #reg_types == 0 then
115 print("No yanks to show.")
116 return nil
117 end
···123 local current_filetype = vim.bo.filetype
124 vim.api.nvim_set_option_value("filetype", current_filetype, { buf = bufnr })
125126+ local display_lines, line_yank_map = get_display_lines()
127128 -- replace current buffer contents with updated table
129 vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, display_lines)
···187function M.set_keymaps(b)
188 -- key mappings for selection and closing the popup
189 local map_opts = { noremap = true, silent = true, buffer = b.bufnr }
190+ local opts = state.get_opts()
191+192+ local helpers = require("yankbank.helpers")
193194 -- popup buffer navigation binds
195+ if opts.num_behavior == "prefix" then
196+ vim.keymap.set("n", opts.keymaps.navigation_next, function()
197 local count = vim.v.count1 > 0 and vim.v.count1 or 1
198 helpers.next_numbered_item(count)
199 return ""
200 end, { noremap = true, silent = true, buffer = b.bufnr })
201+ vim.keymap.set("n", opts.keymaps.navigation_prev, function()
202 local count = vim.v.count1 > 0 and vim.v.count1 or 1
203 helpers.prev_numbered_item(count)
204 return ""
···206 else
207 vim.keymap.set(
208 "n",
209+ opts.keymaps.navigation_next,
210 helpers.next_numbered_item,
211 map_opts
212 )
213 vim.keymap.set(
214 "n",
215+ opts.keymaps.navigation_prev,
216 helpers.prev_numbered_item,
217 map_opts
218 )
219 end
220221 -- map number keys to jump to entry if num_behavior is 'jump'
222+ if opts.num_behavior == "jump" then
223+ for i = 1, opts.max_entries do
224 vim.keymap.set("n", tostring(i), function()
225 local target_line = nil
226 for line_num, yank_num in pairs(b.line_yank_map) do
···237 end
238239 -- bind paste behavior
240+ vim.keymap.set("n", opts.keymaps.paste, function()
241 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
242 -- use the mapping to find the original yank
243 local yankIndex = b.line_yank_map[cursor]
···245 -- close window upon selection
246 vim.api.nvim_win_close(b.win_id, true)
247 helpers.smart_paste(
248+ state.get_yanks()[yankIndex],
249+ state.get_reg_types()[yankIndex],
250 true
251 )
252 else
···254 end
255 end, map_opts)
256 -- paste backwards
257+ vim.keymap.set("n", opts.keymaps.paste_back, function()
258 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
259 -- use the mapping to find the original yank
260 local yankIndex = b.line_yank_map[cursor]
···262 -- close window upon selection
263 vim.api.nvim_win_close(b.win_id, true)
264 helpers.smart_paste(
265+ state.get_yanks()[yankIndex],
266+ state.get_reg_types()[yankIndex],
267 false
268 )
269 else
···272 end, map_opts)
273274 -- bind yank behavior
275+ vim.keymap.set("n", opts.keymaps.yank, function()
276 local cursor = vim.api.nvim_win_get_cursor(b.win_id)[1]
277 local yankIndex = b.line_yank_map[cursor]
278 if yankIndex then
279+ vim.fn.setreg(
280+ opts.registers.yank_register,
281+ state.get_yanks()[yankIndex]
282+ )
283 vim.api.nvim_win_close(b.win_id, true)
284 end
285 end, map_opts)
286287 -- close popup keybinds
288 -- REFACTOR: check if close keybind is string, handle differently
289+ for _, map in ipairs(opts.keymaps.close) do
290 vim.keymap.set("n", map, function()
291 vim.api.nvim_win_close(b.win_id, true)
292 end, map_opts)
+8-4
lua/yankbank/persistence.lua
···1local M = {}
203local persistence = {}
45---add entry from bank to
···7---@param reg_type string
8---@param pin integer|boolean?
9function M.add_entry(entry, reg_type, pin)
10- if YB_OPTS.persist_type == "sqlite" then
011 persistence:insert_yank(entry, reg_type, pin)
12 end
13end
1415--- get current state of yanks in persistent storage
16function M.get_yanks()
17- if YB_OPTS.persist_type == "sqlite" then
018 return persistence:get_bank()
19 end
20end
···24---@return table
25---@return table
26function M.setup()
27- if not YB_OPTS.persist_type then
028 return {}, {}, {}
29- elseif YB_OPTS.persist_type == "sqlite" then
30 persistence = require("yankbank.persistence.sql").setup()
31 return persistence:get_bank()
32 else
···1local M = {}
23+local state = require("yankbank.state")
4local persistence = {}
56---add entry from bank to
···8---@param reg_type string
9---@param pin integer|boolean?
10function M.add_entry(entry, reg_type, pin)
11+ local opts = state.get_opts()
12+ if opts.persist_type == "sqlite" then
13 persistence:insert_yank(entry, reg_type, pin)
14 end
15end
1617--- get current state of yanks in persistent storage
18function M.get_yanks()
19+ local opts = state.get_opts()
20+ if opts.persist_type == "sqlite" then
21 return persistence:get_bank()
22 end
23end
···27---@return table
28---@return table
29function M.setup()
30+ local opts = state.get_opts()
31+ if not opts.persist_type then
32 return {}, {}, {}
33+ elseif opts.persist_type == "sqlite" then
34 persistence = require("yankbank.persistence.sql").setup()
35 return persistence:get_bank()
36 else
+14-9
lua/yankbank/persistence/sql.lua
···1local M = {}
23local sqlite = require("sqlite")
045-local dbdir = YB_OPTS.db_path
6- or debug.getinfo(1).source:sub(2):match("(.*/).*/.*/.*/")
7- or "./"
8--- or vim.fn.stdpath("data")
0009local max_entries = 10
1011---@class YankBankDB:sqlite_db
12---@field bank sqlite_tbl
13---@field bank sqlite_tbl
14local db = sqlite({
15- uri = dbdir .. "/yankbank.db",
16 bank = {
17 -- yanked text should be unique and be primary key
18 yank_text = { "text", unique = true, primary = true, required = true },
···178--- set up database persistence
179---@return sqlite_tbl data
180function M.setup()
181- max_entries = YB_OPTS.max_entries
0182183 vim.api.nvim_create_user_command("YankBankClearDB", function()
184 data:drop()
185- YB_YANKS = {}
186- YB_REG_TYPES = {}
187 end, {})
188189- if YB_OPTS.debug == true then
190 vim.api.nvim_create_user_command("YankBankViewDB", function()
191 print(vim.inspect(data:get()))
192 end, {})
···1local M = {}
23local sqlite = require("sqlite")
4+local state = require("yankbank.state")
56+local function get_db_path()
7+ local opts = state.get_opts()
8+ return opts.db_path
9+ or debug.getinfo(1).source:sub(2):match("(.*/).*/.*/.*/")
10+ or "./"
11+end
12+13local max_entries = 10
1415---@class YankBankDB:sqlite_db
16---@field bank sqlite_tbl
17---@field bank sqlite_tbl
18local db = sqlite({
19+ uri = get_db_path() .. "/yankbank.db",
20 bank = {
21 -- yanked text should be unique and be primary key
22 yank_text = { "text", unique = true, primary = true, required = true },
···182--- set up database persistence
183---@return sqlite_tbl data
184function M.setup()
185+ local opts = state.get_opts()
186+ max_entries = opts.max_entries
187188 vim.api.nvim_create_user_command("YankBankClearDB", function()
189 data:drop()
190+ state.set_yanks({})
191+ state.set_reg_types({})
192 end, {})
193194+ if opts.debug == true then
195 vim.api.nvim_create_user_command("YankBankViewDB", function()
196 print(vim.inspect(data:get()))
197 end, {})
···1-local M = {}
2-3---- get the last zero entry in a table
4----
5----@param t table
6----@return integer?
7-function M.last_zero_entry(t)
8- for i = #t, 1, -1 do
9- if t[i] == 0 then
10- return i
11- end
12- end
13- return nil
14-end
15-16-return M