Vim: Zastąpienie jednej linii inną, wcześniej szarpaną


112

Przynajmniej raz dziennie mam następującą sytuację:

A: This line should also replace line X
...
X: This is line should be replaced

Uważam, że nie wykonuję tego zadania skutecznie.

Co robię:

  • Przejdź do linii A: AG
  • Linia Yank A: yy
  • Przejdź do wiersza X: XG
  • Wklej wiersz A: P
  • Przejdź do starej linii: j
  • Usuń starą linię: dd

Ma to tę dodatkową wadę, że linia X jest obecnie w domyślnej rejestru, co jest irytujące, jeśli znajdę inną linię, która powinna zostać zastąpiona A. szarpiąc się i wklejanie z dodatkowego rejestru ( „ayy , ” AP ) sprawia, że to proste zadanie nawet mniej wydajne.

Moje pytania:

  • Czy przegapiłem wbudowane polecenie Vima, aby zastąpić wcześniej szarpaną linię?
  • Jeśli nie, w jaki sposób mogę powiązać własne polecenie, które pozostawia (lub przywraca) szarpaną linię w rejestrze domyślnym?

2
To jest mój największy problem z modelem edycji Vima. Bardzo chciałbym poznać rozwiązanie. Edytor CUA rozróżnia wycinanie i usuwanie, więc po prostu wycinasz tekst, a następnie możesz usunąć i wkleić wszystko, co chcesz. Z Vimem każde usunięcie, które zrobisz, kasuje wycięty tekst. W efekcie używasz znacznie większej liczby naciśnięć klawiszy niż w przypadku innego edytora.
Błoto


@Mud poznać :movei czarna dziura rejestr ( _) (lub w rzeczywistości, tylko rejestry)
sehe

2
@sehe Jestem doskonale świadomy istnienia rejestrów, ale to dodaje 4 naciśnięcia klawiszy na operację wycinania / wklejania i wymaga więcej przemyślenia. Kiedy robisz dużo edycji, szybko się to sumuje.
Błoto

Czy poza zapisaniem kilku bajtów pamięci istnieje przewaga korzystania z rejestru czarnej dziury w porównaniu z jakimkolwiek innym rejestrem? Twierdziłbym, że każdy rejestr może być rejestrem czarnej dziury, jeśli nie przeczytasz z niego.
sleblanc

Odpowiedzi:


91

Co ja bym zrobił:

  1. aG
  2. Y
  3. xG
  4. Vp

Nie musisz wychodzić z trybu normalnego, ale powoduje to szarpnięcie linii. Możesz jednak użyć polecenia, V"0pktóre zawsze spowoduje wstawienie linii szarpanej w kroku 2.


11
@duddle: tak, Yjest synonimemyy
icecrime

8
Kroki 1 i 2 można łączyć za pomocą: ay [np. 20y], a następnie Vp powinno załatwić sprawę. Nie musisz podchodzić do linii, aby go szarpnąć.
Bharad

2
Jeśli nadpisać dodatkowe linie z ccCTRL + r0ESC zamiast V "0P wtedy wszystkie następujące wiersze można zastąpić tylko (repeater).
Jordan Morris

Yjest synonimem dla yy, ale sugeruję przemapowanie go tak, y$aby pasował do Di C.
mgold

Sprawdź odpowiedź Jordana Morrisa stackoverflow.com/users/970673/jordan-morris poniżej - naprawdę wykorzystuje polecenia Vima w pełni, umożliwiając wielokrotne powtarzanie polecenia.
JESii,

105

Vp: wybierz linię, wklej to, co zostało szarpane


3
VPdziała równie dobrze, co jest przydatne, ponieważ możesz przytrzymać Shift przez całą sekwencję.
George Hilliard

24
bardzo fajna sztuczka, choć warto zauważyć (być może) istotne zastrzeżenie: powoduje to, że rejestr yank jest aktualizowany zawartością nadpisywanej linii, więc może nie grać dobrze z niektórymi zadaniami - np. jeśli chcesz nadpisać tę samą linię do wielu miejsc docelowych.
underscore_d

