Получение Emacs для немедленного хранения при сохранении определенных типов файлов (и только тех типов файлов)
У меня есть следующее в файле .emacs:
(defun c++-mode-untabify ()
(save-excursion
(goto-char (point-min))
(while (re-search-forward "[ \t]+$" nil t)
(delete-region (match-beginning 0) (match-end 0)))
(goto-char (point-min))
(if (search-forward "\t" nil t)
(untabify (1- (point)) (point-max))))
nil)
(add-hook 'c++-mode-hook
'(lambda ()
(make-local-hook 'write-contents-hooks)
(add-hook 'write-contents-hooks 'c++-mode-untabify)))
В основном срывается с http://www.jwz.org/doc/tabs-vs-spaces.html. Это приводит к тому, что emacs запускает untabify
в буфере перед сохранением файла С++.
Проблема в том, что после того, как я загрузил файл С++, к all записывается следующий файл untabify
, даже для буферов других типов файлов. Это означает, что если я открою файл на С++ и отредактирую, скажем, текстовый файл с разделителями табуляции, вкладки будут сбиты при сохранении файла.
Я не гуру elisp, но я думаю, что строка (make-local-hook 'write-contents-hooks)
пытается сделать дополнение к write-contents-hooks
применимым только к локальному буферу. Однако он не работает, а c++-mode-untabify
находится в write-contents-hooks
для всех буферов.
Я использую EmacsW32 22.0 в окне Windows XP. Кто-нибудь может подумать, как сделать замену write-contents-hooks
локальным на определенный буфер или как reset на nil
при переключении на другие буферы, отличные от С++?
Ответы
Ответ 1
write-content-hooks также устарел. Это то, что вам нужно:
(add-hook 'c++-mode-hook
'(lambda ()
(add-hook 'before-save-hook
(lambda ()
(untabify (point-min) (point-max))))))
Это дистиллируется из того, что я использую, что делает несколько других вещей и абстрагируется для работы с режимами, специфичными для программирования:
(defun untabify-buffer ()
"Untabify current buffer"
(interactive)
(untabify (point-min) (point-max)))
(defun progmodes-hooks ()
"Hooks for programming modes"
(yas/minor-mode-on)
(add-hook 'before-save-hook 'progmodes-write-hooks))
(defun progmodes-write-hooks ()
"Hooks which run on file write for programming modes"
(prog1 nil
(set-buffer-file-coding-system 'utf-8-unix)
(untabify-buffer)
(copyright-update)
(maybe-delete-trailing-whitespace)))
(defun delete-trailing-whitespacep ()
"Should we delete trailing whitespace when saving this file?"
(save-excursion
(goto-char (point-min))
(ignore-errors (next-line 25))
(let ((pos (point)))
(goto-char (point-min))
(and (re-search-forward (concat "@author +" user-full-name) pos t) t))))
(defun maybe-delete-trailing-whitespace ()
"Delete trailing whitespace if I am the author of this file."
(interactive)
(and (delete-trailing-whitespacep) (delete-trailing-whitespace)))
(add-hook 'php-mode-hook 'progmodes-hooks)
(add-hook 'python-mode-hook 'progmodes-hooks)
(add-hook 'js2-mode-hook 'progmodes-hooks)
Ответ 2
Документация в моем Emacs говорит, что make-local-hook теперь устарел с 21.1, так как add-hook теперь принимает необязательный аргумент для создания локального буфера-буфера. Поэтому вы можете попробовать:
(add-hook 'c++-mode-hook
'(lambda ()
(add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))
Другой вариант - проверить, что функция С++ - mode-untabify проверяет текущий режим. Я бы просто написал это как-то вроде:
(defun c++-mode-untabify ()
(if (string= (substring mode-name 0 3) "C++")
(save-excursion
(delete-trailing-whitespace)
(untabify (point-min) (point-max)))))
Ответ 3
Попробуйте добавить свой крючок так:
(add-hook 'c++-mode-hook
'(lambda ()
(add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))
Обратите внимание на два дополнительных приложения для добавления крюка. Если я читаю это правильно, согласно документации, что trailing t должен делать то, что делает локальный крючок (или наоборот), но я также видел ссылки на make-local-hook, которые устарели. По крайней мере, на моем ящике (linux, gnu emacs 21.3.1) Я вижу эффект, который вы хотите - крюк привязан только к буферам С++, а не ко всем другим.
В качестве последнего средства вы всегда можете поместить чек в свою функцию С++ - mode-untabify, чтобы сделать это только магия, если текущий основной режим - С++ - режим.
Это любопытное решение. Если вы удалите все вкладки, что вы делаете, чтобы вернуть вкладки? Если вы остановите все, что вам не понадобится, вам это не понадобится.