Neovim plugin improving access to clipboard history (mirror)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(WIP file persistence, setting up base infrastructure)

+164
+25
lua/yankbank/persistence.lua
··· 1 + -- persistence.lua 2 + 3 + local M = {} 4 + 5 + -- TODO: for file-based persistence: 6 + -- - need system for moving entries around in list 7 + -- - either use tags and search by tag (could be out of order) 8 + -- - or keep list in sorted order (likely more i/o heavy) 9 + -- - store local copy of list in memory, to make accesses to popup quick 10 + -- - might need plenary for the asynchronous r/w accesses 11 + 12 + function M.enable_persistence(yanks, opts) 13 + if not opts.method then 14 + return 15 + elseif opts.method == "file" then 16 + -- TODO: 17 + require("persistence.file").setup_persistence( 18 + yanks, opts.persist_file, opts.max_entries) 19 + elseif opts.method == "sqlite" then 20 + -- TODO: 21 + print("sqlite persistence not yet implemented.") 22 + end 23 + end 24 + 25 + return M
+139
lua/yankbank/persistence/file.lua
··· 1 + -- persistence/file.lua 2 + 3 + local M = {} 4 + 5 + local n_entries = 0 6 + 7 + -- function that checks if a file exists 8 + ---@param file string: file path 9 + ---@return boolean 10 + local function file_exists(file) 11 + local f = io.open(file, "rb") 12 + if f then f:close() end 13 + return f ~= nil 14 + end 15 + 16 + -- function that reads all lines of file into a table 17 + ---@param file string: file path 18 + ---@return table 19 + local function read_lines(file) 20 + if not file_exists(file) then return {} end 21 + local lines = {} 22 + for line in io.lines(file) do 23 + lines[#lines+1] = line 24 + end 25 + return lines 26 + end 27 + 28 + -- check first line from file for presence of yankbank list header. 29 + -- if it exists, populate current number of entries. 30 + ---@param line string 31 + ---@return boolean 32 + local function check_for_header(line) 33 + local n = string.match(line, "<YANKBANK_LIST:(%d+)>") 34 + if n then 35 + n_entries = n 36 + return true 37 + end 38 + return false 39 + end 40 + 41 + -- function that checks for the presence of a yankbank header on a given line. 42 + -- returns t/f and index, length for entries that exist 43 + ---@param line string: line from file being checked 44 + ---@return table|nil 45 + local function check_for_entry(line) 46 + local i, l, ft, rt = string.match(line, "<YANKBANK_ENTRY:(%d+),(%d+),(%a+),(%a+)>") 47 + if i then 48 + return { 49 + index = tonumber(i), 50 + length = tonumber(l), 51 + file_type = ft, 52 + reg_type = rt, 53 + } 54 + end 55 + end 56 + 57 + -- function that reads a yankbank entry from an index to an offset. 58 + ---@param i integer: starting index 59 + ---@param offset integer: stopping point = i+offset 60 + ---@param lines table: file contents 61 + ---@return table: yankbank entry in string table form 62 + local function read_entry(i, offset, lines) 63 + local entry = {} 64 + for j = i, i + offset - 1 do 65 + entry[#entry + 1] = lines[j] 66 + end 67 + return entry 68 + end 69 + 70 + -- populate yankbank with entries contained in file. 71 + ---@param yanks table: table to populate with yanks 72 + ---@param file string: yankbank persistence file 73 + ---@param max_entries integer: maximum number of yankbank entries 74 + local function populate_yankbank(yanks, file, max_entries) 75 + -- read lines from file 76 + local lines = read_lines(file) 77 + if not check_for_header(lines[1]) then 78 + print("YankBank list header not found in file...") 79 + return 80 + end 81 + 82 + -- iterate through remaining lines in file, adding entries to yankbank 83 + local entries = {} 84 + local i = 2 85 + while i <= #lines do 86 + local res = check_for_entry(lines[i]) 87 + if res then 88 + local entry = read_entry(i + 1, res.length, lines) 89 + if res.index < max_entries then 90 + -- add to entries 91 + -- NOTE: might need to sort entries afterwards 92 + -- TODO: populate yankbank entries 93 + -- - update yanks table, reg_type, and place at correct spot in list 94 + entries[#entries + 1] = entry -- TODO: might need to convert to string 95 + -- NOTE: ^ should I use table.insert instead? (probably) 96 + end 97 + -- skip lines that were added to entries 98 + i = i + res.length 99 + end 100 + i = i + 1 101 + end 102 + 103 + -- TODO: add entries to bank 104 + print(yanks) 105 + 106 + print(vim.inspect(entries)) 107 + end 108 + 109 + -- setup function for a persistence file. 110 + -- should be called in plugin setup function 111 + ---@param yanks table: table to populate with yanks 112 + ---@param file string: file path 113 + ---@param max_entries integer: maximum number of yankbank entries 114 + function M.setup_persistence(yanks, file, max_entries) 115 + -- check if file exists, create it (with header) if it does not 116 + if not file_exists(file) then 117 + print("Creating file...") 118 + local f, err = io.open(file, "w") 119 + if f then 120 + f:write("<YANKBANK_LIST:0>") 121 + f:close() 122 + else 123 + print(err) 124 + end 125 + return 126 + end 127 + populate_yankbank(yanks, file, max_entries) 128 + end 129 + 130 + -- local lines = read_lines("test.txt") 131 + -- print(vim.inspect(lines)) 132 + -- TEST: remove later 133 + local yanks = {} 134 + print(M.setup_persistence(yanks, "test.txt", 10)) 135 + yanks = {} 136 + print(M.setup_persistence(yanks, "test1.txt", 10)) 137 + 138 + 139 + return M