Jika saya memiliki teks berikut:
foo
bar
Saya secara visual memilih dan menyalinnya.
Teks sekarang disimpan dalam register tanpa nama "
dan di sini adalah isinya (keluaran dari :reg "
):
"" foo^Jbar^J
Menurut bagan ini , tampaknya ^J
adalah notasi tanda untuk Line Feed.
Jika saya ingin menduplikasi register yang tidak disebutkan namanya dalam a
register dengan mengetik: :let @a = @"
Ini isinya (output dari :reg a
):
"a foo^Jbar^J
Itu tidak berubah.
Jika sekarang saya menggandakannya dalam register pencarian dengan mengetik :let @/ = @"
, berikut isinya (keluaran dari :reg /
):
"/ foo^@bar^@
Menurut grafik sebelumnya, nampaknya ^@
adalah tanda sisipan untuk karakter Null.
Mengapa Umpan Baris dikonversi secara otomatis menjadi karakter Null di dalam register pencarian (tetapi bukan a
register)?
Jika saya memasukkan register yang tidak disebutkan namanya pada baris perintah (atau di dalam pencarian setelah /
), dengan mengetik :<C-R>"
, inilah yang dimasukkan:
:foo^Mbar^M
Sekali lagi, menurut grafik terakhir, ^M
tampaknya notasi tanda sisipan untuk Pengembalian Carriage.
Mengapa Umpan Garis diubah secara otomatis menjadi Pengembalian Carriage di baris perintah?
Edit :
Biasanya Anda dapat memasukkan karakter kontrol literal dengan mengetik:
<C-V><C-{character in caret notation}>
Misalnya, Anda bisa memasukkan literal <C-R>
dengan mengetik <C-V><C-R>
.
Anda dapat melakukannya untuk setiap karakter kontrol yang tampaknya.
Namun saya perhatikan bahwa saya tidak dapat memasukkan LF literal ke dalam buffer atau pada baris perintah, karena jika saya mengetik: <C-V><C-J>
itu menyisipkan ^@
, karakter nol, alih-alih ^J
.
Apakah karena alasan yang sama LF diubah menjadi NUL di dalam register pencarian?
Edit 2 :
Di :h key-notation
, kita bisa membaca ini:
<Nul> zero CTRL-@ 0 (stored as 10) <Nul>
<NL> linefeed CTRL-J 10 (used for <Nul>)
Bagian stored as 10
pada baris pertama dan used for <Nul>
pada baris kedua dapat menunjukkan bahwa ada semacam tumpang tindih antara LF dan NUL, dan bahwa mereka dapat ditafsirkan sebagai hal yang sama. Tetapi mereka tidak bisa menjadi hal yang sama, karena setelah menjalankan perintah sebelumnya :let @/ = @"
, jika saya mengetik n
dalam mode normal untuk mendapatkan kemunculan berikutnya dari 2 baris foo
dan bar
, alih-alih mendapatkan kecocokan positif, saya memiliki pesan kesalahan berikut:
E486: Pattern not found: foo^@bar^@
Selain itu tautan ini tampaknya menjelaskan bahwa NUL menunjukkan akhir suatu string, sedangkan LF menunjukkan akhir suatu baris dalam file teks.
Dan jika NUL adalah stored as 10
seperti kata bantuan, yang merupakan kode yang sama dengan LF, bagaimana Vim dapat membuat perbedaan antara 2?
Edit 3 :
Mungkin LF dan NUL dikodekan dengan kode desimal yang sama 10
,, seperti kata bantuan. Dan Vim membuat perbedaan antara 2 berkat konteksnya. Jika memenuhi karakter yang kode desimalnya ada 10
di buffer atau register apa pun, kecuali pencarian dan register perintah, itu menafsirkannya sebagai LF.
Tetapi dalam register pencarian ( :reg /
) ia mengartikannya sebagai NUL karena dalam konteks pencarian, Vim hanya mencari string di mana konsep end of line in a file
tidak masuk akal karena string bukan file (yang aneh karena Anda dapat masih menggunakan atom \n
dalam pola yang dicari, tapi mungkin itu hanya fitur mesin regex?). Jadi itu secara otomatis mengartikan 10
sebagai NUL karena itu konsep terdekat ( end of string
≈ end of line
).
Dan dengan cara yang sama, pada baris perintah / register perintah ( :reg :
) ia mengartikan kode 10
sebagai CR, karena konsep end of line in a file
tidak masuk akal di sini. Konsep terdekat end of command
begitu Vim mengartikan 10
sebagai CR, karena memukul Enter
adalah cara untuk mengakhiri / mengeksekusi perintah dan CR sama dengan memukul Enter
, karena ketika Anda memasukkan yang literal dengan <C-V><Enter>
, ^M
ditampilkan.
Mungkin interpretasi karakter yang kode-nya 10
berubah sesuai dengan konteksnya:
- akhir baris dalam buffer (
^J
) - akhir string dalam pencarian (
^@
) - akhir perintah pada baris perintah (
^M
)
sumber
NULL
karakter yang tidak terduga disebabkan oleh fungsi C yang mendasarinya yaitu menangani string. Ini penjelasan tentang bagaimana C memproses string yang Anda terkait dengan menjelaskan bahwa secara internal C delimits string denganNULL
.NULL
S jarang terjadi dalam teks sehingga membuatnya menjadi karakter yang baik untuk tujuan ini. Konsekuensi dari ini adalah bahwa jika program C (vim) mencoba untuk meneruskan string "kosong" ke fungsi C internalsomeFunction(arg1, "")
mana arg 2 adalah""
"item antara tanda kutip, yang secara harfiah tidak ada -" kosong ". sebuah NULL dapat muncul, karena itu" ditambahkan "oleh implementasi C yang mendasari karena membatasi string. Saya tidak tahu bagaimana Anda akan memeriksa ini - tetapi terlintas dalam pikiran sebagai kemungkinan penyebab\r
dan\n
perbedaan dalam:substitute
.Jawaban:
Pertama, terima kasih untuk posting yang sangat komprehensif dan penuh perhatian ini.
Setelah beberapa pengujian, saya sampai pada kesimpulan ini:
Karakter kontrol ditampilkan menggunakan notasi caret:
^M
for<CR>
(carriage return) dan^J
untuk<LF>
(line feed). Dalam buffer,<EOL>
(end-of-line) ditampilkan sebagai baris layar baru dan dimasukkan dengan tombol enter.<EOL>
tergantung pada format file dari buffer:<EOL> = <CR>|<LF>|<CR><LF>
untukmac|unix|dos
masing - masing.Saat mengedit buffer, format file selalu diatur. Untuk mengubah format file buffer yang dibuka, Anda dapat menggunakan perintah berikut yang mengonversi
<EOL>
:Selain mengkonversi
<EOL>
, perintah ini bertobat<LF>
untuk<CR>
ketika mengubah format file darimac
keunix|dos
, dan sebaliknya,<CR>
untuk<LF>
saat mengubah format file dariunix|dos
kemac
. Untuk melihat byte sebenarnya dari buffer, Anda dapat menggunakan perintah berikut yang mengubah representasi tekstual dari buffer menjadi representasi heksadesimal menggunakan editor heksadesimal nyaman xxd:Dalam register (menunjukkan dengan perintah
:reg[isters]
atau:di[splay]
),<EOL>
selalu ditampilkan sebagai^J
(tetapi tidak semua^J
yang<EOL>
), terlepas dari format file dari buffer. Namun<EOL>
yang disimpan sebagaimana mestinya. Untuk dapat membedakan visual nyata^J
(yaitu<LF>
) dari yang lain^J
(yaitu<EOL>
) di register, Anda dapat menggunakan perintah berikut yang menampilkan nilai heksadesimal alih-alih notasi tanda kuret dari karakter kontrol yang berbeda dari<EOL>
:Dalam pola pencarian dan string pengganti:
Dimana mana:
Ini menunjukkan bahwa ketika format file adalah
dos
, tidak mungkin untuk memasukkan<LF>
, karena<EOL> = <CR><LF>
dan<C-V><C-M>|<C-V><EOL> = <CR>
.Dalam string pengganti:
baris baru yang berbeda dari
<EOL>
yang diartikan sebagai<EOL>
;<EOL>
yang ditafsirkan sebagai<NUL>
.Jadi, menurut 4.,
:%s[ubstitute]/\r/\r/g
mengganti setiap baris baru yang berbeda dari<EOL>
dalam buffer dengan<EOL>
, sedangkan:%s[ubstitute]/\n/\n/g
menggantikan setiap<EOL>
baris dalam buffer dengan<NUL>
.Dalam pencarian mendaftar
/
dan perintah mendaftar:
,<EOL>
yang dikonversi kebaris baru berbeda dari
<EOL>
ketika dimasukkan dari register dengan/<C-R>{register}
atau:<C-R>{register}
masing - masing;<NUL>
ketika dimasukkan dari register dengan:let @/=@{register}
atau:let @:=@{register}
masing - masing.Dalam buffer, baris baru yang berbeda dari
<EOL>
yang dikonversi ke<EOL>
saat dimasukkan dari register menggunakani<C-R>{register}
.Sebelum menyalin
<LF>
dari register tanpa nama"
ke register lain, Anda perlu memasukkan<LF>
dan memasukkannya ke dalam register"
. Jika format file adalahunix
, Anda dapat melakukannya dengan menggunakanyy
baris kosong; jika format file adalahmac
, Anda dapat melakukannya dengan menggunakani<C-V><C-M><Esc>yl
; jika format file adalahdos
, Anda tidak dapat memasukkan<LF>
(lih. 5.).Sekarang sebagian pernyataan Anda salah, karena
Anda tidak menggunakan metode yang sama untuk menyalin
<LF>
dari register"
ke register pencarian/
dan register perintah:
. Anda menggunakan:let @/=@"
untuk menyalin ke dalam register/
dan:<C-R>"
untuk menyalin ke dalam register:
. Menggunakan/<C-R>"
dan:<C-R>"
masing - masing akan memberi Anda hasil yang sama (<CR>
) dalam kedua kasus;konversi
<LF>
yang terjadi dengan dua metode salin berbeda hanya terjadi ketika format fileunix
. Jikamac
,<LF>
ini tidak diubah ketika disalin ke register/
atau register:
, dan jikados
Anda tidak dapat bahkan masukan<LF>
.Pernyataan yang benar diberikan oleh 7. Tapi saya benar-benar tidak tahu alasan di baliknya.
sumber