Skip to content

fix: fuzzy autocompletion with blink #1010

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
32 changes: 29 additions & 3 deletions lua/orgmode/org/autocompletion/blink.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,34 @@ end
function Source:get_completions(ctx, callback)
local line = ctx.line:sub(1, ctx.cursor[2])
local offset = org.completion:get_start({ line = line }) + 1
local base = string.sub(line, offset)
local full_base = string.sub(line, offset)

-- Create a simplified base that preserves completion context but avoids over-filtering
local simplified_base = full_base

-- For file links, keep only the protocol part to preserve context
if full_base:match('^file:') then
simplified_base = 'file:'
elseif full_base:match('^~/') then
simplified_base = '~/'
elseif full_base:match('^%./') then
simplified_base = './'
elseif full_base:match('^/') then
simplified_base = '/'
-- For other contexts, use a minimal base to get all results
elseif full_base:match('^%*') then
simplified_base = '*'
elseif full_base:match('^#%+') then
simplified_base = '#+'
elseif full_base:match('^:') then
simplified_base = ':'
end

-- Pass simplified base to orgmode sources to preserve context but get more results
local results = org.completion:complete({
line = line,
base = base,
base = simplified_base,
framework = 'blink', -- Still signal framework for any remaining filtering
})

local cb = function(items)
Expand Down Expand Up @@ -55,14 +79,16 @@ function Source:get_completions(ctx, callback)
return 0
end

local baseOffset = getInsertTextOffset(base)
-- Use full_base for insertText calculation
local baseOffset = getInsertTextOffset(full_base)
local insertTextOffset = baseOffset > 0 and math.max(2, baseOffset) or 0

local items = {}

for _, item in ipairs(results) do
table.insert(items, {
label = item.word,
filterText = item.word, -- Text to fuzzy match against
insertText = insertTextOffset > 0 and item.word:sub(insertTextOffset) or item.word,
labelDetails = item.menu and { description = item.menu } or nil,
})
Expand Down
7 changes: 6 additions & 1 deletion lua/orgmode/org/autocompletion/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,15 @@ end

function OrgCompletion:_get_valid_results(results, context)
local base = context.base or ''
local framework = context.framework or 'nvim-cmp'

local valid_results = {}
for _, item in ipairs(results) do
if base == '' or item:find('^' .. vim.pesc(base)) then
-- For blink.cmp, skip prefix filtering and return all results
-- Let blink.cmp's fuzzy matcher handle the filtering
local should_include = framework == 'blink' or base == '' or item:find('^' .. vim.pesc(base))

if should_include then
table.insert(valid_results, {
word = item,
menu = self.menu,
Expand Down
4 changes: 2 additions & 2 deletions tests/plenary/org/autocompletion_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,8 @@ describe('Blink completion', function()

assert(directive_item, 'Should find a directive completion item')
assert(
directive_item.insertText:match('^#%+'),
string.format("insertText should start with '+#', got: %s", directive_item.insertText)
directive_item.insertText and directive_item.insertText:match('^#%+'),
string.format("completion text should start with '#+', got: %s", directive_item.insertText or 'nil')
)

assert(line:sub(1, 4) == '#+fi', "Original line should contain '#+fi'")
Expand Down