VIM Vô hiệu hóa dòng mới tự động ở cuối tệp


250

Vì vậy, tôi làm việc trong một cửa hàng PHP và tất cả chúng tôi đều sử dụng các trình soạn thảo khác nhau và tất cả chúng tôi phải làm việc trên các cửa sổ. Tôi sử dụng vim và mọi người trong cửa hàng cứ phàn nàn rằng bất cứ khi nào tôi chỉnh sửa một tập tin đều có một dòng mới ở phía dưới. Tôi đã tìm kiếm xung quanh và thấy rằng đây là hành vi được ghi lại của vi & vim ... nhưng tôi tự hỏi liệu có cách nào để tắt tính năng này không. (Sẽ tốt nhất nếu tôi có thể vô hiệu hóa nó cho các phần mở rộng tệp cụ thể).

Nếu bất cứ ai biết về điều này, đó sẽ là tuyệt vời!


23
bạn nên nói với họ rằng họ thật ngớ ngẩn - thực sự có một lý do chính đáng tại sao vim làm điều đó: stackoverflow.com/questions/729692/ . Tôi đoán rằng nó chỉ có liên quan nếu bạn đang triển khai trên các máy chủ giống như unix.
hdgarrood

5
Thực tiễn đề xuất PHP chính thức là bỏ qua ?>thẻ đóng cuối cùng , chỉ vì lý do này.
Sebastián Grignoli

câu hỏi này có lẽ có trước siêu người dùng ... nhưng nó nên ở đó.
gcb

20
Câu hỏi đặt ra thực sự cần là: Làm thế nào để chúng ta nói với tất cả các biên tập viên khác mà mọi người trong cửa hàng của bạn đang sử dụng để đảm bảo dòng cuối cùng của tập tin không cuối với một EOL. ;-)
TJ Crowder

Câu trả lời:


360

Và đối với vim7.4+, bạn có thể sử dụng (tốt nhất là trên .vimrc của mình) (nhờ cho chút tin tức cuối cùng đó!):

:set nofixendofline

Bây giờ liên quan đến các phiên bản cũ hơn của vim.

Ngay cả khi tệp đã được lưu với dòng mới ở cuối:

vim -b file và một lần trong vim:

:set noeol
:wq

làm xong.

Ngoài ra, bạn có thể mở tệp trong vim với :e ++bin file

Một lựa chọn khác:

:set binary
:set noeol
:wq

6
Bạn cũng có thể thêm set binaryset noeoltrong .vimrc của mình
Dryobs

17
Chú ý : binaryghi đè expandtab, điều này sẽ dẫn bạn đến các tab theo nghĩa đen trong nguồn của bạn.
Ciro Santilli 郝海东 冠状 病 事件

4
@CiroSantilli cảm ơn bạn! Tôi đã tìm kiếm tác dụng phụ của nhị phân mãi mãi và tự hỏi tại sao nó không phải là mặc định! kể từ khi tôi yêu các tab của mình, tôi nghĩ rằng tôi sẽ xem xét lợi ích bổ sung đó :)
gcb 13/03/2015

11
Bây giờ bạn có thể thêm set nofixendoflineđể giải quyết vấn đề trong Vim 7.4+
罗泽轩

1
@TrevorBoydSmith có, bởi vì trong lịch sử POSIX (tôi có thể sai về tiêu chuẩn thực tế) mong đợi một dòng mới ở cuối dòng, trong một tệp văn bản. Đó là lý do tại sao hầu hết các giải pháp yêu cầu coi nó như một nhị phân. Có lẽ nó rất thuận tiện và ngày nay nó lạc hậu, đó là lý do tại sao bây giờ có cài đặt thuận tiện. Chỉ cần thêm nó vào vimrc của bạn. Có những vấn đề tồi tệ hơn trong các trình soạn thảo khác :)
gcb

23

Thêm lệnh sau vào .vimrc của bạn để bật tùy chọn cuối dòng:

autocmd FileType php setlocal noeol binary fileformat=dos

