I have the following code in my .emacs file, which works as you’d expect:
;; 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))
However, my attempts to DRY it up a bit fail:
(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$"))
… with the following error:
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
I’m a bit confused here … in particular, I don’t understand how ruby-mode is void & so can’t be passed to a function, but can be consed into a pair?
Any pointers (heh) would be greatly appreciated.
In the form:
ruby-modeis part of a quoted list. That means it is read as a symbol name, not evaluated as a variable. In other words, Emacs sees it as the symbolruby-modeand accepts it as is.In the form:
ruby-modeis not quoted, and so is read as the argument to a function. Function arguments are evaluated. Which means Emacs readsruby-mode, recognizes it as a symbol, and tries to evaluate it. Evaluating a symbol means looking for the value that it points to, which in this case doesn’t exist.EDIT:
Your function still doesn’t work, there’s another problem. You’ve used a quoted list inside
set-mode-for-filename-patterns. This works fine in your original code:as you are in effect manually supplying the value for
filename-patternandmode. Inside your function, you need these symbols to be evaluated, which doesn’t happen when they’re quoted! The result is that instead of adding each different string from your list to auto-mode-alist, you get the symbolfilename-patterninstead.To fix this, you need to recognize that the ‘(filename-pattern . mode) is meant to produce a cons cell with the values of
filename-patternandmode. Which we can produce with (cons filename-pattern mode). So the corrected function would be:And the corrected function call is: