Kiedy wyszukuję za pomocą /
polecenia trybu normalnego:
/\vSEARCHTERM
Vim rozpoczyna wyszukiwanie od pozycji kursora i kontynuuje w dół, zawijając do góry. Jednak gdy wyszukuję i zamieniam za pomocą :substitute
polecenia:
:%s/\vBEFORE/AFTER/gc
Zamiast tego Vim zaczyna się od początku pliku.
Czy jest sposób, aby Vim przeprowadzał wyszukiwanie i zastępowanie, zaczynając od pozycji kursora i zawijając do góry, gdy dotrze do końca?
\vpattern
- `` bardzo magiczny '' wzorzec: znaki niealfanumeryczne są interpretowane jako specjalne symbole wyrażeń regularnych (bez konieczności zmiany znaczenia)%
? Nie widzę sensu, żebyś i tak przeglądał cały plik.Odpowiedzi:
1. Nie jest trudno osiągnąć zachowanie za pomocą dwuetapowej substytucji:
Najpierw polecenie substytucji jest uruchamiane dla każdej linii, zaczynając od bieżącej do końca pliku:
Następnie
:substitute
polecenie to jest powtarzane z tym samym wzorcem wyszukiwania, ciągiem zastępczym i flagami, używając:&
polecenia (patrz:help :&
):Ta ostatnia jednak dokonuje podstawienia w zakresie wierszy od pierwszego wiersza pliku do wiersza, w którym ustawiono poprzedni znacznik kontekstu, minus jeden. Ponieważ pierwsze
:substitute
polecenie przechowuje pozycję kursora przed rozpoczęciem rzeczywistych zamian, wiersz, do którego adresowany''
jest adres, jest wierszem bieżącym przed wykonaniem tego polecenia zastępowania. (''
Adres odnosi się do'
pseudoznaku; zobacz:help :range
i:help ''
po szczegóły.)Zauważ, że drugie polecenie (po
|
separatorze polecenia - zobacz:help :bar
) nie wymaga żadnej zmiany, gdy wzorzec lub flagi są zmieniane w pierwszym.2. Aby zaoszczędzić trochę pisania, aby wyświetlić szkielet powyższego polecenia podstawienia w linii poleceń, można zdefiniować mapowanie w trybie normalnym, na przykład:
Końcowa
<c-b><right><right><right><right>
część jest niezbędna, aby przesunąć kursor na początek wiersza poleceń (<c-b>
), a następnie cztery znaki w prawo (<right>
× 4), umieszczając go w ten sposób między pierwszymi dwoma ukośnikami, aby użytkownik mógł rozpocząć wpisywanie wzorca wyszukiwania . Gdy żądany wzór i zamiana są gotowe, wynikowe polecenie można uruchomić, naciskając Enter.(Można rozważyć umieszczenie
//
zamiast///
w odwzorowaniu powyżej, jeśli ktoś woli wpisać wzorzec, a następnie samemu wpisać separujący ukośnik, a następnie ciąg zastępujący, zamiast używać strzałki w prawo, aby przesunąć kursor na już istniejący separujący ukośnik rozpoczynający się część zamienna.)źródło
:noremap <leader>R :,$s///gc\|1,''-&&<c-b><right><right><right><right>
. Wstawia:,$s///gc|1,''-&&
do wiersza poleceń z kursorem między pierwszymi dwoma ukośnikami. Po wpisaniu żądanego wzoru i zamiany możesz uruchomić wynikowe polecenie, naciskając klawisz Enter .Używasz już zakresu,
%
który jest krótką ręką1,$
oznaczającą cały plik. Aby przejść od bieżącej linii do końca, którego używasz.,$
. Kropka oznacza bieżącą linię i$
ostatnią linię. Więc polecenie byłoby następujące:Ale
.
można założyć, że linia lub bieżąca może zostać usunięta:Aby uzyskać więcej pomocy, zobacz
źródło
10:s/pattern/replace/gc
%
jest skrótem do1,$
(Vim help =>
:help :%
równe 1, $ (cały plik).).
jest pozycją kursora, więc możesz to zrobićAby zamienić od początku dokumentu do kursora
itp
Zdecydowanie sugeruję przeczytanie instrukcji o zasięgu,
:help range
ponieważ prawie wszystkie polecenia działają z zakresem.źródło
W KOŃCU znalazłem rozwiązanie na fakt, że zakończenie wyszukiwania zawija się do początku pliku bez pisania ogromnej funkcji ...
Nie uwierzysz, ile czasu zajęło mi wymyślenie tego. Po prostu dodaj monit, czy zawijać: jeśli użytkownik naciśnie
q
ponownie, nie zawijaj. Zasadniczo zakończ wyszukiwanie, dotykającqq
zamiastq
! (A jeśli chcesz zawijać, po prostu wpiszy
.)Właściwie mam to przypisane do skrótu. Na przykład, jeśli chcesz wyszukać i zamienić każde słowo pod kursorem, zaczynając od bieżącej pozycji, na
q*
:źródło
q
,l
lub Esc ) i nie chcesz kontynuować od góry, możesz już ponownie nacisnąćq
lub Esc, aby od razu wyjść z drugiego polecenia. Oznacza to, że proponowane dodanie zachęty wydaje się skutecznie powielać już obecną funkcjonalność.yyyq
kontynuacja edycji bez dezorientujących skoków. Aleyyyqq
jest prawie tak samo dobre, jeśli weźmiesz pod uwagę dwukrotne dotknięcie, a prawie jedno dotknięcie pod względem łatwości użytkowania.q
drugiego naciśnięcia ). Ta ostatnia pozostawia kursor w ostatnim zastąpionym wystąpieniu (tuż przedq
naciśnięciem pierwszego ).norm!``
polecenia::,$s/BEFORE/AFTER/gc|1,''-&&|norm!``
.Oto coś bardzo szorstkiego, które rozwiązuje obawy związane z zawijaniem wyszukiwania metodą dwuetapową (
:,$s/BEFORE/AFTER/gc|1,''-&&
) lub pośrednim „Kontynuować na początku pliku?” podejście:Ta funkcja używa kilku hacków, aby sprawdzić, czy powinniśmy zawinąć do góry:
źródło
Spóźniłem się na imprezę, ale zbyt często polegałem na tak późnych odpowiedziach, aby tego nie robić. Zebrałem wskazówki dotyczące reddit i stackoverflow, a najlepszą opcją jest użycie
\%>...c
wzorca w wyszukiwaniu, który pasuje tylko do kursora.To powiedziawszy, również psuje wzór dla następnego kroku wymiany i jest trudny do wpisania. Aby przeciwdziałać tym efektom, funkcja niestandardowa musi później przefiltrować wzorzec wyszukiwania, a tym samym go zresetować. Zobacz poniżej.
Walczyłem z mapowaniem, które zastępuje następne wystąpienie i przeskakuje do następnego, a nie więcej (i tak było moim celem). Jestem pewien, że opierając się na tym, można wypracować globalną substytucję. Podczas pracy nad rozwiązaniem mającym na celu coś takiego
:%s/.../.../g
, poniższy wzorzec odfiltrowuje dopasowania we wszystkich wierszach po lewej stronie kursora - ale jest czyszczony po zakończeniu pojedynczego zastępowania, więc traci ten efekt bezpośrednio po tym, przeskakuje do następny mecz i dzięki temu jest w stanie przejść przez wszystkie mecze jeden po drugim.fun! g:CleanColFromPattern(prevPattern) return substitute(a:prevPattern, '\V\^\\%>\[0-9]\+c', '', '') endf nmap <F3>n m`:s/\%><C-r>=col(".")-1<CR>c<C-.r>=g:CleanColFromPattern(getreg("/"))<CR>/~/&<CR>:call setreg("/", g:CleanColFromPattern(getreg("/")))<CR>``n
źródło