Zrozumienie różnic odniesienia linii przez: g / ^ / norm i przez:% norm

8

Powiedzmy, że mam następujący bardzo prosty plik

a
b
c
d
e

i zdecydowałem, że chcę dodać puste linie po każdej linii. Kilka różnych metod natychmiast przychodzi mi do głowy. Możemy to po prostu zrobić (a tym samym zaakceptować porażkę). Możemy nagrać makro qqo<ESC>jqi powtórzyć je kilka razy.

Dwie inne metody wydawały mi się wtedy bardziej oczywiste.

Po pierwsze, pomyślałem, że wydam :normpolecenie ow każdej linii. Więc biegnę :%norm o. Ale tak naprawdę dzieje się tak, że otrzymujemy 5 pustych linii, po których następują nierozdzielone linie, jak wyżej. Interpretuję to w ten sposób, że przez %normvim faktycznie odbiera problem z komunikatem następujące pierwsze polecenie w pierwszych pięciu wierszach tego pliku pięciu wierszy . oPolecenie tworzy nową linię i vim jest „głupi” w tym sensie, że jest wykorzystywana przez numer linii i faktycznie nie za pośrednictwem innego identyfikatora.

Cóż, byłem zawstydzony. Pewnie. Próbowałem kilku innych rzeczy, aby sprawdzić, czy powyższa metoda działa, ale niestety nie mogłem. Z ciekawości wypróbowałem inną ulubioną metodę masowego nakładania. To skłoniło mnie do spróbowania :g/^/norm o. Ku mojemu zdziwieniu to działa dobrze! Moim zdaniem wydaje się, że vim nie jest tutaj „głupi” w taki sam sposób jak powyżej i odwołuje się do linii po więcej niż tylko numerze linii.

Co się właściwie dzieje?

davidlowryduda
źródło
2
Na marginesie: można również zrobić to tak: :%s/$/\r/lub tak: :%s/\n/\r\r/. Na wynos można dopasować nowe wiersze \n, ale należy je zapisać jak \rw wartościach zastępczych.
lcd047,

Odpowiedzi:

9

Cóż, %jest skrótem od 1,$(zakres od pierwszej linii do ostatniej). Od :he :%:

Line numbers may be specified with:             :range E14 {address}
        {number}        an absolute line number
        .               the current line                          :.
        $               the last line in the file                 :$
        %               equal to 1,$ (the entire file)            :%

I dla :global:

The global commands work by first scanning through the [range] lines and
marking each line where a match occurs (for a multi-line pattern, only the
start of the match matters).
In a second scan the [cmd] is executed for each marked line with its line
number prepended.  For ":v" and ":g!" the command is executed for each not
marked line.  If a line is deleted its mark disappears.

Tak więc pierwszy przypadek przypomina przemierzanie listy podczas jej modyfikacji, więc licznik elementów listy staje się nieprawidłowy. W drugim przypadku zaznaczamy elementy, na które chcemy celować w jednym przebiegu, dzięki czemu nawet jeśli lista zostanie zmodyfikowana w drugim przebiegu, nadal wiemy, nad którymi elementami chcemy pracować.

muru
źródło
Ach, nawet w pliku pomocy dla globalnego. Jak głupio jestem. Dziękuję
davidlowryduda
człowiek - g jest przesadnie przydatny. Muszę spędzić więcej czasu, aby przejść od przeciętnego użytkownika vi do zaawansowanego użytkownika
javadba,