Когда вы редактируете файл в Emacs, вы фактически работаете с буфером,
который посещает этот файл, — то есть содержимое файла копируется в буфер,
и вы редактируете именно эту копию. Изменения в буфере не влияют на файл,
пока вы не сохраните буфер, что означает копирование содержимого
буфера в файл. Буферы, которые не посещают файл, также можно «сохранять»
в некотором смысле, используя функции в буферно-локальном хуке
write-contents-functions.
Эта функция сохраняет содержимое текущего буфера в его посещаемом файле, если буфер был изменён с момента последнего посещения или сохранения. В противном случае она ничего не делает.
save-buffer отвечает за создание резервных копий. Обычно
backup-option равен nil, и save-buffer создаёт
резервную копию, только если это первое сохранение после посещения файла.
Другие значения backup-option требуют создания резервных копий
в иных обстоятельствах:
save-buffer помечает эту версию файла как подлежащую
резервному копированию при следующем сохранении буфера.
save-buffer безусловно создаёт резервную копию
предыдущей версии файла перед его сохранением.
Эта команда сохраняет некоторые изменённые буферы, посещающие файлы.
Обычно она спрашивает пользователя о каждом буфере. Но если
save-silently-p не равен nil, она сохраняет все
буферы, посещающие файлы, без опроса пользователя.
Необязательный аргумент pred задаёт предикат, который определяет,
какие буферы следует спрашивать (или сохранять молча, если
save-silently-p не равен nil). Если pred равен
nil, это означает использование значения
save-some-buffers-default-predicate вместо pred. Если
результат равен nil, это означает опрос только буферов,
посещающих файлы. Если результат равен t, это означает
предложение сохранить также некоторые другие не-файловые буферы —
те, у которых буферно-локальное значение buffer-offer-save
не равно nil (см. Уничтожение буферов). Пользователь,
согласившийся на сохранение не-файлового буфера, должен будет указать
имя файла для сохранения. Функция save-buffers-kill-emacs
передаёт значение t для pred.
Если предикат не равен ни t, ни nil, то это должна быть
функция без аргументов. Она будет вызвана в каждом буфере, чтобы
определить, предлагать ли сохранение этого буфера. Если она возвращает
значение, не равное nil, в некотором буфере, это означает,
что сохранение этого буфера следует предложить.
Эта функция записывает текущий буфер в файл filename, делает
буфер посещающим этот файл и помечает его как не изменённый. Затем она
переименовывает буфер на основе filename, добавляя строку
наподобие «<2>», если это необходимо для создания уникального
имени буфера. Основную часть работы она выполняет, вызывая
set-visited-file-name (см. Имя файла буфера) и
save-buffer.
Если confirm не равен nil, это означает запрос
подтверждения перед перезаписью существующего файла. Интерактивно
подтверждение требуется, если только пользователь не указал префиксный
аргумент.
Если filename является именем каталога (см. Имена каталогов),
write-file использует имя посещаемого файла в каталоге
filename. Если буфер не посещает файл, вместо этого используется
имя буфера.
Сохранение буфера вызывает несколько хуков. Оно также выполняет
преобразование форматов (см. Преобразование форматов файлов).
Обратите внимание, что эти хуки, описанные ниже, вызываются только
функцией save-buffer, они не вызываются другими примитивами
и функциями, которые записывают текст буфера в файлы, и в частности
автосохранение (см. Автосохранение) не вызывает эти хуки.
Значение этой переменной — список функций, вызываемых перед записью
буфера в его посещаемый файл. Если одна из них возвращает значение,
не равное nil, считается, что файл уже записан, и остальные
функции не вызываются, а обычный код записи файла не выполняется.
Если функция в write-file-functions возвращает значение,
не равное nil, она отвечает за создание резервной копии
(если это уместно). Для этого выполните следующий код:
(or buffer-backed-up (backup-buffer))
Возможно, вы захотите сохранить значение режима файла, возвращаемое
backup-buffer, и использовать его (если оно не равно nil)
для установки битов режима записываемого файла. Именно это обычно
делает save-buffer. См. Создание резервных файлов.
Функции хука в write-file-functions также отвечают за
кодирование данных (если требуется): они должны выбрать подходящую
кодировку и преобразование концов строк (см. Системы кодирования в Lisp),
выполнить кодирование (см. Явное кодирование и декодирование) и
установить last-coding-system-used в использованную систему
кодирования (см. Кодирование и ввод-вывод).
Если вы устанавливаете этот хук локально в буфере, предполагается,
что он связан с файлом или способом получения содержимого буфера.
Таким образом, переменная помечается как постоянная локальная,
чтобы смена основного режима не изменяла буферно-локальное значение.
С другой стороны, вызов set-visited-file-name сбросит его.
Если это не то, что вам нужно, возможно, вы захотите использовать
write-contents-functions вместо него.
Хотя это не обычный хук, вы можете использовать add-hook и
remove-hook для управления списком. См. Хуки.
Работает так же, как write-file-functions, но предназначена для
хуков, относящихся к содержимому буфера, а не к конкретному посещаемому
файлу или его расположению, и может использоваться для создания
произвольных процессов сохранения для буферов, которые вообще не
посещают файлы. Такие хуки обычно настраиваются основными режимами
как буферно-локальные привязки для этой переменной. Эта переменная
автоматически становится буферно-локальной при установке; переключение
на новый основной режим всегда сбрасывает эту переменную, но вызов
set-visited-file-name не делает этого.
Если любая из функций в этом хуке возвращает значение, не равное
nil, считается, что файл уже записан, остальные функции
не вызываются и функции из write-file-functions также не
вызываются.
При использовании этого хука для сохранения буферов, не посещающих
файлы (например, буферов специальных режимов), имейте в виду, что
если функция не сможет сохранить правильно и вернёт значение
nil, save-buffer продолжит запрашивать у пользователя
файл для сохранения буфера. Если это нежелательно, рассмотрите
возможность завершения функции с ошибкой.
Этот обычный хук запускается перед сохранением буфера в его посещаемом файле, независимо от того, выполняется ли это обычным способом или одним из хуков, описанных выше. Например, программа copyright.el использует этот хук, чтобы убедиться, что сохраняемый файл содержит текущий год в уведомлении об авторских правах.
Этот обычный хук запускается после сохранения буфера в его посещаемом файле.
Если эта переменная не равна nil, то save-buffer защищает
от ошибок ввода-вывода при сохранении, записывая новый файл во
временное имя вместо предполагаемого, а затем переименовывая его
в целевое имя после того, как станет ясно, что ошибок нет. Эта
процедура предотвращает проблемы, такие как нехватка места на диске,
которые могут привести к повреждению файла.
Побочным эффектом является то, что резервные копии обязательно создаются копированием. См. Резервное копирование переименованием или копированием?. В то же время сохранение ценного файла всегда разрывает все жёсткие связи между сохраняемым файлом и другими именами файлов.
Некоторые режимы присваивают этой переменной значение, не равное
nil, в качестве буферно-локального значения в определённых
буферах.
Эта переменная определяет, могут ли файлы записываться без завершающей
перевода строки. Если значение переменной равно t, то
save-buffer молча добавляет перевод строки в конце буфера,
если его там нет. Если значение равно visit, Emacs добавляет
недостающий перевод строки сразу после посещения файла. Если значение
равно visit-save, Emacs добавляет недостающий перевод строки
как при посещении, так и при сохранении. Для любого другого значения,
не равного nil, save-buffer спрашивает пользователя,
нужно ли добавлять перевод строки каждый раз, когда возникает такая
ситуация.
Если значение переменной равно nil, то save-buffer вообще
не добавляет переводов строк. Значение nil используется по
умолчанию, но некоторые основные режимы устанавливают его в t
в определённых буферах.
См. также функцию set-visited-file-name (см. Имя файла буфера).