Substytut zachowujący wielkość liter w Vimie

154

Czy to może być wykonane w vim?

Chodzi mi o to, że wyszukanie „BadJob” i zastąpienie go „GoodJob” spowodowałoby następujące zastąpienia

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
davetapley
źródło
16
To powinna być funkcja Vima. To ma taki sens.
Bach

Odpowiedzi:

120

Użyj abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
źródło
13
Nie zasługujemy na Tima Pope'a.
Andrew Keeton
1
Ta wtyczka wydaje się nie działać dla mnie. Jeśli podoba mi się słowo BadJobi chcę je zastąpić GoodJob, nie mogę użyć %S/badjob/goodjob/g. Nie udaje się wykryć dopasowania.
Roymunson,
@Roymunson To, co musisz zrobić %S/BadJob/GoodJob/g, to:, wtedy polecenie Subvert przełączy się na tryb mieszanych wielkości liter i wykona wszystkie podmiany podane przez OP.
shivams
28

Nie wiem, czy jest to rozwiązanie, którego szukasz ... ale użyłem tego: keepcase.vim

W vimie nie ma innego wsparcia ...

LB40
źródło
11

pewnie, że możesz

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

ps. Zgaduję, że keepcase.vim zawiera podobną logikę :)

fc.
źródło
Tak, od 2007::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Czyli od czasu gVima 7.2? Wypróbowałem to w gVim 7.1 (12 maja 2007) i nie działa :(
fc.
Nie, dodałem polecenie: SubstituteCase do wtyczki w 2007 roku. To wszystko. Wtyczka jest dostępna na vim.org i nie jest dostarczana z vimem jak zwykle z większością wtyczek.
Luc Hermitte
1. To się nie powiedzie, gdy użytkownik ma :set ignorecase. 2. Badzostanie zastąpiony przez GOODzamiast Good. 3. Część „ job” pytania jest ignorowana, więc spowoduje to również zastąpienie lambadalamgooda. Poprawki i wyjaśnienia tych błędów i kilka innych rzeczy w mojej odpowiedzi . (Również LOLOWLs!)
Aaron Thoma
7

Możesz po prostu wkleić i dostosować to:
(Oczywiście, jeśli robisz to od czasu do czasu, zamiast tej potworności będziesz potrzebować wtyczki. Ale dla niektórych, którzy się spieszą i potrzebują jej tylko raz, jest to szybki hack dla przyjemności wklejania :)

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

Oprócz wzorca wyszukiwania musisz edytować cztery 'ciągi 'w kodzie zastępczym: Edytuj części pogrubione :

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

Nie używaj tej „pomarańczowej” wersji do wklejania, ponieważ znaki podziału wiersza również spowodują przerwanie polecenia.

/\zeto cukier syntaktyczny vim regex do oznaczania dodatniego wyprzedzenia: wzorzec po \zejest sprawdzany, ale nie zastępowany.


is#?? Pozwól, że wyjaśnię… (jeśli zainteresowany.)

#(także w ==#i inne ) wymusza uwzględnianie wielkości liter. W przeciwnym razie, z :set ignorecase(którego używam, ponieważ jest to wymagane dla użytecznego :set smartcase), vim rozważy 'a' == 'A'!!

Choć jest to szalone, naprawdę powinniśmy to uwzględnić: ponieważ jest to zależne od ustawień użytkownika, ==należy użyć NEVAR! (Z wyjątkiem miejsca, w którym faktycznie byłoby to tym, czego chcesz). Będę nawet postępować zgodnie z zaleceniami dotyczącymi ==#porównywania liczb całkowitych: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is#zamiast ==#to inny sposób kodowania defensywnego: poprawia bezpieczeństwo typów: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Powinien być używany do porównywania z literałem ciągu.

'single-quoted'zamiast "double quoted" ciągów znaków to kolejna dobra praktyka: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - ta odpowiedź opiera się na ich odpowiedzi , naprawiając kilka niedociągnięć.

Aaron Thoma
źródło
4

Jeśli dopasowujesz tylko dokładny (niezależny od wielkości liter) ciąg z kilkoma możliwymi literami, inną możliwością jest:

:s/abc/\={'abc':'xyz','Abc':'Xyz'}[submatch(0)]/i
rampion
źródło
2

Alternatywą dla wtyczki Keepcase jest SmartCase - zastępowanie słów przy zachowaniu oryginalnej wielkości liter . (Nie zrażaj się złymi ocenami).

Ingo Karkat
źródło
1
Czy jest jakiś sposób na skrócenie tych trudnych do zapamiętania i żmudnych poleceń, takich jak :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: Możesz użyć :SmartCasepolecenia. Rozszerzyłem to w swoim własnym widelcu . Zauważ, że wymaga to ingo-library jako zależności.
Ingo Karkat