Почему gedit и vim скрывают от пользователя последнюю новую строку?

Предположим, у нас есть два текстовых документа:

  1. Наш первый файл содержит «hi» в качестве текста.
  2. Наш второй файл содержит «hi» в качестве текста.

Когда мы открываем эти два файла в gedit, vi или vim, эти два файла визуально идентичны во всех отношениях.

Однако, когда мы запускаем xxd для файлов, мы получаем следующее:

  1. Шестнадцатеричный код нашего первого файла: 6869
  2. Шестнадцатеричный код нашего второго файла: 6869 0a

Ага! Есть невидимая новая строка. В vim, если бы мы уделили достаточно внимания строке состояния и поняли, что означает [noeol], то мы могли бы понять это, но в gedit два файла открываются точно так же!

В небольшом опросе, когда я просил людей различать два файла, используя только gedit или vim, они не справились в 100% случаев. Когда я попросил их выполнить ту же задачу с помощью leafpad или emacs, они добились успеха в 100% случаев.

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

(Возьмем, к примеру, двух C-программистов, которые видят содержимое этих двух файлов одинаковым в своем текстовом редакторе vi/gedit, а затем, предполагая, что видят то, что получают, продолжают записывать содержимое в массив char greeting[2]. первый программист, пишущий первый файл, хотя и немного неряшливый со своим кодом, идет к славе и богатству, но второй программист, пишущий второй файл, умирает в нищете, сбитый с толку и сбитый с толку этим невидимым (и предотвратимым) стеком переполнение.)

Итак, скажите, пожалуйста, в чем преимущества текстовых редакторов, таких как vim и gedit, которые добавляют невидимые новые строки в конце каждого документа, который они создают, а затем продолжают скрывать эти новые строки от пользователя, так что истинное содержимое этих файлов только видимо обнаруживаются с помощью других текстовых редакторов?


