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 api pin improvements

+69 -22
+14 -6
lua/yankbank/api.lua
··· 47 47 --- 48 48 ---@param i integer index to pin 49 49 function M.pin_entry(i) 50 - -- TODO: check persistence mode, max_entries 51 - -- - add third table YB_PINS to keep track of pins 52 - -- TODO: show pins differently in popup 50 + if i > #YB_PINS then 51 + return 52 + end 53 + 54 + -- TODO: show pins differently in popup (could use different hl_groups for pinned entries?) 55 + YB_PINS[i] = 1 56 + 53 57 if YB_OPTS.persist_type == "sqlite" then 54 58 return require("yankbank.persistence.sql") 55 59 .data() ··· 61 65 --- 62 66 ---@param i integer index to unpin 63 67 function M.unpin_entry(i) 64 - -- TODO: check persistence mode, max_entries 65 - -- - in sql.lua, add 3rd field (bool) pinned 68 + if i > #YB_PINS then 69 + return 70 + end 71 + 72 + -- TODO: update popup pin highlight 73 + YB_PINS[i] = 0 74 + 66 75 if YB_OPTS.persist_type == "sqlite" then 67 76 return require("yankbank.persistence.sql") 68 77 .data() ··· 71 80 end 72 81 73 82 -- TODO: individual popup keymap setting functions 74 - -- - could just update opts table that is passed into set_keymaps 75 83 76 84 return M
+23 -5
lua/yankbank/clipboard.lua
··· 2 2 3 3 -- import persistence module 4 4 local persistence = require("yankbank.persistence") 5 + local utils = require("yankbank.utils") 5 6 6 7 --- Function to add yanked text to table 7 8 ---@param text string ··· 13 14 return 14 15 end 15 16 17 + local is_pinned = 0 18 + 16 19 -- check for duplicate values already inserted 17 20 for i, entry in ipairs(YB_YANKS) do 18 21 if entry == text then 19 22 -- remove matched entry so it can be inserted at 1st position 20 - -- TODO: pin handling in global tables 21 23 table.remove(YB_YANKS, i) 22 24 table.remove(YB_REG_TYPES, i) 25 + is_pinned = table.remove(YB_PINS, i) 23 26 break 24 27 end 25 28 end 26 29 30 + -- override is_pinned if pin is set 31 + is_pinned = (pin == 1 or pin == true) and 1 32 + or (pin == 0 or pin == false) and 0 33 + or is_pinned 34 + 27 35 -- add entry to bank 28 - -- TODO: pin handling in global tables 29 36 table.insert(YB_YANKS, 1, text) 30 37 table.insert(YB_REG_TYPES, 1, reg_type) 38 + table.insert(YB_PINS, 1, is_pinned) 31 39 32 40 -- trim table size if necessary 33 41 if #YB_YANKS > YB_OPTS.max_entries then 34 - -- TODO: pin handling in global tables 35 - table.remove(YB_YANKS) 36 - table.remove(YB_REG_TYPES) 42 + local i = utils.last_zero_entry(YB_PINS) 43 + 44 + if not i or i == 1 then 45 + -- WARN: undefined behavior 46 + print( 47 + "Warning: all YankBank entries are pinned, insertion behavior is undefined when all entries are pinned." 48 + ) 49 + else 50 + -- remove last non-pinned entry 51 + table.remove(YB_YANKS, i) 52 + table.remove(YB_REG_TYPES, i) 53 + table.remove(YB_PINS, i) 54 + end 37 55 end 38 56 39 57 -- add entry to persistent store
+2 -1
lua/yankbank/init.lua
··· 3 3 -- define global variables 4 4 YB_YANKS = {} 5 5 YB_REG_TYPES = {} 6 + YB_PINS = {} 6 7 YB_OPTS = {} 7 8 8 9 -- local imports ··· 47 48 YB_OPTS = vim.tbl_deep_extend("keep", opts or {}, default_opts) 48 49 49 50 -- enable persistence based on opts (needs to be called before autocmd setup) 50 - YB_YANKS, YB_REG_TYPES = persistence.setup() 51 + YB_YANKS, YB_REG_TYPES, YB_PINS = persistence.setup() 51 52 52 53 -- create clipboard autocmds 53 54 clipboard.setup_yank_autocmd()
+3 -2
lua/yankbank/persistence.lua
··· 22 22 ---initialize bank persistence 23 23 ---@return table 24 24 ---@return table 25 + ---@return table 25 26 function M.setup() 26 27 if not YB_OPTS.persist_type then 27 - return {}, {} 28 + return {}, {}, {} 28 29 elseif YB_OPTS.persist_type == "sqlite" then 29 30 persistence = require("yankbank.persistence.sql").setup() 30 31 return persistence:get_bank() 31 32 else 32 - return {}, {} 33 + return {}, {}, {} 33 34 end 34 35 end 35 36
+11 -8
lua/yankbank/persistence/sql.lua
··· 1 1 local M = {} 2 2 3 - local sqlite = require("sqlite.db") 3 + local sqlite = require("sqlite") 4 4 5 5 -- local dbdir = vim.fn.stdpath("data") .. "/databases" 6 6 local dbdir = debug.getinfo(1).source:sub(2):match("(.*/).*/.*/.*/") or "./" ··· 75 75 function data:trim_size() 76 76 if self:count() > max_entries then 77 77 -- remove the oldest entry 78 - local oldest_entry = db:with_open(function() 78 + local e = db:with_open(function() 79 + -- TODO: figure out what to do if all entries are pinned 79 80 return db:select("bank", { 80 81 where = { pinned = 0 }, 81 82 order_by = { asc = "rowid" }, 82 - limit = { 1 }, 83 + limit = 1, 83 84 })[1] 84 85 end) 85 86 86 - if oldest_entry then 87 + if e then 87 88 db:with_open(function() 88 89 db:eval( 89 90 "DELETE FROM bank WHERE yank_text = :yank_text", 90 - { yank_text = oldest_entry.yank_text } 91 + { yank_text = e.yank_text } 91 92 ) 92 93 end) 93 94 end ··· 95 96 end 96 97 97 98 --- get sqlite bank contents 98 - ---@return table yanks, table reg_types 99 + ---@return table yanks, table reg_types, table pins 99 100 function data:get_bank() 100 - local yanks, reg_types = {}, {} 101 + local yanks, reg_types, pins = {}, {}, {} 101 102 102 103 local bank = self:get() 103 104 for _, entry in ipairs(bank) do 104 105 table.insert(yanks, 1, entry.yank_text) 105 106 table.insert(reg_types, 1, entry.reg_type) 107 + table.insert(pins, 1, entry.pinned) 106 108 end 107 109 108 - return yanks, reg_types 110 + return yanks, reg_types, pins 109 111 end 110 112 111 113 --- remove an entry from the banks table matching input text ··· 143 145 function data.unpin(text, reg_type) 144 146 return db:with_open(function() 145 147 -- TODO: always returns true or nothing 148 + -- - figure out how to return if updated or remove return 146 149 return db:eval( 147 150 "UPDATE bank SET pinned = 0 WHERE yank_text = :yank_text and reg_type = :reg_type", 148 151 { yank_text = text, reg_type = reg_type }
+16
lua/yankbank/utils.lua
··· 1 + local M = {} 2 + 3 + --- DOC: 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