Memahami perbedaan rujukan garis melalui: g / ^ / norma dan melalui:% norma

8

Katakanlah saya memiliki file yang sangat sederhana berikut ini

a
b
c
d
e

dan saya telah memutuskan bahwa saya ingin menambahkan baris kosong setelah setiap baris. Beberapa metode yang berbeda segera melompat ke pikiran saya. Kita mungkin melakukannya (dan dengan demikian menerima kegagalan). Kami mungkin merekam makro seperti qqo<ESC>jqdan mengulanginya beberapa kali.

Dua metode lain tampak lebih jelas bagi saya pada saat itu.

Pertama, saya pikir saya akan mengeluarkan :normperintah odi setiap baris. Jadi saya lari :%norm o. Tapi yang sebenarnya terjadi adalah kita mendapatkan 5 baris kosong, diikuti oleh baris yang tidak terpisahkan seperti di atas. Saya menafsirkan ini berarti bahwa dengan %norm, vim benar-benar mengambil pesan mengeluarkan perintah normal berikut pada lima baris pertama dari file lima baris ini . The operintah menciptakan baris baru dan vim adalah "bodoh" dalam arti bahwa itu referensi oleh nomor baris dan tidak benar-benar oleh beberapa pengenal lainnya.

Yah, saya malu. Tentu. Saya mencoba beberapa hal lain untuk melihat apakah saya dapat membuat metode di atas berhasil, tetapi sayangnya, saya tidak bisa. Karena penasaran, saya mencoba metode mass-apply favorit saya yang lain. Ini membuat saya mencoba :g/^/norm o. Yang mengejutkan saya, ini bekerja dengan baik! Jadi bagi saya, sepertinya vim tidak "bodoh" di sini dengan cara yang sama seperti di atas dan mereferensikan baris dengan lebih dari sekedar nomor baris.

Apa yang sebenarnya terjadi?

davidlowryduda
sumber
2
Di samping catatan: Anda juga dapat melakukannya seperti ini: :%s/$/\r/, atau seperti ini: :%s/\n/\r\r/. Yang perlu diperhatikan adalah bahwa baris baru dapat dicocokkan dengan \n, tetapi harus ditulis sebagai \rnilai pengganti.
lcd047

Jawaban:

9

Yah, %adalah singkatan untuk 1,$(rentang dari baris pertama ke yang terakhir). Dari :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)            :%

Dan untuk :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.

Jadi, kasus pertama adalah seperti melintasi daftar saat memodifikasinya, sehingga penghitung pada elemen daftar menjadi tidak valid. Dalam kasus kedua, kita menandai elemen yang ingin kita targetkan dalam satu pass, sehingga meskipun daftar tersebut dimodifikasi pada pass kedua, kita masih tahu elemen mana yang ingin kita kerjakan.

muru
sumber
Ah, bahkan ada di file bantuan untuk global. Betapa bodohnya saya. Terima kasih
davidlowryduda
Pria - terlalu g banyak berguna gila. Saya harus menghabiskan lebih banyak waktu untuk beralih dari pengguna vi rata-rata menjadi pengguna yang kuat
javadba