···11-- clipboard.lua
22local M = {}
3344+-- TODO: convert string to table yanks to work better with files
55+46-- Function to add yanked text to table
77+---@param yanks table
88+---@param reg_types table
99+---@param text string
1010+---@param reg_type string
1111+---@param max_entries integer
512function M.add_yank(yanks, reg_types, text, reg_type, max_entries)
613 -- avoid adding empty strings
77- if text ~= "" and text ~= " " and text ~= "\n" then
88- -- do not update with duplicate values
99- for _, entry in ipairs(yanks) do
1010- if entry == text then
1111- return
1212- end
1313- end
1414- table.insert(yanks, 1, text)
1515- table.insert(reg_types, 1, reg_type)
1616- if #yanks > max_entries then
1717- table.remove(yanks)
1818- table.remove(reg_types)
1414+ -- TODO: could block adding single characters here
1515+ if text == "" or text == " " or text == "\n" then
1616+ return
1717+ end
1818+ print(
1919+ "yanks: ",
2020+ vim.inspect(yanks),
2121+ "| reg_types: ",
2222+ vim.inspect(reg_types)
2323+ )
2424+2525+ -- do not update with duplicate values
2626+ for _, entry in ipairs(yanks) do
2727+ if entry == text then
2828+ return
1929 end
2030 end
3131+3232+ -- add entry to bank
3333+ table.insert(yanks, 1, text)
3434+ table.insert(reg_types, 1, reg_type)
3535+ if #yanks > max_entries then
3636+ table.remove(yanks)
3737+ table.remove(reg_types)
3838+ end
2139end
22402341-- autocommand to listen for yank events
4242+---@param yanks table
4343+---@param reg_types table
4444+---@param max_entries integer
2445function M.setup_yank_autocmd(yanks, reg_types, max_entries)
2546 vim.api.nvim_create_autocmd("TextYankPost", {
2647 callback = function()
2727- -- TODO: this function can be expanded to incorporate other registers
2828- -- - use vim.v.event.regname and an allowlist
2929- -- local reg_type = vim.v.event.operator
3030- -- if reg_type == "y" or reg_type == "d" then
3131- -- local yanked_text = vim.fn.getreg('"')
3232-3348 -- get register information
3449 local rn = vim.v.event.regname
3535- local reg_type = vim.fn.getregtype('"')
5050+ local reg_type = vim.fn.getregtype("+")
36513752 -- check changes wwere made to default register
3853 if vim.v.event.regname == "" then
3954 local yanked_text = vim.fn.getreg(rn)
4040-4141- -- NOTE: this only blocks adding to list if something else is in plus register
4242- if string.len(yanked_text) <= 1 then
5555+ if #yanked_text <= 1 then
4356 return
4457 end
4545-4658 M.add_yank(yanks, reg_types, yanked_text, reg_type, max_entries)
4759 end
4860 end,
+3
lua/yankbank/data.lua
···22local M = {}
3344-- reformat yanks table for popup
55+---@param yanks table
66+---@param sep string
77+---@return table, table
58function M.get_display_lines(yanks, sep)
69 local display_lines = {}
710 local line_yank_map = {}
+4
lua/yankbank/helpers.lua
···22local M = {}
3344-- navigate to the next numbered item
55+---@param steps integer
56function M.next_numbered_item(steps)
67 steps = steps or 1 -- Default to 1 if no steps are provided
78 local current_line = vim.api.nvim_win_get_cursor(0)[1]
···2425end
25262627-- navigate to the previous numbered item
2828+---@param steps integer
2729function M.prev_numbered_item(steps)
2830 steps = steps or 1 -- Default to 1 if no steps are provided
2931 local current_line = vim.api.nvim_win_get_cursor(0)[1]
···4345end
44464547-- customized paste function that functions like 'p'
4848+---@param text string
4949+---@param reg_type string
4650function M.smart_paste(text, reg_type)
4751 -- convert text string to string list
4852 local lines = {}
+2
lua/yankbank/init.lua
···1212local sep = "-----"
13131414-- wrapper function for main plugin functionality
1515+---@param opts table|nil
1516local function show_yank_bank(opts)
1617 -- Parse command arguments directly if args are provided as a string
1718 opts = opts or {}
···3233end
33343435-- plugin setup
3636+---@param opts table|nil
3537function M.setup(opts)
3638 opts = opts or {}
3739
+138-26
lua/yankbank/persistence/file.lua
···33local M = {}
4455local n_entries = 0
66+local m_entries = 10
6778-- function that checks if a file exists
89---@param file string: file path
···2324 return {}
2425 end
2526 local lines = {}
2626- for line in io.lines(file) do
2727+ local f, err = io.open(file)
2828+ if not f then
2929+ error("Error opening file: " .. err)
3030+ end
3131+ for line in f:lines() do
2732 lines[#lines + 1] = line
2833 end
3434+ f:close()
2935 return lines
3036end
3137···3642local function check_for_header(line)
3743 local n = string.match(line, "<YANKBANK_LIST:(%d+)>")
3844 if n then
3939- n_entries = n
4545+ n_entries = tonumber(n, 10)
4046 return true
4147 end
4248 return false
···7278 return entry
7379end
74808181+-- remove entry from bankfile
8282+---@param file string: bank file name
8383+local function remove_last_entry(file)
8484+ local f, err = io.open(file, "r+")
8585+ if not f then
8686+ error("Could not open file for reading: " .. err)
8787+ end
8888+8989+ -- read lines from file until matching entry is found
9090+ local lines = {}
9191+ -- TODO: does this for loop work?
9292+ for line in f:lines() do
9393+ print(line)
9494+ if
9595+ string.match(
9696+ line,
9797+ "<YANKBANK_ENTRY:" .. n_entries .. ",%d+,%a+,%a+>"
9898+ )
9999+ then
100100+ n_entries = n_entries - 1
101101+ lines[1] = "<YANKBANK_LIST:" .. n_entries .. ">\n"
102102+ break
103103+ else
104104+ lines[#lines + 1] = line
105105+ end
106106+ end
107107+ f:close()
108108+109109+ -- write to file
110110+ f, err = io.open(file, "w")
111111+ if not f then
112112+ error("Could not open file for writing: " .. err)
113113+ end
114114+ for i = 1, #lines do
115115+ f:write(lines[i])
116116+ end
117117+ f:close()
118118+end
119119+120120+local function open_file(file, mode)
121121+ local f, err = io.open(file, mode)
122122+ if not f then
123123+ error("Could not open file: " .. err)
124124+ end
125125+ return f
126126+end
127127+128128+-- add entry bankfile. (this function needs to be callable from outside the module)
129129+---@param file string
130130+---@param entry table|string
131131+---@param reg_type string
132132+-- TODO: trigger in add_yank in clipboard.lua
133133+-- Function scope probably needs to change to a different level (or be callable from persistence.lua)
134134+local function add_to_bankfile(file, entry, reg_type)
135135+ if n_entries >= m_entries then
136136+ remove_last_entry(file)
137137+ end
138138+ n_entries = n_entries + 1
139139+140140+ -- local f, err = io.open(file, "w")
141141+ local lines = read_lines(file)
142142+ print(vim.inspect(lines))
143143+ local f = open_file(file, "w+")
144144+ -- BUG: issues around here surrounding newline behavior
145145+ -- - definintely an issue adding, only appears after inserting first entry
146146+ f:write("<YANKBANK_LIST:" .. n_entries .. ">\n")
147147+ for i = 2, #lines do
148148+ print(i)
149149+ f:write(lines[i] .. "\n")
150150+ print(lines[i])
151151+ end
152152+153153+ -- write entry header
154154+ f:write(
155155+ "<YANKBANK_ENTRY:"
156156+ .. n_entries
157157+ .. ","
158158+ .. #entry
159159+ .. ",nil,"
160160+ .. reg_type
161161+ .. ">\n"
162162+ )
163163+164164+ -- convert string entry to table
165165+ if type(entry) == "string" then
166166+ print(entry)
167167+ -- local text = entry
168168+ -- entry = {}
169169+ -- for line in text:gmatch("[^\r\n]+") do
170170+ -- table.insert(entry, line)
171171+ -- end
172172+ f:write(entry .. "\n")
173173+ return
174174+ end
175175+176176+ for i = 1, #entry do
177177+ f:write(entry[i])
178178+ end
179179+180180+ f:close()
181181+end
182182+75183-- populate yankbank with entries contained in file.
76184---@param yanks table: table to populate with yanks
77185---@param file string: yankbank persistence file
78186---@param max_entries integer: maximum number of yankbank entries
7979-local function populate_yankbank(yanks, file, max_entries)
187187+---@return table, table
188188+local function populate_yankbank(file, max_entries, yanks, reg_types)
80189 -- read lines from file
81190 local lines = read_lines(file)
82191 if not check_for_header(lines[1]) then
83192 print("YankBank list header not found in file...")
8484- return
193193+ return {}, {}
85194 end
8619587196 -- iterate through remaining lines in file, adding entries to yankbank
8888- local entries = {}
89197 local i = 2
90198 while i <= #lines do
91199 local res = check_for_entry(lines[i])
92200 if res then
93201 local entry = read_entry(i + 1, res.length, lines)
94202 if res.index < max_entries then
9595- -- add to entries
9696- -- NOTE: might need to sort entries afterwards
9797- -- TODO: populate yankbank entries
9898- -- - update yanks table, reg_type, and place at correct spot in list
9999- entries[#entries + 1] = entry -- TODO: might need to convert to string
100100- -- NOTE: ^ should I use table.insert instead? (probably)
203203+ yanks[#yanks + 1] = entry
204204+ reg_types[#reg_types + 1] = res.reg_type
205205+ -- NOTE: ^ should I use table.insert instead? (would allow inserting at specific position)
101206 end
102207 -- skip lines that were added to entries
103208 i = i + res.length
104209 end
105210 i = i + 1
106211 end
107107-108108- -- TODO: add entries to bank
109109- print(yanks)
110110-111111- print(vim.inspect(entries))
212212+ return yanks, reg_types
112213end
113214114215-- setup function for a persistence file.
115216-- should be called in plugin setup function
116116----@param yanks table: table to populate with yanks
117217---@param file string: file path
118218---@param max_entries integer: maximum number of yankbank entries
119119-function M.setup_persistence(yanks, file, max_entries)
120120- -- check if file exists, create it (with header) if it does not
219219+---@param yanks table: table to populate with yanks
220220+---@param reg_types table: table containing register types
221221+---@return table, table
222222+function M.setup_persistence(file, max_entries, yanks, reg_types)
223223+ -- check if file exists, otherwise create it (with header)
121224 if not file_exists(file) then
122225 print("Creating file...")
123226 local f, err = io.open(file, "w")
···127230 else
128231 print(err)
129232 end
130130- return
233233+ return {}, {}
131234 end
132132- populate_yankbank(yanks, file, max_entries)
235235+ m_entries = max_entries
236236+ return populate_yankbank(file, max_entries, yanks, reg_types)
133237end
134238135135--- local lines = read_lines("test.txt")
136136--- print(vim.inspect(lines))
137239-- TEST: remove later
138240local yanks = {}
139139-print(M.setup_persistence(yanks, "test.txt", 10))
241241+local reg_types = {}
242242+M.setup_persistence("test.txt", 10, yanks, reg_types)
243243+print(vim.inspect(yanks))
244244+print(vim.inspect(reg_types))
140245yanks = {}
141141-print(M.setup_persistence(yanks, "test1.txt", 10))
142142-print(n_entries)
246246+reg_types = {}
247247+print(vim.inspect(yanks))
248248+print(vim.inspect(reg_types))
249249+M.setup_persistence("test1.txt", 10, yanks, reg_types)
250250+m_entries = 10
251251+add_to_bankfile("test1.txt", "text", "v")
252252+-- BUG: this isnt added to the testing file, file i/o might be too slow
253253+add_to_bankfile("test1.txt", "text1", "V")
254254+-- remove_last_entry("test1.txt")
143255144256return M