summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Morris <rgm@gnu.org>2013-09-10 16:38:52 -0400
committerGlenn Morris <rgm@gnu.org>2013-09-10 16:38:52 -0400
commit1af4c2203ce7954c089133234ba80e6272ce9458 (patch)
tree5b7cf8f2f3f0813abebcb16167e807dace1437b8
parent6a5c15d95f69fc787edda65e0f81440b536653c2 (diff)
downloademacs-1af4c2203ce7954c089133234ba80e6272ce9458.tar.gz
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
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/files.el109
-rw-r--r--lisp/progmodes/cc-mode.el7
-rw-r--r--lisp/progmodes/cperl-mode.el18
-rw-r--r--lisp/progmodes/python.el2
-rw-r--r--lisp/progmodes/ruby-mode.el3
-rw-r--r--lisp/progmodes/sh-script.el17
8 files changed, 99 insertions, 75 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 9914da31859..78f99dbc621 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9282aa16a2d..32ea5e72efd 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -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>
diff --git a/lisp/files.el b/lisp/files.el
index f9ff3c936bd..2315448c549 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -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
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index e977a415d62..bffc5b95d25 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -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)
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 770e78bb3b1..1eea6972707 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -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.
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 05d707acf43..bba4453cce8 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -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."
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 0f868255589..9dc2c4fb6c9 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -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)
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 292bc2369a6..3ea2afb6fc3 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -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)