Mengapa Vim menambahkan baris baru? Apakah ini sebuah konvensi?

22

Jika saya membuka Vim dan mengetik itest<Esc>:wqmaka saya mendapatkan file yang tidak memiliki baris baru di Vim tetapi tampaknya memiliki baris baru dalam kode:

$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a                    |test.|
00000005

Jika saya membuka Vim dan mengetik itest<Return><Esc>:wqmaka saya mendapatkan file yang memiliki satu baris baru di Vim tetapi dua baris baru dalam kode:

$ rm test.txt
$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a 0a                 |test..|
00000006

Perhatikan bahwa saya membuka Vim -u NONEsehingga tidak ada konfigurasi lokal yang digunakan. Perhatikan juga bahwa ini mungkin terkait dengan pertanyaan saya sebelumnya .

Ini info sistem saya:

$ uname -a
Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
Included patches: 1-429
Modified by [email protected]
Compiled by buildd@

Saya dapat mengkonfirmasi perilaku yang sama persis pada sistem ini juga:

$ uname -a
Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
Included patches: 1-547
Modified by [email protected]
Compiled by buildd@

Mengapa Vim menambahkan baris baru? Apakah ini sebuah konvensi?

Berikut adalah beberapa klarifikasi tentang hdperintah yang diinstal di Ubuntu Server:

$ man hd | head -4
HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump
dotancohen
sumber
8
Tampaknya menjadi sebuah konvensi. Berikut ini cara menonaktifkannya jika Anda mau. Inilah sejarahnya.
jliv902

Jawaban:

28

Konvensi untuk file teks Unix adalah bahwa setiap baris diakhiri oleh baris baru, dan bahwa baris baru adalah terminator baris, bukan pemisah baris.

Ketika Vim menyimpan buffer sebagai file, ia mengakhiri setiap baris dengan urutan end-of-line untuk format file itu, yang untuk Unix adalah baris baru. Lihat

:help 'fileformat'

Jika Anda menggunakan alat pemrosesan teks Unix, yang terbaik untuk tetap dengan konvensi ini. Namun, jika Anda perlu untuk tidak meletakkan baris baru di akhir baris terakhir file, Anda dapat melakukannya. Vim menganggap file tersebut sebagai "biner". Lihat

:help 'binary'
:help edit-binary
garyjohn
sumber
1
Oh, itu menarik. Jadi selain yang terkenal \ r \ n vs \ n. Windows menggunakan pemisah baris dan unix menggunakan terminator garis? dan apakah itu didokumentasikan di mana saja? Saya tahu ini didefinisikan di sini mungkin berlaku untuk unix "ISO / IEC 9899: 2011, Bagian §7.21.2 Aliran mengatakan: Aliran teks adalah urutan karakter yang tersusun dalam garis, setiap baris yang terdiri dari nol atau lebih karakter ditambah yang baru mengakhiri karakter-line "
barlop
tetapi di mana didokumentasikan bahwa windows menggunakan pemisah garis?
barlop
2

Vim tidak menambahkan apa pun yang tidak Anda taruh di sana sendiri.

Karakter "baris baru" bukan "baris baru" dan kedua contohnya sangat normal:

  • di yang pertama, file hanya berisi satu baris sehingga Anda mendapatkan satu karakter "baris baru",
  • di yang kedua, file berisi dua baris sehingga Anda mendapatkan dua karakter "baris baru".
romainl
sumber
2
Itu menambah baris baru. Uji sebagai berikut:, printf "\x41" > /tmp/test.txtlalu periksa apakah hanya memiliki karakter 'A' tunggal xxd /tmp/test.txt. Sekarang vim /tmp/test.txt<ENTER>:wq. Periksa lagi untuk melihat file yang memiliki dua byte: 'A \ n'.
Ruslan
Garis diakhiri dengan karakter baris baru. Anda memiliki satu baris sehingga Anda memiliki satu karakter baris baru.
romainl
Nah, setelah di printfsini saya tidak punya "garis" yang terbentuk dengan baik. Setelah vim saya punya satu. Jadi, itu menambahkan sesuatu yang saya tidak taruh di sana.
Ruslan
Apa yang Anda printfbukan garis kecuali Anda menambahkan \n. Menjadi editor teks, Vim penawaran dengan garis-garis secara default, dan setiap teks yang Anda masukkan dalam file adalah pada, setidaknya, garis, kecuali Anda secara eksplisit memberitahu Vim untuk tidak melakukan itu.
romainl
2

