В чем разница между буфером и файлом? Файл — это информация на запоминающем устройстве (на диске), доступная по имени. Буфер — это та же информация в оперативной памяти, доступная для чтения и изменения в Вим. Проще говоря, это копия файла (имеющегося или будущего), которую вы редактируете в Вим. Если вы открыли файл в Вим, то его содержимое скопировано в буфер. Изменения в буфере можно сохранить, в тот же или в другой файл. С буфером может быть связан файл (если вы открыли файл или сохранили буфер в него) или буфер может быть безымянным (если вы создали новый).
Сохранить буфер в связанный с ним файл позволит команда :write, или коротко :w.
Можно указать опции вида ++ff, ++enc, ++bin и ++nobin, позволяющие задать тип конца строки (не меняя опции ff), кодировку файла, а также выставить или сбросить флаг binary. Например:
:w ++enc=cp1251
Можно указать диапазон строк и тогда в файл запишется только он. По умолчанию диапазон 1,$ — весь файл.
Можно указать имя файла: тогда текст будет записан в него, но это копия, а буфер по-прежнему привязан к прежнему файлу (если буфер был безымянный, то теперь он связан с указанным файлом). Если файл уже существует, будет выдано предупреждение и запись не будет произведена. Но можно настоять, применив команду с восклицательным знаком: :w!
И это общее правило. Во всех командах, когда Вим может отказать из соображений безопасности, восклицательный знак означает "я настаиваю!"
Можно выставить флаг writeany, и тогда восклицательный знак подразумевается: Вим будет записывать всё, без предупреждения. Излишне пояснять, что это небезопасно, но вы можете пойти на это. если желаете. Не забываем про флаг confirm: если он выставлен, то Вим будет задавать вопросы.
Можно использовать синтаксис >> file, чтобы дописать текст (весь или диапазон строк) к файлу. В этом случае восклицательный знак предписывает создавать новый файл, если файл не существует.
Можно и передать файл внешней команде cmd: :w !cmd. Можно и диапазон указать. Отличие от :!cmd в том, что можно задать опции вида ++opt. Например, поменять кодировку.
Это бывает полезно при работе с кодировкой cp1251 (Windows). Иногда приходится. Внешние утилиты "видят" не текст, а черт-те что, и вот тогда перекодировка очень пригождается!
Можно использовать файл-устройство, вроде /dev/lpt0, хотя мне ни разу не приходилось записывать туда. Разве что в /dev/null. Читать из /dev/random приходилось... При записи в такой "файл" необходим восклицательный знак, так как файл уже "существует".
Может быть и так, что вы не хотите испортить файл, даже случайно. Защититься несложно: если флаг write сброшен (:set nowrite), то Вим вообще не может записывать файлы. Но временные файлы Вим записывать будет, если нужно.
А если выставлен флаг readonly, то данный буфер защищен от записи. Но его все равно можно записать, применив команду :w!. При этом флаг снимается, и потом можно записывать уже без проблем.
Флаг этот выставляется иногда автоматически. Например, если файл уже открыт в Вим (на сетевом диске или в другом окне), то Вим предложит выбор, в который входит и "открыть только для чтения". Сброс флага можно отключить, если в cpoptions добавить флаг Z. Тогда обойти readonly можно, но при следующей записи придется делать это снова.
И то, и другое может быть логично: иногда вы решили, что эта версия файла будет меняться, и хотите снять флаг (хотя это можно и вручную сделать), а порой вы хотите исправить что-то, но оставить файл защищенным от случайного изменения.
Если вы записываете весь буфер в тот файл, с которым он связан, то снимается признак "не сохранен" (флаг modified сброшен). Если буфер сохранен в другой файл, то обычно нет, файл считается "несохраненным": флаг modified выставлен. Но можно и это обойти, добавив в cpoptions флаг +.
Внимание! Это странно. Вы открыли файл: vim file
Изменили что-то. Выполнили команду :w file1
Если плюсик входит в cpoptions, то файл считается сохраненным, хотя файл file на диске не изменялся!
Есть команда :update, которая работает как :w, но сохраняет файл только в том случае, если буфер изменен. Это полезно, чтобы не менять время доступа к файлу без необходимости, чтобы не тревожить диск понапрасну и сократить число записей, и чтобы сэкономить время при медленной сети или огромных файлах.
Если вы открыли новый буфер, не связанный ни с каким файлом, то :w выдаст ошибку, а :w file сделает то, что вы ожидаете: сохранит буфер в файл и свяжет его с ним.
Будьте очень внимательны, если запись не удалась! Не закрывайте Вим, пока не сохраните всё, что можно, читайте сообщения и не делайте резких движений.
Бывает, что вам надо сохранить копию файла и потом работать с ним, чтобы эта копия была связана с буфером. Для этого есть команда :saveas
Если не определен тип файла, он будет распознан. Флаг readonly будет сброшен. Можно указать опции вида ++opt и восклицательный знак для обхода запретов. Диапазон нельзя указывать: сохраняется всегда весь буфер. Что и логично.
Есть еще команда :wall (:wa), которая не относится ни к какой стене, а сохраняет все буферы в связанные с ними файлы. С восклицательным знаком преодолевает readonly и другие запреты (по возможности). Безымянные буферы не записываются (а куда?!).
При записи может создаваться резервная копия.
При записи нового файла выставляются права на чтение и запись файла (0666). Если в cpoptions есть флаг W, то Вим не будет записывать в защищенный от записи файл — имеются в виду системные права на запись. Если флага нет, то :w! попробует это сделать. Конечно, если прав у вас нет, то всё равно не получится. Но с админскими правами это может быть надо. С флагом W в cpoptions вы защитите свои файлы даже от самого себя!
Команда :wq делает всё то же, что и :w, но при успехе закрывает буфер. Вариант :xit (:x, :exit) тоже, но сохраняет только несохраненный буфер.
Подробно выход из Вим мы уже обсуждали.
Забавная тонкость. Команда :g иногда работает как разрывный диапазон строк, позволяя сделать что-то со строками, которые не обязательно идут подряд. Но для команд сохранения это не подходит! Потому что каждая строка проверяется и, если она подходит, на ней выполняется команда. Попытка выполнить :g/expr/w приведет не к сохранению подпадающих под выражение строк в файл, а к сохранению файла столько раз, сколько совпадений найдется. Можно так: :g/expr/.,.w! >> file. Вот это действительно запишет в файл только те строки, которые подходят.
Удачи, коллеги! God save you.