This repository was archived by the owner on Oct 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathcomplete.lua
More file actions
140 lines (130 loc) · 4.64 KB
/
complete.lua
File metadata and controls
140 lines (130 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
local vim = vim
local api = vim.api
local util = require 'completion.util'
local ins = require 'completion.source.ins_complete'
local match = require'completion.matching'
local lsp = require'completion.source.lsp'
local opt = require 'completion.option'
local manager = require 'completion.manager'
local M = {}
local cache_complete_items = {}
local function checkCallback(callback_array)
for _,val in ipairs(callback_array) do
if not val then return false end
if type(val) == 'function' then
if val() == false then return end
end
end
return true
end
local function assignSourcePriority(items, source)
local source_priority = opt.get_option('source_priority')[source] or 1
for _, item in ipairs(items) do
item.source_priority = source_priority
end
end
local function getCompletionItems(items_array, prefix)
local complete_items = {}
for source, func in pairs(items_array) do
local items = func(prefix)
assignSourcePriority(items, source)
vim.list_extend(complete_items, items)
end
return complete_items
end
M.clearCache = function()
cache_complete_items = {}
lsp.isIncomplete = true
end
-- perform completion
M.performComplete = function(complete_source, complete_items_map, params)
manager.insertChar = false
if vim.fn.has_key(complete_source, "mode") > 0 then
-- ins-complete source
ins.triggerCompletion(complete_source.mode)
elseif vim.fn.has_key(complete_source, "complete_items") > 0 then
local callback_array = {}
local items_array = {}
-- collect getCompleteItems function of current completion source
for _, item in ipairs(complete_source.complete_items) do
-- check isIncomplete for lsp
local complete_items = complete_items_map[item]
-- special case to handle lsp isIncomplete flag
if item == 'lsp' then
if lsp.isIncomplete then
cache_complete_items = {}
table.insert(callback_array, complete_items.callback)
complete_items.trigger(manager, params)
items_array[item] = complete_items.item
end
else
if complete_items ~= nil then
if complete_items.callback == nil then
table.insert(callback_array, true)
else
table.insert(callback_array, complete_items.callback)
-- TODO: still pass in manager here because there's external sources using it
-- will remove it when refactoring aysnc sources
complete_items.trigger(manager, params)
end
items_array[item] = complete_items.item
end
end
end
if #cache_complete_items == 0 then
-- use callback_array to handle async behavior
local timer = vim.loop.new_timer()
timer:start(20, 50, vim.schedule_wrap(function()
if manager.insertChar == true and not timer:is_closing() then
timer:stop()
timer:close()
end
-- only perform complete when callback_array are all true
if checkCallback(callback_array) == true and timer:is_closing() == false then
if api.nvim_get_mode()['mode'] == 'i' or api.nvim_get_mode()['mode'] == 'ic' then
local items = getCompletionItems(items_array, params.prefix)
if opt.get_option('sorting') ~= "none" then
util.sort_completion_items(items)
end
if #items ~= 0 then
-- reset insertChar and handle auto changing source
cache_complete_items = items
vim.fn.complete(params.textMatch+1, items)
manager.changeSource = false
else
manager.changeSource = true
end
end
timer:stop()
timer:close()
end
end))
else
if api.nvim_get_mode()['mode'] == 'i' or api.nvim_get_mode()['mode'] == 'ic' then
local items = {}
for _, item in ipairs(cache_complete_items) do
match.matching(items, params.prefix, item)
end
if opt.get_option('sorting') ~= "none" then
util.sort_completion_items(items)
end
if #items ~= 0 then
local matching_strategy = opt.get_option("matching_strategy_list")
-- don't re-trigger complete when exact matching to avoid flickering
-- reset insertChar and handle auto changing source
cache_complete_items = items
if #matching_strategy == 1 and matching_strategy[1] == 'exact' then
return
else
vim.fn.complete(params.textMatch+1, items)
end
manager.changeSource = false
else
cache_complete_items = {}
manager.changeSource = true
end
end
end
end
end
return M