File teks yang dihapuskan jahat karena berbagai alasan; ini salah satu yang belum saya lihat disebutkan:

Dalam dunia hipotetis di mana file teks tanpa baris baru dapat diterima, tidak akan ada perbedaan antara file yang berisi 0 baris dan file yang berisi 1 baris kosong. Keduanya akan diwakili oleh file 0-byte.

Ketidakmampuan untuk memutuskan berapa banyak baris dalam file akan menjadi buruk.


sumber
File teks dalam sistem non-Unix mengandung nol atau lebih baris lengkap, ditambah baris tidak lengkap dengan nol atau lebih karakter. File kosong tidak mengandung baris kosong; itu berisi nol garis lengkap dan garis parsial karakter nol. Di mana ambiguitasnya?
supercat
"Garis parsial" ini adalah konsep yang tidak menyenangkan. Anda tidak dapat memiliki satu di mana pun selain akhir file, dan Anda tidak dapat membuat file yang tidak memiliki "garis parsial". Ini menambah lebih banyak kerusakan pada penggabungan file - bahkan jika Anda menyisipkan baris baru di antara file-file Anda berakhir dengan sesuatu yang secara semantik tidak setara dengan pasangan file asli (karena dengan 2 file Anda memiliki 2 baris parsial, dan salah satunya menjadi sesuatu berbeda.) Proposal tidak sopan.
Fakta bahwa penggabungan file akan menyebabkan setiap baris parsial pada akhir yang pertama untuk ditambahkan ke file berikutnya umumnya menjengkelkan dalam kasus di mana kedua file berisi baris penuh (kadang-kadang dapat berguna untuk menggabungkan file yang tidak berisi baris penuh ), tetapi itu adalah apa adanya. Unix tidak melarang pembangunan file teks yang diakhiri dengan baris parsial, dan saya percaya menggabungkan file tersebut akan berlaku seperti pada MSDOS. Perbedaannya saya pikir adalah bahwa banyak editor berbasis DOS secara historis mengambil pandangan bahwa memuat dan segera menyimpan file harus menghasilkan file baru ...
supercat
... yang agak identik dengan yang lama (pengguna terdaftar dari PC-Write versi awal diperintahkan untuk menggunakannya untuk membuka salinan dari file yang dapat dieksekusi, beralih ke mode menimpa, menemukan string tertentu, dan menggantinya dengan nomor seri!). Memaksa file diakhiri dengan baris baru saat menyimpannya akan melanggar batasan itu.
supercat
2

Vim 8.0 sekarang menyediakan fixeolopsi ini. Khususnya jika Anda melakukannya:

:set nofixeol

maka Vim tidak akan menambahkan karakter baris baru di akhir baris terakhir jika file belum memilikinya.

Itu bisa masuk dalam plugin tipe file, atau bahkan mungkin plugin Anda .vimrc.

(Ini merupakan peningkatan pada :set binary karena itu hanya mempengaruhi karakter line-break terakhir, sedangkanbinary juga mengubah banyak perilaku lain, yang mungkin tidak Anda inginkan kecuali Anda benar-benar mengedit file biner.)

File yang baru dibuat masih akan memiliki karakter line-break trailing secara default. Anda dapat mengubah itu (dan mengganti file yang sudah memiliki baris terakhir untuk tidak memilikinya) dengan tambahan melakukan:

:set noeol

Itu harus ditetapkan secara khusus untuk setiap file yang ingin Anda ubah: memuat file ke buffer akan selalu diatur eolagar sesuai dengan keadaan file saat ini.

Smylers
sumber
1

Menggunakan perintah 'j' Anda dapat menggabungkan semua baris menjadi satu.

Jika Anda juga ingin menghapus LF atau CRLF pada baris terakhir, lakukan hal berikut di vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Robert
sumber