web-dev-qa-db-fra.com

Substitut de conservation de cas à Vim

Est-ce que this peut être fait dans Vim?

Ce que je veux dire, c'est que la recherche de "BadJob" et son remplacement par "GoodJob" feraient les remplacements suivants

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
144
dukedave

Utilisez abolish.vim :

:%S/badjob/goodjob/g
105
Mark Lodato

Je ne sais pas si c'est le type de solution que vous recherchez ... mais je l'ai utilisé: keepcase.vim

Il n'y a pas d'autre support dans vim ...

27
LB40

bien sûr que tu peux

:s/\cbad/\= strpart(submatch(0), 0 ,1) == toupper(strpart(submatch(0), 0, 1)) ? "GOOD" : "good"/

ps. je suppose que keepcase.vim encapsule une logique similaire :)

10
fc.

Vous pouvez simplement coller et adapter ceci:
(Bien sûr, si vous faites cela de temps en temps, vous voudrez un plugin au lieu de cette monstruosité. Mais pour certains qui sont pressés et n'en ont besoin qu'une seule fois, c'est un hack rapide pour votre plaisir de coller :)

:%s/\cbad\zejob/\= ( submatch(0)[0] is# toupper(submatch(0)[0]) ? 'G' : 'g' ) . ( submatch(0)[1] is# toupper(submatch(0)[1]) ? 'OOD' : 'ood' )

Outre le modèle de recherche, vous devez modifier les quatre 'strings' dans le code de remplacement: Modifiez les pièces en gras :

:% s/\ c mauvaise \ze tâche /\ =
(submatch (0) [0] est # toupper (submatch (0) [0])? ' [~ # ~] g [~ # ~] ':' g ').
(submatch (0) [1] est # toupper (submatch (0) [1])? ' [~ # ~] ood [~ # ~] ':' ood ')

N'utilisez pas cette version 'orange' pour coller, car ses caractères de saut de ligne casseront également la commande.

/\ze est le sucre syntaxique de l'expression rationnelle vim pour marquer une anticipation positive: le modèle après \ze est vérifié, mais non substitué.


is# ?? Laissez-moi vous expliquer… (si vous êtes intéressé.)

# (aussi dans ==# et autres ) applique la sensibilité à la casse. Sinon, avec :set ignorecase (que j'utilise, car cela est nécessaire pour l'utile :set smartcase ), vim considérera 'a' == 'A' !!

Aussi fou qu'il soit, nous devons vraiment en tenir compte: car il dépend des paramètres utilisateur, == devrait NEVAR être utilisé! (Sauf là où ce serait réellement ce que vous voulez.) Je suivrai même la recommandation d'utiliser ==# lors de la comparaison d'entiers: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is# au lieu de ==# est un autre moyen de codage défensif: il améliore la sécurité des types: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Il doit être utilisé lors de la comparaison avec un littéral de chaîne.

'single-quoted' au lieu de "double quoted"chaînes sont une autre bonne pratique: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - cette réponse s'appuie sur leur réponse , corrigeant quelques lacunes.

6
Aaron Thoma

Si vous ne faites correspondre qu'une chaîne exacte (indépendante de la casse) avec quelques majuscules possibles, une autre possibilité est:

:s/abc/\={'abc':'xyz','Abc':'Xyz'}[submatch(0)]/i
3
rampion

Une alternative au plugin keepcase est SmartCase - remplacement des mots tout en conservant la casse d'origine . (Ne vous laissez pas décourager par les mauvaises notes.)

2
Ingo Karkat