将函数传递给elisp中的参数

时间:2014-03-04 09:59:46

标签: emacs elisp

我将以下代码添加到我的.emacs文件中。

(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

我错过了什么或者我该怎么做才能正确使用代码?

3 个答案:

答案 0 :(得分: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))

答案 1 :(得分:2)

要在函数中创建函数,您需要向其中添加特殊形式interactive

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

答案 2 :(得分: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")