Skip to content
Open
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
3 changes: 3 additions & 0 deletions lua/blink/cmp/config/fuzzy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
--- @field use_frecency boolean Tracks the most recently/frequently used items and boosts the score of the item. Note, this does not apply when using the Lua implementation.
--- @field use_proximity boolean Boosts the score of items matching nearby words. Note, this does not apply when using the Lua implementation.
--- @field use_unsafe_no_lock boolean UNSAFE!! When enabled, disables the lock and fsync when writing to the frecency database. This should only be used on unsupported platforms (i.e. alpine termux). Note, this does not apply when using the Lua implementation.
--- @field custom_regex? string Override the default regex with a custom pattern for word matching.
--- @field sorts blink.cmp.Sort[] Controls which sorts to use and in which order.
--- @field prebuilt_binaries blink.cmp.PrebuiltBinariesConfig

Expand Down Expand Up @@ -37,6 +38,7 @@ local fuzzy = {
use_frecency = true,
use_proximity = true,
use_unsafe_no_lock = false,
custom_regex = nil,
sorts = { 'score', 'sort_text' },
prebuilt_binaries = {
download = true,
Expand Down Expand Up @@ -65,6 +67,7 @@ function fuzzy.validate(config)
use_frecency = { config.use_frecency, 'boolean' },
use_proximity = { config.use_proximity, 'boolean' },
use_unsafe_no_lock = { config.use_unsafe_no_lock, 'boolean' },
custom_regex = { config.custom_regex, { 'string', 'nil' } },
sorts = {
config.sorts,
function(sorts)
Expand Down
6 changes: 5 additions & 1 deletion lua/blink/cmp/fuzzy/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ end
function fuzzy.init_db()
if fuzzy.has_init_db then return end

fuzzy.implementation.init_db(vim.fn.stdpath('data') .. '/blink/cmp/fuzzy.db', config.use_unsafe_no_lock)
fuzzy.implementation.init_db(
vim.fn.stdpath('data') .. '/blink/cmp/fuzzy.db',
config.use_unsafe_no_lock,
config.fuzzy.custom_regex
)

vim.api.nvim_create_autocmd('VimLeavePre', {
callback = fuzzy.implementation.destroy_db,
Expand Down
14 changes: 9 additions & 5 deletions lua/blink/cmp/fuzzy/lua/init.lua
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
local config_fuzzy = require('blink.cmp.config').fuzzy
local match = require('blink.cmp.fuzzy.lua.match')
local match_indices = require('blink.cmp.fuzzy.lua.match_indices')
local get_keyword_range = require('blink.cmp.fuzzy.lua.keyword').get_keyword_range
local guess_keyword_range = require('blink.cmp.fuzzy.lua.keyword').guess_keyword_range

local words_regex = vim.regex(
[[\%(-\?\d\+\%(\.\d\+\)\?\|\h\%(\w\|á\|Á\|é\|É\|í\|Í\|ó\|Ó\|ú\|Ú\)*\%(-\%(\w\|á\|Á\|é\|É\|í\|Í\|ó\|Ó\|ú\|Ú\)*\)*\)]]
)
--- @type blink.cmp.FuzzyImplementation
--- @diagnostic disable-next-line: missing-fields
local fuzzy = {
--- @type table<string, blink.cmp.CompletionItem[]>
provider_items = {},
}

function fuzzy.init_db() end
function fuzzy.init_db()
if config_fuzzy.custom_regex then words_regex = vim.regex(config_fuzzy.custom_regex) end
end

function fuzzy.destroy_db() end
function fuzzy.access() end

local words_regex = vim.regex(
[[\%(-\?\d\+\%(\.\d\+\)\?\|\h\%(\w\|á\|Á\|é\|É\|í\|Í\|ó\|Ó\|ú\|Ú\)*\%(-\%(\w\|á\|Á\|é\|É\|í\|Í\|ó\|Ó\|ú\|Ú\)*\)*\)]]
)
function fuzzy.access() end

--- Takes ~0.25ms for 1200 characters split over 40 lines
function fuzzy.get_words(text)
Expand Down
19 changes: 16 additions & 3 deletions lua/blink/cmp/fuzzy/rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@ mod keyword;
mod lsp_item;
mod sort;

static REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"[\p{L}_][\p{L}0-9_\\-]{2,}").unwrap());
static REGEX: LazyLock<RwLock<Regex>> =
LazyLock::new(|| RwLock::new(Regex::new(r"[\p{L}0-9_\\-]{2,}").unwrap()));
static FRECENCY: LazyLock<RwLock<Option<FrecencyTracker>>> = LazyLock::new(|| RwLock::new(None));
static HAYSTACKS_BY_PROVIDER: LazyLock<RwLock<HashMap<String, Vec<LspItem>>>> =
LazyLock::new(|| RwLock::new(HashMap::new()));

pub fn init_db(_: &Lua, (db_path, use_unsafe_no_lock): (String, bool)) -> LuaResult<bool> {
fn update_regex(new_pattern: &str) {
let mut regex = REGEX.write().unwrap();
*regex = Regex::new(new_pattern).unwrap();
}

pub fn init_db(
_: &Lua,
(db_path, use_unsafe_no_lock, custom_regex): (String, bool, Option<String>),
) -> LuaResult<bool> {
if let Some(regex) = custom_regex {
update_regex(&regex);
}
let mut frecency = FRECENCY.write().map_err(|_| Error::AcquireFrecencyLock)?;
if frecency.is_some() {
return Ok(false);
Expand Down Expand Up @@ -211,6 +222,8 @@ pub fn guess_edit_range(

pub fn get_words(_: &Lua, text: mlua::String) -> LuaResult<Vec<String>> {
Ok(REGEX
.read()
.unwrap()
.find_iter(&text.to_string_lossy())
.map(|m| m.as_str().to_string())
.filter(|s| s.len() < 512)
Expand Down
Loading