1
1
local async = require (' blink.cmp.sources.lib.async' )
2
2
local config = require (' blink.cmp.config' )
3
+
4
+ --- @class blink.cmp.Sources
5
+ --- @field current_context blink.cmp.SourcesContext | nil
6
+ --- @field current_signature_help blink.cmp.Task | nil
7
+ --- @field sources_registered boolean
8
+ --- @field providers table<string , blink.cmp.SourceProvider>
9
+ --- @field on_completions_callback fun ( context : blink.cmp.Context , items : blink.cmp.CompletionItem[] )
10
+ ---
11
+ --- @field register fun ()
12
+ --- @field get_enabled_providers fun ( context ?: blink.cmp.Context ): table<string , blink.cmp.SourceProvider>
13
+ --- @field get_trigger_characters fun (): string[]
14
+ --- @field request_completions fun ( context : blink.cmp.Context )
15
+ --- @field cancel_completions fun ()
16
+ --- @field listen_on_completions fun ( callback : fun ( context : blink.cmp.Context , items : blink.cmp.CompletionItem[] ))
17
+ --- @field resolve fun ( item : blink.cmp.CompletionItem , callback : fun ( resolved_item : lsp.CompletionItem | nil )): ( fun (): nil ) | nil
18
+ --- @field get_signature_help_trigger_characters fun (): { trigger_characters : string[] , retrigger_characters : string[] }
19
+ --- @field get_signature_help fun ( context : blink.cmp.SignatureHelpContext , callback : fun ( signature_help : lsp.SignatureHelp | nil )): ( fun (): nil ) | nil
20
+ --- @field cancel_signature_help fun ()
21
+ --- @field reload fun ()
22
+
23
+ --- @type blink.cmp.Sources
24
+ --- @diagnostic disable-next-line : missing-fields
3
25
local sources = {
4
26
current_context = nil ,
5
27
sources_registered = false ,
@@ -8,24 +30,38 @@ local sources = {
8
30
}
9
31
10
32
function sources .register ()
11
- assert (# sources .providers == 0 , ' Sources have already been registered' )
33
+ assert (not sources .sources_registered , ' Sources have already been registered' )
34
+ sources .sources_registered = true
35
+
36
+ for key , source_config in pairs (config .sources .providers ) do
37
+ sources .providers [key ] = require (' blink.cmp.sources.lib.provider' ).new (key , source_config )
38
+ end
39
+ end
40
+
41
+ function sources .get_enabled_providers (context )
42
+ local mode_providers = type (config .sources .completion ) == ' function' and config .sources .completion (context )
43
+ or config .sources .completion
44
+ --- @cast mode_providers string[]
12
45
13
- for _ , source_config in ipairs (config .sources .providers ) do
14
- table.insert (sources .providers , require (' blink.cmp.sources.lib.provider' ).new (source_config ))
46
+ --- @type table<string , blink.cmp.SourceProvider>
47
+ local providers = {}
48
+ for key , provider in pairs (sources .providers ) do
49
+ if provider .config .enabled (context ) and vim .tbl_contains (mode_providers , key ) then providers [key ] = provider end
15
50
end
51
+ return providers
16
52
end
17
53
18
54
--- Completion ---
19
55
20
- --- @return string[]
21
56
function sources .get_trigger_characters ()
57
+ local providers = sources .get_enabled_providers ()
22
58
local blocked_trigger_characters = {}
23
59
for _ , char in ipairs (config .trigger .completion .blocked_trigger_characters ) do
24
60
blocked_trigger_characters [char ] = true
25
61
end
26
62
27
63
local trigger_characters = {}
28
- for _ , source in pairs (sources . providers ) do
64
+ for _ , source in pairs (providers ) do
29
65
local source_trigger_characters = source :get_trigger_characters ()
30
66
for _ , char in ipairs (source_trigger_characters ) do
31
67
if not blocked_trigger_characters [char ] then table.insert (trigger_characters , char ) end
36
72
37
73
function sources .listen_on_completions (callback ) sources .on_completions_callback = callback end
38
74
39
- --- @param context blink.cmp.Context
40
75
function sources .request_completions (context )
41
76
-- create a new context if the id changed or if we haven't created one yet
42
77
local is_new_context = sources .current_context == nil or context .id ~= sources .current_context .id
43
78
if is_new_context then
44
79
if sources .current_context ~= nil then sources .current_context :destroy () end
45
- sources .current_context =
46
- require (' blink.cmp.sources.lib.context' ).new (context , sources .providers , sources .on_completions_callback )
80
+ sources .current_context = require (' blink.cmp.sources.lib.context' ).new (
81
+ context ,
82
+ sources .get_enabled_providers (context ),
83
+ sources .on_completions_callback
84
+ )
47
85
end
48
86
49
87
sources .current_context :get_completions (context )
58
96
59
97
--- Resolve ---
60
98
61
- --- @param item blink.cmp.CompletionItem
62
- --- @param callback fun ( resolved_item : blink.cmp.CompletionItem | nil )
63
- --- @return fun (): nil Cancelation function
64
99
function sources .resolve (item , callback )
65
100
local item_source = nil
66
- for _ , source in ipairs (sources .providers ) do
67
- if source .name == item .source then
101
+ for _ , source in pairs (sources .providers ) do
102
+ if source .id == item .source_id then
68
103
item_source = source
69
104
break
70
105
end
82
117
83
118
--- Signature help ---
84
119
85
- --- @return { trigger_characters : string[] , retrigger_characters : string[] }
86
120
function sources .get_signature_help_trigger_characters ()
87
121
local blocked_trigger_characters = {}
88
122
local blocked_retrigger_characters = {}
@@ -97,7 +131,7 @@ function sources.get_signature_help_trigger_characters()
97
131
local retrigger_characters = {}
98
132
99
133
-- todo: should this be all source groups?
100
- for _ , source in ipairs (sources .providers ) do
134
+ for _ , source in pairs (sources .providers ) do
101
135
local res = source :get_signature_help_trigger_characters ()
102
136
for _ , char in ipairs (res .trigger_characters ) do
103
137
if not blocked_trigger_characters [char ] then table.insert (trigger_characters , char ) end
@@ -109,11 +143,9 @@ function sources.get_signature_help_trigger_characters()
109
143
return { trigger_characters = trigger_characters , retrigger_characters = retrigger_characters }
110
144
end
111
145
112
- --- @param context blink.cmp.SignatureHelpContext
113
- --- @param callback fun ( signature_helps : lsp.SignatureHelp )
114
146
function sources .get_signature_help (context , callback )
115
147
local tasks = {}
116
- for _ , source in ipairs (sources .providers ) do
148
+ for _ , source in pairs (sources .providers ) do
117
149
table.insert (tasks , source :get_signature_help (context ))
118
150
end
119
151
sources .current_signature_help = async .task .await_all (tasks ):map (function (tasks_results )
0 commit comments