Jak mogę wkleić (nadpisać) za pomocą vima?

31

W vimużywam yyi pcały czas szarpię i wklejam linie. Jednak jeśli chcę zastąpić jedną linię wieloma miejscami w pliku, nie mogę użyć, yy p dd pponieważ dd usuwa linię do schowka / rejestru. Chociaż prawdopodobnie powinienem wiedzieć, jak lepiej korzystać z rejestrów, wydaje mi się, że jest na to sposóbp zastąpienie bieżącej linii.

cwd
źródło

Odpowiedzi:

27

Domyślnie polecenia wklejania używają "rejestru („bez nazwy”) . W efekcie każde polecenie, które zapisuje do rejestru, również zapisuje do rejestru nienazwanego, więc wyszarpuje, usuwa i zmienia wszystko. Właśnie dlatego twoja sekwencja usuwania i wklejania wkleja usunięty tekst zamiast zrywanego tekstu.

0Rejestr może pomóc tutaj. Wszelkie polecenia szarpnięcia, które nie określają rejestru, umieszczają szarpany tekst w rejestrze 0(oprócz "). Operacje usuwania lub zmiany nie mają na nią wpływu, więc możesz użyć go do wielokrotnego wklejenia szarpanej linii, nawet jeśli wykonujesz pośrednie usuwanie lub zmiany.

  1. yy: Rejestry 0i" oba mają teraz szarpaną linię.
  2. Przejdź do linii, aby zastąpić.
  3. dd: Zarejestruj się "teraz ma usuniętą linię, ale rejestr 0nadal ma szarpaną linię.
    "0P: Wklej oryginalnie szarpaną linię z rejestru 0.
  4. Przejdź do następnego wiersza, aby go zastąpić.
  5. dd"0P (tak samo jak powyżej)

(Ze względu na sposób, w jaki działa pozycjonowanie kursora podczas zastępowania ostatniego wiersza bufora, będziesz chciał użyć "0pzamiast "0P.)

Jest to bardzo zbliżone do odpowiedzi Bruce'a Edigera , z tym wyjątkiem, że nie musisz określać rejestru, gdy początkowo szarpałeś. Używanie jednego lub więcej nazwanych rejestrów może być bardzo przydatne, jeśli musisz (na przykład) zamienić niektóre wiersze na AAA, ale inne wiersze na BBB(wpisz AAAdo rejestru ai BBBdo rejestru b(lub pozostaw jeden z nich w rejestrze)0 ), a następnie wklej je odpowiednio ).

Można również wkleić ze 0w trybie wizualnym linia mądry ( V), aby zapisać klawiszy: V"0p.

Jeśli nie lubisz pisać "0, wygodniejsze może być mapowanie:

noremap <Leader>p "0p
noremap <Leader>P "0P
vnoremap <Leader>p "0p

Alternatywnym podejściem jest usunięcie z _rejestru („czarnej dziury”) . Po usunięciu do "rejestru nie ma to wpływu na rejestr, więc sekwencja yank-delete-paste może nadal wklejać tekst z rejestru bez nazwy.

  1. yy: Zarejestruj się 0i "oba mają teraz szarpaną linię.
  2. "_dd: Brak zmian w rejestrach.
    P: Wklej pierwotnie wyrwany tekst z rejestru ".

Ponownie, mapowanie może być wygodniejsze:

noremap <Leader>d "_d
Chris Johnsen
źródło
2
Lub, tl; dr, po prostu użyj yy(przejdź do linii do zastąpienia) S<C-r>0<Esc>. Ma tę zaletę, że jest powtarzalna z .poleceniem.
Wildcard
11

Wygląda na to, że Kevin ma całkiem dobrą odpowiedź, ale jeśli chcesz spojrzeć na każdą usuwaną linię, a następnie ją zastąpić, istnieje nieco inne rozwiązanie.

1. Find line to copy in some select number of places.
2. Put cursor on it.
3. "ayy copies that line into register 'a'.
4. Find line to replace. Put cursor on it.
5. dd deletes that line. "aP inserts the copied line above where the cursor now lies.
6. Repeat steps 4 and 5.

Ten rodzaj przepisu pozwala na użycie dopasowania wzorca do znalezienia linii do usunięcia i zastąpienia, a także możesz wrócić do początku pliku (1G) i wyszukiwać do przodu tak często, jak chcesz. Jeśli mam 2 lub więcej linii do zebrania i umieszczenia wielokrotnie, używam "ayydla pierwszej linii, "byydla drugiej, "cyydla trzeciej i tak dalej. Przyzwyczaiłem się (co zmniejsza ogólność przepisu), aby zmniejszyć obciążenie psychiczne.

Bruce Ediger
źródło
Bardzo dobrze. Więc jeśli mogę użyć "ayy, a następnie dd, ddnie zastąpi tego, co jest a, ale jeśli wpisuję pto wklej to, co było po prostu usunąć za pomocą dd. A jeśli chciałbym zastąpić to, co jest, "ayytym, co usuwam, to użyłbym "add- czy to prawda?
cwd
„ayy kopiuje linię do rejestru„ a ”.„ dd ”przecina linię do rejestru domyślnego, a nie„ a ”.„ p ”wkleja rejestr domyślny, poprawne. I tak,„ add wycina linię do rejestru „a” , który zastąpiłby treść polecenia „tak.”
Bruce Ediger,
5

Można to zrobić na kilka sposobów :s, w zależności od tego, ile chcesz pisać. Najprostszym sposobem jest proste wyszukiwanie i zamiana:

:%s/find this line/replace with this/

%Przeszuka cały plik i zastąpić wszystkie wystąpienia.

Jeśli to dla Ciebie za dużo pisania, możesz pociągnąć za docelowy ciąg ( yy) i użyć "(domyślnego) rejestru, wstawiając go za pomocą Ctrl+r ":

:%s/<ctrl+r><">/replacement/

Lub, jeśli masz kopię ciągu zastępującego, możesz przeciągnąć je do osobnych rejestrów za pomocą "ayyi, i "byypociągnąć odpowiednio do rejestrów ai b(możesz użyć dowolnej litery dla swoich rejestrów). Następnie użyj Ctrl+r ai, Ctrl+r baby wkleić je do pola wyszukiwania i zamień.

Nie do pojedynczego Bruce'a, ale jeśli chcesz sprawdzić linie przed ich zastąpieniem, po prostu dodaj copcję:

:%s/find this line/replace with this/c
Kevin
źródło
2

Możesz użyć, Vaby podświetlić linię, którą chcesz zastąpić w trybie wizualnym, a następnie naciśnij, ppaby wkleić tę linię.

Dodaje to tylko jedno naciśnięcie klawisza, więc wydaje się, że to całkiem dobre rozwiązanie.

Mouche
źródło
To nie działa: po wklejeniu schowek zawiera tekst, który został zaznaczony przezV
Daniel Kullmann
Tylko jeden p.
Aaron Thoma,
2

Używam polecenia c„zmień” dość często do tego rodzaju rzeczy, w połączeniu z regularnym wyszukiwaniem. Możesz przeszukać plik pod kątem każdego interesującego cię wiersza / tekstu, a następnie użyć kolejnych n.poleceń ( ndla następnego, a następnie, .aby powtórzyć ostatnią zmianę).

/^hello- znajdź linię zaczynającą się od hello;
c$goodbye- zmień linię na do widzenia;
n.- powtórz wyszukiwanie, powtórz zmianę

Jeśli chcesz zmienić wiersz na jeden już w pliku, możesz po prostu skopiować go do bufora wejściowego (zakładając, że GUI na to pozwala), a następnie wkleić, aby uzyskać treść pierwszego polecenia zmiany.

Jak w przypadku wszystkich rzeczy vi, dobrze jest mieć wiele opcji w kieszeni, w zależności od tego, jaką edycję chcesz wykonać.

rghome
źródło