Skip to content

Commit d324508

Browse files
authored
feat(buffer): add configurable sync/async buffer size thresholds (#1795)
Add `max_sync_buffer_size` and `max_async_buffer_size` options for controlling processing mode. Also refactor buffer source initialization to use unified option table with basic validation. Related #1789
1 parent c2bac7f commit d324508

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

doc/configuration/reference.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,10 @@ sources.providers = {
563563
end,
564564
-- buffers when searching with `/` or `?`
565565
get_search_bufnrs = function() return { vim.api.nvim_get_current_buf() } end,
566+
-- Maximum total number of characters (across all selected buffers) for which buffer completion runs synchronously. Above this, asynchronous processing is used.
567+
max_sync_buffer_size = 20000
568+
-- Maximum total number of characters (across all selected buffers) for which buffer completion runs asynchronously. Above this, buffer completions are skipped to avoid performance issues.
569+
max_async_buffer_size = 500000
566570
}
567571
},
568572

lua/blink/cmp/sources/buffer.lua

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,24 +113,37 @@ end
113113
--- @class blink.cmp.BufferOpts
114114
--- @field get_bufnrs fun(): integer[]
115115
--- @field get_search_bufnrs fun(): integer[]
116+
--- @field max_sync_buffer_size integer Maximum buffer text size for sync processing
117+
--- @field max_async_buffer_size integer Maximum buffer text size for async processing
116118

117119
--- Public API
118120

119121
local buffer = {}
120122

121123
function buffer.new(opts)
122-
--- @cast opts blink.cmp.BufferOpts
123-
124124
local self = setmetatable({}, { __index = buffer })
125-
self.get_bufnrs = opts.get_bufnrs
126-
or function()
125+
126+
--- @type blink.cmp.BufferOpts
127+
opts = vim.tbl_deep_extend('keep', opts or {}, {
128+
get_bufnrs = function()
127129
return vim
128130
.iter(vim.api.nvim_list_wins())
129131
:map(function(win) return vim.api.nvim_win_get_buf(win) end)
130132
:filter(function(buf) return vim.bo[buf].buftype ~= 'nofile' end)
131133
:totable()
132-
end
133-
self.get_search_bufnrs = opts.get_search_bufnrs or function() return { vim.api.nvim_get_current_buf() } end
134+
end,
135+
get_search_bufnrs = function() return { vim.api.nvim_get_current_buf() } end,
136+
max_sync_buffer_size = 20000,
137+
max_async_buffer_size = 500000,
138+
})
139+
require('blink.cmp.config.utils').validate('sources.providers.buffer', {
140+
get_bufnrs = { opts.get_bufnrs, 'function' },
141+
get_search_bufnrs = { opts.get_search_bufnrs, 'function' },
142+
max_sync_buffer_size = { opts.max_sync_buffer_size, 'number' },
143+
max_async_buffer_size = { opts.max_async_buffer_size, 'number' },
144+
}, opts)
145+
146+
self.opts = opts
134147
return self
135148
end
136149

@@ -141,7 +154,7 @@ function buffer:get_completions(_, callback)
141154

142155
vim.schedule(function()
143156
local is_search = vim.tbl_contains({ '/', '?' }, vim.fn.getcmdtype())
144-
local get_bufnrs = is_search and self.get_search_bufnrs or self.get_bufnrs
157+
local get_bufnrs = is_search and self.opts.get_search_bufnrs or self.opts.get_bufnrs
145158
local bufnrs = require('blink.cmp.lib.utils').deduplicate(get_bufnrs())
146159

147160
local buf_texts = {}
@@ -151,10 +164,10 @@ function buffer:get_completions(_, callback)
151164
local buf_text = table.concat(buf_texts, '\n')
152165

153166
-- should take less than 2ms
154-
if #buf_text < 20000 then
167+
if #buf_text < self.opts.max_sync_buffer_size then
155168
run_sync(buf_text, transformed_callback)
156169
-- should take less than 10ms
157-
elseif #buf_text < 500000 then
170+
elseif #buf_text < self.opts.max_async_buffer_size then
158171
if fuzzy.implementation_type == 'rust' then
159172
return run_async_rust(buf_text, transformed_callback)
160173
else

0 commit comments

Comments
 (0)