Emacs has a few mechanisms for choosing which major mode is selected when you find a file.
auto-mode-alist determines the mode from the file extension, e.g. you might want to load a c++ mode for a file named a.cc.
interpreter-mode-alist chooses a mode depending on the first line of a file. If a file begins with
#!/bin/sh you probably want to choose
I worked on a code base where the extensions used a variety of capitalization. The perl scripts could be .Perl, .perl, .PL, .Pl or .pl and there were numerous other extensions. It is fairly easy to make a regular expression to match all of these but I thought it warranted a helper function.
'(pl perl) to transform to
\.\([Pp][Ll]\|[Pp][Ee][Rr][Ll]\)\'. The basic technique is to make a character class with the upper case and lower case version of each character in the string. We also accept a symbol on the input in order that the caller doesn’t have to add double quotes to every element.
(mapconcat (lambda (c) (let ((c (upcase (char-to-string c)))) (concat "[" c (downcase c) "]"))) (symbol-name s) ""))
This code converts
We want to handle a list of extensions so we can cope with permutations of .pl or .perl. We therefore surround the previous mapconcat with the following.
(mapconcat (lambda (s) ...) l "\\|")
The final part of the function adds the appropriate prefix and suffix to make the regex work in auto-mode-alist.
(defun file-extensions (l) (concat "\\.\\(" (mapconcat (lambda (s) (mapconcat (lambda (c) (let ((c (upcase (char-to-string c)))) (concat "[" c (downcase c) "]"))) (symbol-name s) "")) l "\\|") "\\)\\'"))
I added a wrapper function to marry the regex to the major mode.
(defun ext-mode-map (extensions mode) (cons (file-extensions extensions) mode))
And now you can simply specify your mode mappings like this:
(add-to-list 'auto-mode-alist (ext-mode-map '(pl perl) 'cperl-mode))