我使用类似于这个最小例子的习语和宏来编写我自己的Emacs次要模式:
(define-minor-mode foo-mode
"Toggle Foo mode."
:init-value nil
:lighter " Foo"
:group 'foo
(if foo-mode
(do-enable-foo)
(do-disable-foo))
)
(defun do-enable-foo ()
"Enable foo minor mode"
(message "Enabling foo...")
(if test-something
(message "Foo enabled after disabling was canceled!")
(message "Foo enabled from scratch"))
)
(defun do-disable-foo ()
"Disable foo minor mode"
(message "Disabling foo...")
(if (not certain-situation)
(message "... done.") ; finish disabling foo
;; else forms:
(message "Need to cancel disabling foo!")
(foo-mode 1)) ; turning foo mode on again
)
在轻微模式切换期间,当我必须取消切换时,可能会出现'certain-situation
。目前,我在想,因为我使用的是define-minor-mode
宏,我无法摆脱困境,只需要使用(foo-mode 1)
以编程方式再次打开模式,如代码所示。
如果我走这条路线,我将不得不在启用函数do-enable-foo
中处理这个问题 - 所以我的第一个问题是如何使用上面代码中的占位符'test-something
来检测这种情况?
或者,是否有更简洁的方法来实现取消,例如,通过发出错误信号而不是(foo-mode 1)
来阻止模式切换通过?
答案 0 :(得分:1)
如果您想取消“关闭”,而不是致电user_size - 1
,则可以(foo-mode 1)
。
如果出于某种原因你真的想以递归方式调用(setq foo-mode t)
来重新启用该模式,那么你可以通过以下方式进行:
(foo-mode 1)
答案 1 :(得分:0)
我会非常害怕阻止用户关闭次要模式。我的意思是,如果次要模式被打破或行为不端,你就会留下一个必须被杀死的破坏的Emacs。你想要的条件是什么?
相反的情况 - 在某些情况下拒绝开启的模式 - 已经发生 - paredit-mode是一个很好的例子。它只会在define-minor-mode主体中抛出一个错误。
答案 2 :(得分:0)
我最终使用Stefan的建议,使用变量向次模式定义发出信号,表明由于取消了禁用过程(实际上是用户查询的结果),模式已启用。我不敢使用简单地将模式变量设置为t
的想法,但我找不到那些警告它的文档。可能值得看看使用(setq foo-mode t)
实际上是否允许我删除新变量canceled-foo-off
。
(defvar canceled-foo-off nil "Set to `true' if user canceled toggling off foo.")
(make-variable-buffer-local 'canceled-foo-off)
(define-minor-mode foo-mode
...
(if foo-mode
(if canceled-foo-off
(setq canceled-foo-off nil) ; Mode was turned back on from cancelling
(do-enable-foo)) ; Mode was turned on from scratch
(do-disable-foo))
)
(defun do-disable-foo ()
"Disable foo minor mode"
(if (not certain-situation)
...
;; else forms:
(setq canceled-foo-off t) ; make sure mode starting procedure is not run!
(foo-mode 1)) ; turning foo mode on again
)