Tại sao Vim thêm một dòng mới? Đây có phải là một quy ước?


22

Nếu tôi mở Vim và gõ itest<Esc>:wqthì tôi nhận được một tệp không có dòng mới trong Vim nhưng dường như không có dòng mới trong mã:

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

Nếu tôi mở Vim và gõ itest<Return><Esc>:wqthì tôi nhận được một tệp có một dòng mới trong Vim nhưng có hai dòng mới trong mã:

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

Lưu ý rằng tôi đang mở Vim với -u NONEvì vậy không có cấu hình cục bộ nào được sử dụng. Cũng lưu ý rằng điều này có thể liên quan đến một câu hỏi trước đây của tôi .

Đây là thông tin hệ thống của tôi:

$ 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 pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Tôi cũng có thể xác nhận chính xác hành vi trên hệ thống này:

$ 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 pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Tại sao Vim thêm một dòng mới? Đây có phải là một quy ước?

Dưới đây là một số giải thích về hdlệnh được cài đặt trên Ubuntu Server:

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

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump

8
Nó dường như là một quy ước. Đây là cách vô hiệu hóa nó nếu bạn muốn. Đây là lịch sử của điều này.
jliv902

Câu trả lời:


28

Quy ước cho các tệp văn bản Unix là mọi dòng được kết thúc bởi một dòng mới và các dòng mới là các đầu cuối dòng, không phải là dấu phân cách dòng.

Khi Vim lưu bộ đệm dưới dạng tệp, nó sẽ chấm dứt mọi dòng với chuỗi cuối dòng cho định dạng tệp đó, đối với Unix là một dòng mới. Xem

:help 'fileformat'

Nếu bạn đang sử dụng các công cụ xử lý văn bản Unix, tốt nhất bạn nên tuân thủ quy ước này. Tuy nhiên, nếu bạn có một số nhu cầu không đặt dòng mới ở cuối dòng cuối cùng của tệp, bạn có thể làm như vậy. Vim coi các tập tin đó là "nhị phân". Xem

:help 'binary'
:help edit-binary

1
ah điều đó thật thú vị. Vì vậy, bên cạnh sự nổi tiếng \ r \ n vs \ n. Windows sử dụng trình phân tách dòng và unix sử dụng trình kết thúc dòng? và đó là tài liệu ở bất cứ đâu? Tôi biết nó được xác định ở đây có lẽ áp dụng cho unix "ISO / IEC 9899: 2011, Mục §7.21.2 Luồng cho biết: Luồng văn bản là một chuỗi các ký tự được sắp xếp thành các dòng, mỗi dòng gồm 0 hoặc nhiều ký tự cộng với một ký tự kết thúc mới -line character "
barlop

nhưng tài liệu ở đâu được ghi rằng windows sử dụng dấu phân cách dòng?
barlop

2

Vim không thêm bất cứ thứ gì mà bạn không đặt vào đó.

Một ký tự "dòng mới" không phải là "dòng mới" và cả hai ví dụ là hoàn toàn bình thường:

  • trong phần đầu tiên, tệp chỉ chứa một dòng để bạn có được một ký tự "dòng mới",
  • trong phần thứ hai, tệp chứa hai dòng để bạn có hai ký tự "dòng mới".

2
Nó không thêm dòng mới. Kiểm tra nó như sau : printf "\x41" > /tmp/test.txt, sau đó kiểm tra xem nó chỉ có ký tự 'A' duy nhất với xxd /tmp/test.txt. Bây giờ vim /tmp/test.txt<ENTER>:wq. Kiểm tra lại để xem tệp có hai byte: 'A \ n'.
Ruslan

Dòng kết thúc với một ký tự dòng mới. Bạn có một dòng do đó bạn có một ký tự dòng mới.
romainl

Chà, sau printfđây tôi không có "đường" nào được định hình tốt. Sau vim tôi có một cái. Vì vậy, nó có thêm một cái gì đó mà tôi đã không đặt ở đó.
Ruslan

Những gì bạn printfkhông phải là một dòng trừ khi bạn chắp thêm \n. Là một trình soạn thảo văn bản, Vim xử lý các dòng theo mặc định và bất kỳ văn bản nào bạn chèn trong tệp đều bật, ít nhất là một dòng, trừ khi bạn nói rõ với Vim không làm điều đó.
romainl

