自定义带参数的方法,在 global-set-key 绑定快捷键时无效?

(global-set-key (kbd "C-c e") (lambda () (interactive) (find-file "~/org/gtd.org")))

这样能 work,但我想将 find-file 抽象个方法

(defun my/find-file (filename)
  (interactive)
  (find-file filename))

(global-set-key (kbd "C-c e") '(my/find-file "~/org/gtd.org"))

但这样设置就报错, command-execute: Wrong type argument: commandp, (my/find-file "~/org/gtd.org")

直接在方法里写死 filename 可以,但要通过参数传递进来一直报错,试了好久,谷歌也找不到答案,求大神解惑,谢啦~

1 个赞

缺少lambda 或者你把这个函数改造成返回function的宏也行

(global-set-key (kbd "C-c e") (lambda()(interactive) (my/find-file "~/org/gtd.org")))

(defmacro my/find-file (file)
  `(lambda () (interactive) (find-file ,file)))

(global-set-key (kbd "C-c e") (my/find-file "~/org/gtd.org"))

噢,有点明白为什么报错了

谢谢啦,这正是我想要的

楼上只贴代码不说话……因为按键需要绑定到一个command / interactive function,而主帖里my/find-file返回的是它的body的最后一个表达式,(find-file filename)的值,显然不是一个function。

这样也可以:

; lexical binding才能用higher order function,才能用closure存住一个变量
(setq lexical-binding t)

; 返回一个lambda
(defun test/find-file (test/file)
  (lambda () (interactive) (find-file test/file)))

; dynamically set 这个变量,可以看出closure是不是真的生效了
(setq test/file "~")

(setq test/generated (test/find-file "~/.bashrc"))

(funcall test/generated)
; =>打开了.bashrc这个文件

; 改回默认,别把emacs搞坏了
(setq lexical-binding nil)

然后我又发现生成test/generated和调用它用

(defun test/generated () (test/find-file "~/.bashrc"))

(funcall (test/generated))

也是可以的。[第999次理解lexical/dynamic scope和symbol]

PS上面两个setqdefun出来的test/generated可以共存,因为: