Получение 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, чтобы сделать это только магия, если текущий основной режим - С++ - режим.

Это любопытное решение. Если вы удалите все вкладки, что вы делаете, чтобы вернуть вкладки? Если вы остановите все, что вам не понадобится, вам это не понадобится.