Tuy nhiên , chính PHP sẽ bỏ qua dòng cuối cùng đó - nó không phải là một vấn đề. Tôi gần như chắc chắn rằng trong trường hợp của bạn có một cái gì đó khác là thêm ký tự dòng mới cuối cùng, hoặc có thể có một kết hợp với các loại kết thúc dòng windows / unix ( \nhoặc \r\n, v.v.).

Cập nhật:

Một giải pháp thay thế có thể là chỉ cần thêm dòng này vào .vimrc của bạn:

set fileformats+=dos

Tôi biết rằng php không phân tích sai ... Tôi đã chỉ ra điều đó với đồng nghiệp của mình, nhưng winmerge thấy họ khác biệt ... Tôi sẽ thử và cho bạn biết nó diễn ra như thế nào.
Boushley

Làm điều này có ảnh hưởng mong muốn của không có dòng cuối cùng, nhưng nó cũng chuyển đổi tệp thành kết thúc dòng unix ... (ngay cả trên hộp cửa sổ) ... Vì vậy, tôi đã làm điều đó trước khi chuyển sang chế độ nhị phân ... nhưng sau đó các kết thúc dòng không hiển thị ghi vào notepad ... mọi thứ chỉ là một dòng.
Boushley

Thật không may, những lời đề nghị đó không hoạt động. Thêm tệp
formformat

Xin lỗi, tôi đã nhầm, sử dụng 'set filetypes + = dos', không phải 'set fileformats ...'
quá nhiều php

17

Có một cách khác để tiếp cận điều này nếu bạn đang sử dụng Git để kiểm soát nguồn. Lấy cảm hứng từ một câu trả lời ở đây , tôi đã viết bộ lọc của riêng mình để sử dụng trong tệp gitattribut .

Để cài đặt bộ lọc này, hãy lưu nó dưới dạng noeol_filtermột nơi nào đó trong của bạn $PATH, làm cho nó có thể thực thi được và chạy các lệnh sau:

git config --global filter.noeol.clean noeol_filter
git config --global filter.noeol.smudge cat

Để chỉ bắt đầu sử dụng bộ lọc, hãy đặt dòng sau vào $GIT_DIR/info/attributes:

*.php filter=noeol

Điều này sẽ đảm bảo bạn không cam kết bất kỳ dòng mới nào tại eof trong một .phptệp, bất kể Vim làm gì.

Và bây giờ, chính kịch bản:

#!/usr/bin/python

# a filter that strips newline from last line of its stdin
# if the last line is empty, leave it as-is, to make the operation idempotent
# inspired by: /programming/1654021/how-can-i-delete-a-newline-if-it-is-the-last-character-in-a-file/1663283#1663283

import sys

if __name__ == '__main__':
    try:
        pline = sys.stdin.next()
    except StopIteration:
        # no input, nothing to do
        sys.exit(0)

    # spit out all but the last line
    for line in sys.stdin:
        sys.stdout.write(pline)
        pline = line

    # strip newline from last line before spitting it out
    if len(pline) > 2 and pline.endswith("\r\n"):
        sys.stdout.write(pline[:-2])
    elif len(pline) > 1 and pline.endswith("\n"):
        sys.stdout.write(pline[:-1])
    else:
        sys.stdout.write(pline)

Đó là một giải pháp tuyệt vời ... mặc dù tiếc là tôi đã không sử dụng git. Tôi đã sử dụng svn, mặc dù tôi nghi ngờ một cách tiếp cận tương tự có thể đã được thực hiện. Dù sao, tôi đã chuyển từ vị trí đó và không phải lo lắng về điều đó nữa :)
Boushley

12

Tôi chưa thử tùy chọn này, nhưng thông tin sau được cung cấp trong hệ thống trợ giúp vim (tức là trợ giúp eol):

'endofline' 'eol'   boolean (default on)
            local to buffer
            {not in Vi}

When writing a file and this option is off and the 'binary' option
is on, no <EOL> will be written for the last line in the file.  This
option is automatically set when starting to edit a new file, unless
the file does not have an <EOL> for the last line in the file, in
which case it is reset.  

