Caso sustituto de preservación en Vim

154

¿Puede esto se puede hacer de Vim?

Lo que quiero decir es: buscar 'BadJob' y reemplazarlo con 'GoodJob' haría los siguientes reemplazos

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
davetapley
fuente
16
Esto debería ser una característica vim. Tiene mucho sentido.
Bach

Respuestas:

120

Use abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
fuente
13
No merecemos a Tim Pope.
Andrew Keeton
1
Este complemento no parece funcionar para mí. Si me gusta una palabra BadJoby quiero reemplazarla GoodJob, no puedo usarla %S/badjob/goodjob/g. No puede detectar una coincidencia.
Roymunson
@Roymunson Lo que debe hacer es esto: %S/BadJob/GoodJob/gluego, el comando Subvertir cambiará al modo de mayúsculas y minúsculas y realizará todas las subtensiones según lo dispuesto por OP.
Shivams
28

No sé si este es el tipo de solución que estás buscando ... pero he usado esto: keepcase.vim

No hay soporte de otra manera en vim ...

LB40
fuente
11

seguro que puedes

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

PD. Supongo que keepcase.vim encapsula una lógica similar :)

fc.
fuente
Sí, lo hace desde 2007::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Significado desde gVim 7.2? Lo probé en gVim 7.1 (12 de mayo de 2007) y no funciona :(
fc.
No, agregué el comando: SubstituteCase al complemento en 2007. Eso es todo. El complemento está disponible en vim.org, y no se envía con vim como de costumbre con la mayoría de los complementos.
Luc Hermitte
1. Esto falla cuando el usuario tiene :set ignorecase. 2. Badserá sustituido por en GOODlugar de Good. 3. La parte " job" de la pregunta se ignora, por lo que también reemplazará lambadalamgooda. Correcciones y explicaciones para estos errores y algunas otras cosas en mi respuesta . (¡También LOLOWLs!)
Aaron Thoma
7

Simplemente puede pegar y adaptar esto:
(Por supuesto, si lo hace de vez en cuando, querrá un complemento en lugar de esta monstruosidad. Pero para algunos que tienen prisa y solo lo necesitan una vez, este es un truco rápido para tu placer pegar :)

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

Además del patrón de búsqueda, debe editar las cuatro 'cadenas 'en el código de reemplazo: Edite las partes en negrita :

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

No use esta versión 'naranja' para pegar, ya que sus caracteres de salto de línea también romperán el comando.

/\zees el azúcar sintáctico vim regex para marcar una anticipación positiva: el patrón posterior \zese verifica pero no se sustituye.


is#?? Déjame explicarte ... (si está interesado)

#(también en ==#y otros ) impone mayúsculas y minúsculas. De lo contrario, con :set ignorecase(que uso, porque eso es necesario para lo útil :set smartcase), ¡¡¡vim lo considerará 'a' == 'A'!!

Loco como es, realmente deberíamos tenerlo en cuenta: ==dado que depende de la configuración del usuario, ¡ debería usarse NEVAR! (Excepto donde eso sería realmente lo que desea). Incluso seguiré la recomendación de usar ==#al comparar enteros: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is#en lugar de ==#es otra forma de codificar a la defensiva: mejora la seguridad de los tipos: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Se debe usar al comparar con una cadena literal.

'single-quoted'en lugar de "double quoted" cadenas hay otra buena práctica: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - esta respuesta se basa en su respuesta , solucionando algunas deficiencias.

Aaron Thoma
fuente
4

Si solo está haciendo coincidir una cadena exacta (independiente de mayúsculas y minúsculas) con algunas mayúsculas posibles, otra posibilidad es:

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

Una alternativa al complemento keepcase es SmartCase, que reemplaza las palabras mientras se mantiene la carcasa original . (No se deje desanimar por las malas calificaciones).

Ingo Karkat
fuente
1
¿Hay algún truco para acortar los que son difíciles de recordar y tediosos para escribir comandos :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: puede usar el :SmartCasecomando. Lo he extendido en mi propio tenedor . Tenga en cuenta que esto requiere ingo-library como una dependencia.
Ingo Karkat