Chciałbym scalić dwa bloki linii w Vimie, tzn. Pobrać linie n..m
i dołączyć je do linii a..b
. Jeśli wolisz wyjaśnienie pseudokodu:[a[i] + b[i] for i in min(len(a), len(b))]
Przykład:
abc
def
...
123
45
...
powinno stać się
abc123
def45
Czy istnieje dobry sposób na zrobienie tego bez ręcznego kopiowania i wklejania?
x
z łączeniemx+2
?[a[i] + b[i] for i in min(len(a), len(b))]
Odpowiedzi:
Z pewnością możesz to wszystko zrobić za pomocą pojedynczego kopiowania / wklejania (przy użyciu wyboru trybu blokowego), ale zgaduję, że nie tego chcesz.
Jeśli chcesz to zrobić za pomocą tylko poleceń Ex
przekształci się
w
AKTUALIZACJA: Odpowiedź na tak wiele pozytywnych opinii zasługuje na dokładniejsze wyjaśnienie.
W Vimie możesz użyć znaku potoku (
|
) do połączenia wielu poleceń Ex, więc powyższe jest równoważne zWiele poleceń Ex akceptuje zakres wierszy jako argument przedrostka - w powyższym przypadku
5,8
przeddel
i1,4
przeds///
określają, na których wierszach działają polecenia.del
usuwa podane linie. Może przyjmować argument rejestru, ale jeśli go nie podano, zrzuca linie do rejestru bez nazwy@"
, podobnie jak usuwanie w trybie normalnym.let l=split(@")
następnie dzieli usunięte linie na listę, używając domyślnego separatora: białe znaki. Aby działać poprawnie na danych wejściowych, które miały białe znaki w usuniętych wierszach, takie jak:musielibyśmy określić inny separator, aby zapobiec „praca” od bycia podzielony na dwie listy elementów:
let l=split(@","\n")
.Wreszcie w podstawieniu
s/$/\=remove(l,0)/
zamieniamy koniec każdej linii ($
) wartością wyrażeniaremove(l,0)
.remove(l,0)
zmienia listęl
, usuwając i zwracając jej pierwszy element. To pozwala nam zastąpić usunięte linie w kolejności, w jakiej je czytamy. Zamiast tego możemy zastąpić usunięte linie w odwrotnej kolejności za pomocąremove(l,-1)
.źródło
s/\s*$/
zamiasts/$/
.:sil5,8del | let l=split(@") | sil1,4s/$/\=remove(l,0)/ | call histdel("/", -1) | nohls
wydaje się być jeszcze lepszy, ponieważ czyści historię wyszukiwania po uruchomieniu. I nie wyświetla komunikatu „x więcej / mniej linii” wymagającego naciśnięcia Enter.:help range
,:help :d
,:help :let
,:help split()
,:help :s
,:help :s\=
,:help remove()
.Elegancki i zwięzły komenda Ex rozwiązywania problemu można uzyskać poprzez połączenie
:global
,:move
oraz:join
poleceń. Zakładając, że pierwszy blok linii zaczyna się w pierwszym wierszu bufora i że kursor znajduje się w linii bezpośrednio poprzedzającej pierwszą linię drugiego bloku, polecenie jest następujące.Aby uzyskać szczegółowe wyjaśnienie tej techniki, zobacz moją odpowiedź na podobne pytanie „ zachowanie wklejania VIM-a” po wyjęciu z pudełka? ”.
źródło
E16: Invalid Range
- ale i tak działa. Po usunięciu1,
działa bezbłędnie.:move
, a:join!
, ani co''
rozumie jako argument zakres (:help ''
) i co+
i-
rozumie jako modyfikatory Range (:help range
). Dzięki!sil!
się do polecenia.Aby połączyć bloki linii, musisz wykonać następujące czynności:
jj
CTRL-v
$
CTRL-END
x
kk$
p
Ten ruch nie jest najlepszy (nie jestem ekspertem), ale działa tak, jak chciałeś. Mam nadzieję, że będzie krótsza wersja.
Oto warunki wstępne, aby ta technika działała dobrze:
abc
idef
) mają tę samą długość XORźródło
abc
idef
są tej samej długości. Wybór bloku zachowa wcięcia usuniętego tekstu, więc jeśli kursor znajduje się w krótkiej linii podczas wstawiania tekstu, linie są wstawiane między literami na dłuższych - a spacje są dodawane do krótszych, jeśli kursor znajduje się na dłuższym jeden.:%s/ \+/ /g
set ve=all
powinien pomóc, patrz vimdoc.sourceforge.net/htmldoc/options.html#'virtualedit 'Oto jak bym to zrobił (z kursorem w pierwszym wierszu):
Musisz wiedzieć dwie rzeczy:
Oto co się dzieje:
qa
zapisuje wszystko do następnegoq
w „buforze” wa
.ma
tworzy znak w bieżącej linii.:5<CR>
przechodzi do następnej grupy.y$
szarpnie resztę linii.'a
wraca do znaku, ustawionego wcześniej.$p
wkleja na końcu linii.:5<CR>
wraca do pierwszej linii drugiej grupy.dd
usuwa to.'a
wraca do znaku.jq
przechodzi w dół o jedną linię i zatrzymuje nagrywanie.3@a
powtarza akcję dla każdej linii (3 w moim przypadku)źródło
[Enter]
po:5
każdym wpisaniu, inaczej to nie zadziała.:norm qama:5<CR>y$'a$p:5<CR>dd'ajq3@a
ale wydaje się, że to tylko wykonanieq
.:let @a="ma:5^My$'a$p:5^Mdd'aj" | normal 4@a
, gdzie^M
znaki są wpisane przez naciśnięcie CTRL-V, a następnie Enter.Jak wspomniano w innym miejscu, najlepszym rozwiązaniem jest wybór bloku. Możesz jednak użyć dowolnego wariantu:
:!tail -n -6 % | paste -d '\0' % - | head -n 5
Ta metoda opiera się na wierszu poleceń systemu UNIX.
paste
Narzędziowy został stworzony do obsługi tego rodzaju linii łączących.źródło
paste -d
podobne) zachowanie można zrealizować za pomocą krótkiego polecenia Vima, jak pokazano w mojej odpowiedzi .Przykładowe dane są takie same jak dane rampionu.
źródło
Nie sądzę, żeby to skomplikowało. Chciałbym tylko ustawić virtualedit na
(
:set virtualedit=all
)Wybierz blok 123 i wszystkie poniżej.
Umieść po pierwszej kolumnie:
i usuń wielokrotne spacje od do 1 spacji:
źródło
gvV:'<,'>s/\s+//g
(vim powinien automatycznie wstawić'<,'>
dla ciebie, więc nie musisz ręcznie pisać).Użyłbym skomplikowanych powtórzeń :)
Biorąc to pod uwagę:
Po ustawieniu kursora w pierwszym wierszu naciśnij następujące polecenie:
a następnie naciśnij
@a
(a następnie możesz użyć@@
) tyle razy, ile potrzeba.Powinieneś skończyć z:
(Plus nowa linia.)
Wyjaśnienie:
qa
rozpoczyna nagrywanie złożonego powtórzenia wa
}
przeskakuje do następnej pustej liniijdd
usuwa następny wiersz''
wraca do pozycji przed ostatnim skokiemp
wklej usuniętą linię pod bieżącąkJ
dołącz bieżącą linię na końcu poprzedniejx
usuń spację, któraJ
dodaje między połączone linie; możesz to pominąć, jeśli chcesz miejscaj
przejdź do następnej liniiq
zakończyć złożone powtarzanie nagrywaniaNastępnie użyjesz
@a
do uruchomienia złożonego powtórzenia złożonego zapisanego wa
, a następnie możesz użyć@@
do ponownego uruchomienia ostatniego uruchomionego powtórzenia złożonego.źródło
Istnieje wiele sposobów osiągnięcia tego celu. Scalę dwa bloki tekstu przy użyciu dowolnej z dwóch poniższych metod.
załóżmy, że pierwszy blok znajduje się na linii 1, a drugi blok zaczyna się od linii 10 z początkową pozycją kursora na linii nr 1.
(\ n oznacza naciśnięcie klawisza enter.)
z makrem za pomocą poleceń: kopiuj, wklej i dołącz.
za pomocą makra za pomocą poleceń przenieś linię na n-ty numer linii i połącz.
źródło