Vim: wstaw te same znaki w wielu wierszach

306

Czasami chcę edytować pewien wizualny blok tekstu w wielu wierszach.

Na przykład wziąłbym tekst, który wygląda następująco:

name
comment
phone
email

I niech tak to wygląda

vendor_name
vendor_comment
vendor_phone
vendor_email

Obecnie chciałbym to zrobić ...

  1. Wybierz wszystkie 4 wiersze wiersza bloku, naciskając, Va następnie jcztery razy.
  2. Wcięcie z >.
  3. Wróć jedną literę za pomocą h.
  4. Przejdź do trybu blokowania wizualnego za pomocą Ctrlv.
  5. Wybierz cztery wiersze w dół, naciskając jcztery razy. W tym momencie wybrałeś wizualne bloki 4x1 białych znaków (cztery rzędy i jedna kolumna).
  6. Prasa C. Zauważ, że to prawie wcięcie w lewo o jedną kolumnę.
  7. Wpisz " vendor_"bez cytatu. Zwróć uwagę na dodatkową przestrzeń, którą musieliśmy przywrócić.
  8. Prasa Esc. To jeden z niewielu razy, kiedy Escwychodzę z trybu wstawiania. Ctrlcedytowałby tylko pierwszy wiersz.
  9. Powtórz krok 1.
  10. Wcięcie w drugą stronę za pomocą <.

Nie muszę wciskać, jeśli przed słowami jest co najmniej jedna kolumna białych znaków. Nie potrzebowałbym białych znaków, gdybym nie musiał wyczyścić bloku wizualnego c.

Ale jeśli muszę to wyczyścić, to czy jest sposób na to, co zrobiłem powyżej, bez tworzenia potrzebnych białych znaków z wcięciem?

Także dlaczego edytowanie wielu linii jednocześnie działa tylko po wyjściu z trybu wstawiania za pomocą Escover Ctrlc?


Oto bardziej skomplikowany przykład:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

do

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

W tym przykładzie wykonałbym pionowy blok wizualny nad ., a następnie włożyłem go ponownie w trybie wstawiania, tj .whatever.. Wpisz . Mam nadzieję, że teraz widać wadę tej metody. Ograniczam się tylko do wybrania kolumny tekstu, które są takie same w pozycji pionowej .

hobbes3
źródło
9
Lepszy sposób: „:% s / ^ / vendor_ /”
Paul Tomblin
1
Dzięki za odpowiedzi. Działa to, jeśli chcę tylko dodać słowo do każdej linii. Ale metodę, której używam, można wykonać w dowolnej pozycji. Pozwól mi dodać kolejny mój przykład z bardziej skomplikowanym przykładem.
hobbes3
3
Następnie zaznacz wiersze, które chcesz zmienić za pomocą shift-V, i wpisz odpowiednie polecenie wyszukiwania i zamień - w drugim przykładzie:s/models\./\0whatever./
Paul Tomblin
Wiele sposobów na osiągnięcie powyższego. Aby w pełni odpowiedzieć na wszystkie części pytania, to część 1) albo regex lub tryb wizualny, edytuję esc działa ładnie, jak w odpowiedziach (wolę selekcję wizualną w GVIM). W części 2) makro jest chyba najłatwiejsze, jak oferuje Brian Neal. Najlepszym zasobem, jaki znam na temat tego rodzaju „how tos”, jest Practical Vim autorstwa Drew Neila. Doskonały szybki odczyt i lekka referencja za każdym razem, gdy zapomnisz formuły. Mam nadzieję, że to zalecenie pomoże komuś, będzie warte wysiłku dla wielu użytkowników vim.
arcseldon
@Paul: a jeśli jesteś klawiszy liczenia , można wymienić \0z &.
icktoofay

Odpowiedzi:

912
  1. Przesuń kursor na nIN name.
  2. Wejdź do trybu blokowania wizualnego ( Ctrlv).
  3. Naciśnij jtrzy razy (lub 3j).
  4. Naciśnij I(duże i).
  5. Wpisz vendor_. Uwaga: zaktualizuje ekran tylko w pierwszej linii - aż do Escnaciśnięcia (6.), w którym to momencie wszystkie linie zostaną zaktualizowane.
  6. Prasa Esc.

mini-screencast przedstawiający metodę

