Treat interpreter-mode-alist as alist of regexps, not literals

Cf http://lists.gnu.org/archive/html/emacs-devel/2005-08/msg00472.html

* lisp/files.el (interpreter-mode-alist): Convert to regexps.
(set-auto-mode): Adapt for this. 

* lisp/progmodes/cperl-mode.el (cperl-clobber-mode-lists):
Comment out unused variable.

* lisp/progmodes/cc-mode.el (interpreter-mode-alist):
* lisp/progmodes/python.el (interpreter-mode-alist):
* lisp/progmodes/ruby-mode.el (interpreter-mode-alist): Convert to regexps.

* lisp/progmodes/sh-script.el (sh-set-shell):
No longer use interpreter-mode-alist to get list of shells.

* etc/NEWS: Mention this.

Fixes: debbugs:15306
This commit is contained in:
Glenn Morris 2013-09-10 16:38:52 -04:00
parent 6a5c15d95f
commit 1af4c2203c
8 changed files with 99 additions and 75 deletions

View file

@ -614,6 +614,14 @@ file using `set-file-extended-attributes'.
** `visited-file-modtime' now returns -1 for nonexistent files.
Formerly it returned a list (-1 LOW USEC PSEC), but this was ambiguous
in the presence of files with negative time stamps.
** The cars of the elements in `interpreter-mode-alist' are now treated
as regexps rather than literal strings. For the time being, any
element whose car does not start with "\\" is still treated as a
literal string, so this change should not cause any incompatibilities
if you have code that just adds elements to the list, only if you are
actually using interpreter-mode-alist for something.
* Lisp Changes in Emacs 24.4

View file

@ -1,5 +1,15 @@
2013-09-10 Glenn Morris <rgm@gnu.org>
* files.el (interpreter-mode-alist): Convert to regexps.
(set-auto-mode): Adapt for this. (Bug#15306)
* progmodes/cperl-mode.el (cperl-clobber-mode-lists):
Comment out unused variable.
* progmodes/cc-mode.el (interpreter-mode-alist):
* progmodes/python.el (interpreter-mode-alist):
* progmodes/ruby-mode.el (interpreter-mode-alist): Convert to regexps.
* progmodes/sh-script.el (sh-set-shell):
No longer use interpreter-mode-alist to get list of shells.
* progmodes/cc-mode.el (awk-mode): Remove duplicate autoload.
2013-09-10 Stefan Monnier <monnier@iro.umontreal.ca>

View file

@ -2447,48 +2447,43 @@ and `magic-mode-alist', which determines modes based on file contents.")
(mapcar
(lambda (l)
(cons (purecopy (car l)) (cdr l)))
'(("perl" . perl-mode)
("perl5" . perl-mode)
("miniperl" . perl-mode)
("wish" . tcl-mode)
("wishx" . tcl-mode)
("tcl" . tcl-mode)
("tclsh" . tcl-mode)
("expect" . tcl-mode)
("scm" . scheme-mode)
("ash" . sh-mode)
("bash" . sh-mode)
("bash2" . sh-mode)
("csh" . sh-mode)
("dtksh" . sh-mode)
("es" . sh-mode)
("itcsh" . sh-mode)
("jsh" . sh-mode)
("ksh" . sh-mode)
("oash" . sh-mode)
("pdksh" . sh-mode)
("rbash" . sh-mode)
("rc" . sh-mode)
("rpm" . sh-mode)
("sh" . sh-mode)
("sh5" . sh-mode)
("tcsh" . sh-mode)
("wksh" . sh-mode)
("wsh" . sh-mode)
("zsh" . sh-mode)
("tail" . text-mode)
("more" . text-mode)
("less" . text-mode)
("pg" . text-mode)
("make" . makefile-gmake-mode) ; Debian uses this
("guile" . scheme-mode)
("clisp" . lisp-mode)
("emacs" . emacs-lisp-mode)))
'(("\\`\\(mini\\)?perl5?\\'" . perl-mode)
("\\`wishx?\\'" . tcl-mode)
("\\`tcl\\(sh\\)?\\'" . tcl-mode)
("\\`expect\\'" . tcl-mode)
("\\`scm\\'" . scheme-mode)
("\\`[acjkwz]sh\\'" . sh-mode)
("\\`bash2?\\'" . sh-mode)
("\\`dtksh\\'" . sh-mode)
("\\`es\\'" . sh-mode)
("\\`itcsh\\'" . sh-mode)
("\\`oash\\'" . sh-mode)
("\\`pdksh\\'" . sh-mode)
("\\`rbash\\'" . sh-mode)
("\\`rc\\'" . sh-mode)
("\\`rpm\\'" . sh-mode)
("\\`sh5?\\'" . sh-mode)
("\\`tcsh\\'" . sh-mode)
("\\`wksh\\'" . sh-mode)
("\\`tail\\'" . text-mode)
("\\`more\\'" . text-mode)
("\\`less\\'" . text-mode)
("\\`pg\\'" . text-mode)
("\\`make\\'" . makefile-gmake-mode) ; Debian uses this
("\\`guile\\'" . scheme-mode)
("\\`clisp\\'" . lisp-mode)
("\\`emacs\\'" . emacs-lisp-mode)))
"Alist mapping interpreter names to major modes.
This is used for files whose first lines match `auto-mode-interpreter-regexp'.
Each element looks like (INTERPRETER . MODE).
If INTERPRETER matches the name of the interpreter specified in the first line
of a script, mode MODE is enabled.
Each element looks like (REGEXP . MODE).
If REGEXP matches the name (minus any directory part) of the interpreter
specified in the first line of a script, enable major mode MODE.
Emacs versions earlier than 24.4 treat the car of each element as a
literal string that must match the entire name, rather than a regexp.
For backwards compatibility, any REGEXP that does not begin with \"\\\\\"
continues to be treated in this way. This behavior may be removed in
future and should not be relied upon.
See also `auto-mode-alist'.")
@ -2683,19 +2678,27 @@ we don't actually set it to the same mode the buffer already has."
;; If we didn't, look for an interpreter specified in the first line.
;; As a special case, allow for things like "#!/bin/env perl", which
;; finds the interpreter anywhere in $PATH.
(unless done
(setq mode (save-excursion
(goto-char (point-min))
(if (looking-at auto-mode-interpreter-regexp)
(match-string 2)
""))
;; Map interpreter name to a mode, signaling we're done at the
;; same time.
done (assoc (file-name-nondirectory mode)
interpreter-mode-alist))
;; If we found an interpreter mode to use, invoke it now.
(if done
(set-auto-mode-0 (cdr done) keep-mode-if-same)))
(and (not done)
(setq mode (save-excursion
(goto-char (point-min))
(if (looking-at auto-mode-interpreter-regexp)
(match-string 2))))
;; Map interpreter name to a mode, signaling we're done at the
;; same time.
(setq done (assoc-default
(file-name-nondirectory mode)
;; Backwards compat: if car of i-m-alist does not start
;; with "\\", treat as literal string.
(mapcar (lambda (e)
(if (string-match-p "\\`\\\\" (car e))
e
(cons
(format "\\`%s\\'" (regexp-quote (car e)))
(cdr e))))
interpreter-mode-alist)
#'string-match-p))
;; If we found an interpreter mode to use, invoke it now.
(set-auto-mode-0 done keep-mode-if-same))
;; Next try matching the buffer beginning against magic-mode-alist.
(unless done
(if (setq done (save-excursion

View file

@ -1555,7 +1555,7 @@ Key bindings:
(cons "Pike" (c-lang-const c-mode-menu pike)))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.\\(u?lpc\\|pike\\|pmod\\(\\.in\\)?\\)\\'" . pike-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("pike" . pike-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("\\`pike\\'" . pike-mode))
;;;###autoload
(define-derived-mode pike-mode prog-mode "Pike"
@ -1589,10 +1589,7 @@ Key bindings:
;; Support for AWK
;;;###autoload (add-to-list 'auto-mode-alist '("\\.awk\\'" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("awk" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("mawk" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("nawk" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("gawk" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("\\`[gmn]?awk\\'" . awk-mode))
(c-define-abbrev-table 'awk-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)

View file

@ -412,15 +412,15 @@ Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
"use cperl-vc-rcs-header or cperl-vc-sccs-header instead."
"22.1")
(defcustom cperl-clobber-mode-lists
(not
(and
(boundp 'interpreter-mode-alist)
(assoc "miniperl" interpreter-mode-alist)
(assoc "\\.\\([pP][Llm]\\|al\\)$" auto-mode-alist)))
"*Whether to install us into `interpreter-' and `extension' mode lists."
:type 'boolean
:group 'cperl)
;;; (defcustom cperl-clobber-mode-lists
;;; (not
;;; (and
;;; (boundp 'interpreter-mode-alist)
;;; (assoc "miniperl" interpreter-mode-alist)
;;; (assoc "\\.\\([pP][Llm]\\|al\\)$" auto-mode-alist)))
;;; "*Whether to install us into `interpreter-' and `extension' mode lists."
;;; :type 'boolean
;;; :group 'cperl)
(defcustom cperl-info-on-command-no-prompt nil
"*Not-nil (and non-null) means not to prompt on C-h f.

View file

@ -225,7 +225,7 @@
;;;###autoload
(add-to-list 'auto-mode-alist (cons (purecopy "\\.py\\'") 'python-mode))
;;;###autoload
(add-to-list 'interpreter-mode-alist (cons (purecopy "python") 'python-mode))
(add-to-list 'interpreter-mode-alist (cons (purecopy "\\`python[23.]*\\'") 'python-mode))
(defgroup python nil
"Python Language's flying circus support for Emacs."

View file

@ -1968,8 +1968,7 @@ The variable `ruby-indent-level' controls the amount of indentation.
"\\)\\'")) 'ruby-mode))
;;;###autoload
(dolist (name (list "ruby" "rbx" "jruby" "ruby1.9" "ruby1.8"))
(add-to-list 'interpreter-mode-alist (cons (purecopy name) 'ruby-mode)))
(add-to-list 'interpreter-mode-alist (cons (purecopy "\\`\\(rbx\\|j?ruby\\(1\\.[89]\\)?\\)\\'") 'ruby-mode))
(provide 'ruby-mode)

View file

@ -2170,11 +2170,18 @@ the visited file executable, and NO-QUERY-FLAG (the second argument)
controls whether to query about making the visited file executable.
Calls the value of `sh-set-shell-hook' if set."
(interactive (list (completing-read (format "Shell \(default %s\): "
sh-shell-file)
interpreter-mode-alist
(lambda (x) (eq (cdr x) 'sh-mode))
nil nil nil sh-shell-file)
(interactive (list (completing-read
(format "Shell \(default %s\): "
sh-shell-file)
;; This used to use interpreter-mode-alist, but that is
;; no longer appropriate now that uses regexps.
;; Maybe there could be a separate variable that lists
;; the shells, used here and to construct i-mode-alist.
;; But the following is probably good enough:
(append (mapcar (lambda (e) (symbol-name (car e)))
sh-ancestor-alist)
'("csh" "rc" "sh"))
nil nil nil nil sh-shell-file)
(eq executable-query 'function)
t))
(if (string-match "\\.exe\\'" shell)