VIM отключить автоматический перевод строки в конце файла


251

Так что я работаю в магазине PHP, и мы все используем разные редакторы, и мы все должны работать над окнами. Я использую vim, и все в магазине продолжают жаловаться, что всякий раз, когда я редактирую файл, внизу появляется новая строка. Я искал вокруг и обнаружил, что это документированное поведение vi & vim ... но мне было интересно, есть ли способ отключить эту функцию. (Было бы лучше, если бы я мог отключить его для определенных расширений файлов).

Если кто-нибудь знает об этом, это было бы здорово!


23
вы должны сказать им, что они глупые - на самом деле есть веская причина, почему vim делает это: stackoverflow.com/questions/729692/… . Полагаю, это актуально, только если вы развертываете на Unix-подобных серверах.
hdgarrood

5
Официальная практика PHP рекомендуется опускать последний ?>закрывающий тег, просто по этой причине.
Себастьян Гриньоли

этот вопрос, вероятно, предшествует суперпользователю ... но он должен быть там.
GCB

20
На самом деле вопрос должен быть: Как мы говорим все другие редактора , что люди в вашем магазине используют для обеспечения последней строки файла делает конец с оконечным резистором. ;-)
TJ Crowder

Ответы:


361

А для vim7.4+ вы можете использовать (желательно на .vimrc) (спасибо 罗泽轩 за последние новости!):

:set nofixendofline

Теперь о старых версиях vim.

Даже если файл уже был сохранен с новыми строками в конце:

vim -b file и однажды в VIM:

:set noeol
:wq

сделано.

В качестве альтернативы вы можете открыть файлы в VIM с :e ++bin file

Еще одна альтернатива:

:set binary
:set noeol
:wq

6
Вы также можете добавить set binaryи set noeolв свой .vimrc
dryobs

17
Осторожно : binaryпереопределения expandtab, которые приведут вас к буквальным вкладкам в вашем источнике.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

4
@CiroSantilli спасибо! Я искал побочные эффекты двоичного файла навсегда и удивляюсь, почему он не используется по умолчанию! так как я люблю свои вкладки, я думаю, что я рассмотрю эту дополнительную выгоду :)
ГКБ

11
Теперь вы можете добавить , set nofixendoflineчтобы решить эту проблему в Vim 7.4+
罗泽轩

1
@TrevorBoydSmith да, потому что исторически POSIX (я могу ошибаться по фактическому стандарту) ожидает новую строку в конце строки в текстовом файле. Вот почему большинство решений требовало рассматривать его как двоичный файл. Это, вероятно, было очень удобно тогда, и это отсталый сегодня, поэтому сейчас есть удобная настройка. Просто добавьте его в свой vimrc. В любом случае, в других редакторах проблемы хуже :)
gcb

23

Добавьте следующую команду в ваш .vimrc, чтобы включить опцию конца строки:

autocmd FileType php setlocal noeol binary fileformat=dos

Однако сам PHP будет игнорировать этот последний конец строки - это не должно быть проблемой. Я почти уверен, что в вашем случае есть что-то еще, что добавляет последний символ новой строки, или, возможно, есть путаница с типами окончания строки windows / unix ( \nили \r\nи т. Д.).

Обновить:

Альтернативным решением может быть добавление этой строки в ваш .vimrc:

set fileformats+=dos

Я знаю, что php не анализирует это неправильно ... Я показал это моим коллегам, но winmerge видит их как отличающихся ... Я попробую это и дам вам знать, как это получается.
Бушли

Выполнение этого не дает желаемого эффекта заключительной строки, но также преобразует файл в окончание строки Unix ... (даже в окне Windows) ... Так что я делал это раньше, переключаясь в двоичный режим ... но затем окончания строк не отображаются, напишите в блокноте ... все это только одна строка.
Бушли

К сожалению, ни одно из этих предложений не работает. Добавление fileformat = dos к autocmd не имеет никакого эффекта, а установка filetype + = dos все еще добавляет завершающий \ n
Boushley

Извините, я ошибся, используйте 'set filetypes + = dos', а не 'set fileformats ...'
слишком много php

17

Есть другой способ приблизиться к этому, если вы используете Git для контроля версий. Вдохновленный ответом здесь , я написал свой собственный фильтр для использования в файле gitattributes .

Чтобы установить этот фильтр, сохраните его как- noeol_filterнибудь в своем$PATH , сделайте его исполняемым и выполните следующие команды:

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

Чтобы начать использовать фильтр только для себя, поставьте следующую строку в $GIT_DIR/info/attributes :

*.php filter=noeol

Это гарантирует, что вы не будете вводить новую строку в eof в .phpфайле, независимо от того, что делает Vim.

А теперь сам скрипт:

#!/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)

Это отличное решение ... хотя, к сожалению, я не использовал git. Я использовал SVN, хотя я подозреваю, что подобный подход мог быть использован. В любом случае, я перешел с этой позиции, и мне больше не нужно об этом беспокоиться :)
Boushley

12

