Cartographie avec mouvement

12

J'essaie de comprendre comment utiliser l'opérateur avec un mouvement ultérieur dans un mappage. Par exemple:

nmap /c c{here we pending for a motion}/<C-r>"<CR>

La carte doit procéder comme suit:

  1. Activez l' copérateur et écoutez le mouvement suivant;
  2. Par exemple, je peux taper ici t,pour tout changer avant la prochaine virgule;
  3. Passez en mode insertion en supprimant tout entre le curseur et la virgule;
  4. Le texte supprimé est automatiquement recherché en tant que motif

Donc, pour faire simple, une fois le texte de mouvement supprimé, je quitte le mode d'insertion avec les occurrences en surbrillance du texte supprimé. Je serais très reconnaissant si quelqu'un m'aide à résoudre ce cas.

MISE À JOUR

Les réponses sont presque ce que je veux. Mais! Lorsque j'appuie sur /cw, saisissez quelque chose au lieu du mot, puis appuyez sur <Esc>. Après je m'attends à faire de même avec les prochaines occurrences. Mais après avoir pressé n(passer à l'occurrence suivante) et .(répéter la dernière commande), il ajoute simplement le dernier texte tapé au lieu de le remplacer. L'objectif principal de la cartographie est de l'utiliser avec n/Net .pour répéter. Ai-je raté quelque chose?

Timur Fayzrakhmanov
la source

Réponses:

9

vim prend en charge le mappage d'opérateur :h map-operator.

Ce dont vous avez besoin est un operatorfuncet une cartographie. pour vos besoins, les codes suivants fonctionnent. Eh bien, ce n'est qu'un exemple, vous affinez davantage.

nmap  <silent> /c :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
    silent exec 'normal! `[v`]d'    
    silent exec 'let @/=@"' 
    startinsert
endfunction

Notez que exec 'let @/=@"'juste pour mettre en évidence les codes dans le tampon. Si vous ne voulez pas voir la surbrillance immédiatement, vous pouvez simplementlet @/=@"

Kent
la source
J'ai mis à jour ma question. Il semble que votre réponse soit la plus proche de mes besoins, mais elle ne fait pas de même avec l'occurrence suivante, j'ai donc expliqué ce moment dans la question.
Timur Fayzrakhmanov,
Vous avez deux opérateurs (les /cet i) vim ne font .que répéter le dernier. Si vous souhaitez l'étendre, vérifiez le repeatplugin. @TimurFayzrakhmanov existe également :get les :scommandes peuvent également vous aider.
Kent
Y a-t-il quelque chose d'étrange "dans votre code 'let @/=@""'? J'ai pensé que c'était possible, par exemple silent exec 'normal! [v ]c', parce que l' copérateur fait ce que j'attends, sauf qu'il n'ajoute pas le texte modifié au modèle de recherche.
Timur Fayzrakhmanov,
1
@TimurFayzrakhmanov "" était une faute de frappe .. correction .. Je suis venu caussi, mais il a ajouté un espace, car il y a un changement de mode, n-i-n-ije suppose ... faites un test que vous verrez.
Kent
@TimurFayzrakhmanov vous pouvez le rendre reproductible sans aucun plugin en changeant dvers yet startinsertvers call feedkeys("cgn", 'n')(voir ma réponse ci-dessous)
Jerome Dalbert
4

Il est plus facile d'implémenter (et de documenter) des mappages complexes en utilisant des fonctions:

function! DoMagic()
   execute "normal! d".input("enter motion: ")
   let @/=@"
   startinsert
endfunction

Ensuite, faites votre appel de mappage cette fonction:

nmap /c :call DoMagic()<CR>

Éditer:

Si votre intention est d'effectuer une recherche et remplacer dans un grand nombre d'endroits où vous devriez essayer la commande de substitution: :s. Vous pouvez modifier votre mappage pour copier la sélection visuelle dans le modèle de recherche:

function! DoMagic2()
   normal! gv"ay
   return @a
endfunction

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>
mMontu
la source
1
c'est même avec une "belle" interface utilisateur, fonctionne pour les besoins de l'OP, et peut être "plus" que prévu, dépend de ce que vous entrez. Par exemple, quand on voit enter motion:, il a donné: t,ggVGJZZ ^ _ ^ C'est un problème commun pour la concaténation de commandes
Kent
C'est presque ce que je veux. Ex: j'appuie sur /cwpuis tape quelque chose au lieu du mot, puis appuie sur <Esc>. Après je veux faire la même chose avec les prochaines occurrences. Mais après avoir pressé n(passer à l'occurrence suivante) et .(répéter la dernière commande), il ajoute simplement le dernier texte tapé au lieu de le remplacer. L'objectif principal de la cartographie est de l'utiliser avec n/Net .pour répéter. Ai-je raté quelque chose?
Timur Fayzrakhmanov,
1
Cette fonction vise à clarifier l'idée d'utiliser des fonctions lorsque vous rencontrez des problèmes avec des mappages complexes. Vous devez le changer pour répondre à vos besoins; essayez de suivre les conseils de Kent pour faire .répéter votre commande.
mMontu
Merci pour la réponse. C'est utile aussi, mais j'accepte celui de @Kent, car il fait un mouvement immédiatement après que je les ai tapés (sans attendre <CR>de input()).
Timur Fayzrakhmanov,
1
@TimurFayzrakhmanov, vous pouvez également essayer le substitut, comme expliqué dans la mise à jour.
mMontu
1

Cette solution fonctionne avec "répéter la dernière commande" (aka .):

nmap <silent> /c :set opfunc=ChangeOccurence<CR>g@

function! ChangeOccurence(type)
  exec 'normal! `[v`]y'
  let @/ = @"
  call feedkeys('cgn', 'n')
endfunction

Lors de la répétition, vous n'avez même pas besoin d'utiliser n, vous pouvez simplement utiliser .pour récupérer directement et remplacer la prochaine occurrence si vous voulez aller plus vite.

Facultativement, si vous aimez avoir les reflets des mots correspondants, vous pouvez les remplacer 'cgn'par 'n``cgn'.

Jerome Dalbert
la source