emacs: является ли переменная before-save-hook локальной переменной? - PullRequest
10 голосов
/ 19 декабря 2009

как бы я это выяснил?

Я добавил delete-trailing-whitespace к before-save-hook в моем c-mode-common-hook, но похоже, что delete-trailing-whitespace вызывается для каждого файла, а не только для буферов с использованием c-mode и производных.

Можно ли сделать буфер before-save-hook локальным?

Ответы [ 5 ]

20 голосов
/ 19 декабря 2009

Добавьте его к write-contents-functions вместо:

(add-hook 'c-mode-common-hook
  (lambda()
    (add-hook 'write-contents-functions
      (lambda()
        (save-excursion
          (delete-trailing-whitespace)))
      nil t)))

Как объясняет Справочное руководство по Emacs Lisp:

Это работает так же, как write-file-functions, но оно предназначено для ловушек, которые относятся к содержимое буфера, а не конкретный посещаемый файл или его местоположение. Такие крючки обычно устанавливаются основными режимами, такими как локальные привязки буфера для этой переменной. Эта переменная автоматически становится локальным для буфера всякий раз, когда он установлен; переключение на новый основной режим всегда сбрасывает эту переменную, но не вызывает set-посещения-имя-файла.

Это правильно работает для меня в Emacs 24.2.1 (то есть он удаляет все конечные пробелы из файлов C, но сохраняет конечные пробелы во всех других типах файлов).

17 голосов
/ 01 февраля 2013

Нет, переменная before-save-hook не является локальным буфером. В документации к переменной не сказано, что она локальная по отношению к буферу, и не сказано, что она автоматически станет локальной по отношению к буферу при установке.

Если вы хотите добавить ловушку локального буфера, правильный способ сделать это - просто использовать необязательный параметр LOCAL стандартной функции add-hook:

(add-hook 'before-save-hook 'foo nil t)

Документация add-hook гласит:

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

Выбранный ответ, чтобы добавить его к local-write-file-hooks, я считаю неправильным. Если вы посмотрите документацию по этой функции в emacs 24.3, она говорит, что переменная устарела с 22.1, и вы должны использовать write-file-functions. И если вы посмотрите документацию write-file-functions, она описывает более сложное поведение и в конце говорит, что «Для выполнения различных проверок или обновлений перед сохранением буфера используйте« before-save-hook »».

3 голосов
/ 19 декабря 2009

Никогда не хотел делать это раньше, но это должно работать:

(set (make-local-variable 'before-save-hook) '((lambda() (rg-msg "foobie")))) 

Как правило, C-h v запрашивает имя переменной и отображает описание, указывающее, является ли переменная локальной буферной.

before-save-hook является определенной переменной в `files.el '. Его значение равно нулю

Эта переменная потенциально опасна при использовании в качестве локальной переменной файла.

Документация: нормальный зацеп перед сохранением буфера в его файл.

Вы можете настроить эту переменную.

против

функция next-error является переменной определено в `simple.el '. Его ценность ноль

Автоматически становится локальным буфером когда установлено любым способом. это переменная потенциально опасна, когда используется как локальная переменная файла.

Документация: функция для поиска следующая ошибка в текущем буфере. Функция вызывается с 2 Параметры:

[...]

0 голосов
/ 01 июля 2018

Да, создайте файл .dir-locals.el в корневом каталоге вашего проекта со следующим содержимым:

((c-mode . ((before-save-hook . (lambda() (delete-trailing-whitespace)) )) ))

Это добавит этот хук только в c-mode буферы ниже этого каталога.

Но если вам нужен только определенный файл, а не целый каталог, вы сможете добавить его в начало файла, используя локальные переменные файла:

-*- eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))); -*-

или конец файла, как это:

;;; Local Variables: ***
;;; eval: (setq before-save-hook (lambda() (delete-trailing-whitespace))) ***
;;; End: ***
0 голосов
/ 19 декабря 2009

Используйте write-contents-function вместо:

write-contents-functions is a variable defined in `files.el'.
Its value is nil

  Automatically becomes buffer-local when set in any fashion.

Documentation:
List of functions to be called before writing out a buffer to a file.
If one of them returns non-nil, the file is considered already written
and the rest are not called and neither are the functions in
`write-file-functions'.

This variable is meant to be used for hooks that pertain to the
buffer's contents, not to the particular visited file; thus,
`set-visited-file-name' does not clear this variable; but changing the
major mode does clear it.

For hooks that _do_ pertain to the particular visited file, use
`write-file-functions'.  Both this variable and
`write-file-functions' relate to how a buffer is saved to file.
To perform various checks or updates before the buffer is saved,
use `before-save-hook'.

Вам следует создать оболочку для вызова delete-trailing-whitespace, так как вы хотите, чтобы вы возвращали nil из оболочки, чтобы иметь место дальнейшая обработка (и возможное сохранение).

...