Skip to content

Commit

Permalink
feat: add execute function for sources
Browse files Browse the repository at this point in the history
  • Loading branch information
Saghen committed Nov 21, 2024
1 parent 3ac471b commit 653b262
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 8 deletions.
12 changes: 10 additions & 2 deletions lua/blink/cmp/accept/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ local text_edits_lib = require('blink.cmp.accept.text-edits')
local brackets_lib = require('blink.cmp.accept.brackets')

--- Applies a completion item to the current buffer
--- @param ctx blink.cmp.Context
--- @param item blink.cmp.CompletionItem
local function accept(item)
local function accept(ctx, item)
local sources = require('blink.cmp.sources.lib')
require('blink.cmp.trigger.completion').hide()

-- let the source execute the item itself if it indicates it can
if sources.should_execute(item) then
sources.execute(ctx, item)
return
end

-- start the resolve immediately since text changes can invalidate the item
-- with some LSPs (i.e. rust-analyzer) causing them to return the item as-is
-- without i.e. auto-imports
require('blink.cmp.sources.lib')
sources
.resolve(item)
:map(function(resolved_item)
local all_text_edits =
Expand Down
12 changes: 7 additions & 5 deletions lua/blink/cmp/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,19 @@ cmp.accept = function()
end

cmp.select_and_accept = function()
if not cmp.windows.autocomplete.win:is_open() then return end
local autocomplete = require('blink.cmp.windows.autocomplete')
if not autocomplete.win:is_open() then return end

vim.schedule(function()
-- select an item if none is selected
if not cmp.windows.autocomplete.get_selected_item() then
if not autocomplete.get_selected_item() then
-- avoid running auto_insert since we're about to accept anyway
cmp.windows.autocomplete.select_next({ skip_auto_insert = true })
autocomplete.select_next({ skip_auto_insert = true })
end

local item = cmp.windows.autocomplete.get_selected_item()
if item ~= nil then require('blink.cmp.accept')(item) end
local ctx = autocomplete.context
local item = autocomplete.get_selected_item()
if item ~= nil and ctx ~= nil then require('blink.cmp.accept')(ctx, item) end
end)
return true
end
Expand Down
26 changes: 26 additions & 0 deletions lua/blink/cmp/sources/lib/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ local config = require('blink.cmp.config')
--- @field listen_on_completions fun(callback: fun(context: blink.cmp.Context, items: blink.cmp.CompletionItem[]))
--- @field apply_max_items_for_completions fun(context: blink.cmp.Context, items: blink.cmp.CompletionItem[]): blink.cmp.CompletionItem[]
--- @field resolve fun(item: blink.cmp.CompletionItem): blink.cmp.Task
--- @field should_execute fun(item: blink.cmp.CompletionItem): boolean
--- @field execute fun(context: blink.cmp.Context, item: blink.cmp.CompletionItem): blink.cmp.Task
--- @field get_signature_help_trigger_characters fun(): { trigger_characters: string[], retrigger_characters: string[] }
--- @field get_signature_help fun(context: blink.cmp.SignatureHelpContext, callback: fun(signature_help: lsp.SignatureHelp | nil)): (fun(): nil) | nil
--- @field cancel_signature_help fun()
Expand Down Expand Up @@ -167,6 +169,30 @@ function sources.resolve(item)
return item_source:resolve(item):catch(function(err) vim.print('failed to resolve item with error: ' .. err) end)
end

--- Execute ---

function sources.should_execute(item)
for _, source in pairs(sources.providers) do
if source.id == item.source_id then return source:should_execute(item) end
end
return false
end

function sources.execute(context, item)
local item_source = nil
for _, source in pairs(sources.providers) do
if source.id == item.source_id then
item_source = source
break
end
end
if item_source == nil then return async.task.new(function(resolve) resolve() end) end

return item_source
:execute(context, item)
:catch(function(err) vim.print('failed to execute item with error: ' .. err) end)
end

--- Signature help ---

function sources.get_signature_help_trigger_characters()
Expand Down
14 changes: 14 additions & 0 deletions lua/blink/cmp/sources/lib/provider/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
--- @field get_completions fun(self: blink.cmp.SourceProvider, context: blink.cmp.Context, enabled_sources: string[]): blink.cmp.Task
--- @field should_show_items fun(self: blink.cmp.SourceProvider, context: blink.cmp.Context, enabled_sources: string[], response: blink.cmp.CompletionResponse): boolean
--- @field resolve fun(self: blink.cmp.SourceProvider, item: blink.cmp.CompletionItem): blink.cmp.Task
--- @field should_execute fun(self: blink.cmp.SourceProvider, item: blink.cmp.CompletionItem): boolean
--- @field execute fun(self: blink.cmp.SourceProvider, context: blink.cmp.Context, item: blink.cmp.CompletionItem, callback: fun()): blink.cmp.Task
--- @field get_signature_help_trigger_characters fun(self: blink.cmp.SourceProvider): string[]
--- @field get_signature_help fun(self: blink.cmp.SourceProvider, context: blink.cmp.SignatureHelpContext): blink.cmp.Task
--- @field reload (fun(self: blink.cmp.SourceProvider): nil) | nil
Expand Down Expand Up @@ -134,6 +136,18 @@ function source:resolve(item)
return tasks[item]
end

--- Execute ---

function source:should_execute(item)
if self.module.should_execute == nil then return self.module.execute ~= nil end
return self.module:should_execute(item)
end

function source:execute(context, item)
if self.module.execute == nil then return async.task.new(function(resolve) resolve() end) end
return async.task.new(function(resolve) self.module:execute(context, item, resolve) end)
end

--- Signature help ---

function source:get_signature_help_trigger_characters()
Expand Down
4 changes: 4 additions & 0 deletions lua/blink/cmp/sources/lib/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
--- @field filter_completions? fun(self: blink.cmp.Source, response: blink.cmp.CompletionResponse): blink.cmp.CompletionItem[]
--- @field should_show_completions? fun(self: blink.cmp.Source, context: blink.cmp.Context, response: blink.cmp.CompletionResponse): boolean
--- @field resolve? fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem, callback: fun(resolved_item?: lsp.CompletionItem)): ((fun(): nil) | nil)
--- @field should_execute? fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem): boolean Optional function to check if the source should execute the specified item
--- @field execute? fun(self: blink.cmp.Source, context: blink.cmp.Context, item: blink.cmp.CompletionItem, callback: fun()): (fun(): nil) | nil
--- @field get_signature_help_trigger_characters? fun(self: blink.cmp.Source): string[]
--- @field get_signature_help? fun(self: blink.cmp.Source, context: blink.cmp.SignatureHelpContext, callback: fun(signature_help: lsp.SignatureHelp | nil)): (fun(): nil) | nil
--- @field reload? fun(self: blink.cmp.Source): nil
Expand All @@ -27,6 +29,8 @@
--- @field filter_completions? fun(self: blink.cmp.Source, response: blink.cmp.CompletionResponse): blink.cmp.CompletionItem[]
--- @field should_show_completions? fun(self: blink.cmp.Source, context: blink.cmp.Context, response: blink.cmp.CompletionResponse): boolean
--- @field resolve? fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem, callback: fun(resolved_item: lsp.CompletionItem | nil)): ((fun(): nil) | nil)
--- @field should_execute? fun(self: blink.cmp.Source, item: blink.cmp.CompletionItem): boolean
--- @field execute? fun(self: blink.cmp.Source, context: blink.cmp.Context, item: blink.cmp.CompletionItem, callback: fun()): (fun(): nil) | nil
--- @field get_signature_help_trigger_characters? fun(self: blink.cmp.Source): string[]
--- @field get_signature_help? fun(self: blink.cmp.Source, context: blink.cmp.SignatureHelpContext, callback: fun(signature_help: lsp.SignatureHelp | nil)): (fun(): nil) | nil
--- @field reload? fun(self: blink.cmp.Source): nil
5 changes: 4 additions & 1 deletion lua/blink/cmp/windows/autocomplete.lua
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ end
---------- Selection/Accept ----------

function autocomplete.accept()
local context = autocomplete.context
if context == nil then return end

local selected_item = autocomplete.get_selected_item()
if selected_item == nil then return end

Expand All @@ -202,7 +205,7 @@ function autocomplete.accept()
end

-- apply
require('blink.cmp.accept')(selected_item)
require('blink.cmp.accept')(context, selected_item)
return true
end

Expand Down

0 comments on commit 653b262

Please sign in to comment.