From bf76a01482f6a3f7e019d0050df73ccf8ad93cf6 Mon Sep 17 00:00:00 2001 From: Liam Dyer Date: Tue, 23 Jul 2024 15:11:44 -0400 Subject: [PATCH] feat: .local/state db location and misc --- lua/blink/cmp/accept.lua | 2 +- lua/blink/cmp/fuzzy/init.lua | 70 ++++++++++++++++--------- lua/blink/cmp/fuzzy/lib.lua | 17 +++++- lua/blink/cmp/fuzzy/src/lib.rs | 21 ++++++-- lua/blink/cmp/init.lua | 6 +-- lua/blink/cmp/sources/buffer.lua | 4 +- lua/blink/cmp/sources/init.lua | 8 +-- lua/blink/cmp/windows/documentation.lua | 8 +-- lua/blink/cmp/windows/lib.lua | 2 + 9 files changed, 93 insertions(+), 45 deletions(-) diff --git a/lua/blink/cmp/accept.lua b/lua/blink/cmp/accept.lua index d75a26a6..1a75c0c4 100644 --- a/lua/blink/cmp/accept.lua +++ b/lua/blink/cmp/accept.lua @@ -2,7 +2,7 @@ local utils = {} local function accept(item) local sources = require('blink.cmp.sources') - local fuzzy = require('blink.cmp.fuzzy') + local fuzzy = require('blink.cmp.fuzzy.lib') local text_edit = item.textEdit if text_edit ~= nil then diff --git a/lua/blink/cmp/fuzzy/init.lua b/lua/blink/cmp/fuzzy/init.lua index d8fd7b58..1c06281f 100644 --- a/lua/blink/cmp/fuzzy/init.lua +++ b/lua/blink/cmp/fuzzy/init.lua @@ -6,6 +6,13 @@ + + +typedef struct { + const int32_t *ptr; + size_t len; + size_t capacity; +} blink_fuzzy__Vec_int32_t; typedef struct { const uint32_t *ptr; size_t len; @@ -16,13 +23,11 @@ typedef struct { size_t len; size_t capacity; } blink_fuzzy__Vec___string_ptr; - - -typedef struct { - const int32_t *ptr; - size_t len; - size_t capacity; -} blink_fuzzy__Vec_int32_t; +int32_t init_db( + const char *, + int8_t*); +int32_t __gc_init_db( + int8_t); int32_t fuzzy( const char *, const blink_fuzzy__Vec___string_ptr*, @@ -51,28 +56,11 @@ int32_t __gc_get_lines_words( -local __const_c_typename___string_ptr = ffi.typeof("const char *[?]") -local __c_function_argument___string_ptr = ffi.typeof("const char *[?]") -local __c_mut_function_argument___string_ptr = ffi.typeof("char *[?]") - - local __const_c_typename_uint32_t = ffi.typeof("const uint32_t[?]") local __c_function_argument_uint32_t = ffi.typeof("uint32_t[?]") local __c_mut_function_argument_uint32_t = ffi.typeof("uint32_t[?]") -local __typename_Vec_uint32_t = ffi.metatype("blink_fuzzy__Vec_uint32_t", {}) -local __const_c_typename_Vec_uint32_t = ffi.typeof("const blink_fuzzy__Vec_uint32_t[?]") -local __c_function_argument_Vec_uint32_t = ffi.typeof("const blink_fuzzy__Vec_uint32_t*[?]") -local __c_mut_function_argument_Vec_uint32_t = ffi.typeof("blink_fuzzy__Vec_uint32_t*[?]") - - -local __typename_Vec___string_ptr = ffi.metatype("blink_fuzzy__Vec___string_ptr", {}) -local __const_c_typename_Vec___string_ptr = ffi.typeof("const blink_fuzzy__Vec___string_ptr[?]") -local __c_function_argument_Vec___string_ptr = ffi.typeof("const blink_fuzzy__Vec___string_ptr*[?]") -local __c_mut_function_argument_Vec___string_ptr = ffi.typeof("blink_fuzzy__Vec___string_ptr*[?]") - - local __const_c_typename_bool = ffi.typeof("const int8_t[?]") local __c_function_argument_bool = ffi.typeof("int8_t[?]") local __c_mut_function_argument_bool = ffi.typeof("int8_t[?]") @@ -83,11 +71,45 @@ local __c_function_argument_int32_t = ffi.typeof("int32_t[?]") local __c_mut_function_argument_int32_t = ffi.typeof("int32_t[?]") +local __const_c_typename___string_ptr = ffi.typeof("const char *[?]") +local __c_function_argument___string_ptr = ffi.typeof("const char *[?]") +local __c_mut_function_argument___string_ptr = ffi.typeof("char *[?]") + + local __typename_Vec_int32_t = ffi.metatype("blink_fuzzy__Vec_int32_t", {}) local __const_c_typename_Vec_int32_t = ffi.typeof("const blink_fuzzy__Vec_int32_t[?]") local __c_function_argument_Vec_int32_t = ffi.typeof("const blink_fuzzy__Vec_int32_t*[?]") local __c_mut_function_argument_Vec_int32_t = ffi.typeof("blink_fuzzy__Vec_int32_t*[?]") + +local __typename_Vec_uint32_t = ffi.metatype("blink_fuzzy__Vec_uint32_t", {}) +local __const_c_typename_Vec_uint32_t = ffi.typeof("const blink_fuzzy__Vec_uint32_t[?]") +local __c_function_argument_Vec_uint32_t = ffi.typeof("const blink_fuzzy__Vec_uint32_t*[?]") +local __c_mut_function_argument_Vec_uint32_t = ffi.typeof("blink_fuzzy__Vec_uint32_t*[?]") + + +local __typename_Vec___string_ptr = ffi.metatype("blink_fuzzy__Vec___string_ptr", {}) +local __const_c_typename_Vec___string_ptr = ffi.typeof("const blink_fuzzy__Vec___string_ptr[?]") +local __c_function_argument_Vec___string_ptr = ffi.typeof("const blink_fuzzy__Vec___string_ptr*[?]") +local __c_mut_function_argument_Vec___string_ptr = ffi.typeof("blink_fuzzy__Vec___string_ptr*[?]") + +function M.init_db( + db_path) + local __typeof = __c_mut_function_argument_bool + local __ret_ptr = __typeof(1, {}) + local status = rust.init_db( + (function(value) return value end)(db_path), + __ret_ptr + ) + if status ~= 0 then + error("init_db failed with status "..status) + end + local __ret = __ret_ptr[0] + + local f = function(value) return value ~= 0 end + return f(__ret) +end + function M.fuzzy( needle, haystack, diff --git a/lua/blink/cmp/fuzzy/lib.lua b/lua/blink/cmp/fuzzy/lib.lua index 36c3bde8..fa9ab0b7 100644 --- a/lua/blink/cmp/fuzzy/lib.lua +++ b/lua/blink/cmp/fuzzy/lib.lua @@ -2,7 +2,20 @@ local fuzzy = { rust = require('blink.cmp.fuzzy'), } -fuzzy.filter_items = function(needle, items) +function fuzzy.init_db(db_path) + fuzzy.rust.init_db(db_path) + return fuzzy +end + +function fuzzy.fuzzy(needle, haystack, haystack_score_offsets, nearby_words, max_items) + return fuzzy.rust.fuzzy(needle, haystack, haystack_score_offsets, nearby_words, max_items) +end + +function fuzzy.access(item) fuzzy.rust.access(item) end + +function fuzzy.get_lines_words(lines) return fuzzy.rust.get_lines_words(lines) end + +function fuzzy.filter_items(needle, items) -- convert to table of strings local haystack = {} local haystack_score_offsets = {} @@ -28,7 +41,7 @@ fuzzy.filter_items = function(needle, items) return filtered_items end -fuzzy.get_query = function() +function fuzzy.get_query() local bufnr = vim.api.nvim_get_current_buf() local current_line = vim.api.nvim_win_get_cursor(0)[1] - 1 local current_col = vim.api.nvim_win_get_cursor(0)[2] - 1 diff --git a/lua/blink/cmp/fuzzy/src/lib.rs b/lua/blink/cmp/fuzzy/src/lib.rs index a7454965..8cdbdfff 100644 --- a/lua/blink/cmp/fuzzy/src/lib.rs +++ b/lua/blink/cmp/fuzzy/src/lib.rs @@ -10,12 +10,11 @@ pub mod extern_ffi { use regex::Regex; use std::cmp::Reverse; use std::collections::HashSet; - use std::sync::{Arc, Mutex}; + use std::sync::RwLock; lazy_static! { static ref REGEX: Regex = Regex::new(r"[A-Za-z][A-Za-z0-9]{2,50}").unwrap(); - static ref FRECENCY_CWD: Arc> = - Arc::new(Mutex::new(FrecencyTracker::new("/home/saghen/frecency.db"))); + static ref FRECENCY: RwLock> = RwLock::new(None); } struct Item { @@ -23,6 +22,15 @@ pub mod extern_ffi { score: u32, } + pub fn init_db(db_path: String) -> bool { + let mut frecency = FRECENCY.write().unwrap(); + if frecency.is_some() { + return false; + } + *frecency = Some(FrecencyTracker::new(&db_path)); + true + } + pub fn fuzzy( needle: String, haystack: Vec, @@ -30,7 +38,9 @@ pub mod extern_ffi { nearby_words: Vec, max_items: u32, ) -> Vec { - let frecency = FRECENCY_CWD.lock().unwrap(); + let frecency_handle = FRECENCY.read().unwrap(); + let frecency = frecency_handle.as_ref().unwrap(); + let nearby_words = nearby_words .iter() .map(|s| s.as_str()) @@ -63,7 +73,8 @@ pub mod extern_ffi { } pub fn access(item: String) -> bool { - let mut frecency = FRECENCY_CWD.lock().unwrap(); + let mut frecency_handle = FRECENCY.write().unwrap(); + let mut frecency = frecency_handle.as_mut().unwrap(); frecency.access(item.as_str()).unwrap(); true } diff --git a/lua/blink/cmp/init.lua b/lua/blink/cmp/init.lua index ccac273c..34d0ce34 100644 --- a/lua/blink/cmp/init.lua +++ b/lua/blink/cmp/init.lua @@ -22,19 +22,19 @@ m.setup = function(opts) -- fuzzy combines smith waterman with frecency -- and bonus from proximity words but I'm still working -- on tuning the weights - m.fuzzy = require('blink.cmp.fuzzy.lib') + m.fuzzy = require('blink.cmp.fuzzy.lib').init_db(vim.fn.stdpath('data') .. '/blink/cmp/fuzzy.db') m.trigger.listen_on_show(function(context) m.sources.completions(context) end) m.trigger.listen_on_hide(function() m.sources.cancel_completions() m.windows.autocomplete.close() end) - m.sources.listen_on_completions(function(items) + m.sources.listen_on_completions(function(context, items) -- avoid adding 1-4ms to insertion latency by scheduling for later vim.schedule(function() local filtered_items = m.fuzzy.filter_items(utils.get_query(), items) if #filtered_items > 0 then - m.windows.autocomplete.open_with_items(filtered_items) + m.windows.autocomplete.open_with_items(context, filtered_items) else m.windows.autocomplete.close() end diff --git a/lua/blink/cmp/sources/buffer.lua b/lua/blink/cmp/sources/buffer.lua index f71d6e80..fb88f592 100644 --- a/lua/blink/cmp/sources/buffer.lua +++ b/lua/blink/cmp/sources/buffer.lua @@ -47,12 +47,12 @@ local function words_to_items(words) end local function run_sync(buf_text, callback) - callback(words_to_items(require('blink.cmp.fuzzy').get_lines_words(buf_text))) + callback(words_to_items(require('blink.cmp.fuzzy.lib').get_lines_words(buf_text))) end local function run_async(buf_text, callback) local worker = uv.new_work( - function(items) return table.concat(require('blink.cmp.fuzzy').get_lines_words(items), '\n') end, + function(items) return table.concat(require('blink.cmp.fuzzy.lib').get_lines_words(items), '\n') end, function(words) local items = words_to_items(vim.split(words, '\n')) vim.schedule(function() callback(items) end) diff --git a/lua/blink/cmp/sources/init.lua b/lua/blink/cmp/sources/init.lua index 1b414aad..ee437c2b 100644 --- a/lua/blink/cmp/sources/init.lua +++ b/lua/blink/cmp/sources/init.lua @@ -81,7 +81,7 @@ function sources.completions(context) sources.in_flight_id[source_name] = -1 sources.add_source_completions(source_name, items, cursor_column) - if not sources.some_in_flight() then sources.send_completions() end + if not sources.some_in_flight() then sources.send_completions(context) end end) end) end @@ -89,7 +89,7 @@ function sources.completions(context) -- no completions will be in flight if none of them ran, -- so we send the completions - if not sources.some_in_flight() then sources.send_completions() end + if not sources.some_in_flight() then sources.send_completions(context) end end function sources.add_source_completions(source_name, source_items, cursor_column) @@ -108,7 +108,7 @@ function sources.some_in_flight() return false end -function sources.send_completions() +function sources.send_completions(context) local sources_items = sources.sources_items -- apply source filters for _, source in pairs(sources.registered) do @@ -121,7 +121,7 @@ function sources.send_completions() vim.list_extend(flattened_items, response.items) end - sources.on_completions_callback(flattened_items) + sources.on_completions_callback(context, flattened_items) end function sources.cancel_completions() diff --git a/lua/blink/cmp/windows/documentation.lua b/lua/blink/cmp/windows/documentation.lua index 35115939..77606077 100644 --- a/lua/blink/cmp/windows/documentation.lua +++ b/lua/blink/cmp/windows/documentation.lua @@ -31,20 +31,20 @@ function docs.show_item(item) end sources.resolve(item, function(resolved_item) - if resolved_item.documentation == nil then + item = resolved_item or item + if item.documentation == nil then docs.win:close() return end - -- todo: respect .kind (MarkupKind) which is markdown or plaintext local doc_lines = {} - for s in resolved_item.documentation.value:gmatch('[^\r\n]+') do + for s in item.documentation.value:gmatch('[^\r\n]+') do table.insert(doc_lines, s) end vim.api.nvim_buf_set_lines(docs.win:get_buf(), 0, -1, true, doc_lines) vim.api.nvim_set_option_value('modified', false, { buf = docs.win:get_buf() }) - local filetype = resolved_item.documentation.kind == 'markdown' and 'markdown' or 'plaintext' + local filetype = item.documentation.kind == 'markdown' and 'markdown' or 'plaintext' if filetype ~= vim.api.nvim_get_option_value('filetype', { buf = docs.win:get_buf() }) then vim.api.nvim_set_option_value('filetype', filetype, { buf = docs.win:get_buf() }) end diff --git a/lua/blink/cmp/windows/lib.lua b/lua/blink/cmp/windows/lib.lua index a229567d..ae061f29 100644 --- a/lua/blink/cmp/windows/lib.lua +++ b/lua/blink/cmp/windows/lib.lua @@ -82,6 +82,8 @@ function win:update_position(relative_to, offset) local cursor_col = cursor[2] -- set width to current content width, bounded by min and max + -- todo: should be determined based on the items since we format the items to the current width + -- so the get_content_width() will always be the window width local width = math.max(math.min(self:get_content_width(), config.max_width), config.min_width) vim.api.nvim_win_set_width(winnr, width)