2010-03-22 174 views
9

我有一個小模式。如果該模式處於活動狀態並且用戶點擊了DEL,我想 需要執行一些操作,但只有在某些條件成立的情況下才會執行。如果 條件成立並且執行操作,那麼在此之後我不想做任何其他更多 。但是,如果條件失敗,我不想做任何事情 並讓默認的DEL操作執行。Emacs鍵綁定回退

不知道我該如何解決這個問題。但我想我能做到這一點有兩種方式:

1) 我可以重新綁定DEL鍵功能在小模式,然後 檢查,如果條件成立OT沒有。但是,我怎麼知道DEL的默認命令是 ?

2) 我可以添加一個像這樣的預命令鉤子。執行命令然後打破鏈。但是,我如何打破這個鏈條?

(add-hook 'pre-command-hook 
      (lambda() 
      (when (equal last-input-event 'backspace) 
       ;; Do something and then stop (do not execute the 
       ;; command that backspace is bound to) 
      ))) 

你會以何種方式解決它?謝謝!

+0

del和backspace是否一樣? – Amos 2010-03-22 16:53:14

回答

12

要做到這一點的方法是暫時禁用您的次要模式,然後查找鍵綁定。

假裝已綁定'do-thingy刪除。那麼這會做的伎倆(假設要觸發關閉條件是(equal last-input-event 'backspace)

(defun do-thingy() 
    "Do something, unless last event was backspace." 
    (interactive) 
    (if (equal last-input-event 'backspace) 
     (let* ((my-minor-mode nil) 
      (original-func (key-binding (kbd "DEL")))) 
     ;; original-func is whatever DEL would be if 
     ;; my-minor-mode were disabled 
     (call-interactively original-func)) 
    (message "Here's my minor mode behavior!"))) 

注:此行爲假定您已經設置了key bindingsstandard way a minor-mode would具體地說,應該將你的鍵盤映射添加到變量minor-mode-map-alist。通過添加元素(my-minor-mode . my-minor-mode-keymap),這是上面的let聲明是如何工作的,它查找你想要你的模式暫時禁用綁定。

如果使用define-minor-mode來定義你的未成年人模式下,鍵盤映射被建立「正道「自動。」

+0

完美,謝謝! – rejeep 2010-03-22 19:17:34

+2

如果你事先不知道關鍵是你想要回退到哪個關鍵位置,那麼對於任意回退怎麼樣?如何以編程方式查找綁定以用於original-func的值? (從不介意:它看起來像使用這個命令鍵向量)。 – 2011-08-09 19:28:54

-3

似乎沒有辦法可靠地做你想做的事情。如果你的新命令綁定到DEL,那麼在當前鍵盤映射中綁定到DEL之前的東西不再存在。您提出的另一種方法將不起作用,因爲預命令掛鉤不會阻止發生以下操作。你也許會想用^ G(Keyboard-Quit)中斷進一步的執行,但這是一個不受控制的中斷,可能會阻止比你想要的更多的事情。

即使您設置新綁定的過程比剛剛重新綁定更復雜一點,並且記住之前綁定的內容,所以您可以事後調用它,但您並沒有真正擁有自己的外觀對於。如果有人想重新綁定「默認」動作,他們必須通過修改您的功能來完成,而不是替換鍵綁定。

你想做什麼並不符合Emacs的鍵綁定工作模式。

2

這就是我用於我的smart-tab包,正是這樣做。

(defun smart-tab-default() 
    "Indents region if mark is active, or current line otherwise." 
    (interactive) 
    (if mark-active 
     (indent-region (region-beginning) 
        (region-end)) 

    (call-interactively 
    (or 
     ;; Minor mode maps for tab (without smart-tab-mode) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding "\t"))) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding [(tab)]))) 
     (local-key-binding "\t") 
     (local-key-binding [(tab)]) 
     (global-key-binding "\t") 
     (global-key-binding [(tab)]))))) 

,並在命令smart-tab(這是一個在小 模式綁定到選項卡),它具有以下:

(if (smart-tab-must-expand prefix) 
    ;; use smart tab 
    (smart-tab-default)) 

它首先檢查是否有任何次要模式綁定標籤(不包括 smart-tab-mode),然後是本地,最後是全局鍵綁定。