2

我正在使用类似于这个最小示例的习语和宏来编写我自己的 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当我必须取消切换时可能会出现a。目前,我在想,因为我正在使用define-minor-mode宏,所以我无法退出,而只需要以编程方式再次使用(foo-mode 1)代码中所示的方式打开模式。

如果我走这条路,我将不得不在启用功能中以不同的方式处理这个do-enable-foo问题——所以我的第一个问题是如何使用上面代码中的占位符来检测这种情况'test-something

或者,是否有更简洁的方法来实现取消,例如,通过发出错误信号而不是(foo-mode 1)阻止模式切换通过?

4

3 回答 3

1

如果你想取消“关闭”,而不是打电话(foo-mode 1),你可以(setq foo-mode t)

如果由于某种原因您真的想(foo-mode 1)递归调用以(重新)启用该模式,那么您可以通过以下方式执行此操作:

(defvar foo-mode--reenabling nil)
....
(defun do-enable-foo ()
  (if foo-mode--reenabling
      ...
    ...))
...
(defun do-disable-foo ()
  ...
  (let ((foo-mode--reenabling t))
    (foo-mode 1)))
于 2015-05-16T13:25:23.843 回答
0

我会非常害怕阻止用户关闭次要模式。我的意思是,如果次要模式被破坏或行为不端,你就会给他们留下一个必须被杀死的损坏的 Emacs。你正在考虑的条件是什么?

相反的情况——在某些情况下拒绝打开的模式——已经发生了——paredit-mode就是一个很好的例子。它只是在 define-minor-mode 正文中引发错误。

于 2015-05-15T13:48:42.073 回答
0

我最终以下列方式使用 Stefan 的建议,使用变量向次要模式定义发出信号,即由于取消禁用过程(实际上是用户查询的结果)而启用了该模式。我不敢使用简单地将模式变量设置为的想法,t但我再也找不到警告它的文档了。看看 using 是否(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
  )
于 2015-09-28T14:12:35.533 回答