@@ -5,38 +5,54 @@ local source = require 'completion.source'
5
5
local signature = require ' completion.signature_help'
6
6
local hover = require ' completion.hover'
7
7
local opt = require ' completion.option'
8
+ local manager = require ' completion.manager'
8
9
local M = {}
9
10
11
+
10
12
---- --------------------------------------------------------------------
11
- -- local function --
13
+ -- external commands --
12
14
---- --------------------------------------------------------------------
13
15
14
- M .completionConfirm = false
15
-
16
- -- Manager variable to keep all state accross completion
17
- local manager = {
18
- -- Handle insertCharPre event, turn off imediately when preforming completion
19
- insertChar = false ,
20
- -- Handle insertLeave event
21
- insertLeave = false ,
22
- -- Handle auto hover
23
- textHover = false ,
24
- -- Handle selected items in v:complete-items for auto hover
25
- selected = - 1 ,
26
- -- Handle changeTick
27
- changedTick = 0 ,
28
- -- handle auto changing source
29
- changeSource = false ,
30
- autoChange = false
31
- }
16
+ M .insertCompletionItems = function (completed_items , prefix , item )
17
+ match .matching (completed_items , prefix , item )
18
+ end
19
+
20
+ M .addCompletionSource = function (key , completed_item )
21
+ source .addCompleteItems (key , completed_item )
22
+ end
23
+
24
+ M .nextSource = function ()
25
+ source .nextCompletion ()
26
+ end
27
+
28
+ M .prevSource = function ()
29
+ source .prevCompletion ()
30
+ end
31
+
32
+ M .triggerCompletion = function ()
33
+ source .triggerCompletion (true , manager )
34
+ end
35
+
36
+ M .completionToggle = function ()
37
+ local enable = api .nvim_call_function (' completion#get_buffer_variable' , {' completion_enable' })
38
+ if enable == nil then
39
+ M .on_attach ()
40
+ elseif enable == 0 then
41
+ api .nvim_buf_set_var (0 , ' completion_enable' , 1 )
42
+ else
43
+ api .nvim_buf_set_var (0 , ' completion_enable' , 0 )
44
+ end
45
+ end
46
+
32
47
33
48
---- --------------------------------------------------------------------
34
- -- member function --
49
+ -- confirm completion --
35
50
---- --------------------------------------------------------------------
36
51
37
- function M .autoAddParens (complete_item )
38
- if complete_item .kind == nil then return end
39
- if string.match (complete_item .kind , ' .*Function.*' ) ~= nil or string.match (complete_item .kind , ' .*Method.*' ) then
52
+ -- I want to deprecate this...
53
+ local function autoAddParens (completed_item )
54
+ if completed_item .kind == nil then return end
55
+ if string.match (completed_item .kind , ' .*Function.*' ) ~= nil or string.match (completed_item .kind , ' .*Method.*' ) then
40
56
api .nvim_input (" ()<left>" )
41
57
end
42
58
end
45
61
-- confirmCompletion is now triggered by CompleteDone autocmd to solve issue with noselect
46
62
-- Will cause snippets to expand with not pressing confirm key
47
63
-- Add a flag completionConfirm to avoid this issue
48
- function M .toggleConfirm ( )
49
- M . completionConfirm = true
64
+ function M .confirmCompletion ( completed_item )
65
+ manager . confirmedCompletion = true
50
66
end
51
67
52
- function M .confirmCompletion ()
53
- if M .completionConfirm == true then
54
- local complete_item = api .nvim_get_vvar (' completed_item' )
55
- local lnum , _ = unpack (api .nvim_win_get_cursor (0 ))
56
- if complete_item .user_data .lsp ~= nil then
57
- local item = complete_item .user_data .lsp .completion_item
58
- if vim .fn .exists (' g:loaded_vsnip_integ' ) == 1 then
59
- api .nvim_call_function (' vsnip_integ#do_complete_done' , {
60
- {
61
- completed_item = complete_item ,
62
- completion_item = item ,
63
- apply_additional_text_edits = true
64
- }
65
- })
66
- else
67
- if item .additionalTextEdits then
68
- local bufnr = api .nvim_get_current_buf ()
69
- local edits = vim .tbl_filter (
70
- function (x ) return x .range .start .line ~= (lnum - 1 ) end ,
71
- item .additionalTextEdits
72
- )
73
- vim .lsp .util .apply_text_edits (edits , bufnr )
74
- end
68
+ -- apply additionalTextEdits in LSP specs
69
+ local function applyAddtionalTextEdits (completed_item )
70
+ local lnum = api .nvim_win_get_cursor (0 )[0 ]
71
+ if completed_item .user_data .lsp ~= nil then
72
+ local item = completed_item .user_data .lsp .completion_item
73
+ -- vim-vsnip have better additional text edits...
74
+ if vim .fn .exists (' g:loaded_vsnip_integ' ) == 1 then
75
+ api .nvim_call_function (' vsnip_integ#do_complete_done' , {
76
+ {
77
+ completed_item = completed_item ,
78
+ completion_item = item ,
79
+ apply_additional_text_edits = true
80
+ }
81
+ })
82
+ else
83
+ if item .additionalTextEdits then
84
+ local bufnr = api .nvim_get_current_buf ()
85
+ local edits = vim .tbl_filter (
86
+ function (x ) return x .range .start .line ~= (lnum - 1 ) end ,
87
+ item .additionalTextEdits
88
+ )
89
+ vim .lsp .util .apply_text_edits (edits , bufnr )
75
90
end
76
91
end
92
+ end
93
+ end
77
94
78
- if opt .get_option (' enable_auto_paren' ) == 1 then
79
- M .autoAddParens (complete_item )
80
- end
81
- if complete_item .kind == ' UltiSnips' then
82
- api .nvim_call_function (' UltiSnips#ExpandSnippet' , {})
83
- elseif complete_item .kind == ' Neosnippet' then
84
- api .nvim_input (" <c-r>" .. " =neosnippet#expand('" .. complete_item .word .. " ')" .. " <CR>" )
85
- elseif complete_item .kind == ' vim-vsnip' then
86
- api .nvim_call_function (' vsnip#expand' , {})
87
- end
88
- M .completionConfirm = false
95
+ -- handle completeDone stuff here
96
+ local function hasConfirmedCompletion ()
97
+ local completed_item = api .nvim_get_vvar (' completed_item' )
98
+ if completed_item .user_data .lsp ~= nil then
99
+ applyAddtionalTextEdits (completed_item )
89
100
end
90
- if hover .winnr ~= nil and api .nvim_win_is_valid (hover .winnr ) then
91
- api .nvim_win_close (hover .winnr , true )
101
+ if opt .get_option (' enable_auto_paren' ) == 1 then
102
+ autoAddParens (completed_item )
103
+ end
104
+ if completed_item .kind == ' UltiSnips' then
105
+ api .nvim_call_function (' UltiSnips#ExpandSnippet' , {})
106
+ elseif completed_item .kind == ' Neosnippet' then
107
+ api .nvim_input (" <c-r>" .. " =neosnippet#expand('" .. completed_item .word .. " ')" .. " <CR>" )
108
+ elseif completed_item .kind == ' vim-vsnip' then
109
+ api .nvim_call_function (' vsnip#expand' , {})
92
110
end
93
111
end
94
112
113
+ ---- --------------------------------------------------------------------
114
+ -- autocommands --
115
+ ---- --------------------------------------------------------------------
95
116
96
117
function M .on_InsertCharPre ()
97
118
manager .insertChar = true
98
119
manager .textHover = true
99
120
manager .selected = - 1
100
- if opt .get_option (' auto_change_source' ) == 1 then
101
- manager .autoChange = true
102
- end
103
121
end
104
122
105
123
function M .on_InsertLeave ()
106
124
manager .insertLeave = true
107
125
end
108
126
127
+ -- TODO: need further refactor, very messy now:(
109
128
function M .on_InsertEnter ()
110
129
local enable = api .nvim_call_function (' completion#get_buffer_variable' , {' completion_enable' })
111
130
if enable == nil or enable == 0 then
112
131
return
113
132
end
114
133
local timer = vim .loop .new_timer ()
115
134
-- setup variable
116
- manager .changedTick = api . nvim_buf_get_changedtick ( 0 )
117
- manager . insertLeave = false
118
- manager . insertChar = false
119
- manager . changeSource = false
135
+ manager .init ( )
136
+
137
+ -- TODO: remove this
138
+ local autoChange = false
120
139
if opt .get_option (' auto_change_source' ) == 1 then
121
- manager . autoChange = true
140
+ autoChange = true
122
141
end
123
142
124
143
-- reset source
125
- source . chain_complete_index = 1
144
+ manager . chainIndex = 1
126
145
source .stop_complete = false
127
- local l_complete_index = source . chain_complete_index
146
+ local l_complete_index = manager . chainIndex
128
147
local timer_cycle = opt .get_option (' timer_cycle' )
129
148
130
149
timer :start (100 , timer_cycle , vim .schedule_wrap (function ()
@@ -133,7 +152,7 @@ function M.on_InsertEnter()
133
152
if l_changedTick ~= manager .changedTick then
134
153
manager .changedTick = l_changedTick
135
154
if opt .get_option (' enable_auto_popup' ) == 1 then
136
- source .autoCompletion (manager )
155
+ source .autoCompletion ()
137
156
end
138
157
if opt .get_option (' enable_auto_hover' ) == 1 then
139
158
hover .autoOpenHoverInPopup (manager )
@@ -143,25 +162,25 @@ function M.on_InsertEnter()
143
162
end
144
163
end
145
164
-- change source if no item is available
146
- if manager .changeSource and manager . autoChange then
165
+ if manager .changeSource and autoChange then
147
166
manager .changeSource = false
148
- if source . chain_complete_index ~= source .chain_complete_length then
149
- source . chain_complete_index = source . chain_complete_index + 1
150
- l_complete_index = source . chain_complete_index
167
+ if manager . chainIndex ~= source .chain_complete_length then
168
+ manager . chainIndex = manager . chainIndex + 1
169
+ l_complete_index = manager . chainIndex
151
170
manager .insertChar = true
152
171
source .triggerCompletion (false , manager )
153
172
else
154
173
source .stop_complete = true
155
174
end
156
175
end
157
176
-- force trigger completion when manaully chaging source
158
- if l_complete_index ~= source . chain_complete_index then
177
+ if l_complete_index ~= manager . chainIndex then
159
178
-- force clear completion
160
179
if vim .api .nvim_get_mode ()[' mode' ] == ' i' or vim .api .nvim_get_mode ()[' mode' ] == ' ic' then
161
180
vim .fn .complete (vim .api .nvim_win_get_cursor (0 )[2 ], {})
162
181
end
163
182
source .triggerCompletion (false , manager )
164
- l_complete_index = source . chain_complete_index
183
+ l_complete_index = manager . chainIndex
165
184
end
166
185
-- closing timer if leaving insert mode
167
186
if manager .insertLeave == true and timer :is_closing () == false then
@@ -171,40 +190,15 @@ function M.on_InsertEnter()
171
190
end ))
172
191
end
173
192
174
- M .triggerCompletion = function ()
175
- source .triggerCompletion (true , manager )
176
- end
177
-
178
- M .completionToggle = function ()
179
- local enable = api .nvim_call_function (' completion#get_buffer_variable' , {' completion_enable' })
180
- if enable == nil then
181
- M .on_attach ()
182
- elseif enable == 0 then
183
- api .nvim_buf_set_var (0 , ' completion_enable' , 1 )
184
- else
185
- api .nvim_buf_set_var (0 , ' completion_enable' , 0 )
193
+ -- handle completion confirmation and dismiss hover popup
194
+ function M .on_CompleteDone ()
195
+ if manager .confirmedCompletion then
196
+ manager .confirmedCompletion = false
197
+ hasConfirmedCompletion ()
198
+ end
199
+ if hover .winnr ~= nil and api .nvim_win_is_valid (hover .winnr ) then
200
+ api .nvim_win_close (hover .winnr , true )
186
201
end
187
- end
188
-
189
- -- Deprecated
190
- M .customize_buf_label = function (label )
191
- api .nvim_buf_set_var (0 , " completion_buf_customize_lsp_label" , label )
192
- end
193
-
194
- M .insertCompletionItems = function (complete_items , prefix , item )
195
- match .matching (complete_items , prefix , item )
196
- end
197
-
198
- M .addCompletionSource = function (key , complete_item )
199
- source .addCompleteItems (key , complete_item )
200
- end
201
-
202
- M .nextSource = function ()
203
- source .nextCompletion ()
204
- end
205
-
206
- M .prevSource = function ()
207
- source .prevCompletion ()
208
202
end
209
203
210
204
M .on_attach = function (option )
@@ -217,7 +211,7 @@ M.on_attach = function(option)
217
211
api .nvim_command (" autocmd InsertEnter <buffer> lua require'completion'.on_InsertEnter()" )
218
212
api .nvim_command (" autocmd InsertLeave <buffer> lua require'completion'.on_InsertLeave()" )
219
213
api .nvim_command (" autocmd InsertCharPre <buffer> lua require'completion'.on_InsertCharPre()" )
220
- api .nvim_command (" autocmd CompleteDone <buffer> lua require'completion'.confirmCompletion ()" )
214
+ api .nvim_command (" autocmd CompleteDone <buffer> lua require'completion'.on_CompleteDone ()" )
221
215
api .nvim_command (" augroup end" )
222
216
if string.len (opt .get_option (' confirm_key' )) ~= 0 then
223
217
api .nvim_buf_set_keymap (0 , ' i' , opt .get_option (' confirm_key' ),
0 commit comments