elisp - 通过 Emacs Lisp 中的函数设置模式

标签 elisp

我的 .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成对吗?

如有任何指点(呵呵),我们将不胜感激。

最佳答案

形式:

(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-patternmode 手动提供。在您的函数中,您需要对这些符号进行求值,而当它们被引用时不会发生这种情况!结果是,不是将列表中的每个不同字符串添加到自动模式列表,而是得到符号 filename-pattern

要解决此问题,您需要认识到 '(filename-pattern .mode) 是为了生成一个具有 filename-patternvalues模式。我们可以用(cons filename-pattern mode)产生。所以更正后的函数是:

(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$"))

关于elisp - 通过 Emacs Lisp 中的函数设置模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8750323/

相关文章:

emacs - 在 dired 中调用相同 shell 命令的函数

emacs - 使用空间而不是控制来避免emacs小指?

Emacs:尝试运行交互式功能时参数数量错误

emacs - 如何自动启用 Emacs jtags 模式?

emacs - 突出显示区域时仅删除一个字符

使用内置 javascript 模式对 var block 进行 JavaScript 缩进

emacs - 帮助为 emacs etags 搜索编写 emacs lisp

emacs - defmacro 的主体未被执行

emacs - Emacs 中的 C 注释 - Linux 内核风格 v2

emacs - 这些符号在 Emacs Lisp 中是什么意思?