2015-05-15 39 views
2

我編程使用類似於這個小例子,成語和宏我自己的Emacs的輔助模式: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

我結束了使用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 
) 
+0

你爲什麼要使用'setq'而不是'let'? – Stefan

0

我會非常害怕阻止用戶關閉次要模式。我的意思是,如果次要模式被破壞,或者行爲不當,那麼你必須使用一個必須被殺死的破碎的Emacs。你在想什麼情況?

相反的情況 - 在某些情況下拒絕打開的模式 - 已經發生 - paredit模式就是一個很好的例子。它只是在define-minor-mode主體中拋出一個錯誤。

+0

這是一個很好的建議,但它不是問題的答案。請將其移至評論。 – Chris

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))) 
+0

我對變量做了一個變體,並將其公佈在下面。 – Linda

相關問題