INależy używać wielkich liter zamiast małych i, ponieważ małe litery isą interpretowane jako początek obiektu tekstowego , który sam w sobie jest przydatny, np. Do wybierania wewnątrz bloku znacznika ( it):

mini-screencast pokazujący użyteczność obiektu tekstowego „it”

icktoofay
źródło
12
Nie mogłem tego uruchomić w systemie Windows (ponieważ CTRL + V jest mapowany na wklej ze schowka). Ale Vim zamapował to również na Ctrl + Q dla wersji Windows.
Arnestig
2
@Ven: Vim nie jest w tym czasie zajęty - po prostu czeka, aż naciśniesz inny klawisz, a ostatecznie skończy się limit czasu. Dwa eksperymenty dla Ciebie: najpierw naciśnij klawisz Escape, a następnie natychmiast naciśnij inny klawisz, taki jak jlub ^L. Powinieneś zobaczyć, że Vim wcale nie był zajęty; to tylko czekało. Po drugie, spróbuj zmienić 'timeout'na niższą wartość, taką jak 80(zamiast domyślnej 1000) i zauważ, że upłynie ona szybciej.
icktoofay
1
@icktoofay Wygląda na to, że zmienna, którą chcesz ustawić, timeoutlennie jest timeout.
jez
4
@ANjaNA: Jeśli wszystko, co chcesz wstawić, znajduje się w tej samej kolumnie (np. Jeśli liczby są tej samej długości), możesz użyć tej samej techniki, z wyjątkiem naciśnięcia Azamiast zamiast I, która wstawi się po wybranym bloku, a nie wcześniej. Jeśli twoje linie mają różne długości, to nie zadziała; Lubię używać do tego podstawienia pasującego do końca każdej linii, np. Wybierając niektóre linie i używając :s/$/inserted/.
icktoofay
3
Musiałem nacisnąć strzałkę w dół po naciśnięciu klawisza esc, aby to zadziałało
GeoSword
69

Innym podejściem jest użycie polecenia .( dot) w połączeniu z I.

  1. Przesuń kursor w miejsce, od którego chcesz zacząć
  2. naciśnij I
  3. Wpisz żądany prefiks (np. vendor_)
  4. Prasa esc.
  5. Naciśnij, jaby przejść w dół linii
  6. Wpisz, .aby powtórzyć ostatnią edycję, automatycznie wstawiając prefiks
  7. Przełączaj szybko między ji.

Uważam, technika ta jest często szybciej niż w trybie wizualnym grupowego dla małych ilości dodatków i ma dodatkową zaletę, że jeśli nie trzeba wstawić tekst na każdej linii w zakresie można łatwo pominąć je, naciskając dodatkowe j„s .

Należy zauważyć, że w przypadku dużej liczby ciągłych dodatków podejście blokowe lub makro będzie prawdopodobnie lepsze.

danprice
źródło
Miło widzieć inne podejście.
Ibn Saeed,
Wolę to tylko dla kilku linii. O wiele łatwiej wykonać IMO.
Dan Bechard
Po wpisaniu żądanego prefiksu nie musisz naciskać klawisza Escape?
iamnotsam
41
  1. Wybierz linie, które chcesz zmodyfikować, używając CtrlV.
  2. Naciśnij:

    • I: Wstaw przed tym, co jest zaznaczone.
    • A: Dołącz po zaznaczeniu.
    • c: Zastąp wybrane elementy.
  3. Wpisz nowy tekst.

  4. Naciśnij, Escaby zastosować zmiany do wszystkich wybranych linii.
Loukan ElKadi
źródło
4
Świetny! Chciałbym tylko podkreślić ostatni krok Escdla VIM noobów takich jak ja - zajęło mi trochę czasu, aby dowiedzieć się, że zmiany są propagowane „później”!
Królik Bugs
1
Fajnie, nie wiedziałem też o opcjach „A” i „C”.
hobbes3
Dlaczego to nie działa v? Mogę to zrobić Ctrl+V --> A, ale vzaznaczanie tekstu nie działa - Atylko dołącza się do tej linii. Czy nie oba są wyborem? Również bardzo dziwne - Adołącza się tylko do końca linii JEŚLI przedłużę blok wizualny do końca linii; w przeciwnym razie dołącza się tam, gdzie kończy się blok wizualny dla każdej linii. To tak, jakby nie rozpoznało różnicy między ai A.
Alex G
1
Musiałem użyć czamiast C, ale działało idealnie dobrze. Dziękuję
Tarol
29

