В моем файле .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++?





В документации моего Emacs сказано, что make-local-hook теперь устарел с 21.1, поскольку add-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)))))
Попробуйте добавить свой крючок следующим образом:
(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++.
Однако это любопытное решение. Если вы удалите все вкладки, что вы делаете, чтобы вставить вкладки обратно? Если вы прекратите что бы то ни было, этот хак вам не понадобится.
write-contents-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)
Спасибо! Я вставил это, чтобы автоматически удалять вкладки из старого кода, который я не писал, но иногда должен поддерживать,