2014-10-28 27 views
4

如果我做Emacs:使用添加掛機內部函數(defun定義)

(add-hook 'haskell-mode-hook 
    (lambda() 
     (setq indent-tabs-mode t) 
     (setq tab-width 4) 
     (message "OK"))) 

在我~/.emacs.d/init.el,則(lambda ...)並得到執行,當我進入haskell-mode

但是,如果我用這樣的功能:

(defun my-add-hook (hook tmode twidth) 
    (add-hook hook 
     (lambda() 
      (setq indent-tabs-mode tmode) 
      (setq tab-width twidth) 
      (message "OK")))) 

,然後再打它~/.emacs.d/init.el像這樣:

(my-add-hook 'haskell-mode-hook t 4) 

然後什麼也不會發生(即使是 「OK」 的消息ISN」 t顯示)。 add-hook a 從defun內無法使用的特殊功能?我在單獨的初始化文件中定義了每個項目 設置,該文件檢測緩衝區名稱 並將(lambda()...)調用添加到相關的主要模式(在上面的示例中爲 ,haskell-mode);我想通過使用上面的my-add-hook這樣的薄 包裝來減少代碼的詳細程度,但我不知道爲什麼add-hook難以如此 。

EDIT1:增加了用於說明的代碼。編輯2:當我嘗試使用my-add-hook時,出現「文件模式規範錯誤:(void-variable tmode)」消息。

+2

我認爲你需要在t'詞法binding',或使用報價/所享有的拉姆達。 – 2014-10-28 16:34:27

+1

問題是Emacs Lisp沒有使用詞法作用域,所以'twidth'在鉤子被調用時不會有'4'的值。 – Barmar 2014-10-28 16:34:40

+0

@Barmar:我不知道Emacs中的詞彙範圍意味着什麼,但是我忘了提及當使用'my-add-hook'時我得到了「File mode specification error:(void-variable tmode)」;所以,你是對的變量是無效的,但我該如何解決它? – 2014-10-28 16:49:19

回答

6

這裏有一個簡單的解決,而無需瞭解詞彙的結合:

(defun my-add-hook (hook tmode twidth) 
    (add-hook hook 
      `(lambda() 
       (setq indent-tabs-mode ,tmode) 
       (setq tab-width ,twidth) 
       (message "OK")))) 
+1

這是在emacs中解決此問題的典型方法,還是使用詞法綁定更慣用? – 2014-10-28 16:53:41

+0

詞法綁定相對較新。您可以根據每個文件進行設置,但您必須確保不會破壞任何內容。這種方法是爲了快速做東西。 – 2014-10-28 16:55:21

+0

謝謝,這個作品!我可以看到正在打印的信息。即使我最終使用的東西,我將不得不添加「詞法綁定」到我的emacs學習列表。非常感謝你。 – 2014-10-28 16:56:02

2

可以使用詞彙,讓重新綁定變量,那麼拉姆達功能將保留它們的值:

(defun my-add-hook (hook tmode twidth) 
    (lexical-let ((tmode tmode) 
       (twidth twidth)) 
    (add-hook hook 
     (lambda() 
      (setq indent-tabs-mode tmode) 
      (setq tab-width twidth) 
      (message "OK"))))) 

我不確定這是否是最慣用的Emacs Lisp代碼,但它確實遵循Emacs Wiki文章DynamicBindingVsLexicalBinding中顯示的相同模式,它定義組成爲:

(defun compose (f g) 
    (lexical-let ((f f) 
       (g g)) 
    (lambda (x) 
     (funcall f (funcall g x))))) 
+0

謝謝你。這也按預期工作。爲後代提供多種替代解決方案非常重要。是的,我同意你的說法,即試圖使用慣用的Emacs lisp非常重要。 :) – 2014-10-28 16:58:38