Chciałbym zoptymalizować mój przepływ pracy „znajdź i zamień” w Vimie. Często to robię, bo jestem pewien, że większość z was też. Zwykle coś w stylu - skopiuj blok i zmień nazwę zmiennej w kilku miejscach. Wiem, wiem, to prawdopodobnie wyzwala odruch „dlaczego kopiujesz i wklejasz kod”, ale nie idźmy tą drogą… Jest wiele ważnych przypadków użycia :)
Jestem świadom poszukiwaniu i zastąpienie polecenia: :s
albo :%s
ale ja ich nie lubię. Zmusza mnie do wpisania zarówno pełnej nazwy zmiennej, której szukam, jak i tego, na co ją zmieniam. Może jest lepszy sposób, aby naprawić ilość pisania :%s
? Często używam długich opisowych nazw zmiennych, więc jest to dla mnie naprawdę przełom. Nie podoba mi się również to, jak pisanie od podstaw nazwy zmiennej jest podatne na literówki i może pochłaniać czas i siłę roboczą podczas wyszukiwania literówek. Wolę pisać raz, a potem kopiować i wklejać, aby w miarę możliwości całkowicie tego uniknąć.
Mój obecny przepływ pracy wykorzystuje kombinację ruchów / yank / select / search / put, aby poruszać się po pliku i zamieniać jeden po drugim. To nie jest świetne, ale ma tę zaletę, że pozwala uniknąć wpisywania pełnych nazw zmiennych. Być może będę musiał po prostu wpisać kilka pierwszych liter /
lub użyć innego polecenia ruchu (np. fx
) W zależności od tego, co jest w pobliżu, a następnie naciśnij, ve
aby zaznaczyć całe słowo. Nie przeszkadza mi również to, że muszę powtarzać za każdym razem. Nigdy nie dokonuję pełnego znalezienia zamiennika bez potwierdzenia każdej zmiany. Byłoby jednak znacznie lepiej, gdybym mógł powtórzyć czynność zastępowania jednym naciśnięciem klawisza (czego nie mogę zrobić z tą metodą). każda wymiana jest zazwyczaj coś w n
czym ve
wtedy p
(lub nawet gorzej "0p
)
Czy jest szybszy sposób?
źródło
.
powtarza ostatni „blok poleceń” (nie jestem pewien dokładnego terminu. na przykład: move + action + text. na przykład:cwtoto<Esc>
(zmień kursor na koniec słowa za pomocą „toto”),c/foo<enter>bar<Esc>
(zmień kursor na tuż przed „ foo ”i zamień na„ bar ”). następnie możesz przenieść (kursorem, hjkl lub liczbą + hjkl (robi to n razy), G (przejdź na koniec pliku), / coś (przejdź tuż przed„ coś ”) itp.), a następnie naciśnij przycisk,.
aby ponownie wykonać ten sam„ blok poleceń ”n
ve
"0p
. Które niestety nie da się powielić za pomocą.
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Odpowiedzi:
W rzeczywistości mam bardzo podobny przepływ pracy (kopiowanie i wklejanie bloków, które są podobne, a następnie używanie
:s
do zmiany nazw zmiennych), zwłaszcza gdy piszę wiele wierszy, które są podobne, z wyjątkiem używanych przez nich zmiennych. Ale robię kilka rzeczy, które mogą ci się przydać.Ogólne rzeczy vim
Pierwszą rzeczą, która pomoże ci, jest uświadomienie sobie, że
:s//foo/g
wypełnisz wyszukiwane hasło użyte ostatnio i zastąpisz je foo . Samo to może zaoszczędzić dużo czasu, ale jeśli połączysz je z poleceniem gwiazdką (wyszukaj słowo pod bieżącym kursorem), zaoszczędzisz mnóstwo czasu. Na przykład, aby zmienić wszystkofoo
naspam
, zamiast robićCo wymaga wpisania zarówno foo, jak i spamu (które mogą być długimi zmiennymi), możesz po prostu przejść do foo i wykonać:
W ten sposób możesz szybko uzyskać nazwę zmiennej, którą zmieniasz, wyszukując ją, wtedy nie będziesz musiał jej wpisywać. Będzie to również dobrze działać przy bieżącym przepływie pracy przy częstym używaniu
n
. Pomocne jest równieżhlsearch
włączenie, ponieważ wtedy możesz wizualnie określić, gdzie znajdują się zmienne, które zastępujesz.(dygresja: Komenda gwiazdka doda granic słów, że jest
\<
i\>
wokół słowa pod kursorem Jeśli nie chcesz tego używać.g*
zamiast).Możesz użyć
@:
do ponownego wykonania ostatniego polecenia zastępczego. To dobrze, jeśli chcesz wykonać:s
polecenie na wielu liniach, ale nie wszystkie, więc:%s
nie będą działać. Inną opcją jest flaga potwierdzenia, tj:%s///gc
. Umożliwi to wpisaniey
lubn
przy każdym wystąpieniu, aby zdecydować, czy chcesz go zastąpić, czy nie.Jak wskazał Desty , możesz również zrobić &ponowne uruchomienie ostatniego polecenia zastępczego, ale pamiętaj, że to nie zachowa twoich flag (takich jak
global
lubconfirm
). To, czy to dobrze, czy źle, zależy od Twojej osobistej opinii. Jeśli chcesz tego użyć, ale masz też swoje flagi, możesz to zrobićJeśli chcesz zmienić każde wystąpienie w bloku, ale nie każde dopasowanie w pliku, zawsze możesz użyć wizualnego wyboru bloku, który wypełni
do twojego zamiennika, co ogranicza go do wybranych linii. W połączeniu z podejściem z gwiazdką uważam to za niezwykle przydatne. Ponadto, jeśli tworzysz wiele poleceń zastępczych w tym samym bloku linii, możesz użyć gvtego samego wiersza, aby wykonać inne polecenie. (czy to
:substitute
polecenie normalne)Jeśli wykonasz inne polecenie zastępcze, nie musisz ponownie wybierać tych samych linii, ponieważ
:'<,'>
nadal będą działać na tych samych liniach. Jednak wygodniej jest pisaćzamiast
Wtyczki / mapowania lubię
Mam w sobie następujące mapowanie,
.vimrc
które rozszerza podejście do gwiazdki, więc muszę tylko wpisać nową pożądaną nazwę:Aby tego użyć, po prostu ustaw kursor na słowie, które chcesz zmienić, i wpisz
<leader>rNewVarName<cr>
i gotowe. Pamiętaj, że spowoduje to zastąpienie wszystkich dopasowań bez możliwości ich potwierdzenia, więc może Ci się to nie podobać. Oczywiście możesz to zmienićAby zezwolić na opcję potwierdzenia.
edytuj : Po odpowiedzi zarówno Mszy, jak i komentarza rcorre , możesz również napisać to jako
Co ma tę zaletę, że twój bezimienny rejestr pozostaje taki sam.
Jeśli zmieniasz nazwy grup podobnych zmiennych w tym samym czasie, na przykład zmieniając
do
zastąpienie ich wszystkich osobno może być uciążliwe. Tutaj przydaje się tpope / vim-abolish . Możesz zamienić je wszystkie w jednym poleceniu na:
i dba o twoje wielkie litery.
To powinno ci bardzo pomóc, ale daj mi znać, jeśli jest coś w tych podejściach, które ci się nie podobają lub których brakuje. Cieszę się, że mogę mówić o innych podejściach. :)
Rekomendowane lektury:
:h s_c
:h *
:h g*
:h @:
:h /\<
:h &
źródło
<leader>rc
(lubcr
) dodanie tego/c
na końcu. Ponadtoset gdefault
ustawiłem, ponieważ prawie nigdy nie chcę zastąpić jednego wyniku, więc byłoby to po prostuyiw:%s/\<<C-r>"\>//<left><left>
ctrl+r-ctrl+w
mapowania (jak sugeruje @Mass), powinno działać tak samo, ale nie zadziała z twoim rejestrem yank (co może, ale nie musi być pożądane).
do wykonywania kolejnych podstawień.c_CTRL-R
Rodzina map może poprawić przepływ pracy sporo:Podczas używania nie musisz wpisywać nazw zmiennych
:s/
, po prostu użyj,CTRL-R
CTRL-W
aby wstawić słowo pod kursorem do wiersza poleceń (zastrzeżenie: nie unika znaków specjalnych, jak to*
robi).Po wprowadzeniu niewielkiej zmiany za pomocą
ce
, możesz wyszukać stare słowo za pomocą/
CTRL-R
-
. Następnie użyj,.
aby powtórzyć zmianę.Jeśli chcesz wprowadzić zmiany we wzorcu wyszukiwania, umieści
CTRL-R
/
istniejące wyszukiwanie w wierszu polecenia.Na koniec możesz umieścić zawartość dowolnego rejestru za pomocą
CTRL-R
{register}
źródło
Ctrl-R
/
? Używam tego dość często w:s
poleceniach, jeśli chcę użyć wyszukiwanego terminu, który jest prawie, ale nie całkiem taki sam, jak poprzedni.Jest jeszcze kilka metod, które (ku mojemu zaskoczeniu!) Nie zostały jeszcze wspomniane.
Korzystanie z
gn
poleceniagndziała jak npolecenie, tyle że oprócz przeskakiwania do meczu wchodzi w tryb wizualny z zaznaczonym całym dopasowaniem.
Aby więc zmienić słowo (lub cokolwiek, co możesz dopasować wyrażeniem regularnym!) Najpierw wyszukaj je 1 , a następnie naciśnij, cgna następnie tekst, który chcesz zastąpić dopasowaniem, i Escpowróć do trybu normalnego.
(Wspominasz, że czasami tekst zastępczy, którego chcesz użyć, jest przechowywany w
"0
rejestrze szarpnięć - pamiętaj, że możesz go szybko wprowadzić bez konieczności ponownego wpisywania, naciskając Ctrl+R0w trybie wstawiania).Możesz następnie przejść do następnego meczu i powtórzyć zmianę jednym .naciśnięciem klawisza!
Jeśli są jakieś miejsca, w których nie chcesz dokonywać zamiany, po prostu naciśnij, unaby cofnąć zmianę i przejść do następnego meczu.
1: szybszego, wykorzystując inne sugestie na tej stronie, takich jak *, Ctrl+RCtrl+Witp Zobacz również komentarz Petera Rincker za więcej sugestii o tym, jak początkowo wypełnić swoje wyszukiwanie.
Korzystanie z trybu wyboru
(Nauczyłem się tego od romainl „s postu na subreddita vim . Nie wiem, czy wymyślił to sam lub po prostu przekazania go).
Tryb zaznaczania jest trochę podobny do trybu wizualnego, z tym wyjątkiem, że jeśli zaczniesz pisać zaznaczony tekst zostanie natychmiast zastąpiony tym, co piszesz (np. Jak zaznaczenie działa w większości innych edytorów).
W ten sposób możesz użyć tego trio mapowań, aby szybko znaleźć / zamienić, w razie potrzeby możesz zmienić plik środkowy:
Mapowanie w trybie normalnym : Wejście do trybu wyboru ze słowem najbliższym wybranym kursorem.
Następnie możesz wpisać zamiennik dla wybranego słowa i ( bez naciskania Esc) użyć:
Wstaw tryb mapowania : Przeskakuje do następnego dopasowania i przechodzi do trybu wyboru.
Następnie możesz wpisać nowy zamiennik lub nacisnąć, .aby użyć:
Wybierz tryb mapowania : Ponownie wprowadza ostatnio wstawiony tekst - w zasadzie powtarza ostatni wstawiony tekst.
źródło
gn
metodę na końcu moją odpowiedź vi.stackexchange.com/a/13696/488 wczoraj za co jej wartości! Twoja odpowiedź ma jednak znacznie ładniejsze formatowanie.gn
raz) i jest to szczególna metoda (a nie tylkogn
polecenie), która mnie zaskoczyła, nie została jeszcze wspomniana.gn
. Daje ci więcej opcji wyszukiwania. Wizualne odwzorowanie gwiazda biedaka:xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>
. Powiązany odcinek Vimcasts: Operacja wyszukiwania wyników za pomocą gnWtyczka https://github.com/terryma/vim-multiple-cursors zajmuje się tym problemem w przeważającej części.
Mój przepływ pracy jest zwykle następujący:
ctrl-n
aż wszystko zostanie wybrane.c
i zacznij pisać zamiennik.Wygodną rzeczą jest to, że możesz wykonywać bardziej skomplikowane operacje niż tylko wyszukiwanie-zamień, chociaż uważam, że jeśli posuniesz się za daleko, wtyczka zacznie wykazywać pewne usterki.
źródło
Kolejny sposób na zrobienie rzeczy, o których jeszcze nie wspomniano: Możesz użyć okna wiersza poleceń (otwartego
q:
w trybie normalnym -:help q:
więcej informacji), w którym masz pełny dostęp do funkcji autouzupełniania Vima (i_CTRL-N
/i_CTRL-P
i różnychi_CTRL-X
sekwencji bycie wśród nich).W oknie wiersza poleceń możesz także używać poleceń trybu normalnego do edycji wiersza poleceń, co oznacza na przykład, że możesz szarpać i wklejać części poprzednich poleceń w historii wiersza poleceń.
Zauważ, że podczas korzystania z niego kursor zostanie przeniesiony do okna wiersza polecenia, co oznacza, że
CTRL-R CTRL-W
i podobne metody polegające na wstawianiu tekstu pod kursorem nie będą tam działać, w przeciwieństwie do zwykłego wiersza poleceń.źródło
:substitute
polecenia, naciskając<ctrl-f>
Dla mnie rozwiązanie jest nieco pomiędzy innymi odpowiedziami:
Załóżmy, że masz 6 identycznych wierszy i chcesz zastąpić „jabłko” w środkowych dwóch:
To co robię to:
v
aby przejść do trybu wizualnego2j
:s/<C-R><C-W>/
który wykorzystuje zaznaczenie wizualne jako zakres:s
, a następnie wstawia słowo pod kursorem<C-F>
co powoduje przejście do trybu, w którym możesz edytować swoje polecenie tak, jakby to był bufor. Możesz więc użyć dowolnego uzupełnienia lub wtyczek, aby wybrać słowo zastępcze i gotowe.Wszystko w jednej linii, przepływ byłby taki,
/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>
ale wygląda to gorzej niż jest w rzeczywistości.W twoim przypadku można dołączyć
/c
do:s
polecenia, aby pominąć te, których nie chcesz, jeśli zakres zawiera kilka chcesz pominąć::s/<C-R><C-W/orange/c
.Alternatywnie (a może prościej), można szukać całego wyrazu, który chcesz zastąpić,
c
mień, a potemgn
i.
powtórzyć szukanie i stosują tę samą zmianę ponownie. Wygląda na to, że/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.
powtarza się trzy, następnie pomija instancję, a następnie powtarza ją po raz ostatni.źródło
vim -Nu NONE
). Po pierwszym naciśnięciu wydaje sygnał dźwiękowy.
. Masz pomysł, dlaczego tak jest? W każdym razie łatwiej byłoby używaćciw
zamiastviw
in
zamiastgn
wprowadzać zmiany w ten sposób.Nie jest to całkowicie związane z pytaniem, ale nadal powinno pomóc w wyborze słowa do zastąpienia.
Przyrostowe wyszukiwanie (
set incsearch
) pozwala wpisać prefiks słowa, które musisz znaleźć, a vim automatycznie przeskoczy do pierwszego wystąpienia tego słowa, gdy będziesz pisać coraz więcej. Wyszukiwanie zostanie potwierdzone, jeśli naciśniesz Enter i odrzucisz klawisz Esc (w tym drugim przypadku kursor wróci do miejsca, w którym był przed rozpoczęciem wyszukiwania).Jednak wyszukiwanie przyrostowe zapewnia jeszcze jedną przydatną funkcję. Gdy już wpiszesz prefiks słowa, a kursor znajdzie się we właściwej pozycji, naciśnij,
<C-L>
aby dodać znaki ze słowa pod kursorem do wyszukiwanego ciągu. Pozwala to wprowadzić zastąpiony ciąg bez prawie żadnych naciśnięć klawiszy.Tak więc, jeśli chcę wymienić
someOddVariableName
zevenOdderVariableName
, ja/someOddV
i dotrzyj do wystąpieniasomeOddVariableName
;<C-L>
ażsomeOddVariableName
pojawi się całkowicie w linii wyszukiwania;:%s//evenOdderVariableName/g
lub cokolwiek zastąpi potrzebne polecenie; możesz tutaj skorzystać z innych odpowiedzi.źródło
Możesz najpierw umieścić nazwę zmiennej w buforze (
yw
aby skopiować słowo), a następnie skopiować i wkleić ją:%s
, naciskając<C-r>"
.źródło
Jeśli chcesz zastąpić zmienną w nowym (wklejonym) bloku, mam dwie sugestie:
Zautomatyzowana wymiana
Przejdź do pierwszego wiersza nowego bloku, naciśnij
ma
. Oznacza to lokalizację i nadanie jej nazwya
.Przejdź do ostatniego wiersza nowego bloku, naciśnij
mb
. Teraz masz dwie nazwane lokalizacje.Teraz wymienić między dwiema liniami, tak:
:'a,'bs/oldVarName/newVarName/g
.Oznacza to, że zakres zamiany znajduje się między dwoma znakami.
Sposób ręczny
Przejdź do pierwszego wiersza nowego bloku.
Użyj,
/oldVarName
aby znaleźć pierwsze wystąpienieoldVarName
.Zmień to w ten sposób:,
cwnewVarName<Esc>
co zmieni słowo nanewVarName
i uderzy w ucieczkę.Użyj,
n
aby przejść do następnej instancjioldVarName
.Użyj,
.
aby powtórzyć ostatnią zmianę (tj. Powtarza tocw
).źródło
Wiele innych odpowiedzi tutaj obejmuje już wbudowane sposoby poprawy przepływu pracy znajdowania i zastępowania, ale chciałem wspomnieć o abolish.vim , wtyczce Tima Pope'a. Dokonuje zamienników tam, gdzie chcesz objąć szerszy zakres przypadków, zwykle spowodowanych przez różnice w przypadkach lub ponieważ musisz radzić sobie zarówno z pojedynczą, jak i mnogą formą słowa.
:S/child{,ren}/adult{,s}/g
poprawnie konwertujechild
naadult
,Children
naAdults
iCHILD
naADULT
.Jeśli masz do czynienia ze słowami wielbłąda, musisz zamienić stolice tam, gdzie są potrzebne, w słowach oryginalnych i zastępczych.
%:S/wordWrap/textBreak/g
poprawnie obsługuje zarównowordWrap
iwordwrap
.źródło
Jak już zauważyli inni, jeśli kursor znajduje się nad słowem, możesz użyć rodziny poleceń Ctrl + r, ponieważ Ctrl + r Ctrl + w jest prawdopodobnie najbardziej odpowiednim do użycia.
Ta metoda działa jednak tylko w przypadku wstawienia jednego słowa (tego tuż pod kursorem), ale co zrobić, jeśli w buforze znajduje się kilka części tekstu, których chcemy użyć? Gdy nie możesz poruszać kursorem w wierszu polecenia. Najlepszym sposobem na to jest skopiowanie potrzebnych fragmentów tekstu do różnych rejestrów, co można zrobić, poprzedzając operatora „{reg_letter} (cytat i litera z rejestru) operatorowi kopiowania. W ten sposób będzie można wstaw różne słowa w wierszu poleceń później za pomocą Ctrl + r {reg_letter}. To trochę dziwne, ale działa.
Ale wracając do poprzedniego pomysłu, byłoby wspaniale, gdybyśmy przesuwali kursor nad buforem podczas pisania wzoru. W ten sposób mogliśmy „wybierać” tekst z różnych pozycji za pomocą Ctrl + r Ctrl + w, więc stworzyłem wtyczkę, która to robi: EXtend.vim Wtyczka ma również wiele innych funkcji do wykonywania operacji podstawiania.
źródło