Skip to content

feat(storage) optional persistant history #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,33 @@ That's it!

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

Hold on, `neoclip` optionally also supports persistent history between sessions powered by [`sqlite.lua`](https://github.com/tami5/sqlite.lua).

![neoclip](https://user-images.githubusercontent.com/23341710/129557093-7724e7eb-7427-4c53-aa98-55e624843589.png)


## Installation
```lua
use {
"AckslD/nvim-neoclip.lua",
config = function()
require('neoclip').setup()
end,
"AckslD/nvim-neoclip.lua",
config = function()
require('neoclip').setup()
end,
}
```
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.

If you want to use persistent history between sessions you also need [`sqlite.lua`](https://github.com/tami5/sqlite.lua) installed, for example by:
```lua
use {
"AckslD/nvim-neoclip.lua",
requires = {'tami5/sqlite.lua', module = 'sqlite'},
config = function()
require('neoclip').setup()
end,
}
```

## Configuration
You can configure `neoclip` by passing a table to `setup` (all are optional).
The following are the defaults and the keys are explained below:
Expand All @@ -48,6 +61,8 @@ use {
config = function()
require('neoclip').setup({
history = 1000,
enable_persistant_history = false,
db_path = vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3",
filter = nil,
preview = true,
default_register = '"',
Expand All @@ -72,6 +87,9 @@ use {
}
```
* `history`: The max number of entries to store (default 1000).
* `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.
* `db_path`: The path to the sqlite database to store history if `enable_persistant_history=true`.
Defaults to `vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3` which on my system is `~/.local/share/nvim/databases/neoclip.sqlite3`
* `filter`: A function to filter what entries to store (default all are stored).
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:
* `event`: The event from `TextYankPost` (see `:help TextYankPost` for which keys it contains).
Expand Down
5 changes: 5 additions & 0 deletions lua/neoclip.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local function setup_auto_command()
augroup neoclip
autocmd!
autocmd TextYankPost * :lua require("neoclip.handlers").handle_yank_post()
autocmd VimLeavePre * :lua require("neoclip.handlers").on_exit()
augroup end
]])
end
Expand All @@ -25,6 +26,10 @@ M.toggle = function()
M.stopped = not M.stopped
end

M.clear_history = function()
require('neoclip.storage').clear()
end

M.setup = function(opts)
settings.setup(opts)
setup_auto_command()
Expand Down
68 changes: 68 additions & 0 deletions lua/neoclip/db.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
local settings = require('neoclip.settings').get()

local M = {}

local has_sqlite, sqlite = pcall(require, "sqlite")
if not has_sqlite then
print "Couldn't find sqlite.lua. Cannot use persistent history"
return nil
end

local function dirname(str)
return string.match(str, '(.*[/\\])')
end

local function make_db_dir(db_path)
os.execute('mkdir -p ' .. dirname(db_path))
end

local function get_tbl()
local db_path = settings.db_path
make_db_dir(db_path)
local db = sqlite.new(db_path)
db:open()
local tbl = db:tbl("neoclip", {
regtype = "text",
contents = "luatable",
filetype = "text",
})

return tbl
end

M.tbl = get_tbl()

local function copy(t)
local new = {}
for k, v in pairs(t) do
if type(v) == 'table' then
new[k] = copy(v)
else
new[k] = v
end
end
return new
end

M.get = function(query)
local success, entries = pcall(M.tbl.get, M.tbl, query)
if success then
return entries
else
print("Couldn't load history since:", entries)
return {}
end
end

M.update = function(storage)
local success, msg = pcall(M.tbl.remove, M.tbl)
if not success then
print("Couldn't remove clear database since:", msg)
end
success, msg = pcall(M.tbl.insert, M.tbl, storage)
if not success then
print("Couldn't insert in database since:", msg)
end
end

return M
4 changes: 4 additions & 0 deletions lua/neoclip/handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ M.handle_yank_post = function()
end
end

M.on_exit = function()
storage.on_exit()
end

M.set_register = function(register_name, entry)
vim.fn.setreg(register_name, entry.contents, entry.regtype)
end
Expand Down
2 changes: 2 additions & 0 deletions lua/neoclip/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ local M = {}

local settings = {
history = 1000,
enable_persistant_history = false,
db_path = vim.fn.stdpath("data") .. "/databases/neoclip.sqlite3",
filter = nil,
preview = true,
default_register = '"',
Expand Down
17 changes: 16 additions & 1 deletion lua/neoclip/storage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,31 @@ local M = {}
local settings = require('neoclip.settings').get()

local storage = {}
if settings.enable_persistant_history then
storage = require('neoclip.db').get()
end

M.get = function()
return storage
end

M.insert = function(contents)
if #storage >= settings.history then
while #storage >= settings.history do
table.remove(storage, #storage)
end
table.insert(storage, 1, contents)
end

M.clear = function()
while #storage > 0 do
table.remove(storage, 1)
end
end

M.on_exit = function()
if settings.enable_persistant_history then
require('neoclip.db').update(storage)
end
end

return M