person schulwitz    schedule 08.10.2013    source источник
comment
Естественно, Emacs добавит последнюю новую строку, если вы захотите, с помощью переменной `require-final-newline'. Я думаю, что есть способ, специфичный для режима, тоже. Кажется довольно самонадеянным, чтобы редактор общего назначения добавлял байты к файлу, о котором вы его не просили, но если Vim предназначен только для использования в системах Unix для записи определенных типов файлов, то, возможно, это несправедливо. назвать его редактором общего назначения.   -  person EvansWinner    schedule 09.10.2013


Ответы (2)


То, что вы воспринимаете последнюю строку как «визуально скрытую», проистекает из противоположных точек зрения.

Многие люди (особенно с фоном Unix) утверждают, что текстовые файлы всегда должны заканчиваться новой строкой (например, см. Почему текстовые файлы должны заканчиваться символом новой строки?), и что любой текстовый редактор, позволяющий создавать файлы без него, в корне неисправен. С этой точки зрения отсутствие дополнительных пустых строк в Vim соответствует только этому взгляду на мир. Файл появляется в редакторе так же, как если бы он был cat загружен в терминал.

С точки зрения Vim, файл с отсутствующей новой строкой является еретическим и дефектным; вот почему он отображается сообщением [noeol] при загрузке (и довольно сложно редактировать файл, сохраняя отсутствующую новую строку; хотя я написал PreserveNoEOL plugin, чтобы помочь с этим).

person Ingo Karkat    schedule 08.10.2013
comment
Исходя из фона Windows, ваш ответ помогает прояснить ожидания текстового редактора / текстового файла Unix, спасибо. Однако я не думаю, что визуально скрытое можно отклонить просто как точку зрения (т. Е. Если два разных текстовых файла отображаются одинаково для глаза пользователя, то есть что-то - объективно говоря - визуально скрытое). Если бы vi отображал неизменяемую пустую строку в конце каждого создаваемого им файла, это соответствовало бы ожиданиям вашего текстового файла/текстового редактора unix, а также обеспечивало контрастное визуальное представление для пользователя, который сталкивается с текстовыми файлами без последней строки. - person schulwitz; 08.10.2013
comment
@schulwitz, почему Vim должен отображать строку, которой нет, как если бы она была? Как насчет того, чтобы вместо этого исправить все неправильные интерпретации символа EOL? И пользователь может прекрасно видеть, не заканчивается ли последняя строка EOL с [noeol] в строке состояния. - person romainl; 08.10.2013
comment
Спасибо. С точки зрения Unix эти два файла практически идентичны (и они будут после первой команды :write). С этой точки зрения просто не стоит заботиться о различиях. Вы правы, что это вызывает трения при взаимодействии с другим миром. - person Ingo Karkat; 08.10.2013
comment
@romainl пользователь может прекрасно видеть, не заканчивается ли последняя строка EOL с [noeol] в строке состояния. Именно по моему мнению, если единственное, что визуально отличает один файл от другого, находится в строке состояния, ваш визуальный дизайн не смог передать пользователю надлежащее значение. - person schulwitz; 08.10.2013
comment
Я не согласен. Последняя строка текстового файла должна заканчиваться символом EOL: это нормально и имеет смысл. Что не имеет смысла, так это отображение пустой строки после самого последнего символа файла, а Vim корректно избегает этого. Наличие EOL является нормальным и ожидаемым, поэтому показывать особо нечего! Когда Vim обнаруживает файл без EOL, он услужливо предупреждает вас. Как бы вы указали, что нет EOL? Символ в конце последней строки? Что, если эта последняя строка имеет номер 4325, и вы ее не видите? Строка состояния, очевидно, является единственным разумным решением. - person romainl; 08.10.2013
comment
@romaini Единственная причина, по которой вы не сможете увидеть строку № 4325, заключается в том, что вы не пытались на нее посмотреть (т. Е. Если бы мы не использовали визуальный интерфейс vi, чтобы увидеть eol), поэтому нет причин для беспокойства. об этом. И кстати, я не против [noeol] в строке состояния, но это ни в коем случае не единственное разумное решение, просто одно из них. Ваше предложение символа сработало бы хорошо, красный ~ (чтобы контрастировать с синими) отлично справился бы с задачей, IMO. - person schulwitz; 11.10.2013

Я считаю, что это условность, перенесенная из vi. Одним из преимуществ этого является то, что при объединении файлов вы по-прежнему можете различать, где заканчивался каждый файл.

Дополнительный контекст предоставляется в этой ветке списка рассылки vim_use.

person Christian Brabandt    schedule 08.10.2013
comment
Я понимаю (и признаю), что конечная новая строка имеет свои преимущества. Чего я не понимаю, так это почему это визуально скрыто от пользователя? (т.е. в vim конечная новая строка не имеет визуального представления, вместо этого появляется ~, как будто в файле ничего не осталось. Однако буквально каждая вторая новая строка в vim имеет пустую строку, указывающую на ее присутствие, почему не последняя? ) - person schulwitz; 08.10.2013
comment
@schulwitz, эта пустая строка не отображается, потому что ее там нет. Символ EOL обычно интерпретируется двояко: все, что следует после меня, должно рассматриваться как находящееся на новой строке, а после меня следует новая строка. Большинство текстовых редакторов / IDE с графическим интерфейсом, с фоном UNIX или без него, следуют первому (неправильному): то, что идет после EOL, считается строкой, и редактор отображает ее как таковую, даже если логическое определение строки не встречается. Большинство текстовых редакторов UNIX следуют второму: потому что после последнего EOL вообще ничего не нужно показывать. - person romainl; 08.10.2013
comment
Я думаю, что это просто другой взгляд на понятия. В мире Unix последняя новая строка считается ограничителем строки, в то время как в мире Windows она считается разделителем строк. /b>, просто нет последней новой строки, скрытой от пользователя. - person Christian Brabandt; 08.10.2013
comment
Мне нравится ваш ответ, Кристиан, который я бы перефразировал так: в концептуальном представлении Vim о символе EOL, когда в конце файла нет EOL, тогда есть только одна неполная строка, потому что у нее нет EOL. С EOL по-прежнему есть только одна линия, и она правильно завершена. С точки зрения других редакторов, когда в конце файла нет EOL, значит, в файле есть одна строка, и в этой строке нет ничего особенного. Когда в конце файла есть EOL, есть две строки, разделенные EOL, и последняя строка пуста. - person Ben; 06.11.2013