This commit is contained in:
Senghan Bright 2021-01-15 12:16:18 +01:00
parent 2c2b8b16c2
commit 6dd33341e7
5 changed files with 82 additions and 37 deletions

View File

@ -6,9 +6,10 @@ if not has_telescope then
end end
-- start the database client -- start the database client
print("start") -- print("start")
local db_client = require("telescope._extensions.frecency.db_client") local db_client = require("telescope._extensions.frecency.db_client")
vim.defer_fn(db_client.init, 100) -- TODO: this is a crappy attempt to lessen loadtime impact, use VimEnter? -- vim.defer_fn(db_client.init, 100) -- TODO: this is a crappy attempt to lessen loadtime impact, use VimEnter?
db_client.init() -- TODO: this is a crappy attempt to lessen loadtime impact, use VimEnter?
-- finder code -- finder code
@ -77,9 +78,15 @@ local frecency = function(opts)
}):find() }):find()
end end
local validate = function()
print("validate db")
db_client.validate()
end
return telescope.register_extension { return telescope.register_extension {
exports = { exports = {
frecency = frecency, frecency = frecency,
validate = validate,
}, },
} }

View File

@ -1,4 +1,5 @@
local sqlwrap = require("telescope._extensions.frecency.sql_wrapper") local sqlwrap = require("telescope._extensions.frecency.sql_wrapper")
local util = require("telescope._extensions.frecency.util")
local MAX_TIMESTAMPS = 10 local MAX_TIMESTAMPS = 10
@ -23,15 +24,10 @@ local function init()
-- setup autocommands -- setup autocommands
vim.api.nvim_command("augroup TelescopeFrecency") vim.api.nvim_command("augroup TelescopeFrecency")
vim.api.nvim_command("autocmd!") vim.api.nvim_command("autocmd!")
vim.api.nvim_command("autocmd BufEnter * lua require'telescope._extensions.frecency.db_client'.autocmd_handler(vim.fn.expand('<amatch>'))") vim.api.nvim_command("autocmd BufWinEnter,BufWritePost * lua require'telescope._extensions.frecency.db_client'.autocmd_handler(vim.fn.expand('<amatch>'))")
vim.api.nvim_command("augroup END") vim.api.nvim_command("augroup END")
end end
-- TODO: move these to util.lua
local function string_isempty(s)
return s == nil or s == ''
end
local function calculate_file_score(frequency, timestamps) local function calculate_file_score(frequency, timestamps)
local recency_score = 0 local recency_score = 0
for _, ts in pairs(timestamps) do for _, ts in pairs(timestamps) do
@ -83,17 +79,38 @@ local function get_file_scores()
end end
local function autocmd_handler(filepath) local function autocmd_handler(filepath)
if not sql_wrapper or string_isempty(filepath) then return end if not sql_wrapper or util.string_isempty(filepath) then return end
-- check if file is registered as loaded -- check if file is registered as loaded
if not vim.b.frecency_registered then if not vim.b.frecency_registered then
-- allow noname files to go unregistered until BufWritePost
if not util.fs_stat(filepath).exists then return end
-- TODO: only register buffer if update did something?
-- TODO: apply filetype_ignore here?
vim.b.frecency_registered = 1 vim.b.frecency_registered = 1
-- print("registered buffer")
sql_wrapper:update(filepath) sql_wrapper:update(filepath)
end end
end end
local function validate()
if not sql_wrapper then return {} end
local files = sql_wrapper:do_transaction('get_all_filepaths')
for _, entry in pairs(files) do
if not util.fs_stat(entry.path).exists then
-- remove entries from file and timestamp tables
print("removing entry: " .. entry.path .. "[" .. entry.id .."]")
sql_wrapper:do_transaction('file_delete_entry', { id = entry.id })
sql_wrapper:do_transaction('timestamp_delete_with_file_id', { file_id = entry.id })
end
end
end
return { return {
init = init, init = init,
get_file_scores = get_file_scores, get_file_scores = get_file_scores,
autocmd_handler = autocmd_handler, autocmd_handler = autocmd_handler,
validate = validate,
} }

View File

