comparison lisp/files.el @ 4699:f57fe6dbf4a0

(hack-local-variables-prop-line): Ignore any specification for `mode:', since set-auto-mode has already handled it. (set-auto-mode): Clean up. Handle more than one `mode:' spec in -*-.
author Richard M. Stallman <rms@gnu.org>
date Sat, 11 Sep 1993 10:45:25 +0000
parents f00c973bc8a4
children 97c1e7309a2d
comparison
equal deleted inserted replaced
4698:196fac1c1086 4699:f57fe6dbf4a0
830 section of the file; for that, use `hack-local-variables'. 830 section of the file; for that, use `hack-local-variables'.
831 831
832 If `enable-local-variables' is nil, this function does not check for a 832 If `enable-local-variables' is nil, this function does not check for a
833 -*- mode tag." 833 -*- mode tag."
834 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- 834 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
835 (let (beg end mode) 835 (let (beg end done)
836 (save-excursion 836 (save-excursion
837 (goto-char (point-min)) 837 (goto-char (point-min))
838 (skip-chars-forward " \t\n") 838 (skip-chars-forward " \t\n")
839 (if (and enable-local-variables 839 (and enable-local-variables
840 ;; Don't look for -*- if this file name matches any 840 ;; Don't look for -*- if this file name matches any
841 ;; of the regexps in inhibit-local-variables-regexps. 841 ;; of the regexps in inhibit-local-variables-regexps.
842 (let ((temp inhibit-local-variables-regexps)) 842 (let ((temp inhibit-local-variables-regexps))
843 (while (and temp 843 (while (and temp
844 (not (string-match (car temp) 844 (not (string-match (car temp)
845 buffer-file-name))) 845 buffer-file-name)))
846 (setq temp (cdr temp))) 846 (setq temp (cdr temp)))
847 (not temp)) 847 (not temp))
848 (search-forward "-*-" (save-excursion 848 (search-forward "-*-" (save-excursion
849 ;; If the file begins with "#!" 849 ;; If the file begins with "#!"
850 ;; (exec interpreter magic), look 850 ;; (exec interpreter magic), look
851 ;; for mode frobs in the first two 851 ;; for mode frobs in the first two
852 ;; lines. You cannot necessarily 852 ;; lines. You cannot necessarily
853 ;; put them in the first line of 853 ;; put them in the first line of
854 ;; such a file without screwing up 854 ;; such a file without screwing up
855 ;; the interpreter invocation. 855 ;; the interpreter invocation.
856 (end-of-line (and (looking-at "^#!") 2)) 856 (end-of-line (and (looking-at "^#!") 2))
857 (point)) t) 857 (point)) t)
858 (progn 858 (progn
859 (skip-chars-forward " \t") 859 (skip-chars-forward " \t")
860 (setq beg (point)) 860 (setq beg (point))
861 (search-forward "-*-" 861 (search-forward "-*-"
862 (save-excursion (end-of-line) (point)) 862 (save-excursion (end-of-line) (point))
863 t)) 863 t))
864 (progn 864 (progn
865 (forward-char -3) 865 (forward-char -3)
866 (skip-chars-backward " \t") 866 (skip-chars-backward " \t")
867 (setq end (point)) 867 (setq end (point))
868 (goto-char beg) 868 (goto-char beg)
869 (if (search-forward ":" end t) 869 (if (save-excursion (search-forward ":" end t))
870 (progn 870 ;; Find all specifications for the `mode:' variable
871 (goto-char beg) 871 ;; and execute hem left to right.
872 (if (let ((case-fold-search t)) 872 (while (let ((case-fold-search t))
873 (search-forward "mode:" end t)) 873 (search-forward "mode:" end t))
874 (progn 874 (skip-chars-forward " \t")
875 (skip-chars-forward " \t") 875 (setq beg (point))
876 (setq beg (point)) 876 (if (search-forward ";" end t)
877 (if (search-forward ";" end t) 877 (forward-char -1)
878 (forward-char -1) 878 (goto-char end))
879 (goto-char end)) 879 (skip-chars-backward " \t")
880 (skip-chars-backward " \t") 880 (funcall (intern (concat (downcase (buffer-substring beg (point))) "-mode"))))
881 (setq mode (buffer-substring beg (point)))))) 881 ;; Simple -*-MODE-*- case.
882 (setq mode (buffer-substring beg end))))) 882 (funcall (intern (concat (downcase (buffer-substring beg end)) "-mode"))))
883 (setq mode (intern (concat (downcase mode) "-mode"))) 883 (setq done t)))
884 (if buffer-file-name 884 ;; If we didn't find a mode from a -*- line, try using the file name.
885 (let ((alist auto-mode-alist) 885 (if (and (not done) buffer-file-name)
886 (name buffer-file-name)) 886 (let ((alist auto-mode-alist)
887 (let ((case-fold-search (eq system-type 'vax-vms))) 887 (name buffer-file-name)
888 ;; Remove backup-suffixes from file name. 888 mode)
889 (setq name (file-name-sans-versions name)) 889 (let ((case-fold-search (eq system-type 'vax-vms)))
890 ;; Find first matching alist entry. 890 ;; Remove backup-suffixes from file name.
891 (while (and (not mode) alist) 891 (setq name (file-name-sans-versions name))
892 (if (string-match (car (car alist)) name) 892 ;; Find first matching alist entry.
893 (setq mode (cdr (car alist)))) 893 (while (and (not mode) alist)
894 (setq alist (cdr alist)))))))) 894 (if (string-match (car (car alist)) name)
895 (if mode (funcall mode)))) 895 (setq mode (cdr (car alist))))
896 (setq alist (cdr alist))))
897 (if mode (funcall mode)))))))
896 898
897 (defun hack-local-variables-prop-line () 899 (defun hack-local-variables-prop-line ()
898 ;; Set local variables specified in the -*- line. 900 ;; Set local variables specified in the -*- line.
899 ;; Returns t if mode was set. 901 ;; Ignore any specification for `mode:';
902 ;; set-auto-mode should already have handled that.
900 (save-excursion 903 (save-excursion
901 (goto-char (point-min)) 904 (goto-char (point-min))
902 (skip-chars-forward " \t\n\r") 905 (skip-chars-forward " \t\n\r")
903 (let ((result '()) 906 (let ((result '())
904 (end (save-excursion (end-of-line) (point))) 907 (end (save-excursion (end-of-line) (point))))
905 mode-p)
906 ;; Parse the -*- line into the `result' alist. 908 ;; Parse the -*- line into the `result' alist.
907 (cond ((not (search-forward "-*-" end t)) 909 (cond ((not (search-forward "-*-" end t))
908 ;; doesn't have one. 910 ;; doesn't have one.
909 nil) 911 nil)
910 ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)") 912 ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
932 (narrow-to-region (point) end) 934 (narrow-to-region (point) end)
933 (read (current-buffer))))) 935 (read (current-buffer)))))
934 (setq result (cons (cons key val) result)) 936 (setq result (cons (cons key val) result))
935 (skip-chars-forward " \t;"))) 937 (skip-chars-forward " \t;")))
936 (setq result (nreverse result)))) 938 (setq result (nreverse result))))
937
938 ;; Mode is magic.
939 (let (mode)
940 (while (setq mode (assq 'mode result))
941 (setq mode-p t result (delq mode result))
942 (funcall (intern (concat (downcase (symbol-name (cdr mode)))
943 "-mode")))))
944 939
945 (if (and result 940 (if (and result
946 (or (eq enable-local-variables t) 941 (or (eq enable-local-variables t)
947 (and enable-local-variables 942 (and enable-local-variables
948 (save-window-excursion 943 (save-window-excursion
950 (y-or-n-p (format "Set local variables as specified in -*- line of %s? " 945 (y-or-n-p (format "Set local variables as specified in -*- line of %s? "
951 (file-name-nondirectory buffer-file-name))))))) 946 (file-name-nondirectory buffer-file-name)))))))
952 (while result 947 (while result
953 (let ((key (car (car result))) 948 (let ((key (car (car result)))
954 (val (cdr (car result)))) 949 (val (cdr (car result))))
955 ;; 'mode has already been removed from this list. 950 (or (eq key 'mode)
956 (hack-one-local-variable key val)) 951 (hack-one-local-variable key val)))
957 (setq result (cdr result)))) 952 (setq result (cdr result)))))))
958 mode-p)))
959 953
960 (defun hack-local-variables () 954 (defun hack-local-variables ()
961 "Parse and put into effect this buffer's local variables spec." 955 "Parse and put into effect this buffer's local variables spec."
962 (hack-local-variables-prop-line) 956 (hack-local-variables-prop-line)
963 ;; Look for "Local variables:" line in last page. 957 ;; Look for "Local variables:" line in last page.