Używałbym makra do rejestrowania moich działań, a następnie powtarzałbym je.

  1. Umieść kursor na pierwszej literze w nazwie .
  2. Naciśnij, qqaby rozpocząć nagrywanie w buforze q.
  3. Naciśnij, iaby przejść do trybu wstawiania, wpisz wektor_ , a następnie naciśnij, Escaby wyjść z trybu wstawiania.
  4. Teraz naciśnij, 0aby wrócić do początku linii.
  5. Teraz naciśnij, jaby zejść.
  6. Teraz naciśnij qponownie, aby zatrzymać nagrywanie.

Masz teraz ładne makro.

Wpisz, 3@qaby wykonać makro trzy razy, aby wykonać resztę wierszy.

Brian Neal
źródło
Czy „q” jest specjalne (dla „szybkiego makra”?)?
Peter Mortensen
Jak można uprościć makro (działając przez kilka sesji)?
Peter Mortensen
@PeterMortensen Vim ma funkcję o nazwie sesje, która będzie przechowywać bufory (i wiele innych rzeczy), które możesz przeglądać.
Brian Neal
27
:%s/^/vendor_/

czy coś mi brakuje?

srini.venigalla
źródło
Brakuje faktu, że jest to prawdopodobnie podtekst w pliku z wieloma innymi wierszami, w których vender_prefiks jest niepożądany.
Dan Bechard
9
@dan Jeśli potrzebny jest tylko podtekst, możesz ograniczyć wyszukiwanie do zestawu numerów linii, np 1,4s/^/vendor_/
Brad Koch
1
@BradKoch Ciekawe. Dziękuję za to, że nie byłem świadomy ograniczeń numerów linii.
Dan Bechard
8
jest to interesujące, ale bardziej praktyczne jest wizualne blokowanie wyboru za pomocą Vi pisania :. Przedrostek ed wyrażenie, za pomocą :'<,'>którego ed stosuje się tylko do zaznaczenia za pomocą:'<,'>s/^/vendor_/
Dolanor
12

Zaktualizowano w styczniu 2016 r

Chociaż zaakceptowana odpowiedź jest świetnym rozwiązaniem, w rzeczywistości jest to nieco mniej naciśnięć klawiszy i skaluje się lepiej - zasadniczo w oparciu o przyjętą odpowiedź.

  1. Przesuń kursor na nIN name.
  2. Wejdź do trybu blokowania wizualnego ( ctrlv).
  3. naciśnij 3j
  4. Prasa I.
  5. Wpisz vendor_.
  6. Prasa esc.

ilustracja wizualna

Uwaga: liczba naciśnięć klawiszy jest mniejsza niż podana zaakceptowana odpowiedź (porównaj krok 3). Po prostu zliczamy liczbę j akcji do wykonania.

Jeśli masz włączone numery linii (jak pokazano powyżej) i znasz numer linii, do której chcesz przejść, krok 3 można zmienić na #G gdzie # to pożądany numer linii.

W naszym powyższym przykładzie byłoby to 4G. Jednak w przypadku kilku numerów linii wyraźne liczenie działa dobrze.

arcseldon
źródło
7

Chciałem skomentować wiele wierszy w pliku konfiguracyjnym na serwerze, który miał tylko vi (bez nano), więc metoda wizualna również była uciążliwa Oto jak to zrobiłem.

  1. Otwórz plik vi file
  2. Wyświetl numery linii :set number!lub:set number
  3. Następnie użyj numerów linii, aby zamienić początek linii na „#”, jak?

:35,77s/^/#/

Uwaga: liczby są włącznie, wiersze od 35 do 77, oba zawarte zostaną zmodyfikowane.

Aby anulować komentarz / cofnąć to, po prostu użyj :35,77s/^#//

Jeśli chcesz dodać słowo tekstowe jako komentarz po każdym wierszu kodu, możesz również użyć:

:35,77s/$/#test/ (dla języków takich jak Python)

:35,77s/;$/;\/\/test/ (dla języków takich jak Java)

kredyty / referencje:

  1. /unix/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim

  2. /unix/120615/how-to-comment-multiple-lines-at-once