Thông thường bạn không phải đặt hoặc đặt lại tùy chọn này. Khi 'nhị phân' tắt, giá trị không được sử dụng khi ghi tệp. Khi 'nhị phân' được bật, nó được sử dụng để ghi nhớ sự hiện diện của dòng cuối cùng trong tệp, để khi bạn viết tệp, tình huống từ tệp gốc có thể được giữ lại. Nhưng bạn có thể thay đổi nó nếu bạn muốn.

Bạn cũng có thể quan tâm đến câu trả lời cho câu hỏi trước đó: " Tại sao các tệp nên kết thúc bằng một dòng mới ".


Tôi cũng đã đi qua các thiết lập eol ... nhưng nó không hoàn thành nhiệm vụ này. Đó là nhiều hơn một biến xác định xem một đã được đặt ở cuối tập tin hay chưa. Ngoài ra, nó không có tác dụng đối với các tệp văn bản, mà chỉ trên các tệp nhị phân.
Boushley

3
Trợ giúp vim cũng cho biết "Khi 'nhị phân' tắt, giá trị không được sử dụng khi ghi tệp." về eol
Boushley

1
+1 cho câu trả lời của VonC cho câu hỏi đó, trong đó nhấn mạnh rằng "dòng mới" và EOL đang bị xáo trộn. Trình chỉnh sửa kém hơn hiển thị không chính xác một dòng mới vì EOL, vim không thêm "dòng mới"!
ches

9

Tôi đã thêm một mẹo trên wiki Vim cho một vấn đề tương tự (dù khác nhau):

http://vim.wikia.com/wiki/Do_not_auto-add_a_newline_at_EOF


5
Phần mềm Vim 7.4.785 bổ sung fixeoltùy chọn có thể bị vô hiệu hóa để tự động bảo vệ mọi EOL bị thiếu ở cuối tệp. Kịch bản này trở nên không thành công đối với Vim 7.4.785 trở lên. (Nguồn: cùng một trang wiki.) Cảm ơn, tôi không biết về tùy chọn mới đó.
Amir

1
Tôi đã phải thiết lập cả hai noeolnofixeolđể đạt được kết quả mong muốn.
selurvedu

8

OK, bạn đang ở trên Windows làm phức tạp mọi thứ;)

Vì tùy chọn 'nhị phân' đặt lại tùy chọn 'tệp định dạng' (và viết với tập hợp 'nhị phân' luôn luôn viết với các kết thúc dòng unix), chúng ta hãy lấy ra cái búa lớn và thực hiện bên ngoài!

Làm thế nào về việc xác định một autocommand (: help autocommand) cho sự kiện BufWritePost? Autocommand này được thực thi sau mỗi lần bạn viết toàn bộ bộ đệm. Trong autocommand này gọi một công cụ nhỏ bên ngoài (php, perl hoặc bất kỳ tập lệnh nào) loại bỏ dòng mới cuối cùng của tệp vừa viết.

Vì vậy, nó sẽ trông giống như thế này và sẽ đi vào tệp .vimrc của bạn:

autocmd!   "Remove all autocmds (for current group), see below"
autocmd BufWritePost *.php !your-script <afile>

Hãy chắc chắn đọc toàn bộ tài liệu vim về autocommands nếu đây là lần đầu tiên bạn giao dịch với autocommands. Có một số lưu ý, ví dụ: nên xóa tất cả autocmds trong .vimrc của bạn trong trường hợp .vimrc của bạn có thể có nguồn gốc nhiều lần.


Chà ... tôi đã hy vọng rằng có một giải pháp tốt hơn thế này ... nhưng điều này chắc chắn có hiệu quả!
Boushley

3
Điều này làm việc tuyệt vời! Yay! Tuy nhiên tôi có một câu hỏi ... có cách nào để đưa ra câu hỏi để tôi không phải nhấn enter hai lần sau mỗi lần lưu. Tôi phải nhấn enter trong cửa sổ cmd bật lên và sau đó một lần nữa bởi vì vim đang nói với tôi rằng kịch bản được trả về thành công ... Có cách nào để làm cho tất cả biến mất?
Boushley

2
Để tránh lời nhắc <Nhấn Enter>, chỉ cần thêm tiền tố vào lệnh silent. Ví dụ silent !your-script <afile>.
dash-tom-bang

