VIM Вимкнути автоматичний новий рядок в кінці файлу


250

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

Якщо хтось знає про це, це було б чудово!


23
Ви повинні сказати їм , що вони нерозумно - є на насправді хороша причина , чому ВІМ робить це: stackoverflow.com/questions/729692 / ... . Я думаю, це актуально лише в тому випадку, якщо ви розгортаєтесь на серверах, схожих на unix.
hdgarrood

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

це питання, ймовірно, передує суперпользователю ... але воно повинно бути там.
gcb

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

Відповіді:


359

А для 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, що призведе до отримання буквальних вкладок у вашому джерелі.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

4
@CiroSantilli дякую! Я шукав бічні побічні ефекти назавжди і цікавився, чому це не за замовчуванням! оскільки я люблю свої вкладки, я думаю, я вважаю, що це додало переваги :)
gcb

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 сприймає їх як різні ... Я спробую це, і я дам вам знати, як це виходить.
Boushley

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

На жаль, жодна з цих пропозицій не працює. Додавання fileformat = dos до autocmd не має ефекту, а встановлений тип файлу + = dos все ще додає трейлінг \ n
Boushley

Вибачте, я помилився, використовуйте "встановити файли + = dos", а не "встановити формати файлів ..."
занадто багато 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.  

Зазвичай цю опцію не потрібно встановлювати чи скидати. Якщо значення "binary" вимкнено, значення не використовується при записі файлу. Якщо ввімкнено "бінарний", він запам'ятовує наявність останнього рядка у файлі, щоб під час запису файла ситуація з вихідного файлу могла зберігатися. Але ви можете змінити це, якщо захочете.

Вас може зацікавити і відповідь на попереднє запитання: " Чому файли закінчуються новим рядком ".


Я також натрапив на налаштування eol ... але це завдання не виконує. Це більше змінна, яка визначає, розміщена вона вже в кінці файлу чи ні. Також це не впливає на текстові файли, а лише на бінарні файли.
Бушлі

3
Довідка vim також говорить: "Коли" бінарний "вимкнено, значення не використовується при записі файлу". про eol
Boushley

1
+1 за відповідь VonC на це запитання, яка підкреслює, що "newline" та EOL плутаються. Недосконалі редактори неправильно відображають додатковий новий рядок через EOL, vim не додає "новий рядок"!
чес

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' завжди пише з кінцями рядка 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 може отримати кілька разів.


Ну ... я сподівався, що є кращого рішення, ніж це ... але це безумовно працює!
Boushley

3
Це чудово працює! Так! Однак у мене є одне питання ... чи є спосіб зробити так, що мені не потрібно двічі натискати клавішу Enter після кожного збереження. Мені потрібно натиснути клавішу Enter у вікні cmd, яке вискочило, а потім ще раз, тому що vim каже мені, що сценарій повернувся успішно ... Будь-який спосіб просто змусити їх все піти?
Бушлі

2
Щоб уникнути запиту <Натисніть Enter>, просто встановіть команду silent. Напр silent !your-script <afile>.
dash-tom-bang

6

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


Я не перевіряв її ретельно, але це здається кращим рішенням.
Бушлі

Плагін працює, але після встановлення мені довелося вставити let g:PreserveNoEOL = 1у свій .vimrcфайл! Довелося навчитися vimscript, щоб зрозуміти це з опису плагіна! : D
ДартВангер

1
@DarthVanger: :help PreserveNoEOL-usageсказав би і вам. RTFM :-)
Ingo Karkat

@IngoKarkat О, вибачте. Шукав це під INSTALLATIONі CONFIGURATION. Навіть не USAGE
описали

3

Можливо, ви могли поглянути на те, чому вони скаржаться. Якщо файл php має новий рядок після закінчення?>, Php виведе його як частину сторінки. Це не проблема, якщо ви не спробуєте надіслати заголовки після включення файлу.

Однак?> В кінці файлу php необов'язково. Немає кінця?>, Немає проблем з новим рядком в кінці файлу.


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

1
Крім того, ви знаєте, що php автоматично розбере ваш кінцевий тег як?> Або як?> \ N (тому що в Linux всі дійсні файли повинні закінчуватися символом \ n) ... Отже, мій код не викликає цих проблем ... їм просто не подобається зовнішній вигляд.
Бушлі


2

Я думаю, що я знайшов краще рішення, ніж прийнята відповідь. Альтернативні рішення не працювали для мене, і мені не хотілося постійно працювати у двійковому режимі. На щастя, це, здається, виконало роботу, і я ще не стикався з жодними неприємними побічними ефектами: збережіть пропущені кінці рядка в кінці текстових файлів . Я щойно додав все до мого ~ / .vimrc.


1

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

Якщо ви робите: встановіть бінарний,: w і: set nobinary, файл буде записаний без нового рядка, якщо не було з чого починати.

Ця послідовність команд, звичайно, може бути поміщена у визначену користувачем команду чи відображення.


На жаль, оскільки я працюю з Windows, якщо я зберігаю його у двійковому режимі, він змушує економити в режимі unix. Навіть коли я роблю: встановити бінарний: встановити файлформат = dos: w: встановити nobinary Після того, як я вийшов, він зберег файл у форматі unix ... Я не можу повірити, що не існує способу просто вимкнути це.
Бушлі


0

Я виявив, що цей плагін vimscript корисний для цієї ситуації.

Plugin 'vim-scripts/PreserveNoEOL'

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.