所以我试图在某些elisp模式钩子中添加一些东西 - 具体来说,我想定义一个钩子prettify-symbols-alist
,然后通过调用prettify-symbols-mode
来专门激活它。
在任何情况下,我都会org-babel
将值导出到表中的一对列表中,使用pairlis
将它们绑定在一起作为列表,add-hook
它使用匿名函数进入所需模式。
所以,问题是,现在如果我使用全局变量,如下所示,它可以工作:
(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda")))
(code (quote (172 215 247 8594 8614 8800 8804 8805 955)))) ; Generated automatically using org-babel
(require 'cl)
(setq *globalvar (pairlis token code))
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(setq prettify-symbols-alist *globalvar)
(prettify-symbols-mode 1))))
但是,如果我尝试不使用全局变量,通过这种方式,它不起作用:
(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda")))
(code (quote (172 215 247 8594 8614 8800 8804 8805 955)))) ; Generated automatically using org-babel
(let (localv)
(require 'cl)
(setq localv (pairlis token code))
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(setq prettify-symbols-alist localv)
(prettify-symbols-mode 1))))
我知道为什么:如果我C-h v emacs-lisp-mode-hook
,我会看到它引用我在let
形式中使用的任何变量,该变量在变量存在时起作用,如{{1}但是,当我使用*globalvar
时,它不再存在于localvar
形式之外。但我不确定如何强制评估局部变量本身,因为我仍然在努力研究elisp中的许多概念,这些概念对我来说并不是很清楚。
我错过了什么?我在哪里错了?
答案 0 :(得分:2)
首先将lexical-binding
设置为非nil
,否则localv
将成为钩子函数中的自由变量。最好将lexical-binding
设置为文件局部变量。
此外,您的代码中没有任何内容可以使localv
缓冲区本地。大概你想给它一个在该模式下缓冲区本地的值。绑定它的代码应该在相关的模式(即缓冲区)中进行评估。
答案 1 :(得分:1)
好的,这就是我最后所做的:
(let ((token (quote ("not" "*" "/" "->" "map" "/=" "<=" ">=" "lambda")))
(code (quote (172 215 247 8594 8614 8800 8804 8805 955))))
(require 'cl)
(lexical-let (localv)
(setq localv (pairlis token code))
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(setq prettify-symbols-alist localv)
(prettify-symbols-mode 1)))))
我最终使用phils'建议使用lexical-let
而不是Drew的建议,主要是因为我正在使用org-babel
将代码块纠缠到我的源代码中代码(基本上我使用org-mode
来组织我的设置文件),似乎没有办法设置lexical-binding
文件局部变量 - 根据this页面,你需要将它设置为第一行(使用;; -*- lexical-binding: t -*-
),我还找不到办法。
无论如何,感谢所有帮助我解决这个问题的人!
答案 2 :(得分:1)
我喜欢这个解决方案。使用lexical-let
,对lambda
(内部add-hook
)的调用会生成一个闭包,因为您可以看到键入M-x ielm RET
和{{1检查它的价值。
你也可以使用这样的老式风格反击:
emacs-lisp-mode-hook RET
(编辑)
请注意(add-hook 'emacs-lisp-mode-hook
`(lambda ()
(setq prettify-symbols-alist ',localv)
(prettify-symbols-mode 1)))
之前的backtick
和lambda
之前的quote-comma
(如tarikq所述)。
我认为你有意义!
实际上,不是“展开它然后引用它”,我会说“插入它的值(来自词汇环境),然后引用它”。
如果你尝试这样的话:
localv
然后你会得到lisp在运行时实际会做的事情:
(macroexpand '`(lambda ()
(setq prettify-symbols-alist ',localv)
(prettify-symbols-mode 1)))
您将看到如何构建整个列表,以及 (cons 'lambda
(cons nil
(cons
(list 'setq 'prettify-symbols-alist (list 'quote localv))
'((prettify-symbols-mode 1)))))
通常评估的方式,即未引用(与符号localv
和{{1}进行比较}和列表'setq
)