@ -1,20 +1,21 @@
local sorters = require "telescope.sorters" local sorters = require "telescope.sorters"
local util = require("telescope._extensions.frecency.util")
local my_sorters = {} local my_sorters = {}
local function split(s, delimiter) -- local function split(s, delimiter)
local result = {} -- local result = {}
for match in (s .. delimiter):gmatch("(.-)" .. delimiter) do -- for match in (s .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match) -- table.insert(result, match)
end -- end
return result -- return result
end -- end
local substr_highlighter = function(_, prompt, display) local substr_highlighter = function(_, prompt, display)
local highlights = {} local highlights = {}
display = display:lower() display = display:lower()
local search_terms = split(prompt, " ") local search_terms = util.split(prompt, " ")
local hl_start, hl_end local hl_start, hl_end
for _, word in pairs(search_terms) do for _, word in pairs(search_terms) do
@ -35,7 +36,7 @@ my_sorters.get_substr_matcher = function(opts)
substr.scoring_function = function(_, prompt, _, entry) substr.scoring_function = function(_, prompt, _, entry)
local display = entry.name:lower() local display = entry.name:lower()
local search_terms = split(prompt, " ") local search_terms = util.split(prompt, " ")
local matched local matched
for _, word in pairs(search_terms) do for _, word in pairs(search_terms) do
matched = display:find(word, 1, true) and 1 or -1 matched = display:find(word, 1, true) and 1 or -1

View File

@ -1,5 +1,5 @@
local util = require("telescope._extensions.frecency.util")
local vim = vim local vim = vim
local uv = vim.loop
local has_sql, sql = pcall(require, "sql") local has_sql, sql = pcall(require, "sql")
if not has_sql then if not has_sql then
@ -29,9 +29,11 @@ local schemas = {[[
local queries = { local queries = {
["file_add_entry"] = "INSERT INTO files (path, count) values(:path, 1);", ["file_add_entry"] = "INSERT INTO files (path, count) values(:path, 1);",
["file_update_counter"] = "UPDATE files SET count = count + 1 WHERE path = :path;", ["file_delete_entry"] = "DELETE FROM files WHERE id == :id;",
["file_update_counter"] = "UPDATE files SET count = count + 1 WHERE path == :path;",
["timestamp_add_entry"] = "INSERT INTO timestamps (file_id, timestamp) values(:file_id, julianday('now'));", ["timestamp_add_entry"] = "INSERT INTO timestamps (file_id, timestamp) values(:file_id, julianday('now'));",
["timestamp_delete_before_id"] = "DELETE FROM timestamps WHERE id < :id and file_id == :file_id;", ["timestamp_delete_before_id"] = "DELETE FROM timestamps WHERE id < :id and file_id == :file_id;",
["timestamp_delete_with_file_id"] = "DELETE FROM timestamps WHERE file_id == :file_id;",
["get_all_filepaths"] = "SELECT * FROM files;", ["get_all_filepaths"] = "SELECT * FROM files;",
["get_all_timestamp_ages"] = "SELECT id, file_id, CAST((julianday('now') - julianday(timestamp)) * 24 * 60 AS INTEGER) AS age FROM timestamps;", ["get_all_timestamp_ages"] = "SELECT id, file_id, CAST((julianday('now') - julianday(timestamp)) * 24 * 60 AS INTEGER) AS age FROM timestamps;",
["get_row"] = "SELECT * FROM files WHERE path == :path;", ["get_row"] = "SELECT * FROM files WHERE path == :path;",
@ -42,14 +44,6 @@ local queries = {
-- } -- }
-- --
local function fs_stat(path) -- TODO: move this to new file with M
local stat = uv.fs_stat(path)
local res = {}
res.exists = stat and true or false -- TODO: this is silly
res.isdirectory = (stat and stat.type == "directory") and true or false
return res
end
local M = {} local M = {}
M.queries = queries M.queries = queries
@ -108,7 +102,7 @@ function M:get_row_id(filepath)
end end
function M:update(filepath) function M:update(filepath)
local filestat = fs_stat(filepath) local filestat = util.fs_stat(filepath)
if (vim.tbl_isempty(filestat) or if (vim.tbl_isempty(filestat) or
filestat.exists == false or filestat.exists == false or
filestat.isdirectory == true) then filestat.isdirectory == true) then

View File

@ -0,0 +1,26 @@
local uv = vim.loop
local util = {}
util.string_isempty = function(s)
return s == nil or s == ''
end
util.split = function(s, delimiter)
local result = {}
for match in (s .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match)
end
return result
end
util.fs_stat = function(path) -- TODO: move this to new file with M
local stat = uv.fs_stat(path)
local res = {}
res.exists = stat and true or false -- TODO: this is silly
res.isdirectory = (stat and stat.type == "directory") and true or false
return res
end
return util