J'essaie d'améliorer une ancienne fonction d'achèvement. Je voudrais qu'il mette à jour les choix affichés dans le menu contextuel lorsque je tape de nouveaux caractères
Ma fonction d'achèvement est
function! lh#icomplete#ecm(findstart, base) abort
if a:findstart
let l = getline('.')
let startcol = match(l[0:col('.')-1], '\v\S+$')
if startcol == -1
let startcol = col('.')-1
endif
" let g:debug+= ["findstart(".a:base.") -> ".(startcol)]
return startcol
else
" let g:debug += ["matching(".a:base.")"]
let words = ['un', 'deux', 'trois', 'trente-deux', 'unité']
call filter(words, 'v:val =~ a:base')
" return { 'words' : words}
return { 'words' : words, 'refresh' : 'always'}
endif
endfunction
Que j'utilise avec
:set completefunc=lh#icomplete#ecm
:inoremap µ <c-x><c-u><c-p>
D'après ma compréhension de la documentation, du fait que j'utilise <c-p>
, j'entre dans le troisième état (selon | ins-complétement-menu |), et quand je tape "n'importe quel caractère imprimable et non blanc" je devrais pouvoir "Ajouter ce caractère et réduire le nombre de correspondances. "
Lorsque je tape en mode insertion uµ
, le menu de fin apparaît comme prévu. Hélas quand je tape x
(juste après le µ
), je suis en mode de fin et ux
c'est ce que j'obtiens dans mon buffer.
Qu'est-ce que j'ai fait de mal ou manqué dans la documentation?
NB: J'ai vu que sans refresh=always
, les résultats sont filtrés, sauf que je voudrais rappeler la fonction afin d'appliquer un filtre personnalisé.
(Juste au cas où, j'utilise gvim 7.4-908)
la source
Réponses:
Après de nouvelles investigations (et quelques reverse engineering).
Je ne peux pas expliquer pourquoi l'achèvement ne suit pas strictement la documentation. Je vais devoir demander sur vim_dev je suppose.
Quoi qu'il en soit, il semble que la façon de le faire consiste à enregistrer un écouteur sur
CursorMovedI
qui déclenchera à nouveau l'achèvement à chaque fois qu'un personnage est inséré.La difficulté est alors de savoir quand s'arrêter.
CompletionDone
est inutile car il sera déclenché après chaque frappe de touche.InsertLeave
est un bon début, mais il ne couvre pas tous les cas, c'est-à-direJe n'ai trouvé d'autre moyen que de passer outre
<cr>
et<c-y>
.D'autres difficultés consistent à détecter quand rien n'a changé afin d'éviter des boucles infinies et ainsi de suite.
Quoi qu'il en soit, voici mon code actuel (qui sera utilisé dans d'autres plugins). La dernière version sera conservée ici . C'est assez long, mais le voici:
Qui peut être utilisé avec:
Vous devriez pouvoir observer (indirectement) le résultat appliqué à la sélection d'extraits C ++ pour mon plugin d'extension de modèle sur ce screencast .
la source