aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Abrahamsen2019-06-06 20:43:27 -0700
committerEric Abrahamsen2019-08-03 14:52:56 -0700
commit727e0eab0a0d8043d09225f63f8bef2abc045562 (patch)
treedf219ce120264cc4e4dde41efc37ce3bb3b2d0bf
parentcb12a84f2c519a48dd87453c925e3bc36d9944db (diff)
downloademacs-727e0eab0a0d8043d09225f63f8bef2abc045562.tar.gz
emacs-727e0eab0a0d8043d09225f63f8bef2abc045562.zip
Temporarily preserve encoded Gnus group names in Gnus files
Non-ascii Gnus groups should be written to files in their encoded version until we're ready to bump Gnus' version and add an upgrade routine. * lisp/gnus/gnus-start.el (gnus-gnus-to-quick-newsrc-format): * lisp/gnus/gnus-agent.el (gnus-category-read): (gnus-category-write): Handle non-ascii group names appropriately. * lisp/gnus/gnus-registry.el (gnus-registry--munge-group-names): New function to encode/decode group names. (gnus-registry-fixup-registry): (gnus-registry-save): Use function.
-rw-r--r--lisp/gnus/gnus-agent.el102
-rw-r--r--lisp/gnus/gnus-registry.el59
-rw-r--r--lisp/gnus/gnus-start.el39
3 files changed, 144 insertions, 56 deletions
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index d9c9e940700..dd30dda2a10 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -2693,52 +2693,74 @@ The following commands are available:
2693 "Read the category alist." 2693 "Read the category alist."
2694 (setq gnus-category-alist 2694 (setq gnus-category-alist
2695 (or 2695 (or
2696 (with-temp-buffer 2696 (let ((list
2697 (ignore-errors 2697 (with-temp-buffer
2698 (nnheader-insert-file-contents (nnheader-concat gnus-agent-directory "lib/categories")) 2698 (ignore-errors
2699 (goto-char (point-min)) 2699 (nnheader-insert-file-contents (nnheader-concat gnus-agent-directory "lib/categories"))
2700 ;; This code isn't temp, it will be needed so long as 2700 (goto-char (point-min))
2701 ;; anyone may be migrating from an older version. 2701 ;; This code isn't temp, it will be needed so long as
2702 2702 ;; anyone may be migrating from an older version.
2703 ;; Once we're certain that people will not revert to an 2703
2704 ;; earlier version, we can take out the old-list code in 2704 ;; Once we're certain that people will not revert to an
2705 ;; gnus-category-write. 2705 ;; earlier version, we can take out the old-list code in
2706 (let* ((old-list (read (current-buffer))) 2706 ;; gnus-category-write.
2707 (new-list (ignore-errors (read (current-buffer))))) 2707 (let* ((old-list (read (current-buffer)))
2708 (if new-list 2708 (new-list (ignore-errors (read (current-buffer)))))
2709 new-list 2709 (if new-list
2710 ;; Convert from a positional list to an alist. 2710 new-list
2711 (mapcar 2711 ;; Convert from a positional list to an alist.
2712 (lambda (c) 2712 (mapcar
2713 (setcdr c 2713 (lambda (c)
2714 (delq nil 2714 (setcdr c
2715 (gnus-mapcar 2715 (delq nil
2716 (lambda (valu symb) 2716 (gnus-mapcar
2717 (if valu 2717 (lambda (valu symb)
2718 (cons symb valu))) 2718 (if valu
2719 (cdr c) 2719 (cons symb valu)))
2720 '(agent-predicate agent-score-file agent-groups)))) 2720 (cdr c)
2721 c) 2721 '(agent-predicate agent-score-file agent-groups))))
2722 old-list))))) 2722 c)
2723 old-list)))))))
2724 ;; Possibly decode group names.
2725 (dolist (cat list)
2726 (setf (alist-get 'agent-groups cat)
2727 (mapcar (lambda (g)
2728 (if (string-match-p "[^[:ascii:]]" g)
2729 (decode-coding-string g 'utf-8-emacs)
2730 g))
2731 (alist-get 'agent-groups cat))))
2732 list)
2723 (list (gnus-agent-cat-make 'default 'short))))) 2733 (list (gnus-agent-cat-make 'default 'short)))))
2724 2734
2725(defun gnus-category-write () 2735(defun gnus-category-write ()
2726 "Write the category alist." 2736 "Write the category alist."
2727 (setq gnus-category-predicate-cache nil 2737 (setq gnus-category-predicate-cache nil
2728 gnus-category-group-cache nil) 2738 gnus-category-group-cache nil)
2729 (gnus-make-directory (nnheader-concat gnus-agent-directory "lib")) 2739 ;; Temporarily encode non-ascii group names when saving to file,
2730 (with-temp-file (nnheader-concat gnus-agent-directory "lib/categories") 2740 ;; pending an upgrade of Gnus' file formats.
2731 ;; This prin1 is temporary. It exists so that people can revert 2741 (let ((gnus-category-alist
2732 ;; to an earlier version of gnus-agent. 2742 (mapcar (lambda (cat)
2733 (prin1 (mapcar (lambda (c) 2743 (setf (alist-get 'agent-groups cat)
2734 (list (car c) 2744 (mapcar (lambda (g)
2735 (cdr (assoc 'agent-predicate c)) 2745 (if (multibyte-string-p g)
2736 (cdr (assoc 'agent-score-file c)) 2746 (encode-coding-string g 'utf-8-emacs)
2737 (cdr (assoc 'agent-groups c)))) 2747 g))
2738 gnus-category-alist) 2748 (alist-get 'agent-groups cat)))
2739 (current-buffer)) 2749 cat)
2740 (newline) 2750 (copy-tree gnus-category-alist))))
2741 (prin1 gnus-category-alist (current-buffer)))) 2751 (gnus-make-directory (nnheader-concat gnus-agent-directory "lib"))
2752 (with-temp-file (nnheader-concat gnus-agent-directory "lib/categories")
2753 ;; This prin1 is temporary. It exists so that people can revert
2754 ;; to an earlier version of gnus-agent.
2755 (prin1 (mapcar (lambda (c)
2756 (list (car c)
2757 (cdr (assoc 'agent-predicate c))
2758 (cdr (assoc 'agent-score-file c))
2759 (cdr (assoc 'agent-groups c))))
2760 gnus-category-alist)
2761 (current-buffer))
2762 (newline)
2763 (prin1 gnus-category-alist (current-buffer)))))
2742 2764
2743(defun gnus-category-edit-predicate (category) 2765(defun gnus-category-edit-predicate (category)
2744 "Edit the predicate for CATEGORY." 2766 "Edit the predicate for CATEGORY."
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index e488858ebe0..e949179b3cc 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -264,6 +264,50 @@ This can slow pruning down. Set to nil to perform no sorting."
264 (cadr (assq 'creation-time r)) 264 (cadr (assq 'creation-time r))
265 (cadr (assq 'creation-time l)))) 265 (cadr (assq 'creation-time l))))
266 266
267;; Remove this from the save routine (and fix it to only decode) at
268;; next Gnus version bump.
269(defun gnus-registry--munge-group-names (db &optional encode)
270 "Encode/decode group names in DB, before saving or after loading.
271Encode names if ENCODE is non-nil, otherwise decode."
272 (let ((datahash (slot-value db 'data))
273 (grouphash (registry-lookup-secondary db 'group))
274 reset-pairs)
275 (when (hash-table-p grouphash)
276 (maphash
277 (lambda (group-name val)
278 (if encode
279 (when (multibyte-string-p group-name)
280 (remhash group-name grouphash)
281 (puthash (encode-coding-string group-name 'utf-8-emacs)
282 val grouphash))
283 (when (string-match-p "[^[:ascii:]]" group-name)
284 (remhash group-name grouphash)
285 (puthash (decode-coding-string group-name 'utf-8-emacs) val grouphash))))
286 grouphash))
287 (maphash
288 (lambda (id data)
289 (let ((groups (cdr-safe (assq 'group data))))
290 (when (seq-some (lambda (g)
291 (if encode
292 (multibyte-string-p g)
293 (string-match-p "[^[:ascii:]]" g)))
294 groups)
295 ;; Create a replacement DATA.
296 (push (list id (cons (cons 'group (mapcar
297 (lambda (g)
298 (funcall
299 (if encode
300 #'encode-coding-string
301 #'decode-coding-string)
302 g 'utf-8-emacs))
303 groups))
304 (assq-delete-all 'group data)))
305 reset-pairs))))
306 datahash)
307 (pcase-dolist (`(,id ,data) reset-pairs)
308 (remhash id datahash)
309 (puthash id data datahash))))
310
267(defun gnus-registry-fixup-registry (db) 311(defun gnus-registry-fixup-registry (db)
268 (when db 312 (when db
269 (let ((old (oref db tracked))) 313 (let ((old (oref db tracked)))
@@ -281,7 +325,8 @@ This can slow pruning down. Set to nil to perform no sorting."
281 '(mark group keyword))) 325 '(mark group keyword)))
282 (when (not (equal old (oref db tracked))) 326 (when (not (equal old (oref db tracked)))
283 (gnus-message 9 "Reindexing the Gnus registry (tracked change)") 327 (gnus-message 9 "Reindexing the Gnus registry (tracked change)")
284 (registry-reindex db)))) 328 (registry-reindex db))
329 (gnus-registry--munge-group-names db)))
285 db) 330 db)
286 331
287(defun gnus-registry-make-db (&optional file) 332(defun gnus-registry-make-db (&optional file)
@@ -358,14 +403,20 @@ non-nil."
358(defun gnus-registry-save (&optional file db) 403(defun gnus-registry-save (&optional file db)
359 "Save the registry cache file." 404 "Save the registry cache file."
360 (interactive) 405 (interactive)
361 (let ((file (or file gnus-registry-cache-file)) 406 (let* ((file (or file gnus-registry-cache-file))
362 (db (or db gnus-registry-db))) 407 (db (or db gnus-registry-db))
408 (clone (clone db)))
363 (gnus-message 5 "Saving Gnus registry (%d entries) to %s..." 409 (gnus-message 5 "Saving Gnus registry (%d entries) to %s..."
364 (registry-size db) file) 410 (registry-size db) file)
365 (registry-prune 411 (registry-prune
366 db gnus-registry-default-sort-function) 412 db gnus-registry-default-sort-function)
413 ;; Write a clone of the database with non-ascii group names
414 ;; encoded as 'utf-8. Let-bind `gnus-registry-db' so that
415 ;; functions in the munging process work on our clone.
416 (let ((gnus-registry-db clone))
417 (gnus-registry--munge-group-names clone 'encode))
367 ;; TODO: call (gnus-string-remove-all-properties v) on all elements? 418 ;; TODO: call (gnus-string-remove-all-properties v) on all elements?
368 (eieio-persistent-save db file) 419 (eieio-persistent-save clone file)
369 (gnus-message 5 "Saving Gnus registry (size %d) to %s...done" 420 (gnus-message 5 "Saving Gnus registry (size %d) to %s...done"
370 (registry-size db) file))) 421 (registry-size db) file)))
371 422
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index f7ede54b105..930d522c41b 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -42,6 +42,7 @@
42(defvar gnus-agent-covered-methods) 42(defvar gnus-agent-covered-methods)
43(defvar gnus-agent-file-loading-local) 43(defvar gnus-agent-file-loading-local)
44(defvar gnus-agent-file-loading-cache) 44(defvar gnus-agent-file-loading-cache)
45(defvar gnus-topic-alist)
45 46
46(defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc") 47(defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
47 "Your `.newsrc' file. 48 "Your `.newsrc' file.
@@ -2869,7 +2870,12 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'."
2869 (princ "(setq gnus-newsrc-file-version ") 2870 (princ "(setq gnus-newsrc-file-version ")
2870 (princ (gnus-prin1-to-string gnus-version)) 2871 (princ (gnus-prin1-to-string gnus-version))
2871 (princ ")\n")) 2872 (princ ")\n"))
2872 2873 ;; Sort `gnus-newsrc-alist' according to order in
2874 ;; `gnus-group-list'.
2875 (setq gnus-newsrc-alist
2876 (mapcar (lambda (g)
2877 (nth 1 (gethash g gnus-newsrc-hashtb)))
2878 (delete "dummy.group" gnus-group-list)))
2873 (let* ((print-quoted t) 2879 (let* ((print-quoted t)
2874 (print-readably t) 2880 (print-readably t)
2875 (print-escape-multibyte nil) 2881 (print-escape-multibyte nil)
@@ -2889,18 +2895,27 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'."
2889 ;; Remove the `gnus-killed-list' from the list of variables 2895 ;; Remove the `gnus-killed-list' from the list of variables
2890 ;; to be saved, if required. 2896 ;; to be saved, if required.
2891 (delq 'gnus-killed-list (copy-sequence gnus-variable-list))))) 2897 (delq 'gnus-killed-list (copy-sequence gnus-variable-list)))))
2898 ;; Encode group names in `gnus-newsrc-alist' and
2899 ;; `gnus-topic-alist' in order to keep newsrc.eld files
2900 ;; compatible with older versions of Gnus. At some point,
2901 ;; if/when a new version of Gnus is released, stop doing
2902 ;; this and move the corresponding decode in
2903 ;; `gnus-read-newsrc-el-file' into a conversion routine.
2904 (gnus-newsrc-alist
2905 (mapcar (lambda (info)
2906 (cons (encode-coding-string (car info) 'utf-8-emacs)
2907 (cdr info)))
2908 gnus-newsrc-alist))
2909 (gnus-topic-alist
2910 (when (memq 'gnus-topic-alist variables)
2911 (mapcar (lambda (elt)
2912 (cons (car elt) ; Topic name
2913 (mapcar (lambda (g)
2914 (encode-coding-string
2915 g 'utf-8-emacs))
2916 (cdr elt))))
2917 gnus-topic-alist)))
2892 variable) 2918 variable)
2893 ;; A bit of a fake-out here: the original value of
2894 ;; `gnus-newsrc-alist' isn't written to file, instead it is
2895 ;; constructed at the last minute by combining the group
2896 ;; ordering in `gnus-group-list' with the group infos from
2897 ;; `gnus-newsrc-hashtb'.
2898 (set (nth (seq-position gnus-variable-list 'gnus-newsrc-alist)
2899 gnus-variable-list)
2900 (mapcar (lambda (g)
2901 (nth 1 (gethash g gnus-newsrc-hashtb)))
2902 (delete "dummy.group" gnus-group-list)))
2903
2904 ;; Insert the variables into the file. 2919 ;; Insert the variables into the file.
2905 (while variables 2920 (while variables
2906 (when (and (boundp (setq variable (pop variables))) 2921 (when (and (boundp (setq variable (pop variables)))