computingfreak
źródło
To było dla mnie idealne rozwiązanie, ponieważ często używam tylko vim-tiny.
JSON C11
7

Możesz również mieć przypadek użycia, w którym chcesz usunąć blok tekstu i zastąpić go.

Lubię to

Hello World

Hello World

Do

Hello Cool

Hello Cool

Możesz po prostu zablokować wizualnie zaznacz „Świat” w obu liniach.

Wpisz czmiany - teraz będziesz w trybie wstawiania.

Wstaw żądane rzeczy i naciśnij klawisz Escape.

Oba odbijają się w pionie. Działa tak samo jak „I”, z tą różnicą, że zastępuje blok nowym tekstem zamiast go wstawiać.

Nishant
źródło
6

Załóżmy, że masz ten plik:

something

name
comment
phone
email

something else
and more ...

Chcesz dodać „vendor_” przed „name”, „comment”, „phone” i „email”, niezależnie od tego, gdzie występują w pliku .

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

cFlag poprosi o potwierdzenie. Możesz to upuścić, jeśli nie chcesz monitu.

Manish
źródło
5

Alternatywa, która może być bardziej elastyczna:

Przykład: Aby wprowadzić tekst XYZ na początku wiersza

:%norm IXYZ

Co tu się dzieje?

  • % == Wykonaj w każdej linii
  • norm == Wykonaj następujące klucze w trybie normalnym
  • I == Wstaw na początku linii
  • XYZ == Tekst, który chcesz wprowadzić

Więc uderzyłeś Enter i to się wykonuje.

Specyficzne dla twojego żądania:

:%norm Ivendor_

Możesz również wybrać konkretny zakres:

:2,4norm Ivendor_

Lub wykonaj w wybranym zakresie wizualnym:

:'<,'>norm Ivendor_
Aubrey Lavigne
źródło
1
czy można wysyłać sekwencje klawiszy, takie jak <Esc>, w trybie wstawiania (norma Iabc <ESC>), aby robić bardziej interesujące rzeczy?
batbrat
1
@batbrat Właśnie to rozgryzłem! Możesz nacisnąć, ctrl-v ctrl-[aby wstawić „Esc Esc”, co spowoduje powrót do „trybu normalnego” w celu wykonania normalnego polecenia. Właśnie przetestowałem to z '<,'>norm Iaa^[ysiw", gdzie ^[jest ucieczka Esc.
Aubrey Lavigne,
4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line
Arpan Saini
źródło
czy ta metoda działa dla wszystkich wersji vima lub wymaga jakichkolwiek wtyczek vim? powodem, dla którego pytam, jest b / c, czasami działa na niektórych komputerach, a czasami nie. nie mogę zrozumieć różnicy. vim, który pochodzi z git na Windows - nie mogę go uruchomić. na niektórych komputerach z Linuksem Ubuntu i Centos nie mogę go uruchomić. Odniosłem sukces w kilku rzadkich przypadkach, ale nie byłem w stanie odtworzyć sukcesu. to tajemnica. wydaje się, że nic się nie dzieje po tym, jak uderzyłem ESC
davidj411
co dziwne, to działa teraz dla mnie. nic się nie zmieniło, może oprócz gwiazd :) szukając rozwiązania mojego problemu, znalazłem coś na tej stronie, choć wspomina o czymś, czego można szukać w vim vim.wikia.com/wiki/Inserting_text_in_multiple_lines W Vimie sprawdź, czy masz funkcja operatorów blokowych (I, A i więcej) poprzez wprowadzenie polecenia: version. Dane wyjściowe powinny zawierać + visualextra.
davidj411,
Chciałem dodać komentarz, a nie odpowiedź. Większość z tych odpowiedzi mówi to samo, ale używa różnych słów. Mój miał coś innego do zaoferowania i zawierał link.
davidj411,
2
  1. Ctrl + v, aby przejść do trybu blokowania wizualnego
  2. Wybierz linie za pomocą strzałki w górę i w dół
  3. Wpisz małe litery 3i(naciśnij małe litery I trzy razy )
  4. I (kapitał prasowy I . Spowoduje to przejście do trybu wstawiania).
  5. Napisz tekst, który chcesz dodać
  6. Esc
  7. Naciśnij strzałkę w dół
Arpan Saini
źródło