我的.emacs文件中有以下代码,其工作方式与您预期的一样:
;; Ruby
(global-font-lock-mode 1)
(autoload 'ruby-mode "ruby-mode" "Ruby editing mode." t)
(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.rsel$" . ruby-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.rhtml$" . html-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.erb$" . html-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("\\.prawn$" . html-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("Rakefile$" . ruby-mode) auto-mode-alist))然而,我试图把它弄干的尝试却失败了:
(defun set-mode-for-filename-patterns (mode filename-pattern-list)
(mapcar
(lambda (filename-pattern)
(setq
auto-mode-alist
(cons '(filename-pattern . mode) auto-mode-alist)))
filename-pattern-list))
;; Ruby
(global-font-lock-mode 1)
(autoload 'ruby-mode "ruby-mode" "Ruby editing mode." t)
(set-mode-for-filename-patterns
ruby-mode
'("\\.rb$"
"\\.rsel$"
"\\.rhtml$"
"\\.erb$"
"\\.prawn$"
"Rakefile$"
"Gemfile$"))..。有以下错误:
Debugger entered--Lisp error: (void-variable ruby-mode)
(set-mode-for-filename-patterns ruby-mode (quote ("\\.rb$" "\\.rsel$" "\\.rhtml$" "\\.erb$" "\\.prawn$" "Rakefile$" "Gemfile$")))
eval-buffer(#<buffer *load*> nil "/home/duncan/.emacs" nil t) ; Reading at buffer position 1768
load-with-code-conversion("/home/duncan/.emacs" "/home/duncan/.emacs" t t)
load("~/.emacs" t t)
#[nil "\205\264我有点糊涂..。特别是,我不明白ruby-mode为什么是空的&所以不能传递给函数,但是可以将cons编辑成一对吗?
任何指点(呵呵)都将不胜感激。
发布于 2012-01-05 22:39:16
形式如下:
(cons '("\\.rb$" . ruby-mode) ...ruby-mode是引用列表的一部分。这意味着它是作为符号名读取的,而不是作为变量计算的。换句话说,Emacs将其视为ruby-mode符号,并接受它的原样。
形式如下:
(set-mode-for-filename-patterns
ruby-mode
'("\\.rb$"
"\\.rsel$"
...ruby-mode不被引用,因此被读取为函数的参数。计算函数参数。这意味着Emacs读取ruby-mode,将其识别为符号,并试图对其进行计算。计算符号意味着寻找它所指向的值,在这种情况下,这个值并不存在。
编辑:
你的功能仍然不起作用,还有另外一个问题。您在set-mode-for-filename-patterns中使用了一个引用的列表。这在您的原始代码中运行得很好:
(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist))因为您实际上是手动为filename-pattern和mode提供值的。在您的函数中,您需要对这些符号进行评估,这在引用时不会发生!其结果是,与其将列表中的每个不同的字符串添加到自动模式列表中,相反,您将得到符号filename-pattern。
要解决这个问题,您需要识别‘(文件名-模式)。模式)用于生成一个具有filename-pattern和mode值的cons单元格。我们可以用(反文件名-模式模式)来生产。因此,修正后的职能是:
(defun set-mode-for-filename-patterns (mode filename-pattern-list)
(mapcar
(lambda (filename-pattern)
(setq
auto-mode-alist
(cons (cons filename-pattern mode) auto-mode-alist)))
filename-pattern-list))修正后的函数调用是:
(set-mode-for-filename-patterns
'ruby-mode
'("\\.rb$"
"\\.rsel$"
"\\.rhtml$"
"\\.erb$"
"\\.prawn$"
"Rakefile$"
"Gemfile$"))发布于 2012-01-05 22:35:28
看这里:
(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist))
----------------------------^这是一个quote,这意味着您阻止了对下一个表单的计算,因此'("\\.rb$" . ruby-mode)等同于(cons '"hello" 'ruby-mode)。
但是,当您调用函数set-mode-for-filename-patterns时,参数首先进行计算,然后将其结果传递给函数。这就是为什么计算(set-mode-for-filename-patterns ruby-mode ..)会引发错误,因为emacs解释器试图将ruby-mode计算为变量,但是ruby-mode在这个上下文中没有值,因此出现了(void-variable ruby-mode)错误。您想要的是传递符号ruby-mode,所以您必须引用如下(set-mode-for-filename-patterns 'ruby-mode ...)
请注意,可以使用ruby-mode将值设置为let模式。
(let ((ruby-mode 'ruby-mode))
(set-mode-for-filename-patterns ruby-mode ...))在这里,当计算表单(set-...)的参数时,它会计算ruby-mode并为它找到一个值(即符号ruby-mode),然后将它传递给函数。
发布于 2012-06-25 01:43:36
我认为set-mode-for-filename-patterns是一个有趣的函数。我将把它添加到我的配置中,但是使用一个更优化的实现。
这里的实现都为每个文件后缀向auto-mode-alist变量添加了一个项。Emacs每次找到文件时都会搜索这个列表。因此,auto-mode-alist越短,Emacs找到文件的速度就越快。
此版本在启动时可能更慢,但在找到文件时更快:
(defun set-mode-for-filename-patterns (mode filename-pattern-list)
(push (cons (regexp-opt filename-pattern-list) mode)
auto-mode-alist))`这将适用于相同的调用:
(set-mode-for-filename-patterns
'ruby-mode
'("\\.rb$"
"\\.rsel$"
"\\.rhtml$"
"\\.erb$"
"\\.prawn$"
"Rakefile$"
"Gemfile$"))如果您查看auto-mode-alist的值,您将看到许多内置模式出于相同的性能原因使用regexp。
顺便说一句,我建议你相信regexp-opt会做正确的事情。它所产生的效应对眼睛(和大脑)来说是相当困难的。
https://stackoverflow.com/questions/8750323
复制相似问题