Substituto de preservação de caso no Vim

154

Pode isso pode ser feito no vim?

O que quero dizer é: procurar 'BadJob' e substituir por 'GoodJob' faria as seguintes substituições

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
Davetapley
fonte
16
Esse deve ser um recurso do vim. faz muito sentido.
Bach

Respostas:

120

Use abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
fonte
13
Nós não merecemos Tim Pope.
Andrew Keeton
1
Este plugin parece não funcionar para mim. Se eu gosto de uma palavra BadJobe quero substituí-la GoodJob, não posso usá-la %S/badjob/goodjob/g. Falha ao detectar uma correspondência.
Roymunson 16/07/19
@ Roymunson O que você precisa fazer é %S/BadJob/GoodJob/go seguinte:, o comando Subvert mudará para o modo de maiúsculas e minúsculas e fará todas as subestações fornecidas pelo OP.
shivams 26/04
28

Não sei se esse é o tipo de solução que você está procurando ... mas usei isso: keepcase.vim

Caso contrário, não há suporte no vim ...

LB40
fonte
11

com certeza você pode

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

ps. Eu estou supondo keepcase.vim encapsula alguma lógica semelhante :)

fc.
fonte
Sim, é verdade desde 2007::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Significado desde gVim 7.2? Eu tentei-o em gVim 7,1 (12 De Maio de 2007) e di não trabalho :(
. Fc
Não, adicionei o comando: SubstituteCase ao plug-in em 2007. Isso é tudo. O plug-in está disponível no vim.org e não é enviado com o vim como de costume na maioria dos plug-ins.
11559 Luc Hermitte
1. Isso falha quando o usuário tem :set ignorecase. 2. Badserá substituído por em GOODvez de Good. 3. A jobparte " " da pergunta é ignorada, então isso também substituirá lambadalamgooda. Correções e explicações para esses erros e algumas outras coisas na minha resposta . (Também LOLOWLs!)
Aaron Thoma
7

Você pode simplesmente colar e adaptar o seguinte:
(é claro, se você fizer isso de vez em quando, desejará um plugin em vez dessa monstruosidade. para o seu prazer de colar :)

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

Além do padrão de pesquisa, você deve editar as quatro 'cadeias 'no código de substituição: Edite as peças em negrito :

:% s / \ c trabalho \ ze ruim / \ = (submatch (0) [0] é # toupper (submatch (0) [0])? ' G ': ' g '). (submatch (0) [1] é # toupper (submatch (0) [1])? ' OOD ': ' ood ')

Não use esta versão 'laranja' para colar, pois seus caracteres de quebra de linha também quebrarão o comando.

/\zeé o açúcar sintático do vim regex para marcar um lookahead positivo: o padrão após \zeé verificado, mas não substituído.


is#?? Deixe-me explicar ... (Se estiver interessado.)

#(também em ==#e outros ) reforça a distinção entre maiúsculas e minúsculas. Caso contrário, com :set ignorecase(o qual eu uso, porque isso é necessário para o útil :set smartcase), o vim considerará 'a' == 'A'!!

Por mais louco que seja, devemos realmente ==prestar contas: como é dependente das configurações do usuário, o NEVAR deve ser usado! (Exceto onde realmente seria o que você deseja.) Eu seguirei a recomendação a ser usada ==#ao comparar números inteiros: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is#em vez de, ==#é outra maneira de codificar defensivamente: melhora a segurança de tipos: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Deve ser usado ao comparar com um literal de cadeia de caracteres.

'single-quoted'em vez de "double quoted" seqüências de caracteres, é outra boa prática: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - esta resposta baseia-se na resposta deles , corrigindo algumas deficiências.

Aaron Thoma
fonte
4

Se você estiver correspondendo apenas uma sequência exata (independente de maiúsculas e minúsculas) com algumas maiúsculas possíveis, outra possibilidade é:

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

Uma alternativa ao plugin keepcase é o SmartCase - substituindo palavras, mantendo o caso original . (Não se deixe desencorajar pelas más classificações.)

Ingo Karkat
fonte
1
Existe um truque para encurtar aqueles que são difíceis de lembrar e tediosos para digitar comandos como :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: Você pode usar o :SmartCasecomando. Eu estendi isso no meu próprio garfo . Observe que isso requer ingo-library como uma dependência.
Ingo Karkat