Substitut de conservation de cas dans Vim

154

Peut cela peut se faire dans vim?

Ce que je veux dire, c'est: rechercher «BadJob» et le remplacer par «GoodJob» ferait les remplacements suivants

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
Davetapley
la source
16
Cela devrait être une fonctionnalité vim. Cela a tellement de sens.
Bach

Réponses:

120

Utilisez abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
la source
13
Nous ne méritons pas Tim Pope.
Andrew Keeton
1
Ce plugin ne semble pas fonctionner pour moi. Si j'aime un mot BadJobet que je veux le remplacer par GoodJob, je ne peux pas l'utiliser %S/badjob/goodjob/g. Il ne parvient pas à détecter une correspondance.
Roymunson
@Roymunson Ce que vous devez faire est ceci:, %S/BadJob/GoodJob/galors la commande Subvert passera en mode casse mixte et effectuera toutes les sous-stations comme indiqué par OP.
shivams le
28

Je ne sais pas si c'est le genre de solution que vous recherchez ... mais j'ai utilisé ceci: keepcase.vim

Il n'y a pas de support autrement dans vim ...

LB40
la source
11

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 :)

fc.
la source
Oui, depuis 2007::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Signification depuis gVim 7.2? Je l'ai essayé dans gVim 7.1 (12-mai-2007) et ça n'a pas fonctionné :(
fc.
Non, j'ai ajouté la commande: SubstituteCase au plugin en 2007. C'est tout. Le plugin est disponible sur vim.org, et il n'est pas livré avec vim comme d'habitude avec la plupart des plugins.
Luc Hermitte
1. Cela échoue lorsque l'utilisateur a :set ignorecase. 2. Badsera remplacé par GOODau lieu de Good. 3. La jobpartie " " de la question est ignorée, elle remplacera donc également lambadalamgooda. Corrections et explications de ces bugs et quelques autres choses dans ma réponse . (Aussi LOLOWLs!)
Aaron Thoma
7

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 éditer les quatre 'chaînes 'du code de remplacement: Modifiez les parties en gras :

:% s / \ c mauvais \ ze job / \ =
(sous-correspondance (0) [0] est # toupper (sous-correspondance (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 interrompront également la commande.

/\zeest un sucre syntaxique vim regex pour marquer une anticipation positive: Le modèle après \zeest vérifié, mais pas remplacé.


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

#(également 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 prendra en compte 'a' == 'A'!!

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

is#au lieu de ==#est une autre façon de coder défensivement: Cela 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 une chaîne littérale.

'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.

Aaron Thoma
la source
4

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
rampion
la source
2

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

Ingo Karkat
la source
1
Existe-t-il une astuce pour raccourcir les commandes difficiles à retenir et fastidieuses à saisir :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: Vous pouvez utiliser la :SmartCasecommande. J'ai étendu cela dans ma propre fourchette . Notez que cela nécessite ingo-library en tant que dépendance.
Ingo Karkat