[PATCH 21.5] Reading and writing abbrev file under MULE

[email protected] (Nickolay Pakoulin)
Newsgroups gmane.emacs.xemacs.design,gmane.emacs.xemacs.patches
Message-ID <[email protected]>
Current implementation of abbrev.el does not care about coding systems for
reading and writing abbreviations.

Under Mule, using non-ascii (e.g. russian) characters in abbreviations leads to
incorrect behavior.  Write/read cycle corrupts such abbreviations.

The patch below provides a new user option and adds coding system selection to
`read-abbrev-file' and `write-abbrev-file'.  The patch was tested on
XEmacs-21.5, Windows 2000, both MULE and non-MULE.

The user option, abbrev-file-coding-system, stores user's preferred coding
system.  This coding system is used to read and write abbreviation files.

Changes to `read-abbrev-file'.

Try to make a reasonable guess on what coding system to use when reading abbrev
file.  Try in order: 
	`coding-system-for-read',
        magic cookie in the abbrev file,
	`file-coding-system-alist',
        `abbrev-file-coding-system',
	`buffer-file-coding-system-for-read'

Changes to `write-abbrev-file'.

Try to make a reasonable guess on what coding system to use when writing abbrev
file. Try in order:
	`coding-system-for-write',
        `abbrev-file-coding-system',
	`abbrev-file-used-coding-system',
        `buffer-file-coding-system'

Any comments?

Nick.

Changelog entry.

2003-12-08  Nickolay Pakoulin  <[email protected]>

	* abbrev.el (coding-system-name-p): new function.  
	(abbrev-file-coding-system): New user option.
	(abbrev-file-used-coding-system): New variable.
	(read-abbrev-file): Try to make a reasonable guess on what coding
	system to use when reading abbrev file.  
	(write-abbrev-file): Try to make a reasonable guess on what coding
	system to use when writing abbrev file.
abbrev.diff (text/x-patch, 5 KB)
--- abbrev.el.orig	2003-12-06 00:13:29.121334400 +0300
+++ abbrev.el	2003-12-08 19:22:02.368708800 +0300
@@ -60,6 +60,24 @@
   :type 'boolean
   :group 'abbrev)
 
+;; ### Move it to mule-related files
+(defun coding-system-name-p (object)
+  "Return non-nil when OBJECT is a symbol naming a coding system."
+  (and (symbolp object)
+       (find-coding-system object)))
+
+(defcustom abbrev-file-coding-system nil
+  "Coding system for reading and writing abbreviation file.
+
+See `read-abbrev-file' and `write-abbrev-file' for details about coding
+system selection."
+:type '(restricted-sexp :match-alternatives (coding-system-name-p nil))
+:group 'abbrev)
+
+(defvar abbrev-file-used-coding-system nil
+  "
+Coding system used to load last abbrev file.")
+
 ;;; XEmacs: the following block of code is not in FSF
 (defvar abbrev-table-name-list '()
   "List of symbols whose values are abbrev tables.")
@@ -403,11 +421,43 @@
   "Read abbrev definitions from file written with `write-abbrev-file'.
 Optional argument FILE is the name of the file to read;
 it defaults to the value of `abbrev-file-name'.
-Optional second argument QUIETLY non-nil means don't print anything."
+Optional second argument QUIETLY non-nil means don't print anything.
+
+Under MULE, try the following coding systems in order:
+1.  `coding-system-for-read', if non-nil;
+2.  magic cookie in the abbrev file.  See
+    `find-coding-system-magic-cookie-in-file' about magic cookies;
+3.  The matching value for abbrev file name from `file-coding-system-alist',
+    if any;
+4.  `abbrev-file-coding-system', if non-nil;
+5.  Default value of `buffer-file-coding-system-for-read', if non-nil.
+
+Actual coding system that was used for the decoding is stored in
+`abbrev-file-used-coding-system' variable."
   (interactive "fRead abbrev file: ")
-  (load (if (and file (> (length file) 0)) file abbrev-file-name)
-	nil quietly)
-  (setq save-abbrevs t abbrevs-changed nil))
+  (let ((used-codesys nil)
+        (coding-system nil)
+        (file (if (and (stringp file) (< 0 (length file))) file
+                abbrev-file-name)))
+    (setq coding-system
+          (or coding-system-for-read
+              ;; find magic-cookie in the abbrev file
+              (let ((codesys
+                     (ignore-errors
+                       (find-coding-system-magic-cookie-in-file file))))
+                (when codesys
+                  (setq codesys (intern codesys))
+                  (if (find-coding-system codesys) codesys)))
+              (find-file-coding-system-for-read-from-filename file)
+              abbrev-file-coding-system
+              (default-value 'buffer-file-coding-system-for-read)))
+    (load-internal file
+                   nil quietly nil
+                   coding-system 'used-codesys)
+    ;; ### Should we warn if used-codesys differs greatly from the
+    ;; abbrev-file-coding-system???  That is, not a subsidiary coding system?
+    (setq save-abbrevs t abbrevs-changed nil
+          abbrev-file-used-coding-system used-codesys)))
 
 (defun quietly-read-abbrev-file (&optional file)
   "Read abbrev definitions from file written with `write-abbrev-file'.
@@ -420,7 +470,15 @@
 (defun write-abbrev-file (file)
   "Write all abbrev definitions to a file of Lisp code.
 The file written can be loaded in another session to define the same abbrevs.
-The argument FILE is the file name to write."
+The argument FILE is the file name to write.
+
+Coding system for writing is selected as follows:
+1.  `coding-system-for-write' if non-nil; else
+2.  `abbrev-file-coding-system' if non-nil; else
+3.  `abbrev-file-used-coding-system' if non-nil.  write uses the same coding
+    system as read does.
+4.  default value of `buffer-file-coding-system'
+"
   (interactive
    (list
     (read-file-name "Write abbrev file: "
@@ -431,12 +489,26 @@
   (save-excursion
    (set-buffer (get-buffer-create " write-abbrev-file"))
    (erase-buffer)
-   (let ((tables abbrev-table-name-list))
-     (while tables
-       (insert-abbrev-table-description (car tables) nil)
-       (setq tables (cdr tables))))
-   (write-region 1 (point-max) file)
-   (erase-buffer)))
+   (let (codesys name-sym)
+     (setq codesys
+           (or coding-system-for-write
+               abbrev-file-coding-system
+               abbrev-file-used-coding-system
+               (default-value 'buffer-file-coding-system)))
+     (when codesys
+       (setq name-sym (if (coding-system-p codesys)
+                          (coding-system-name codesys)
+                        codesys))
+       ;; Insert `coding' file variable
+       (insert ";;; -*- coding: " (symbol-name name-sym) " -*-\n"))
+     (let ((tables abbrev-table-name-list))
+       (while tables
+         (insert-abbrev-table-description (car tables) nil)
+         (setq tables (cdr tables))))
+     (let ((coding-system-for-write codesys))
+       (write-region (point-min) (point-max) file)
+       (erase-buffer)))))
+
 
 (defun abbrev-string-to-be-defined (arg)
   "Return the string for which an abbrev will be defined.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.