@@ -301,7 +301,12 @@ function! s:CompleteTypingMatch(...)
301301 let local_menuitems = g: easycomplete_menuitems
302302 endif
303303 let filtered_menu = easycomplete#util#CompleteMenuFilter (local_menuitems, word, 250 )
304- if len (filtered_menu) == 0
304+ if easycomplete#sources#tn#available ()
305+ let tn_result = easycomplete#sources#tn#GetGlobalSourceItems ()
306+ else
307+ let tn_result = []
308+ endif
309+ if len (filtered_menu) == 0 && len (tn_result) == 0
305310 " call s:log(">>>>>>>>>>>>>" . "匹配结果是空,导致pum关闭", "cword:", expand("<cword>"))
306311 " 正常SecondComplete中无匹配词了就关掉 pum 了
307312 if has (' nvim' )
@@ -323,6 +328,25 @@ function! s:CompleteTypingMatch(...)
323328 return
324329 endif
325330
331+ " 如果正常匹配为空,但还存在旧的 TN 占位符,则物理匹配旧的占位符
332+ if len (filtered_menu) == 0 && len (tn_result) != 0
333+ let tn_result = easycomplete#util#CompleteMenuFilter (tn_result, word, 500 )
334+ if len (tn_result) == 0
335+ if has (' nvim' )
336+ call s: CloseCompletionMenu ()
337+ call s: CloseCompleteInfo ()
338+ else
339+ call s: CloseCompletionMenu ()
340+ endif
341+ else
342+ let start_pos = col (' .' ) - strlen (word)
343+ let b: easycomplete_tn_match_done = 1
344+ call s: SecondCompleteRendering (start_pos, tn_result)
345+ endif
346+ let g: easycomplete_stunt_menuitems = []
347+ return
348+ endif
349+
326350 " 如果在 VIM 中输入了':'和'.',一旦没有匹配项,就直接清空
327351 " g:easycomplete_menuitems,匹配状态复位
328352 " 注意:这里其实区分了 跟随匹配 和 Tab 匹配两个不同的动作
@@ -338,16 +362,33 @@ function! s:CompleteTypingMatch(...)
338362endfunction
339363
340364" 这里调用是异步回来,需要记录上一次 complete 的 start_pos
365+ " easycomplete#TabNineCompleteRendering 和 easycomplete#UpdateTNPlaceHolder
366+ " 总会调用其中一个,旧的占位符要么被定时器更新掉,要么被TN新的返回结果更新掉
341367function ! easycomplete#TabNineCompleteRendering ()
342368 let current_items = g: easycomplete_stunt_menuitems [0 : g: easycomplete_maxlength ]
343369 let tabnine_result = easycomplete#sources#tn#GetGlobalSourceItems ()
344370 if empty (tabnine_result) | return | endif
345371 let result = tabnine_result + current_items
346372 let start_pos = empty (s: easycomplete_start_pos ) ? col (' .' ) - strlen (s: GetTypingWord ()) : s: easycomplete_start_pos
347- " call s:trace()
373+ let b: easycomplete_tn_match_done = 1
348374 call s: SecondCompleteRendering (start_pos, result)
349375endfunction
350376
377+ function ! easycomplete#UpdateTNPlaceHolder (word)
378+ if ! exists (" b:easycomplete_tn_match_done" )
379+ let b: easycomplete_tn_match_done = 0
380+ endif
381+ if b: easycomplete_tn_match_done == 0
382+ let l: tn_ret = easycomplete#sources#tn#GetGlobalSourceItems ()
383+ if empty (l: tn_ret ) | return | endif
384+ let tabnine_result = easycomplete#util#CompleteMenuFilter (l: tn_ret , a: word , 500 )
385+ let current_items = g: easycomplete_stunt_menuitems [0 : g: easycomplete_maxlength ]
386+ let result = tabnine_result + current_items
387+ let start_pos = empty (s: easycomplete_start_pos ) ? col (' .' ) - strlen (a: word ) : s: easycomplete_start_pos
388+ call s: SecondCompleteRendering (start_pos, result)
389+ endif
390+ endfunction
391+
351392function ! s: SecondCompleteRendering (start_pos, result)
352393 if g: env_is_iterm
353394 call s: StopAsyncRun ()
@@ -368,9 +409,17 @@ function! s:SecondComplete(start_pos, menuitems, easycomplete_menuitems, word)
368409 if len (result) <= 5
369410 let result = easycomplete#util#uniq (result)
370411 endif
371- " 防止抖动
412+ " 这里功能上是不必要的,因为已经输入新的字符,应该匹配出新的TN结果,而GetGlobalSourceItems
413+ " 返回的是旧的,这里还要加上旧结果只是为了先占位,防止删除+呈现TN新结果时的pum的抖动
414+ "
415+ " 但TN并不是每次都能有返回,如果没有返回结果时,这里的旧的占位的结果也应该更新掉,否则会
416+ " 出现 #368 的问题,所以要有一个定时器判断TN有没有正确的返回,如果没有正确返回,那么占位
417+ " 的TN的旧结果要更新掉
372418 if easycomplete#sources#tn#available ()
373- let result_all = easycomplete#sources#tn#GetGlobalSourceItems () + result
419+ let l: tn_ret = easycomplete#sources#tn#GetGlobalSourceItems ()
420+ let b: easycomplete_tn_match_done = 0
421+ let result_all = l: tn_ret + result
422+ call easycomplete#util#timer_start (" easycomplete#UpdateTNPlaceHolder" , [a: word ], 3 )
374423 else
375424 let result_all = [] + result
376425 endif
0 commit comments