8
@underscore_d, gra ładnie, jeśli to zrobisz V"0p, która wkleja się z ostatniego szarpanego rejestru.
timblaktu

@timblaktu Czy możesz wyjaśnić, co V"0probi? V przechodzi w tryb linii wizualnej, a p służy do wklejania. Co to są "i 0 dla Thanks?
theprogrammer

43

Ma to dodatkową wadę, że linia X jest teraz w rejestrze domyślnym, co jest denerwujące, gdy znajdę inną linię, którą należy zastąpić A.

Aby usunąć tekst bez wpływu na zwykłe rejestry, możesz użyć rejestru czarnej dziury "_:

"_dd

10
Dodałem kilka mapowań do mojego .vimrc, aby stworzyć di ddzawsze używać czarnej dziury xoraz xxwykonywać to, co większość redaktorów nazwałaby "wycięciem" (usuń i zapisz do domyślnego rejestru):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP

2
Obawiam się ponownego mapowania rzeczy w VIM, ponieważ może to nie być łatwe na innych komputerach lub we wtyczkach w stylu VIM dla IDE. Również projektanci VIM mają tendencję do rozwiązywania problemów z domyślnymi mapowaniami, jeśli naprawdę kopiesz.
Jordan Morris

15

Opierając się na odpowiedziach, które sugerują użycie Vplub VPwklejenie w wierszu - aby uniknąć zmiany zawartości rejestru szarpnięć, uważam, że najbardziej ergonomiczne polecenie to po prostu:

VPY


To najprostsze rozwiązanie, które pozostawia tę samą zawartość szarpania. Wielkie dzięki!
heylookltsme

14
  1. rr
  2. j (przejdź do wiersza, który chcesz zamienić), a następnie
  3. Vp (wielkie litery v, a następnie p, zostaną zastąpione przez yankowaną zawartość)

niesamowite! Rzeczywiście bardzo krótki i ułatwia wybór wielu linii w trybie wizualnym. Utrzymuje również nienaruszony bufor pasty. To denerwujące, gdy dd nadpisuje ten bufor ...
Aktau

@Aktau to nie pozostawia nienaruszonego bufora.
Jordan Morris

9

Użyłbym trybu linii poleceń (Ex) i wykonałem następujące dwa polecenia

:XmA
:Ad

To po prostu przesuwa linię X tuż pod A, a usunięcie A przesuwa tę linię w górę

Na przykład

:7m3
:3d

Czy możesz podać przykład? Kiedy naciskam np. 50Gm30G Vim przechodzi do linii 50 a potem na dół i tyle. Ponadto: reklama nic nie robi, gdy A = 50 lub A = 50G
chrupiące

7
  1. Przejdź na początek pierwszej linii.

  2. y, $- skopiuj wiersz bez znaku końca wiersza

  3. Przejdź na początek linii docelowej.

    1. V, p- zamień tylko jedną linię docelową

    2. c, c, Ctrlr, 0, Esc- wymienić linię docelową z oryginalnym szarpnięciem

  4. Przejdź na początek następnej linii docelowej.

  5. . - powtarza polecenie wydane w 4.2.

Uwagi:

  • 4.1 jest y, $bo jeśli nie y, yczy Ymożna skopiować linebreak, i Ctrlr0faktycznie dodaje linebreak poniżej linii docelowej.

  • 4.2 zastępuje V p, co nie działa z powtarzaniem, ponieważ technicznie ostatnią czynnością jest usunięcie, więc .po prostu usunąłby wiersz.

  • Jeśli ktoś wie, jak wydać polecenie „zamień bieżącą linię na register” z trybu EX (wiersz poleceń), chciałbym usłyszeć od Ciebie (i wiedzieć, gdzie znalazłeś dokumentację). Może istnieć powtarzalne polecenie EX, które jest szybsze niż 4,2 i / lub nie ma zastrzeżenia dotyczącego łamania linii.


1
Krok 4.2 jest tutaj zabójcą, ponieważ możesz teraz powtórzyć cały proces za pomocą polecenia kropka, jak w 4.3 - o to właśnie chodzi w vimie!
JESii

