Est-il possible de faire exécuter une fonction autant de fois par un raccourci clavier à préfixe numérique?

7

Je trouve que si vous entrez un préfixe numérique avant d'exécuter une commande ex, la convention qui s'applique est de configurer la commande pour préparer une opération sur une plage de lignes. Il est expliqué dans la documentation,

UN NOMBRE DE LIGNES

Lorsque vous savez combien de lignes vous souhaitez modifier, vous pouvez taper le nombre puis ":". Par exemple, lorsque vous tapez "5:", vous obtenez:

    :.,.+4

Vous pouvez maintenant saisir la commande que vous souhaitez utiliser. Il utilisera la plage "." (ligne actuelle) jusqu'à ". + 4" (quatre lignes plus bas). Ainsi, il s'étend sur cinq lignes.

Maintenant, ce dont je parle est une de mes fonctions personnalisées, celle-ci:

function! MyAmazingEnhancedDot()
    if v:hlsearch == 1
        :normal! .n
    else
        :normal! .j
    endif
endfun

Il s'agit simplement d'un moyen de rationaliser les tâches répétitives qui incluent la répétition d'une opération sur une plage de lignes ou sur une série de correspondances de recherche.

Cette fonction est liée à un raccourci clavier. Tels que Alt+ .ou autre chose.

Mon objectif est de pouvoir faire quelque chose de très puissant: je devrais pouvoir taper /varName<CR>ciwnew-var<ESC>n9<Alt+.>pour réussir à renommer 10 instances de varNameto new-var.

Ce qui se passe réellement si je fais cela, c'est qu'il n'effectue pas le changement de nom et que les 9 lignes sont manipulées avec mon .opération d'édition enregistrée à partir de la colonne 0.

Je ne peux que supposer que Vim interprète donc mes frappes: :.,.+8 normal! .n.

Du côté du verre à moitié plein, le :normal! .jcas de la liaison fonctionne réellement, car le jmouvement sans effet n'a aucune conséquence dans cette situation. (J'ai encore besoin de jpour le faire fonctionner dans un cas d'utilisation interactif non préfixé numérique).

Ma question est donc de savoir comment puis-je remplacer le comportement d'extension de ligne que Vim applique à ma liaison? Ce qui serait fantastique, c'est que je puisse lire le préfixe numérique comme argument ou quelque chose comme ça.

Steven Lu
la source

Réponses:

6

Par défaut, vim traite toutes les fonctions comme s'il s'agissait de commandes ex par défaut, c'est-à-dire que tous les numéros préfixés sont utilisés comme {range}. Pour changer cela, vous devez modifier votre fonction et votre carte pour utiliser un décompte.

Carte avec décompte

Les cartes peuvent compter et sont disponibles via v:countet v:count1. Le premier contient 0 si aucun décompte n'est fourni et le dernier contient 1 par défaut. Vous pouvez créer une carte pour votre fonction:

nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>

Pour plus d'informations :h v:count

Commandes avec nombre

Les commandes peuvent avoir l'option de a {range}ou a countcomme préfixe. Lors de la création de la commande, l'indicateur -countdésactive l'option de plage et la valeur par défaut de la <count>variable à 0. En option, une valeur par défaut peut être fournie -count=N. La valeur du préfixe est alors disponible via la variable countde votre fonction.

Une commande utilisant count ressemblerait à ceci:

:command -count=1 EDot call MyAmazingEnhancedDot(<count>)

Maintenant, lorsque vous appelez, 9EDotvotre fonction est appelée avec le nombre de 9au lieu d'une plage.

Pour plus d'informations, voir :h command-count

Les deux exemples

Voici votre code:

function MyAmazingEnhancedDot(count)
  let c = a:count
  while c > 0
    if v:hlsearch == 1
      :normal! .n
    else
      :normal! .j
    endif
    let c -= 1
  endwhile
endfunction

command -count=1 EDot call MyAmazingEnhancedDot(<count>)

nnoremap <M-.> :<C-u>exe v:count1 . "EDot"<CR>

Vous pouvez maintenant faire votre exemple

/varName<CR>ciwvar-name<esc>n9<M-.>
jecxjo
la source
1
Cool. Maintenant, il semble y avoir trop de façons de résoudre mon problème! Je comprends que vous avez combiné les deux mécanismes dans l'exemple que vous avez donné afin d'illustrer comment les utiliser. Mais je me demande s'il ne suffit pas d'utiliser nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>et de sauter le command -count=1 EDot call MyAmazingEnhancedDot(<count>)?
Steven Lu
Ignorer l'option de commande est très bien. Le seul avantage que vous obtenez de l'option de commande est de pouvoir l'appeler à partir d'ex commandes telles que :9EDot. Si vous n'utilisez pas beaucoup les commandes ex, sautez-la.
jecxjo
Impressionnant. Maintenant, votre réponse parfaite est complète!
Steven Lu