changeset 19648:e9031152e052

(set-auto-coding): Name changed from auto-file-coding-system. The argument STRING is now a concatination of the heading 1K-byte and the tailing 3K-byte of a file. (set-auto-coding-function): Set it to `set-auto-coding'.
author Kenichi Handa <handa@m17n.org>
date Mon, 01 Sep 1997 07:19:38 +0000
parents 9b9af28bee8d
children b2bf3c43c86a
files lisp/international/mule.el
diffstat 1 files changed, 70 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/international/mule.el	Mon Sep 01 07:19:38 1997 +0000
+++ b/lisp/international/mule.el	Mon Sep 01 07:19:38 1997 +0000
@@ -613,34 +613,80 @@
 
 ;;; FILE I/O
 
-(defun auto-file-coding-system (head-lines)
-  "Return coding system for a file which has HEAD-LINES at the head.
-HEAD-LINES is a string of the first two lines of the file.
-This checks for a -*- coding tag in the buffers's text,
-and return the specified coding system.
+(defun set-auto-coding (string)
+  "Return coding system for a file which has STRING at the head and tail.
+STRING is a concatination of the first 1K-byte and
+ the last 3K-byte of the file.
+
+It checks for a -*- coding: tag in the first one or two lines of STRING.
+If there's no coding: tag in the head, it checks local variables spec
+in the tailing 3K-byte oof STRING.
+
+The return value is the specified coding system,
+or nil if nothing specified.
 
 The variable `auto-file-coding-system' (which see) is set to this
 function by default."
-  (let ((limit (string-match "\n" head-lines))
-	(coding-system nil))
-    (if limit
-	(when (string-match "^#!" head-lines)
-	  ;; If the file begins with "#!" (exec interpreter magic),
-	  ;; look for coding frobs in the first two lines.  You cannot
-	  ;; necessarily put them in the first line of such a file
-	  ;; without screwing up the interpreter invocation.
-	  (setq limit (string-match "\n" head-lines limit))
-	  (or limit
-	      (setq limit (length head-lines))))
-      (setq limit (length head-lines)))
-    (when (and (string-match "-\\*-[ \t]*coding:[ \t]*\\([^ ;]+\\)" head-lines)
-	       (< (match-beginning 1) limit))
-      (setq coding-system
-	    (intern (substring head-lines (match-beginning 1) (match-end 1))))
-      (if (coding-system-p coding-system)
-	  coding-system))))
+  (condition-case nil
+      (let ((case-fold-search t)
+	    (len (length string))
+	    (limit (string-match "\n" string))
+	    (coding-system nil))
+
+	;; At first check the head.
+	(if limit
+	    (when (string-match "^#!" string)
+	      ;; If the file begins with "#!" (exec interpreter
+	      ;; magic), look for coding frobs in the first two lines.
+	      ;; You cannot necessarily put them in the first line of
+	      ;; such a file without screwing up the interpreter
+	      ;; invocation.
+	      (setq limit (string-match "\n" string limit))
+	      (or limit
+		  (setq limit len)))
+	  (setq limit len))
+	(when (and (string-match "-\\*-[ \t]*coding:[ \t]*\\([^ ;]+\\)" string)
+		   (< (match-beginning 1) limit))
+	  (setq coding-system
+		(intern (substring string (match-beginning 1) (match-end 1))))
+	  (if (not (coding-system-p coding-system))
+	      (setq coding-system nil)))
 
-(setq auto-file-coding-system-function 'auto-file-coding-system)
+	;; If no coding system is specified in the head, check the tail.
+	(when (and (not coding-system)
+		   (let ((idx (if (> len 3000) (- len 3000) 0))
+			 start)
+		     (while (setq start (string-match "\n\^L" string idx))
+		       (setq idx (+ start 2)))
+		     (string-match
+		      "^\\(.*\\)[ \t]*Local Variables:[ \t]*\\(.*\\)$"
+		      string idx)))
+	  ;; The prefix is what comes before "local variables:" in its line.
+	  ;; The suffix is what comes after "local variables:" in its line.
+	  (let* ((idx (1+ (match-end 0)))
+		 (prefix (regexp-quote
+			  (substring string
+				     (match-beginning 1) (match-end 1))))
+		 (suffix (regexp-quote
+			  (substring string
+				     (match-beginning 2) (match-end 2))))
+		 (re-coding (concat "^" prefix
+				    "coding[ \t]*:[ \t]*\\([^ \t]+\\)[ \t]*"
+				    suffix "$"))
+		 (re-end (concat "^" prefix "end *:[ \t]*" suffix "$"))
+		 (limit (or (string-match re-end string idx) len)))
+	    (when (and (setq idx (string-match re-coding string idx))
+		       (< idx limit))
+	      (setq coding-system
+		    (intern (substring string
+				       (match-beginning 1) (match-end 1))))
+	      (or (coding-system-p coding-system)
+		  (setq coding-system nil)))))
+
+	coding-system)
+    (error nil)))
+
+(setq set-auto-coding-function 'set-auto-coding)
 
 ;; Set buffer-file-coding-system of the current buffer after some text
 ;; is inserted.