1
Nie rozumiem tego. „AG” umieszcza mój ekspres na końcu linii, wchodzi w tryb wstawiania i wprowadza „G”. Czego nie dostaję?
gustafbstrom

@gustafbstrom uczciwa krytyka - przepraszam, że A miało reprezentować numer linii, ale nie wskazałem tego. Edytowano.
Jordan Morris

5

Oto co bym zrobił

  • Przenieś początek wiersza A, AG (gdzie A jest oczywiście numerem wiersza)
  • Yank linię do jakiegoś rejestru, np. A (bez nowej linii). Rodzaj"ay$
  • Przejdź do wstawienia linii, XG
  • Linia zastępcza, S
  • Wstaw z rejestru a, Ctrl-Ra

4

Możesz tego użyć w trybie wizualnym.

  • Przejdź do linii A: AG
  • Wybierz linię z trybem wizualnym: VESC
  • przejdź do linii X: XG
  • Wejdź w tryb zastępowania linii: S
  • Wklej skopiowaną linię: shift+ insert(lub jakiekolwiek inne mapowanie, które masz do wklejenia ze schowka).

Ach. Nie wiem o V i S . Jednak twoje kroki nie działają dla mnie, ponieważ nie szarpię do schowka mojego systemu operacyjnego, który jest jedynym, do którego mam dostęp w trybie wstawiania. Więc najpierw musiałbym opuścić tryb wstawiania.
chrupiące

3

Możesz też:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Nie tworzy spacji ani końców linii.
  • Kursor jest umieszczony na początku kopiowanego tekstu.

Te same klawisze mogą służyć do szarpania / wklejania więcej niż jednej linii.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)

2

Możesz użyć tych poleceń w trybie normalnym:

:AmX | Xd

mkomenda jest m[ove], który porusza się numer linii A po numer linii X, jeśli chcesz skopiować zamiast przesunąć linię, używania co[py]. dkomenda jest d[elete].

Możesz przenosić (kopiować używając co) zakres linii używając

:start,end m X

2

W świetle niedawnego komentarza cicld (dziękuję!) Widzę, że nie zrozumiałem w pełni oryginalnego numeru. Przenoszenie linii nie jest właściwe, ale kopiowanie jest (ponieważ linia jest szarpana). Więc poprawiłbym to, aby:

:1t20:20d_
  1. Skopiuj pierwszą linię ( :tpolecenie jest aliasem dla :copy) po linii 20 (umieści ją w linii 21)

  2. Usuń linię 20, umieszczając usuniętą linię w rejestrze „czarnej dziury” ( _) (tj. Bez wpływu na bieżący bufor szarpania)

Jak wspomniano w ostatnim komentarzu, nie wpłynie to na bieżącą pozycję kursora.


1
  1. : ay (gdzie a to numer linii. Przykład: 20y). To szarpie linię (gra słów zamierzona).
  2. Vp

1

W tym celu łatwiej mi jest użyć polecenia Ex; dawny. aby przenieść linię 9 do 46:

 :46|9m.|-1d

Spowoduje to przeniesienie kursora do linii 46, przeniesienie linii 9 poniżej bieżącej, a następnie usunięcie poprzedniej linii (ponieważ przesunięta linia jest bieżącą).

Lub używając znaków, używając znaku „a”:

:46ma a|9m'a|'ad

Piękno poleceń EX polega na tym, że można je uruchamiać w dowolnym miejscu kursora (w trybie normalnym). Wolę :1m20|.+1d(przenieś linię 1 do linii 20 i usuń następną linię, tj. Tekst, który był poprzednio w linii 20). Jednak ten sam pomysł!
okrążono

1

Często muszę wstawiać Y jedną linię i zastępować ją w wielu miejscach, z których każde ma inną wartość (co oznacza, że ​​nie mogę zrobić wyrażenia regularnego).

Y szarpnąć żądaną oryginalną linię

a potem w każdym wierszu, który chcesz zamienić, VpzeroY


0

po prostu użyłbym rejestru „Czarna dziura”:

dany:

nnoremap <Cd> "_dd

rozwiązaniem byłoby:

<CD> yy

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.