]> git.eshelyaron.com Git - emacs.git/commitdiff
(find-auto-coding): Provide filename to `auto-coding-functions`
authorStefan Monnier <monnier@iro.umontreal.ca>
Tue, 4 Jun 2024 14:58:29 +0000 (10:58 -0400)
committerEshel Yaron <me@eshelyaron.com>
Sun, 9 Jun 2024 09:52:43 +0000 (11:52 +0200)
Allow `auto-coding-functions` to know the file name.
Motivated by the needs of Editorconfig support.

* lisp/international/mule.el (auto-coding-file-name): New var.
(find-auto-coding): Let-bind it for `auto-coding-functions`.
Document the expectation that the arg be an absolute file name.

* doc/lispref/nonascii.texi (Default Coding Systems):
Mention `auto-coding-file-name`.

* test/lisp/international/mule-util-resources/test.utf-16le: New file.
* test/lisp/international/mule-tests.el (mule-tests--dir): New var.
(mule-tests--auto-coding): New fun.
(mule-tests--auto-coding-functions): New test.

(cherry picked from commit 3ecc6b4f3c2b070ed2c4463e2c5d8755ccc19f1c)

doc/lispref/nonascii.texi
etc/NEWS
lisp/international/mule.el
test/lisp/international/mule-tests.el
test/lisp/international/mule-util-resources/test.utf-16le [new file with mode: 0644]

index b33082e2b24b570debadd33a1f2e2ea8e81ae739..1482becb9f57d4a0866f4d15bbfa77189ef51b98 100644 (file)
@@ -1654,6 +1654,9 @@ argument, @var{size}, which tells it how many characters to look at,
 starting from point.  If the function succeeds in determining a coding
 system for the file, it should return that coding system.  Otherwise,
 it should return @code{nil}.
+Each function can also find the name of the file to which
+the buffer's content belong in the variable
+@code{auto-coding-file-name}.
 
 The functions in this list could be called either when the file is
 visited and Emacs wants to decode its contents, and/or when the file's
index 0fc8956fd2367a26b9006bb01f2048b1967dcd01..e5159b5d08ff2cf3f7e8c46666f30bb2ee7512d4 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2281,6 +2281,11 @@ unibyte string.
 \f
 * Lisp Changes in Emacs 30.1
 
++++
+** 'auto-coding-functions' can know the name of the file.
+The functions on this hook can now find the name of the file to
+which the text belongs by consulting the variable 'auto-coding-file-name'.
+
 +++
 ** New user option 'compilation-safety' to control safety of native code.
 It's now possible to control how safe is the code generated by native
index a17221e6d2165655889f06e4ba0a88221c675ec4..ed74fdae75532d28936a1835ae9969d03ab1de23 100644 (file)
@@ -1806,6 +1806,9 @@ or nil."
            (setq alist (cdr alist)))))
       coding-system)))
 
+(defvar auto-coding-file-name nil
+  "Variable holding the name of the file for `auto-coding-functions'.")
+
 ;; See the bottom of this file for built-in auto coding functions.
 (defcustom auto-coding-functions '(sgml-xml-auto-coding-function
                                   sgml-html-meta-auto-coding-function)
@@ -1820,6 +1823,9 @@ called both when the file is visited and Emacs wants to decode
 its contents, and when the file's buffer is about to be saved
 and Emacs wants to determine how to encode its contents.
 
+The name of the file is provided to the function via the variable
+`auto-coding-file-name'.
+
 If one of these functions succeeds in determining a coding
 system, it should return that coding system.  Otherwise, it
 should return nil.
@@ -1847,13 +1853,17 @@ files.")
     coding-system))
 
 (put 'enable-character-translation 'permanent-local t)
-(put 'enable-character-translation 'safe-local-variable        'booleanp)
+(put 'enable-character-translation 'safe-local-variable        #'booleanp)
 
 (defun find-auto-coding (filename size)
+  ;; FIXME: Shouldn't we use nil rather than "" to mean that there's no file?
+  ;; FIXME: Clarify what the SOURCE is for in the return value?
   "Find a coding system for a file FILENAME of which SIZE bytes follow point.
 These bytes should include at least the first 1k of the file
 and the last 3k of the file, but the middle may be omitted.
 
+FILENAME should be an absolute file name
+or \"\" (which means that there is no associated file).
 The function checks FILENAME against the variable `auto-coding-alist'.
 If FILENAME doesn't match any entries in the variable, it checks the
 contents of the current buffer following point against
@@ -1998,7 +2008,8 @@ use \"coding: 'raw-text\" instead." :warning)
          (setq coding-system (ignore-errors
                                (save-excursion
                                  (goto-char (point-min))
-                                 (funcall (pop funcs) size)))))
+                                 (let ((auto-coding-file-name filename))
+                                   (funcall (pop funcs) size))))))
        (if coding-system
            (cons coding-system 'auto-coding-functions)))))
 
@@ -2013,7 +2024,7 @@ function by default."
     (if (and found (coding-system-p (car found)))
        (car found))))
 
-(setq set-auto-coding-function 'set-auto-coding)
+(setq set-auto-coding-function #'set-auto-coding)
 
 (defun after-insert-file-set-coding (inserted &optional visit)
   "Set `buffer-file-coding-system' of current buffer after text is inserted.
index 9a80ced55aeef8a60829b6268c51f422226cd3e9..9c869cc8e6fd6a766d9e240618d07cba0585423f 100644 (file)
@@ -25,6 +25,8 @@
 
 (require 'ert-x)                        ;For `ert-simulate-keys'.
 
+(defconst mule-tests--dir (file-name-directory (macroexp-file-name)))
+
 (ert-deftest find-auto-coding--bug27391 ()
   "Check that Bug#27391 is fixed."
   (with-temp-buffer
   ;; The chinese-hz encoding is not ASCII compatible.
   (should-not (coding-system-get 'chinese-hz :ascii-compatible-p)))
 
+(defun mule-tests--auto-coding (_size)
+  (when (and (stringp auto-coding-file-name)
+             (string-match-p "\\.utf-16le\\'" auto-coding-file-name))
+    'utf-16le-with-signature))
+
+(ert-deftest mule-tests--auto-coding-functions ()
+  (unwind-protect
+      (progn
+        (add-hook 'auto-coding-functions #'mule-tests--auto-coding)
+        (with-temp-buffer
+          (insert-file-contents
+           (expand-file-name "mule-util-resources/test.utf-16le"
+                             mule-tests--dir))
+          (goto-char (point-min))
+          (should (search-forward "été" nil t))))
+    (remove-hook 'auto-coding-functions #'mule-tests--auto-coding)))
+
 ;;; Testing `sgml-html-meta-auto-coding-function'.
 
 (defvar sgml-html-meta-pre "<!doctype html><html><head>"
diff --git a/test/lisp/international/mule-util-resources/test.utf-16le b/test/lisp/international/mule-util-resources/test.utf-16le
new file mode 100644 (file)
index 0000000..8536adb
Binary files /dev/null and b/test/lisp/international/mule-util-resources/test.utf-16le differ