Получение Emacs untabify при сохранении определенных типов файлов (и только этих типов файлов) - PullRequest
11 голосов
/ 25 ноября 2008

В моем файле .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 в буфере перед сохранением файла C ++.

Проблема в том, что после того, как я загрузил файл C ++, хук untabify применяется для всех последующих операций записи в файл, даже для буферов других типов файлов. Это означает, что если я открою файл C ++, а затем отредактирую, скажем, текстовый файл с разделителями табуляции, вкладки при сохранении файла закроются.

Я не гуру elisp, но я думаю, что строка (make-local-hook 'write-contents-hooks) пытается сделать добавление к write-contents-hooks применимым только к локальному буферу. Однако это не работает, и c++-mode-untabify находится в write-contents-hooks для всех буферов.

Я использую EmacsW32 22.0 на Windows XP. Кто-нибудь знает, как заставить write-contents-hooks изменить локально для определенного буфера или как сбросить его на nil при переключении на другие буферы, отличные от C ++?

Ответы [ 3 ]

20 голосов
/ 27 ноября 2008

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)
5 голосов
/ 25 ноября 2008

Документация в моем Emacs гласит, что make-local-hook теперь устарел с 21.1, поскольку add-hook теперь принимает необязательный аргумент для создания hook-буфера локальным. Так что вы можете попробовать:

(add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

Другой вариант - заставить функцию c ++ - mode-untabify проверять текущий режим. Я бы просто написал это как-то так:

(defun c++-mode-untabify ()
  (if (string= (substring mode-name 0 3) "C++")
      (save-excursion
       (delete-trailing-whitespace)
       (untabify (point-min) (point-max)))))
2 голосов
/ 25 ноября 2008

Попробуйте добавить свой хук так:

 (add-hook 'c++-mode-hook
           '(lambda ()
              (add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))

Обратите внимание на два дополнительных инструмента для добавления крючка. Если я правильно понял, в соответствии с документацией, трейлинг t должен делать то, что делает make-local-hook (или наоборот), но я также видел ссылки на make-local-hook как устаревшие. По крайней мере, на моем компьютере (linux, gnu emacs 21.3.1) я вижу эффект, который вы хотите - хук прикреплен только к буферам c ++, а не ко всем остальным.

В качестве последнего средства вы всегда можете поставить галочку в вашей функции c ++ - mode-untabify, чтобы творить чудеса, только если текущий основной режим - c ++ - mode.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...