6

Tôi đã triển khai các đề xuất của Blixtor với xử lý hậu kỳ Perl và Python, hoặc chạy bên trong Vim (nếu nó được biên dịch với sự hỗ trợ ngôn ngữ như vậy) hoặc thông qua tập lệnh Perl bên ngoài. Nó có sẵn dưới dạng plugin PreserveNoEOL trên vim.org.


Tôi đã không kiểm tra nó kỹ lưỡng, nhưng đó có vẻ là một giải pháp tốt hơn.
Boushley

Plugin hoạt động, nhưng sau khi cài đặt, tôi phải đưa let g:PreserveNoEOL = 1vào .vimrctập tin của mình ! Phải học vimscript để tìm ra điều đó từ mô tả plugin! : D
DarthVanger

1
@DarthVanger: :help PreserveNoEOL-usagecũng sẽ nói với bạn. RTFM :-)
Ingo Karkat

@IngoKarkat ơi, xin lỗi. Đã tìm kiếm điều này dưới INSTALLATIONCONFIGURATION. Thậm chí không nhận thấy USAGEphần trong mô tả, vì nó nằm trên phần cài đặt :)
DarthVanger

3

Có lẽ bạn có thể nhìn vào lý do tại sao họ đang phàn nàn. Nếu một tệp php có một dòng mới sau khi kết thúc?>, Php sẽ xuất nó dưới dạng một phần của trang. Đây không phải là vấn đề trừ khi bạn cố gắng gửi tiêu đề sau khi tệp được bao gồm.

Tuy nhiên,?> Ở cuối tệp php là tùy chọn. Không có kết thúc?>, Không có vấn đề với một dòng mới ở cuối tập tin.


2
Bạn đã đúng, nhưng chúng tôi với tư cách là một cửa hàng đã quyết định rằng kết thúc có vẻ tốt hơn?> Tôi biết chúng tôi có thể ngừng sử dụng nó ... nhưng tôi thích điều chỉnh trình soạn thảo của mình để phù hợp với phong cách mã hóa của mình hơn là cách khác.
Boushley

1
Ngoài ra, để bạn biết php sẽ tự động phân tích thẻ kết thúc của bạn là?> Hoặc là?> \ N (vì trong linux, tất cả các tệp hợp lệ sẽ kết thúc bằng \ n) ... Vì vậy, mã của tôi không gây ra những vấn đề này ... họ chỉ không thích vẻ ngoài.
Boushley

2

Tôi thêm vào .vimrc

set binary

và nó giúp, hãy thử nó


2

Tôi nghĩ rằng tôi đã tìm thấy một giải pháp tốt hơn câu trả lời được chấp nhận. Các giải pháp thay thế không hoạt động đối với tôi và tôi không muốn phải làm việc ở chế độ nhị phân mọi lúc. May mắn là điều này dường như đã hoàn thành công việc và tôi chưa gặp phải bất kỳ tác dụng phụ khó chịu nào: bảo toàn phần cuối dòng bị thiếu ở cuối tệp văn bản . Tôi vừa thêm toàn bộ vào ~ / .vimrc của tôi.


1

Bạn có thể sử dụng một lệnh đặc biệt để lưu các tệp này không?

Nếu bạn thực hiện: đặt nhị phân ,: w và: đặt cao quý, tệp sẽ được ghi mà không có dòng mới nếu không có gì để bắt đầu.

Chuỗi lệnh này có thể được đưa vào một lệnh do người dùng xác định hoặc ánh xạ, tất nhiên.


Thật không may bởi vì tôi đang làm việc với các cửa sổ, nếu tôi lưu nó ở chế độ nhị phân, nó buộc lưu ở chế độ unix. Ngay cả khi tôi làm: set binary: set fileformat = dos: w: set nobinary Một khi tôi thoát, nó đã lưu tệp ở định dạng unix ... Tôi không thể tin rằng không có cách nào để tắt cái này.
Boushley


0

Tôi thấy plugin vimscript này hữu ích cho tình huống này.

Plugin 'vim-scripts/PreserveNoEOL'

Hoặc đọc thêm tại github

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.