Możesz spróbować wykonać następujące polecenie:
:let c=0 | g/^* /let c+=1 | s//\=c.'. '
Najpierw inicjuje zmienną c
( let c=0
), a następnie wykonuje polecenie globalne, g
które szuka wzorca ^*
(początek linii, a następnie gwiazdka i spacja).
Za każdym razem, gdy zostanie znaleziona linia zawierająca ten wzorzec, polecenie globalne wykonuje polecenie:
let c+=1 | s//\=c.'. '
zwiększa zmienną c
( let c+=1
), a następnie ( |
) zastępuje ( s
) poprzednio wyszukiwany wzorzec ( //
) oceną wyrażenia ( \=
):
zawartość zmiennej c
połączonej ( .
) z ciągiem'. '
Jeśli nie chcesz modyfikować wszystkich linii z bufora, ale tylko określony akapit, możesz przekazać zakres do polecenia globalnego. Na przykład, aby zmodyfikować tylko linie, których liczba wynosi od 5 do 10:
:let c=0 | 5,10g/^* /let c+=1 | s//\=c.'. '
Jeśli masz plik zawierający kilka podobnych list, które chcesz przekonwertować, na przykład coś takiego:
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
some other random stuff some other random stuff
==>
some random stuff some random stuff
* foo 1. foo
* bar 2. bar
* baz 3. baz
* qux 4. qux
some other random stuff some other random stuff
Możesz to zrobić za pomocą następującego polecenia:
:let [c,d]=[0,0] | g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Jest to tylko wariant poprzedniego polecenia, które resetuje zmienną c
po przełączeniu na inną listę. Aby wykryć, czy znajdujesz się na innej liście, zmienna d
służy do przechowywania numeru ostatniego wiersza, w którym dokonano podstawienia.
Komenda globalna porównuje bieżący numer linii ( line('.')
) z d+1
. Jeśli są takie same, oznacza to, że znajdujemy się na tej samej liście, co poprzednio, więc c
jest zwiększana ( c+1
), w przeciwnym razie oznacza to, że znajdujemy się na innej liście, więc c
jest resetowana ( 1
).
Wewnątrz funkcji polecenie let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')]
można przepisać w następujący sposób:
let c = line('.') == d+1 ? c+1 : 1
let d = line('.')
Lub tak:
if line('.') == d+1
let c = c+1
else
let c = 1
endif
let d = line('.')
Aby zapisać niektóre naciśnięcia klawiszy, możesz również zdefiniować niestandardowe polecenie :NumberedLists
, które akceptuje zakres, którego wartością domyślną jest 1,$
( -range=%
):
command! -range=% NumberedLists let [c,d]=[0,0] | <line1>,<line2>g/^* /let [c,d]=[line('.')==d+1 ? c+1 : 1, line('.')] | s//\=c.'. '
Kiedy :NumberedLists
zostanie wykonany <line1>
i <line2>
zostanie automatycznie zastąpiony użytym zakresem.
Aby przekonwertować wszystkie listy w buforze, wpisz: :NumberedLists
Tylko listy między wierszem 10 a 20: :10,20NumberedLists
Tylko wybór wizualny: :'<,'>NumberedLists
Aby uzyskać więcej informacji, zobacz:
:help :range
:help :global
:help :substitute
:help sub-replace-expression
:help list-identity (section list unpack)
:help expr1
:help :command