Я не пробовал эту опцию, но в справочной системе vim указана следующая информация (т.е. help 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.  

Обычно вам не нужно устанавливать или сбрасывать эту опцию. Когда «бинарный» выключен, значение не используется при записи файла. Когда «двоичный» включен, он используется для запоминания наличия последней строки в файле, так что при записи файла можно сохранить ситуацию из исходного файла. Но вы можете изменить его, если хотите.

Вас также может заинтересовать ответ на предыдущий вопрос: « Почему файлы должны заканчиваться символом новой строки ».


Я также сталкивался с настройкой eol ... но она не выполняет эту задачу. Это скорее переменная, которая определяет, был ли он уже помещен в конец файла или нет. Кроме того, это не влияет на текстовые файлы, но только на двоичные файлы.
Бушли

3
Справка vim также говорит: «Когда« двоичный »выключен, значение не используется при записи файла». о
EOL

1
+1 за ответ VonC на этот вопрос, который подчеркивает, что «новая строка» и EOL объединяются. Нижестоящие редакторы некорректно отображают дополнительную новую строку из-за EOL, vim не добавляет "новую строку"!
ches

9

Я добавил подсказку на вики Vim для аналогичной (хотя и другой) проблемы:

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


5
«Vim 7.4.785 добавляет fixeolопцию, которая может быть отключена для автоматического сохранения любого отсутствующего EOL в конце файла. Этот сценарий становится ненужным для Vim 7.4.785 и более поздних версий ». (Источник: та же вики-страница.) Спасибо, я не знал об этой новой опции.
Амир

1
Я должен был установить оба noeolи nofixeolдостичь желаемого результата.
selurvedu

8

Хорошо, ты находишься на Windows, все усложняет;)

Так как опция 'binary' сбрасывает опцию 'fileformat' (а запись с использованием 'binary' set всегда записывает с окончанием строки Unix), давайте возьмем большой молоток и сделаем это внешне!

Как насчет определения автокоманды (: help autocommand) для события BufWritePost? Эта автокоманда выполняется после каждой записи целого буфера. В этой автокоманде вызывается небольшой внешний инструмент (php, perl или любой другой скрипт), который удаляет последний символ новой строки только что написанного файла.

Так что это будет выглядеть примерно так и попадет в ваш файл .vimrc:

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

Обязательно прочитайте всю документацию vim об автокомандах, если вы впервые работаете с автокомандами. Есть некоторые предостережения, например, рекомендуется удалить все autocmds из вашего .vimrc на тот случай, если ваш .vimrc может быть получен несколько раз.


Ну ... я надеялся, что было лучшее решение, чем это ... но это определенно работает!
Бушли

3
Это прекрасно работает! Ура! Однако у меня есть один вопрос ... есть ли способ сделать это, чтобы мне не приходилось нажимать клавишу ввода дважды после каждого сохранения. Я должен нажать Enter в появившемся окне cmd, а затем снова, потому что vim сообщает мне, что скрипт успешно завершен ... Есть ли способ просто заставить их всех исчезнуть?
Бушли

2
Чтобы избежать подсказок <Press Enter>, просто добавьте к команде префикс silent. Например silent !your-script <afile>.
Даш-Том-Банг

6

Я реализовал предложения Blixtor с помощью постобработки Perl и Python, либо выполняющейся внутри Vim (если она скомпилирована с такой поддержкой языка), либо с помощью внешнего сценария Perl. Он доступен как плагин PreserveNoEOL на vim.org.


Я не проверил это полностью, но это кажется лучшим решением.
Boushley

Плагин работает, но после установки мне пришлось положить let g:PreserveNoEOL = 1в мой .vimrcфайл! Пришлось учить vimscript, чтобы понять это из описания плагина! : D
ДартВангер

1
@DarthVanger: :help PreserveNoEOL-usageсказал бы и вам тоже. RTFM :-)
Инго Каркат

@IngoKarkat Ой, прости. Искал это под INSTALLATIONа CONFIGURATION. Даже не заметил USAGEраздел в описании, потому что он выше установки :)
DarthVanger

3

Может быть, вы могли бы посмотреть, почему они жалуются. Если в файле php после новой строки есть символ новой строки?>, Php выведет его как часть страницы. Это не проблема, если вы не попытаетесь отправить заголовки после включения файла.

Тем не менее,?> В конце php-файла не является обязательным. Нет конца?>, Нет проблем с переводом строки в конец файла.


2
Вы правы, но мы, как магазин, решили, что лучше иметь окончание?> Я знаю, что мы можем перестать его использовать ... но я бы предпочел настроить свой редактор так, чтобы он соответствовал моему стилю кодирования, а не наоборот.
Бушли

1
Кроме того, вы знаете, что php автоматически проанализирует ваш конечный тег как?> Или как?> \ N (потому что в linux все допустимые файлы должны заканчиваться на \ n) ... Так что мой код не вызывает этих проблем ... им просто не нравится внешний вид.
Бушли

2

Я добавляю в .vimrc

set binary

и это помогает, попробуйте


2

Я думаю, что нашел лучшее решение, чем принятый ответ. Альтернативные решения не работали для меня, и я не хотел постоянно работать в двоичном режиме. К счастью, это, кажется, делает работу, и я еще не столкнулся с какими-либо неприятными побочными эффектами: сохраняйте пропущенный конец строки в конце текстовых файлов . Я просто добавил все это в мой ~ / .vimrc.


1

Можно ли использовать специальную команду для сохранения этих файлов?

Если вы сделаете: set binary,: w и: set nobinary, файл будет записан без перевода строки, если не было ни одного, с которого нужно начинать.

Эта последовательность команд может быть помещена в определенную пользователем команду или отображение, конечно.


К сожалению, потому что я работаю с окнами, если я сохраняю его в двоичном режиме, это приводит к тому, что сохранение происходит в режиме Unix. Даже когда я делаю: set binary: set fileformat = dos: w: set nobinary После того, как я ушел, он сохранил файл в формате Unix ... Я не могу поверить, что нет никакого способа просто отключить это.
Бушли


0

Я обнаружил, что этот плагин vimscript полезен в этой ситуации.

Plugin 'vim-scripts/PreserveNoEOL'

Или читайте больше на github

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.