2014-03-04 35 views
3

我將下面的代碼添加到我的.emacs文件中。將函數傳遞給elisp中的參數

(defun delete-right-window() 
    (interactive) 
    (windmove-right) 
    (delete-window)) 

(defun delete-left-window() 
    (interactive) 
    (windmove-left) 
    (delete-window)) 

(defun delete-below-window() 
    (interactive) 
    (windmove-down) 
    (delete-window)) 

(defun delete-above-window() 
    (interactive) 
    (windmove-up) 
    (delete-window)) 

(global-set-key (kbd "C-s-<right>") 'delete-right-window) 
(global-set-key (kbd "C-s-<left>") 'delete-left-window) 
(global-set-key (kbd "C-s-<down>") 'delete-below-window) 
(global-set-key (kbd "C-s-<up>") 'delete-above-window) 

正如您所看到的,大部分代碼都是重複的。 我讀How do I pass a function as a parameter to in elisp?,並試圖將代碼重構傳遞windmove-*功能如下:

(defun delete-other-window (callback) 
    (interactive) 
    (funcall callback) 
    (delete-window)) 
... 

(defun delete-right() 
    (delete-other-window 'windmove-right)) 

我必將按鍵這樣的:

(global-set-key (kbd "C-s-<right>") 'delete-right) 

但是,當我打C-s-<right>它不工作,只在迷你緩衝區中顯示Wrong type argument: commandp, delete-right

我錯過了什麼,或者該怎麼做才能正確使用代碼?

回答

2

這裏有一個修復:

(defun delete-after (fn) 
    `(lambda() (interactive) 
     (,fn) 
     (delete-window))) 

(global-set-key (kbd "C-s-<right>") (delete-after 'windmove-right)) 
(global-set-key (kbd "C-s-<left>") (delete-after 'windmove-left)) 
(global-set-key (kbd "C-s-<down>") (delete-after 'windmove-down)) 
(global-set-key (kbd "C-s-<up>") (delete-after 'windmove-up)) 
+0

好了,下面我們就誰是剛剛開始學習elisp的用戶。你真的認爲提供一個解決方案是一個好主意,它使用lambda和backticks等進步技巧產生匿名函數,特別是當他已經有一個簡單而直接的方法來實現這個功能時? – Lindydancer

+0

是的。在問題提出之前,操作系統的實現問題已經清楚地解決了。 OP是要求優雅,我展示給他。 –

+0

將lambda綁定到鍵或將其添加到鉤子永遠不會優雅。當用戶檢查一個鍵是綁定的還是一個鉤子包含的時候,一個匿名lambda就像是一個死衚衕,裏面有一堆瓦礫(當然是用一粒鹽做的) – Lindydancer

2

爲了使功能變成命令,需要特殊形式interactive添加到它:

(defun delete-right() 
    (interactive) 
    (delete-other-window 'windmove-right)) 
+0

'interactive'應該位於與擊鍵綁定的函數內。謝謝。 – ntalbs

2

的問題與您的代碼是,它的函數綁定到應該交互的密鑰。不是函數之一調用它:

(defun delete-other-window (callback) 
    (funcall callback) 
    (delete-window)) 

(defun delete-right() 
    (interactive) 
    (delete-other-window 'windmove-right)) 

你也可以使用宏:

(defmacro defun-delete-other-window (direction) 
    `(defun ,(intern (concat "delete-" direction))() 
    (interactive) 
    (,(intern (concat "windmove-" direction))) 
    (delete-window))) 

(defun-delete-other-window "right") 
+0

宏觀方法的一個小缺點是,你不能再跳轉到 的定義。 'windmove-right'。 –

+0

謝謝你教我「交互式」應該在綁定到按鍵的功能中。在將'interactive'移動到'delete-right'後,它運行良好。 – ntalbs