我的.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在保存C ++文件之前在缓冲区上运行untabify
。
问题是我加载了一个C ++文件后,untabify
挂钩被应用于所有后续文件写入,即使对于其他文件类型的缓冲区也是如此。这意味着如果我打开一个C ++文件,然后编辑一个制表符分隔的文本文件,那么在保存文件时标签会被破坏。
我不是elisp guru,但我认为(make-local-hook 'write-contents-hooks)
行试图使write-contents-hooks
的添加仅适用于本地缓冲区。但是,它不起作用,c++-mode-untabify
对于所有缓冲区都在write-contents-hooks
。
我在Windows XP的盒子上使用EmacsW32 22.0。有没有人知道如何在特定缓冲区本地进行write-contents-hooks
更改,或者在切换到其他非C ++缓冲区时如何将其重置为nil
?
答案 0 :(得分:20)
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)
答案 1 :(得分:5)
我的Emacs中的文档说自从21.1开始,make-local-hook现在已经过时,因为add-hook现在需要一个可选的参数来创建一个hook buffer-local。所以你可以试试:
(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 :(得分:2)
尝试添加这样的钩子:
(add-hook 'c++-mode-hook
'(lambda ()
(add-hook 'write-contents-hooks 'c++-mode-untabify nil t)))
注意添加两个额外的aguments。如果我正确地阅读它,根据文档说明t应该做make-local-hook所做的事情(反之亦然),但我也看到过对make-local-hook的引用被弃用了。至少在我的盒子上(linux,gnu emacs 21.3.1)我看到你想要的效果 - 钩子只附加到c ++缓冲区而不是所有其他缓冲区。
作为最后的手段,你可以随时检查你的c ++ - mode-untabify函数,只有当前的主要模式是c ++模式才能做到这一点。
然而,这是一个奇怪的解决方案。如果删除所有选项卡,您要做什么才能将标签重新放入?如果你停止任何你不需要这个黑客。