(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上面两个setq
和defun
出来的test/generated
可以共存,因为: