@@ -14,11 +14,12 @@ local sources = {
14
14
snippets = - 1 ,
15
15
},
16
16
17
- sources_items = {},
17
+ sources_responses = {},
18
18
current_context_id = - 1 ,
19
19
on_completions_callback = function (_ ) end ,
20
20
}
21
21
22
+ --- @return string[]
22
23
function sources .get_trigger_characters ()
23
24
local blocked_trigger_characters = {}
24
25
for _ , char in ipairs (config .trigger .blocked_trigger_characters ) do
39
40
40
41
function sources .listen_on_completions (callback ) sources .on_completions_callback = callback end
41
42
43
+ --- @param context ShowContext
42
44
function sources .completions (context )
43
45
-- a new context means we should refetch everything
44
46
local is_new_context = context .id ~= sources .current_context_id
45
47
sources .current_context_id = context .id
46
48
47
- if is_new_context then sources .sources_items = {} end
49
+ if is_new_context then sources .sources_responses = {} end
48
50
49
51
for source_name , source in pairs (sources .registered ) do
50
52
-- the source indicates we should refetch when this character is typed
51
53
local trigger_characters = source .get_trigger_characters ~= nil and source .get_trigger_characters () or {}
52
54
local trigger_character = context .trigger_character
53
55
and vim .tbl_contains (trigger_characters , context .trigger_character )
54
56
-- the source indicates the previous results were incomplete and should be refetched on the next trigger
55
- local previous_incomplete = sources .sources_items [source_name ] ~= nil
56
- and sources .sources_items [source_name ].isIncomplete
57
+ local previous_incomplete = sources .sources_responses [source_name ] ~= nil
58
+ and sources .sources_responses [source_name ].isIncomplete
57
59
-- check if we have no data and no calls are in flight
58
- local no_data = sources .sources_items [source_name ] == nil and sources .in_flight_id [source_name ] == - 1
60
+ local no_data = sources .sources_responses [source_name ] == nil and sources .in_flight_id [source_name ] == - 1
59
61
60
62
-- if none of these are true, we can use the existing cached results
61
63
if is_new_context or trigger_character or previous_incomplete or no_data then
@@ -76,15 +78,13 @@ function sources.completions(context)
76
78
-- fixme: what if we refetch due to incomplete items or a trigger_character? the context trigger id wouldnt change
77
79
-- change so stale data would be returned if the source doesn't support cancellation
78
80
local cursor_column = vim .api .nvim_win_get_cursor (0 )[2 ]
79
- vim .schedule (function ()
80
- source .completions ({ trigger = trigger_context }, function (items )
81
- -- a new call was made or this one was cancelled
82
- if sources .in_flight_id [source_name ] ~= in_flight_id then return end
83
- sources .in_flight_id [source_name ] = - 1
84
-
85
- sources .add_source_completions (source_name , items , cursor_column )
86
- if not sources .some_in_flight () then sources .send_completions (context ) end
87
- end )
81
+ source .completions ({ trigger = trigger_context }, function (items )
82
+ -- a new call was made or this one was cancelled
83
+ if sources .in_flight_id [source_name ] ~= in_flight_id then return end
84
+ sources .in_flight_id [source_name ] = - 1
85
+
86
+ sources .add_source_completions (source_name , items , cursor_column )
87
+ if not sources .some_in_flight () then sources .send_completions (context ) end
88
88
end )
89
89
end
90
90
end
@@ -94,34 +94,43 @@ function sources.completions(context)
94
94
if not sources .some_in_flight () then sources .send_completions (context ) end
95
95
end
96
96
97
- function sources .add_source_completions (source_name , source_items , cursor_column )
98
- for _ , item in ipairs (source_items .items ) do
97
+ --- @param source_name string
98
+ --- @param source_response CompletionResponse
99
+ --- @param cursor_column number
100
+ function sources .add_source_completions (source_name , source_response , cursor_column )
101
+ for _ , item in ipairs (source_response .items ) do
99
102
item .source = source_name
100
103
item .cursor_column = cursor_column
101
104
end
102
105
103
- sources .sources_items [source_name ] = source_items
106
+ sources .sources_responses [source_name ] = source_response
104
107
end
105
108
109
+ --- @return boolean
106
110
function sources .some_in_flight ()
107
111
for _ , in_flight in pairs (sources .in_flight_id ) do
108
112
if in_flight ~= - 1 then return true end
109
113
end
110
114
return false
111
115
end
112
116
117
+ --- @param context ShowContext
113
118
function sources .send_completions (context )
114
- local sources_items = sources .sources_items
119
+ local sources_responses = sources .sources_responses
115
120
-- apply source filters
116
121
for _ , source in pairs (sources .registered ) do
117
- if source .filter_completions ~= nil then sources_items = source .filter_completions (context , sources_items ) end
122
+ if source .filter_completions ~= nil then
123
+ sources_responses = source .filter_completions (context , sources_responses )
124
+ end
118
125
end
119
126
120
127
-- flatten the items
121
128
local flattened_items = {}
122
- for source_name , response in pairs (sources .sources_items ) do
129
+ for source_name , response in pairs (sources .sources_responses ) do
123
130
local source = sources .registered [source_name ]
124
- if source .should_show == nil or source .should_show () then vim .list_extend (flattened_items , response .items ) end
131
+ if source .should_show_completions == nil or source .should_show_completions (context , sources_responses ) then
132
+ vim .list_extend (flattened_items , response .items )
133
+ end
125
134
end
126
135
127
136
sources .on_completions_callback (context , flattened_items )
@@ -134,10 +143,16 @@ function sources.cancel_completions()
134
143
end
135
144
end
136
145
146
+ --- @param item CompletionItem
147
+ --- @param callback fun ( resolved_item : CompletionItem | nil )
148
+ --- @return fun (): nil Cancelation function
137
149
function sources .resolve (item , callback )
138
150
local item_source = sources .registered [item .source ]
139
- if item_source == nil or item_source .resolve == nil then return callback (item ) end
140
- item_source .resolve (item , callback )
151
+ if item_source == nil or item_source .resolve == nil then
152
+ callback (nil )
153
+ return function () end
154
+ end
155
+ return item_source .resolve (item , callback ) or function () end
141
156
end
142
157
143
158
return sources
0 commit comments