Mapper une séquence de lettres en mode insertion

11

Je peux déjà mapper une combinaison de touches en mode insertion:

:inoremap abc <do stuff>

Cependant, cela présente quelques inconvénients:

  • Lorsque vous tapez une version partielle de la séquence, par exemple ab, les caractères ne s'affichent pas réellement pendant un court laps de temps, car il "attend" pour voir si vous allez taper la commande complète. C'est indésirable; Je souhaite mapper une chaîne de lettres sans faire de pause si une sous-chaîne partielle de la chaîne est entrée.

  • Si je tape ab, puis marque une pause (et attend que les caractères apparaissent réellement comme mentionné au point ci-dessus), puis tape le c, la commande n'est pas exécutée. Je veux que la commande soit exécutée, peu importe le temps que j'attends.

J'utiliserais un iab, mais cela ne fonctionne pas car:

  1. Il faut entrer un espace après la chaîne
  2. Je ne peux pas exécuter de commandes arbitraires avec lui, insérez seulement une chaîne de texte.

Existe-t-il un moyen d'exécuter une commande ou des séquences de touches si une certaine chaîne est entrée en mode insertion, sans utiliser de carte (qui se mettra en pause à chaque fois que je tape un aet ne fonctionnera pas si j'attends trop longtemps)?

Poignée de porte
la source
Ces inconvénients sont également valables pour :cnoremap abc <do stuff>...
Martin Tournoij
1
Il n'y a pas de retard quand vous le faites ab<any key>.
romainl

Réponses:

10

Voici une façon de procéder:

let s:inputBuffer = ''

augroup _silentInsertTrigger
    autocmd!
    autocmd InsertCharPre * call <sid>OnPreEnterChar()
    autocmd InsertLeave * call <sid>OnInsertLeave()
augroup END

function! s:OnPreEnterChar()
    let s:inputBuffer .= v:char

    if s:inputBuffer[-3:] ==# 'abc'
        echo '<do stuff>'
    endif

    return v:char
endfunction

function! s:OnInsertLeave()
    let s:inputBuffer = ''
endfunction
Steve Vermeulen
la source