Skip to content

Commit 56d2793

Browse files
authored
Merge pull request #20 from AckslD/16-persistant-history
feat(storage) optional persistant history
2 parents 4a5ef1a + 8f00994 commit 56d2793

File tree

6 files changed

+117
-5
lines changed

6 files changed

+117
-5
lines changed

README.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,33 @@ That's it!
2525

2626
Oh, one more thing, you can define an optional filter if you don't want some things to be saved.
2727

28+
Hold on, `neoclip` optionally also supports persistent history between sessions powered by [`sqlite.lua`](https://github.com/tami5/sqlite.lua).
29+
2830
![neoclip](https://user-images.githubusercontent.com/23341710/129557093-7724e7eb-7427-4c53-aa98-55e624843589.png)
2931

3032

3133
## Installation
3234
```lua
3335
use {
34-
"AckslD/nvim-neoclip.lua",
35-
config = function()
36-
require('neoclip').setup()
37-
end,
36+
"AckslD/nvim-neoclip.lua",
37+
config = function()
38+
require('neoclip').setup()
39+
end,
3840
}
3941
```
4042
When `require('neoclip').setup()` is called, only the autocommand (for `TextYankPost` event) is setup to save yanked things. This means that `telescope` is not required at this point if you lazy load it.
4143

44+
If you want to use persistent history between sessions you also need [`sqlite.lua`](https://github.com/tami5/sqlite.lua) installed, for example by:
45+
```lua
46+
use {
47+
"AckslD/nvim-neoclip.lua",
48+
requires = {'tami5/sqlite.lua', module = 'sqlite'},
49+
config = function()
50+
require('neoclip').setup()
51+
end,
52+
}
53+
```
54+
4255
## Configuration
4356
You can configure `neoclip` by passing a table to `setup` (all are optional).
4457
The following are the defaults and the keys are explained below:
@@ -48,6 +61,8 @@ use {
4861
config = function()
4962
require('neoclip').setup({
5063
history = 1000,
64+
enable_persistant_history = false,
65+
db_path = vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3",
5166
filter = nil,
5267
preview = true,
5368
default_register = '"',
@@ -72,6 +87,9 @@ use {
7287
}
7388
```
7489
* `history`: The max number of entries to store (default 1000).
90+
* `enable_persistant_history`: If set to `true` the history is stored on `VimLeavePre` using [`sqlite.lua`](https://github.com/tami5/sqlite.lua) and lazy loaded when querying.
91+
* `db_path`: The path to the sqlite database to store history if `enable_persistant_history=true`.
92+
Defaults to `vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3` which on my system is `~/.local/share/nvim/databases/neoclip.sqlite3`
7593
* `filter`: A function to filter what entries to store (default all are stored).
7694
This function filter should return `true` (include the yanked entry) or `false` (don't include it) based on a table as the only argument, which has the following keys:
7795
* `event`: The event from `TextYankPost` (see `:help TextYankPost` for which keys it contains).

lua/neoclip.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ local function setup_auto_command()
99
augroup neoclip
1010
autocmd!
1111
autocmd TextYankPost * :lua require("neoclip.handlers").handle_yank_post()
12+
autocmd VimLeavePre * :lua require("neoclip.handlers").on_exit()
1213
augroup end
1314
]])
1415
end
@@ -25,6 +26,10 @@ M.toggle = function()
2526
M.stopped = not M.stopped
2627
end
2728

29+
M.clear_history = function()
30+
require('neoclip.storage').clear()
31+
end
32+
2833
M.setup = function(opts)
2934
settings.setup(opts)
3035
setup_auto_command()

lua/neoclip/db.lua

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
local settings = require('neoclip.settings').get()
2+
3+
local M = {}
4+
5+
local has_sqlite, sqlite = pcall(require, "sqlite")
6+
if not has_sqlite then
7+
print "Couldn't find sqlite.lua. Cannot use persistent history"
8+
return nil
9+
end
10+
11+
local function dirname(str)
12+
return string.match(str, '(.*[/\\])')
13+
end
14+
15+
local function make_db_dir(db_path)
16+
os.execute('mkdir -p ' .. dirname(db_path))
17+
end
18+
19+
local function get_tbl()
20+
local db_path = settings.db_path
21+
make_db_dir(db_path)
22+
local db = sqlite.new(db_path)
23+
db:open()
24+
local tbl = db:tbl("neoclip", {
25+
regtype = "text",
26+
contents = "luatable",
27+
filetype = "text",
28+
})
29+
30+
return tbl
31+
end
32+
33+
M.tbl = get_tbl()
34+
35+
local function copy(t)
36+
local new = {}
37+
for k, v in pairs(t) do
38+
if type(v) == 'table' then
39+
new[k] = copy(v)
40+
else
41+
new[k] = v
42+
end
43+
end
44+
return new
45+
end
46+
47+
M.get = function(query)
48+
local success, entries = pcall(M.tbl.get, M.tbl, query)
49+
if success then
50+
return entries
51+
else
52+
print("Couldn't load history since:", entries)
53+
return {}
54+
end
55+
end
56+
57+
M.update = function(storage)
58+
local success, msg = pcall(M.tbl.remove, M.tbl)
59+
if not success then
60+
print("Couldn't remove clear database since:", msg)
61+
end
62+
success, msg = pcall(M.tbl.insert, M.tbl, storage)
63+
if not success then
64+
print("Couldn't insert in database since:", msg)
65+
end
66+
end
67+
68+
return M

lua/neoclip/handlers.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ M.handle_yank_post = function()
4141
end
4242
end
4343

44+
M.on_exit = function()
45+
storage.on_exit()
46+
end
47+
4448
M.set_register = function(register_name, entry)
4549
vim.fn.setreg(register_name, entry.contents, entry.regtype)
4650
end

lua/neoclip/settings.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ local M = {}
22

33
local settings = {
44
history = 1000,
5+
enable_persistant_history = false,
6+
db_path = vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3",
57
filter = nil,
68
preview = true,
79
default_register = '"',

lua/neoclip/storage.lua

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,31 @@ local M = {}
33
local settings = require('neoclip.settings').get()
44

55
local storage = {}
6+
if settings.enable_persistant_history then
7+
storage = require('neoclip.db').get()
8+
end
69

710
M.get = function()
811
return storage
912
end
1013

1114
M.insert = function(contents)
12-
if #storage >= settings.history then
15+
while #storage >= settings.history do
1316
table.remove(storage, #storage)
1417
end
1518
table.insert(storage, 1, contents)
1619
end
1720

21+
M.clear = function()
22+
while #storage > 0 do
23+
table.remove(storage, 1)
24+
end
25+
end
26+
27+
M.on_exit = function()
28+
if settings.enable_persistant_history then
29+
require('neoclip.db').update(storage)
30+
end
31+
end
32+
1833
return M

0 commit comments

Comments
 (0)