2

Các tập tin văn bản bị hủy bỏ là xấu vì nhiều lý do; Đây là một cái mà tôi chưa thấy đề cập đến:

Trong một thế giới giả thuyết nơi các tệp văn bản không có dòng mới được chấp nhận, sẽ không có sự khác biệt giữa một tệp chứa 0 dòng và một tệp chứa 1 dòng trống. Cả hai đều được đại diện bởi một tệp 0 byte.

Không có khả năng quyết định có bao nhiêu dòng trong một tệp sẽ là xấu.


Các tệp văn bản trong các hệ thống không phải là Unix chứa 0 hoặc nhiều dòng hoàn chỉnh, cộng với một dòng không hoàn chỉnh gồm 0 hoặc nhiều ký tự. Một tập tin trống không chứa một dòng trống; nó chứa các dòng hoàn chỉnh bằng 0 và một dòng gồm 0 ký tự. Sự mơ hồ ở đâu?
supercat

"Dòng một phần" này là một khái niệm khó chịu. Bạn không thể có bất kỳ nơi nào khác ngoài phần cuối của tệp và bạn không thể tạo một tệp không có "dòng một phần". Nó tạo thêm sự phá vỡ cho việc nối tệp - ngay cả khi bạn chèn một dòng mới giữa các tệp mà bạn kết thúc bằng một thứ không tương đương về mặt ngữ nghĩa với cặp tệp gốc (vì với 2 tệp bạn có 2 dòng một phần và một trong số chúng đã trở thành một thứ gì đó khác nhau.) Một đề nghị không phù hợp.

Thực tế là các tệp ghép nối sẽ khiến bất kỳ dòng một phần nào ở cuối dòng đầu tiên được thêm vào tệp tiếp theo thường rất khó hiểu trong trường hợp cả hai tệp chứa dòng đầy đủ (đôi khi có thể hữu ích để ghép các tệp không chứa bất kỳ dòng đầy đủ nào ), Nhưng đó là những gì nó được. Unix không cấm việc xây dựng các tệp văn bản kết thúc bằng một phần dòng và tôi tin rằng việc ghép các tệp đó sẽ hoạt động như trong MSDOS. Sự khác biệt tôi nghĩ là nhiều biên tập viên dựa trên DOS trong lịch sử đã đưa ra quan điểm rằng việc tải và lưu ngay một tệp sẽ mang lại một tệp mới ...
supercat

... giống hệt với phiên bản cũ (người dùng đã đăng ký phiên bản PC-Write đầu tiên đã được hướng dẫn sử dụng nó để mở một bản sao của tệp thực thi, chuyển sang chế độ ghi đè, tìm một chuỗi nhất định và thay thế bằng chuỗi của họ số sê-ri!). Buộc các tệp kết thúc bằng dòng mới khi lưu chúng sẽ vi phạm ràng buộc đó.
supercat

2

Vim 8.0 hiện cung cấp fixeoltùy chọn này. Cụ thể nếu bạn làm:

:set nofixeol

sau đó Vim sẽ không thêm một ký tự dòng mới ở cuối dòng cuối cùng nếu tệp chưa có.

Điều đó có thể đi trong một plugin filetype, hoặc thậm chí có thể của bạn .vimrc.

(Đây là một cải tiến :set binaryvì nó chỉ ảnh hưởng đến ký tự ngắt dòng cuối cùng, trong khi đó binarycũng thay đổi một loạt các hành vi khác mà bạn có thể không muốn trừ khi bạn thực sự chỉnh sửa tệp nhị phân.)

Một tệp mới được tạo sẽ vẫn có một ký tự ngắt dòng theo mặc định. Bạn có thể thay đổi tệp đó (và chuyển một tệp đã có dòng mới cuối cùng thành không có) bằng cách thực hiện thêm:

:set noeol

Điều đó phải được đặt riêng cho từng tệp bạn muốn thay đổi: tải tệp vào bộ đệm sẽ luôn được đặt eolđể khớp với trạng thái hiện tại của tệp.


1

Sử dụng lệnh 'j', bạn có thể nối tất cả các dòng thành một.

Nếu bạn cũng muốn loại bỏ LF hoặc CRLF trên dòng cuối cùng, hãy làm như sau trong vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.