* gnus-art.el (gnus-use-idna)
[gnus] / lisp / gnus-sum.el
index d9fa84f..1660cc6 100644 (file)
@@ -10,7 +10,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -1080,6 +1080,7 @@ uncached:     Non-nil if the article is uncached."
   :group 'gnus-summary-visual
   :type '(repeat (cons (sexp :tag "Form" nil)
                       face)))
+(put 'gnus-summary-highlight 'risky-local-variable t)
 
 (defcustom gnus-alter-header-function nil
   "Function called to allow alteration of article header structures.
@@ -1138,6 +1139,17 @@ default charset will be used instead."
   :type '(repeat symbol)
   :group 'gnus-charset)
 
+(defcustom gnus-newsgroup-maximum-articles nil
+  "The maximum number of articles a newsgroup.
+If this is a number, old articles in a newsgroup exceeding this number
+are silently ignored.  If it is nil, no article is ignored.  Note that
+setting this variable to a number might prevent you from reading very
+old articles."
+  :group 'gnus-group-select
+  :version "22.2"
+  :type '(choice (const :tag "No limit" nil)
+                integer))
+
 (gnus-define-group-parameter
  ignored-charsets
  :type list
@@ -1586,19 +1598,15 @@ For example:
               (eq gnus-newsgroup-name
                   (car gnus-decode-encoded-word-methods-cache)))
     (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
-    (mapcar (lambda (x)
-             (if (symbolp x)
-                 (nconc gnus-decode-encoded-word-methods-cache (list x))
-               (if (and gnus-newsgroup-name
-                        (string-match (car x) gnus-newsgroup-name))
-                   (nconc gnus-decode-encoded-word-methods-cache
-                          (list (cdr x))))))
-           gnus-decode-encoded-word-methods))
-  (let ((xlist gnus-decode-encoded-word-methods-cache))
-    (pop xlist)
-    (while xlist
-      (setq string (funcall (pop xlist) string))))
-  string)
+    (dolist (method gnus-decode-encoded-word-methods)
+      (if (symbolp method)
+         (nconc gnus-decode-encoded-word-methods-cache (list method))
+       (if (and gnus-newsgroup-name
+                (string-match (car method) gnus-newsgroup-name))
+           (nconc gnus-decode-encoded-word-methods-cache
+                  (list (cdr method)))))))
+  (dolist (method (cdr gnus-decode-encoded-word-methods-cache) string)
+    (setq string (funcall method string))))
 
 ;; Subject simplification.
 
@@ -1670,8 +1678,8 @@ matter is removed.  Additional things can be deleted by setting
       (setq modified-tick (buffer-modified-tick))
       (cond
        ((listp gnus-simplify-subject-fuzzy-regexp)
-       (mapcar 'gnus-simplify-buffer-fuzzy-step
-               gnus-simplify-subject-fuzzy-regexp))
+       (mapc 'gnus-simplify-buffer-fuzzy-step
+             gnus-simplify-subject-fuzzy-regexp))
        (gnus-simplify-subject-fuzzy-regexp
        (gnus-simplify-buffer-fuzzy-step gnus-simplify-subject-fuzzy-regexp)))
       (gnus-simplify-buffer-fuzzy-step "^ *\\[[-+?*!][-+?*!]\\] *")
@@ -1939,6 +1947,7 @@ increase the score of each group you read."
 
 (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
   "k" gnus-summary-kill-thread
+  "E" gnus-summary-expire-thread
   "l" gnus-summary-lower-thread
   "i" gnus-summary-raise-thread
   "T" gnus-summary-toggle-threads
@@ -1997,6 +2006,7 @@ increase the score of each group you read."
   "g" gnus-summary-show-article
   "s" gnus-summary-isearch-article
   "P" gnus-summary-print-article
+  "S" gnus-sticky-article
   "M" gnus-mailing-list-insinuate
   "t" gnus-article-babel)
 
@@ -2183,6 +2193,7 @@ increase the score of each group you read."
   "O" gnus-uu-decode-save
   "b" gnus-uu-decode-binhex
   "B" gnus-uu-decode-binhex
+  "Y" gnus-uu-decode-yenc
   "p" gnus-uu-decode-postscript
   "P" gnus-uu-decode-postscript-and-save)
 
@@ -2444,6 +2455,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
              ["Remove article" gnus-cache-remove-article t])
             ["Translate" gnus-article-babel t]
             ["Select article buffer" gnus-summary-select-article-buffer t]
