偶尔我会手动设置不同于默认值的font-family和size,我使用buffer-face-mode
来执行此操作。 (确切地说,我使用鼠标并从对话框中选择一个。)一旦我设置它,我希望它保持为该缓冲区设置,即使我更改模式,所以我尝试了自定义。这个想法是添加一个change-major-mode-hook
(它在缓冲区 - 本地被杀之前运行),它将保存缓冲区面(如果已设置),在稍后调用的函数中 - 这似乎很有效。但是那个函数似乎太快被调用了,当模式改变结束时,buffer-face-mode
没有激活。
这是我到目前为止所提出的定制
(defun my-preserve-bufface-cmmh ()
"Keep the state of buffer-face-mode between major-mode changes"
(if (and (local-variable-p 'buffer-face-mode) buffer-face-mode)
(delay-mode-hooks
(message "face is %s" buffer-face-mode-face) ; Just to show me it has the right face
(let ((my-inner-face buffer-face-mode-face))
(run-mode-hooks
(message "inner %s" my-inner-face) ; it still has the right face here
(setq buffer-face-mode-face my-inner-face)
(buffer-face-mode))))))
(add-hook 'change-major-mode-hook
'my-preserve-bufface-cmmh)
当我在缓冲区中使用次模式buffer-face-mode
设置更改主模式时,这些消息都会运行并显示自定义面。我原以为delay-mode-hooks
... run-mode-hooks
的组合会在新模式设置后运行setq buffer-face-mode-face
... (buffer-face-mode)
,但显然不会。
这个定制是否“关闭”/可以挽救我的需求?有更清洁的方式吗?
答案 0 :(得分:1)
首先,delayed-mode-hooks
本身就是一个局部变量。
这意味着,如果您在(delay-mode-hooks (run-mode-hooks ...))
中按change-major-mode-hook
进行设置
这将无效,因为它会立即被杀死。
第二件事是你run-mode-hooks
内的东西是
在my-preserve-bufface-cmmh
内进行评估。它应该被定义为后引用钩子函数
`(lambda () ...)
您要在其中拼接要保留的值。
另一种方法是使用词汇绑定(谷歌)。
第二件事在以下示例中说明(逐步评估):
(defun test (str)
(let ((mytest (concat "hello " str)))
(add-hook 'my-own-hook `(lambda () (message "mytest:%S" ,mytest)))))
(test "you")
(run-hooks 'my-own-hook)
(test "world")
(run-hooks 'my-own-hook)
(put :myface 'test)
如果要保留字体缓冲区 - 本地,则必须使用幸存 kill-all-local-variables
的本地变量,例如buffer-file-name
。你可以在那里挂钩:
编辑:即使符号具有缓冲区本地值,其属性也不是缓冲区本地。因此,先前的方法不起作用。更好:创建自己的永久缓冲区局部变量:
(defvar-local my-preserve-bufface nil
"Keep the state of buffer-face-mode between major-mode changes")
(put 'my-preserve-bufface 'permanent-local t)
(defun my-preserve-bufface-put ()
"Keep the state of buffer-face-mode between major-mode changes"
(and (local-variable-p 'buffer-face-mode)
buffer-face-mode
(setq my-preserve-bufface buffer-face-mode-face)))
(defun my-preserve-bufface-get ()
"Keep the state of buffer-face-mode between major-mode changes"
(and my-preserve-bufface
(setq buffer-face-mode-face my-preserve-bufface)
(buffer-face-mode)))
(add-hook 'change-major-mode-hook 'my-preserve-bufface-put)
(add-hook 'after-change-major-mode-hook 'my-preserve-bufface-get)
答案 1 :(得分:1)
感谢教育评论,特别是来自@ user2708138的答案/示例,我将接受,因为它确实回答了这个问题。
然而,我也将回答我自己的问题,因为我确实提出了一种更通用的解决方案。我发现我还希望保持我的字体大小更改并且它们来自text-scale-mode
,还有一个小模式要保留,我走了这条路。此代码读取要保留的次要模式列表,而不必弄清楚它们使用哪些变量。 (对于一个人来说,弄清楚它们并不难,但我想尝试让emacs这样做。)
唉,我知道没有函数来检索次模式使用的变量,但我感兴趣的模式使用约定 minor-mode -var-name,所以这个代码只过滤该模式的缓冲区局部变量。
; Save & restore minor modes I wish to be "permanent" if set
(setq my-preserve-minor-modes '(buffer-face-mode text-scale-mode))
(defun my-preserve-minor-modes-cmmh ()
"Keep the state of desired-permanent minor modes between major-mode changes. Assumes that associated buffer-local minor-mode variables to save begin with `minor-mode-'"
(setq my-restore-minor-modes-acmmh nil)
(dolist (mm my-preserve-minor-modes)
(when (and (local-variable-p mm) (symbol-value mm))
(push mm my-restore-minor-modes-acmmh)))
(when my-restore-minor-modes-acmmh
(add-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
; Predicate-list showing if symbol starts with a preserved mode
(let ((mm-p-l `(lambda (locvar-nm)
(or ,@(mapcar (lambda (mm)
`(and (< ,(length (symbol-name mm))
(length locvar-nm))
(string-prefix-p ,(symbol-name mm)
locvar-nm)))
my-restore-minor-modes-acmmh)))))
; For each found minor mode, create fn to restore its buf-local variables
(dolist (locvar (buffer-local-variables))
(if (and (listp locvar) (funcall mm-p-l (symbol-name (car locvar))))
(push `(lambda()(setq ,(car locvar) ',(cdr locvar)))
my-restore-minor-modes-acmmh))))))
(defun my-restore-minor-modes-acmmh ()
"After major-mode change, restore minor-mode state, and remove self from hook. It restores state by calling the function stored in the variable my-restore-minor-modes-acmmh."
(remove-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
(dolist (restore-f my-restore-minor-modes-acmmh) (funcall restore-f)))
(add-hook 'change-major-mode-hook 'my-preserve-minor-modes-cmmh)
我确实知道permanent-local
属性,但我不确定是否有任何不必要的副作用......我可能是无根据的偏执狂!
如果有办法获得次要模式的变量列表,或者让用户为每个次要模式指定变量列表,我的答案可以得到改善 - 在任何一种情况下我们都不必循环buffer-local-variables
再一次,也许只是将所有permanent-local
全部放在我们需要的地方,简化代码。无论如何,把这一切都搞清楚(在你的帮助下,看看精美的手册)是非常有教育意义的。