@@ -5,38 +5,54 @@ local source = require 'completion.source'
55local signature = require ' completion.signature_help'
66local hover = require ' completion.hover'
77local opt = require ' completion.option'
8+ local manager = require ' completion.manager'
89local M = {}
910
11+
1012---- --------------------------------------------------------------------
11- -- local function --
13+ -- external commands --
1214---- --------------------------------------------------------------------
1315
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+
3247
3348---- --------------------------------------------------------------------
34- -- member function --
49+ -- confirm completion --
3550---- --------------------------------------------------------------------
3651
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
4056 api .nvim_input (" ()<left>" )
4157 end
4258end
4561-- confirmCompletion is now triggered by CompleteDone autocmd to solve issue with noselect
4662-- Will cause snippets to expand with not pressing confirm key
4763-- 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
5066end
5167
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 )
7590 end
7691 end
92+ end
93+ end
7794
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 )
89100 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' , {})
92110 end
93111end
94112
113+ ---- --------------------------------------------------------------------
114+ -- autocommands --
115+ ---- --------------------------------------------------------------------
95116
96117function M .on_InsertCharPre ()
97118 manager .insertChar = true
98119 manager .textHover = true
99120 manager .selected = - 1
100- if opt .get_option (' auto_change_source' ) == 1 then
101- manager .autoChange = true
102- end
103121end
104122
105123function M .on_InsertLeave ()
106124 manager .insertLeave = true
107125end
108126
127+ -- TODO: need further refactor, very messy now:(
109128function M .on_InsertEnter ()
110129 local enable = api .nvim_call_function (' completion#get_buffer_variable' , {' completion_enable' })
111130 if enable == nil or enable == 0 then
112131 return
113132 end
114133 local timer = vim .loop .new_timer ()
115134 -- 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
120139 if opt .get_option (' auto_change_source' ) == 1 then
121- manager . autoChange = true
140+ autoChange = true
122141 end
123142
124143 -- reset source
125- source . chain_complete_index = 1
144+ manager . chainIndex = 1
126145 source .stop_complete = false
127- local l_complete_index = source . chain_complete_index
146+ local l_complete_index = manager . chainIndex
128147 local timer_cycle = opt .get_option (' timer_cycle' )
129148
130149 timer :start (100 , timer_cycle , vim .schedule_wrap (function ()
@@ -133,7 +152,7 @@ function M.on_InsertEnter()
133152 if l_changedTick ~= manager .changedTick then
134153 manager .changedTick = l_changedTick
135154 if opt .get_option (' enable_auto_popup' ) == 1 then
136- source .autoCompletion (manager )
155+ source .autoCompletion ()
137156 end
138157 if opt .get_option (' enable_auto_hover' ) == 1 then
139158 hover .autoOpenHoverInPopup (manager )
@@ -143,25 +162,25 @@ function M.on_InsertEnter()
143162 end
144163 end
145164 -- change source if no item is available
146- if manager .changeSource and manager . autoChange then
165+ if manager .changeSource and autoChange then
147166 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
151170 manager .insertChar = true
152171 source .triggerCompletion (false , manager )
153172 else
154173 source .stop_complete = true
155174 end
156175 end
157176 -- 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
159178 -- force clear completion
160179 if vim .api .nvim_get_mode ()[' mode' ] == ' i' or vim .api .nvim_get_mode ()[' mode' ] == ' ic' then
161180 vim .fn .complete (vim .api .nvim_win_get_cursor (0 )[2 ], {})
162181 end
163182 source .triggerCompletion (false , manager )
164- l_complete_index = source . chain_complete_index
183+ l_complete_index = manager . chainIndex
165184 end
166185 -- closing timer if leaving insert mode
167186 if manager .insertLeave == true and timer :is_closing () == false then
@@ -171,40 +190,15 @@ function M.on_InsertEnter()
171190 end ))
172191end
173192
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 )
186201 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 ()
208202end
209203
210204M .on_attach = function (option )
@@ -217,7 +211,7 @@ M.on_attach = function(option)
217211 api .nvim_command (" autocmd InsertEnter <buffer> lua require'completion'.on_InsertEnter()" )
218212 api .nvim_command (" autocmd InsertLeave <buffer> lua require'completion'.on_InsertLeave()" )
219213 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 ()" )
221215 api .nvim_command (" augroup end" )
222216 if string.len (opt .get_option (' confirm_key' )) ~= 0 then
223217 api .nvim_buf_set_keymap (0 , ' i' , opt .get_option (' confirm_key' ),
0 commit comments