+            ["Make article buffer sticky" gnus-sticky-article t]
             ["Enter digest buffer" gnus-summary-enter-digest-group t]
             ["Isearch article..." gnus-summary-isearch-article t]
             ["Beginning of the article" gnus-summary-beginning-of-article t]
@@ -2484,6 +2496,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
        ["Go up thread" gnus-summary-up-thread t]
        ["Top of thread" gnus-summary-top-thread t]
        ["Mark thread as read" gnus-summary-kill-thread t]
+       ["Mark thread as expired" gnus-summary-expire-thread t]
        ["Lower thread score" gnus-summary-lower-thread t]
        ["Raise thread score" gnus-summary-raise-thread t]
        ["Rethread current" gnus-summary-rethread-current t]))
@@ -4274,21 +4287,19 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
          (erase-buffer)))
       (kill-buffer (current-buffer)))
     ;; Sort over trustworthiness.
-    (mapcar
-     (lambda (relation)
-       (when (gnus-dependencies-add-header
-             (make-full-mail-header
-              gnus-reffed-article-number
-              (nth 3 relation) "" (or (nth 4 relation) "")
-              (nth 1 relation)
-              (or (nth 2 relation) "") 0 0 "")
-             gnus-newsgroup-dependencies nil)
-        (push gnus-reffed-article-number gnus-newsgroup-limit)
-        (push gnus-reffed-article-number gnus-newsgroup-sparse)
-        (push (cons gnus-reffed-article-number gnus-sparse-mark)
-              gnus-newsgroup-reads)
-        (decf gnus-reffed-article-number)))
-     (sort relations 'car-less-than-car))
+    (dolist (relation (sort relations 'car-less-than-car))
+      (when (gnus-dependencies-add-header
+            (make-full-mail-header
+             gnus-reffed-article-number
+             (nth 3 relation) "" (or (nth 4 relation) "")
+             (nth 1 relation)
+             (or (nth 2 relation) "") 0 0 "")
+            gnus-newsgroup-dependencies nil)
+       (push gnus-reffed-article-number gnus-newsgroup-limit)
+       (push gnus-reffed-article-number gnus-newsgroup-sparse)
+       (push (cons gnus-reffed-article-number gnus-sparse-mark)
+             gnus-newsgroup-reads)
+       (decf gnus-reffed-article-number)))
     (gnus-message 7 "Making sparse threads...done")))
 
 (defun gnus-build-old-threads ()
@@ -4806,7 +4817,7 @@ using some other form will lead to serious barfage."
 
 (defsubst gnus-article-sort-by-author (h1 h2)
   "Sort articles by root author."
-  (string-lessp
+  (gnus-string<
    (let ((extract (funcall
                   gnus-extract-address-components
                   (mail-header-from h1))))
@@ -4823,7 +4834,7 @@ using some other form will lead to serious barfage."
 
 (defsubst gnus-article-sort-by-recipient (h1 h2)
   "Sort articles by recipient."
-  (string-lessp
+  (gnus-string<
    (let ((extract (funcall
                   gnus-extract-address-components
                   (or (cdr (assq 'To (mail-header-extra h1))) ""))))
@@ -4840,7 +4851,7 @@ using some other form will lead to serious barfage."
 
 (defsubst gnus-article-sort-by-subject (h1 h2)
   "Sort articles by root subject."
-  (string-lessp
+  (gnus-string<
    (downcase (gnus-simplify-subject-re (mail-header-subject h1)))
    (downcase (gnus-simplify-subject-re (mail-header-subject h2)))))
 
@@ -5397,26 +5408,30 @@ If SELECT-ARTICLES, only select those articles from GROUP."
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
-        articles fetched-articles cached)
+        charset articles fetched-articles cached)
 
     (unless (gnus-check-server
             (set (make-local-variable 'gnus-current-select-method)
                  (gnus-find-method-for-group group)))
       (error "Couldn't open server"))
+    (setq charset (gnus-group-name-charset gnus-current-select-method group))
 
     (or (and entry (not (eq (car entry) t))) ; Either it's active...
        (gnus-activate-group group)     ; Or we can activate it...
        (progn                          ; Or we bug out.
          (when (equal major-mode 'gnus-summary-mode)
            (gnus-kill-buffer (current-buffer)))
-         (error "Couldn't activate group %s: %s"
-                (gnus-group-decoded-name group) (gnus-status-message group))))
+         (error
+          "Couldn't activate group %s: %s"
+          (mm-decode-coding-string group charset)
+          (mm-decode-coding-string (gnus-status-message group) charset))))
 
     (unless (gnus-request-group group t)
-      (when (equal major-mode 'gnus-summary-mode)
-       (gnus-kill-buffer (current-buffer)))
-      (error "Couldn't request group %s: %s"
-            (gnus-group-decoded-name group) (gnus-status-message group)))
+       (when (equal major-mode 'gnus-summary-mode)
+         (gnus-kill-buffer (current-buffer)))
+       (error "Couldn't request group %s: %s"
+              (mm-decode-coding-string group charset)
+              (mm-decode-coding-string (gnus-status-message group) charset)))
 
     (when gnus-agent
       (gnus-agent-possibly-alter-active group (gnus-active group) info)
@@ -5636,7 +5651,15 @@ If SELECT-ARTICLES, only select those articles from GROUP."
              ;; articles in the group, or (if that's nil), the
              ;; articles in the cache.
              (or
-              (gnus-uncompress-range (gnus-active group))
+              (if gnus-newsgroup-maximum-articles
+                  (let ((active (gnus-active group)))
+                    (gnus-uncompress-range
+                     (cons (max (car active)
+                                (- (cdr active)
+                                   gnus-newsgroup-maximum-articles
+                                   -1))
+                           (cdr active))))
+                (gnus-uncompress-range (gnus-active group)))
               (gnus-cache-articles-in-group group))
            ;; Select only the "normal" subset of articles.
            (gnus-sorted-nunion
@@ -6693,23 +6716,27 @@ displayed, no centering will be performed."
         (active (or (gnus-active group) (gnus-activate-group group)))
         (last (or (cdr active)
                   (error "Group %s couldn't be activated " group)))
+        (bottom (if gnus-newsgroup-maximum-articles
+                    (max (car active)
+                         (- last gnus-newsgroup-maximum-articles -1))
+                  (car active)))
         first nlast unread)
     ;; If none are read, then all are unread.
     (if (not read)
-       (setq first (car active))
+       (setq first bottom)
       ;; If the range of read articles is a single range, then the
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
       (if (and (not (listp (cdr read)))
-              (or (< (car read) (car active))
+              (or (< (car read) bottom)
                   (progn (setq read (list read))
                          nil)))
-         (setq first (max (car active) (1+ (cdr read))))
+         (setq first (max bottom (1+ (cdr read))))
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
                                  (caar read)))
                  1)
-         (setq first (car active)))
+         (setq first bottom))
        (while read
          (when first
            (while (< first nlast)
@@ -6734,7 +6761,14 @@ displayed, no centering will be performed."
         (gnus-list-range-difference
          (gnus-list-range-difference
           (gnus-sorted-complement
-           (gnus-uncompress-range active)
+           (gnus-uncompress-range
+            (if gnus-newsgroup-maximum-articles
+                (cons (max (car active)
+                           (- (cdr active)
+                              gnus-newsgroup-maximum-articles
+                              -1))
+                      (cdr active))
+              active))
            (gnus-list-of-unread-articles group))
           (cdr (assq 'dormant marked)))
          (cdr (assq 'tick marked))))))
@@ -6746,23 +6780,27 @@ displayed, no centering will be performed."
   (let* ((read (gnus-info-read (gnus-get-info group)))
         (active (or (gnus-active group) (gnus-activate-group group)))
         (last (cdr active))
+        (bottom (if gnus-newsgroup-maximum-articles
+                    (max (car active)
+                         (- last gnus-newsgroup-maximum-articles -1))
+                  (car active)))
         first nlast unread)
     ;; If none are read, then all are unread.
     (if (not read)
-       (setq first (car active))
+       (setq first bottom)
       ;; If the range of read articles is a single range, then the
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
       (if (and (not (listp (cdr read)))
-              (or (< (car read) (car active))
+              (or (< (car read) bottom)
                   (progn (setq read (list read))
                          nil)))
-         (setq first (max (car active) (1+ (cdr read))))
+         (setq first (max bottom (1+ (cdr read))))
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
                                  (caar read)))
                  1)
-         (setq first (car active)))
+         (setq first bottom))
        (while read
          (when first
             (push (cons first nlast) unread))
@@ -6937,9 +6975,13 @@ If FORCE (the prefix), also save the .newsrc file(s)."
     (gnus-run-hooks 'gnus-summary-prepare-exit-hook)
     ;; If we have several article buffers, we kill them at exit.
     (unless gnus-single-article-buffer
-      (gnus-kill-buffer gnus-article-buffer)
-      (gnus-kill-buffer gnus-original-article-buffer)
-      (setq gnus-article-current nil))
+      (when (gnus-buffer-live-p gnus-article-buffer)
+       (with-current-buffer gnus-article-buffer
+         ;; Don't kill sticky article buffers
+         (unless (eq major-mode 'gnus-sticky-article-mode)
+           (gnus-kill-buffer gnus-article-buffer)
+           (setq gnus-article-current nil))))
+      (gnus-kill-buffer gnus-original-article-buffer))
     (when gnus-use-cache
       (gnus-cache-possibly-remove-articles)
       (gnus-cache-save-buffers))
@@ -6971,11 +7013,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
     (setq group-point (point))
     (if temporary
        nil                             ;Nothing to do.
-      ;; If we have several article buffers, we kill them at exit.
-      (unless gnus-single-article-buffer
-       (gnus-kill-buffer gnus-article-buffer)
-       (gnus-kill-buffer gnus-original-article-buffer)
-       (setq gnus-article-current nil))
       (set-buffer buf)
       (if (not gnus-kill-summary-on-exit)
          (progn
@@ -7408,15 +7445,15 @@ Given a prefix, will force an `article' buffer configuration."
 
 (defun gnus-summary-display-article (article &optional all-header)
   "Display ARTICLE in article buffer."
-  (when (gnus-buffer-live-p gnus-article-buffer)
-    (with-current-buffer gnus-article-buffer
-      (mm-enable-multibyte)))
+  (unless (and (gnus-buffer-live-p gnus-article-buffer)
+              (with-current-buffer gnus-article-buffer
+                (eq major-mode 'gnus-article-mode)))
+    (gnus-article-setup-buffer))
   (gnus-set-global-variables)
-  (when (gnus-buffer-live-p gnus-article-buffer)
-    (with-current-buffer gnus-article-buffer
-      (setq gnus-article-charset gnus-newsgroup-charset)
-      (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
-      (mm-enable-multibyte)))
+  (with-current-buffer gnus-article-buffer
+    (setq gnus-article-charset gnus-newsgroup-charset)
+    (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
+    (mm-enable-multibyte))
   (if (null article)
       nil
     (prog1
@@ -9502,7 +9539,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
-       art-group to-method new-xref article to-groups articles-to-update-marks)
+       art-group to-method new-xref article to-groups
+       articles-to-update-marks encoded)
     (unless (assq action names)
       (error "Unknown action %s" action))
     ;; Read the newsgroup name.
@@ -9520,15 +9558,27 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                (gnus-article-prepare-hook nil)
                (gnus-mark-article-hook nil))
            (gnus-summary-select-article nil nil nil (car articles))))
-      (setq to-newsgroup
-           (gnus-read-move-group-name
-            (cadr (assq action names))
-            (symbol-value (intern (format "gnus-current-%s-group" action)))
-            articles prefix))
-      (set (intern (format "gnus-current-%s-group" action)) to-newsgroup))
-    (setq to-method (or select-method
-                       (gnus-server-to-method
-                        (gnus-group-method to-newsgroup))))
+      (setq to-newsgroup (gnus-read-move-group-name
+                         (cadr (assq action names))
+                         (symbol-value
+                          (intern (format "gnus-current-%s-group" action)))
+                         articles prefix)
+           encoded to-newsgroup
+           to-method (gnus-server-to-method (gnus-group-method to-newsgroup)))
+      (set (intern (format "gnus-current-%s-group" action))
+          (mm-decode-coding-string
+           to-newsgroup
+           (gnus-group-name-charset to-method to-newsgroup))))
+    (unless to-method
+      (setq to-method (or select-method
+                         (gnus-server-to-method
+                          (gnus-group-method to-newsgroup)))))
+    (setq to-newsgroup
+         (or encoded
+             (and to-newsgroup
+                  (mm-encode-coding-string
+                   to-newsgroup
+                   (gnus-group-name-charset to-method to-newsgroup)))))
     ;; Check the method we are to move this article to...
     (unless (gnus-check-backend-function
             'request-accept-article (car to-method))
@@ -9537,7 +9587,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
       (error "Can't open server %s" (car to-method)))
     (gnus-message 6 "%s to %s: %s..."
                  (caddr (assq action names))
-                 (or (car select-method) to-newsgroup) articles)
+                 (or (car select-method)
+                     (gnus-group-decoded-name to-newsgroup))
+                 articles)
     (while articles
       (setq article (pop articles))
       (setq
@@ -9549,8 +9601,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
         (gnus-dup-unsuppress-article article)
         (let* ((from-method (gnus-find-method-for-group
                              gnus-newsgroup-name))
-               (to-method (gnus-find-method-for-group
-                           to-newsgroup))
+               (to-method (or select-method
+                              (gnus-find-method-for-group to-newsgroup)))
                (move-is-internal (gnus-method-equal from-method to-method)))
           (gnus-request-move-article
            article                     ; Article to move
@@ -10069,7 +10121,16 @@ groups."
                  (message-options message-options)
                  (message-options-set-recipient)
                  (mail-parse-ignored-charsets
-                  ',gnus-newsgroup-ignored-charsets))
+                  ',gnus-newsgroup-ignored-charsets)
+                 (rfc2047-header-encoding-alist
+                  ',(let ((charset (gnus-group-name-charset
+                                    (gnus-find-method-for-group
+                                     gnus-newsgroup-name)
+                                    gnus-newsgroup-name)))
+                      (append (list (cons "Newsgroups" charset)
+                                    (cons "Followup-To" charset)
+                                    (cons "Xref" charset))
+                              rfc2047-header-encoding-alist))))
              ,(if (not raw) '(progn
                                (mml-to-mime)
                                (mml-destroy-buffers)
@@ -10866,9 +10927,8 @@ even ticked and dormant ones."
        (goto-char (point-min))
        (push gnus-newsgroup-limit gnus-newsgroup-limits)
        (setq gnus-newsgroup-limit (copy-sequence gnus-newsgroup-limit))
-       (mapcar (lambda (x) (push (mail-header-number x)
-                                 gnus-newsgroup-limit))
-               headers)
+       (dolist (x headers)
+         (push (mail-header-number x) gnus-newsgroup-limit))
        (gnus-summary-prepare-unthreaded (nreverse headers))
        (goto-char (point-min))
        (gnus-summary-position-point)
@@ -11331,14 +11391,21 @@ taken."
   (while (gnus-summary-go-up-thread))
   (gnus-summary-article-number))
 
+(defun gnus-summary-expire-thread ()
+  "Mark articles under current thread as expired."
+  (interactive)
+  (gnus-summary-kill-thread 0))
+
 (defun gnus-summary-kill-thread (&optional unmark)
   "Mark articles under current thread as read.
 If the prefix argument is positive, remove any kinds of marks.
+If the prefix argument is zero, mark thread as expired.
 If the prefix argument is negative, tick articles instead."
   (interactive "P")
   (when unmark
     (setq unmark (prefix-numeric-value unmark)))
-  (let ((articles (gnus-summary-articles-in-thread)))
+  (let ((articles (gnus-summary-articles-in-thread))
+       (hide (or (null unmark) (= unmark 0))))
     (save-excursion
       ;; Expand the thread.
       (gnus-summary-show-thread)
@@ -11349,15 +11416,17 @@ If the prefix argument is negative, tick articles instead."
               (gnus-summary-mark-article-as-read gnus-killed-mark))
              ((> unmark 0)
               (gnus-summary-mark-article-as-unread gnus-unread-mark))
+             ((= unmark 0)
+              (gnus-summary-mark-article-as-unread gnus-expirable-mark))
              (t
               (gnus-summary-mark-article-as-unread gnus-ticked-mark)))
        (setq articles (cdr articles))))
-    ;; Hide killed subtrees.
-    (and (null unmark)
+    ;; Hide killed subtrees when hide is true.
+    (and hide
         gnus-thread-hide-killed
         (gnus-summary-hide-thread))
-    ;; If marked as read, go to next unread subject.
-    (when (null unmark)
+    ;; If hide is t, go to next unread subject.
+    (when hide
       ;; Go to next unread subject.
       (gnus-summary-next-subject 1 t)))
   (gnus-set-mode-line 'summary))
@@ -11678,45 +11747,49 @@ save those articles instead."
                      (format "these %d articles" (length articles))
                    "this article")))
         (to-newsgroup
-         (cond
-          ((null split-name)
-           (gnus-completing-read-with-default
-            default prom
-            gnus-active-hashtb
-            'gnus-valid-move-group-p
-            nil prefix
-            'gnus-group-history))
-          ((= 1 (length split-name))
-           (gnus-completing-read-with-default
-            (car split-name) prom
-            gnus-active-hashtb
-            'gnus-valid-move-group-p
-            nil nil
-            'gnus-group-history))
-          (t
-           (gnus-completing-read-with-default
-            nil prom
-            (mapcar 'list (nreverse split-name))
-            nil nil nil
-            'gnus-group-history))))
-        (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))))
+         (let (active group)
+           (when (or (null split-name) (= 1 (length split-name)))
+             (setq active (gnus-make-hashtable (length gnus-active-hashtb)))
+             (mapatoms (lambda (symbol)
+                         (setq group (symbol-name symbol))
+                         (when (string-match "[^\000-\177]" group)
+                           (setq group (gnus-group-decoded-name group)))
+                         (set (intern group active) group))
+                       gnus-active-hashtb))
+           (cond
+            ((null split-name)
+             (gnus-completing-read-with-default
+              default prom active 'gnus-valid-move-group-p nil prefix
+              'gnus-group-history))
+            ((= 1 (length split-name))
+             (gnus-completing-read-with-default
+              (car split-name) prom active 'gnus-valid-move-group-p nil nil
+              'gnus-group-history))
+            (t
+             (gnus-completing-read-with-default
+              nil prom (mapcar 'list (nreverse split-name)) nil nil nil
+              'gnus-group-history)))))
+        (to-method (gnus-server-to-method (gnus-group-method to-newsgroup)))
+        encoded)
     (when to-newsgroup
       (if (or (string= to-newsgroup "")
              (string= to-newsgroup prefix))
          (setq to-newsgroup default))
       (unless to-newsgroup
        (error "No group name entered"))
-      (or (gnus-active to-newsgroup)
-         (gnus-activate-group to-newsgroup nil nil to-method)
+      (setq encoded (mm-encode-coding-string
+                    to-newsgroup
+                    (gnus-group-name-charset to-method to-newsgroup)))
+      (or (gnus-active encoded)
+         (gnus-activate-group encoded nil nil to-method)
          (if (gnus-y-or-n-p (format "No such group: %s.  Create it? "
                                     to-newsgroup))
-             (or (and (gnus-request-create-group to-newsgroup to-method)
-                      (gnus-activate-group
-                       to-newsgroup nil nil to-method)
-                      (gnus-subscribe-group to-newsgroup))
+             (or (and (gnus-request-create-group encoded to-method)
+                      (gnus-activate-group encoded nil nil to-method)
+                      (gnus-subscribe-group encoded))
                  (error "Couldn't create group %s" to-newsgroup)))
-         (error "No such group: %s" to-newsgroup)))
-    to-newsgroup))
+         (error "No such group: %s" to-newsgroup))
+      encoded)))
 
 (defvar gnus-summary-save-parts-counter)
 
@@ -12280,12 +12353,24 @@ returned."
     (when gnus-suppress-duplicates
       (gnus-dup-suppress-articles))
 
-    ;; We might want to build some more threads first.
-    (when (and gnus-fetch-old-headers
-              (eq gnus-headers-retrieved-by 'nov))
-      (if (eq gnus-fetch-old-headers 'invisible)
-         (gnus-build-all-threads)
-       (gnus-build-old-threads)))
+    (if (and gnus-fetch-old-headers
+            (eq gnus-headers-retrieved-by 'nov))
+       ;; We might want to build some more threads first.
+       (if (eq gnus-fetch-old-headers 'invisible)
+           (gnus-build-all-threads)
+         (gnus-build-old-threads))
+      ;; Mark the inserted articles that are unread as unread.
+      (setq gnus-newsgroup-unreads
+           (gnus-sorted-nunion
+            gnus-newsgroup-unreads
+            (gnus-sorted-nintersection
+             (gnus-list-of-unread-articles gnus-newsgroup-name)
+             articles)))
+      ;; Mark the inserted articles as selected so that the information
+      ;; of the marks having been changed by a user may be updated when
+      ;; exiting this group.  See `gnus-summary-update-info'.
+      (dolist (art articles)
+       (setq gnus-newsgroup-unselected (delq art gnus-newsgroup-unselected))))
     ;; Let the Gnus agent mark articles as read.
     (when gnus-agent
       (gnus-agent-get-undownloaded-list))