Fix sa-learn integration to insert a full From in the message envelope.
[gnus] / lisp / gnus-group.el
1 ;;; gnus-group.el --- group mode commands for Gnus
2
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006, 2007, 2008, 2009, 2010, 2011
5 ;;   Free Software Foundation, Inc.
6
7 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
8 ;; Keywords: news
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;;; Code:
28
29 ;; For Emacs <22.2 and XEmacs.
30 (eval-and-compile
31   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
32
33 (eval-when-compile
34   (require 'cl))
35 (defvar tool-bar-mode)
36
37 (require 'gnus)
38 (require 'gnus-start)
39 (require 'nnmail)
40 (require 'gnus-spec)
41 (require 'gnus-int)
42 (require 'gnus-range)
43 (require 'gnus-win)
44 (require 'gnus-undo)
45 (require 'gmm-utils)
46 (require 'time-date)
47 (require 'gnus-ems)
48
49 (eval-when-compile
50   (require 'mm-url)
51   (let ((features (cons 'gnus-group features)))
52     (require 'gnus-sum))
53   (unless (boundp 'gnus-cache-active-hashtb)
54     (defvar gnus-cache-active-hashtb nil)))
55
56 (autoload 'gnus-agent-total-fetched-for "gnus-agent")
57 (autoload 'gnus-cache-total-fetched-for "gnus-cache")
58
59 (autoload 'gnus-group-make-nnir-group "nnir")
60
61 (defcustom gnus-no-groups-message "No Gnus is good news"
62   "*Message displayed by Gnus when no groups are available."
63   :group 'gnus-start
64   :type 'string)
65
66 (defcustom gnus-keep-same-level nil
67   "*Non-nil means that the next newsgroup after the current will be on the same level.
68 When you type, for instance, `n' after reading the last article in the
69 current newsgroup, you will go to the next newsgroup.  If this variable
70 is nil, the next newsgroup will be the next from the group
71 buffer.
72 If this variable is non-nil, Gnus will either put you in the
73 next newsgroup with the same level, or, if no such newsgroup is
74 available, the next newsgroup with the lowest possible level higher
75 than the current level.
76 If this variable is `best', Gnus will make the next newsgroup the one
77 with the best level."
78   :group 'gnus-group-levels
79   :type '(choice (const nil)
80                  (const best)
81                  (sexp :tag "other" t)))
82
83 (defcustom gnus-group-goto-unread t
84   "*If non-nil, movement commands will go to the next unread and subscribed group."
85   :link '(custom-manual "(gnus)Group Maneuvering")
86   :group 'gnus-group-various
87   :type 'boolean)
88
89 (defcustom gnus-goto-next-group-when-activating t
90   "*If non-nil, the \\<gnus-group-mode-map>\\[gnus-group-get-new-news-this-group] command will advance point to the next group."
91   :link '(custom-manual "(gnus)Scanning New Messages")
92   :group 'gnus-group-various
93   :type 'boolean)
94
95 (defcustom gnus-permanently-visible-groups nil
96   "*Regexp to match groups that should always be listed in the group buffer.
97 This means that they will still be listed even when there are no
98 unread articles in the groups.
99
100 If nil, no groups are permanently visible."
101   :group 'gnus-group-listing
102   :type '(choice regexp (const nil)))
103
104 (defcustom gnus-safe-html-newsgroups "\\`nnrss[+:]"
105   "Groups in which links in html articles are considered all safe.
106 The value may be a regexp matching those groups, a list of group names,
107 or nil.  This overrides `mm-w3m-safe-url-regexp' (which see).  This is
108 effective only when emacs-w3m renders html articles, i.e., in the case
109 `mm-text-html-renderer' is set to `w3m'."
110   :version "23.2"
111   :group 'gnus-group-various
112   :type '(choice regexp
113                  (repeat :tag "List of group names" (string :tag "Group"))
114                  (const nil)))
115
116 (defcustom gnus-list-groups-with-ticked-articles t
117   "*If non-nil, list groups that have only ticked articles.
118 If nil, only list groups that have unread articles."
119   :group 'gnus-group-listing
120   :type 'boolean)
121
122 (defcustom gnus-group-default-list-level gnus-level-subscribed
123   "Default listing level.
124 Ignored if `gnus-group-use-permanent-levels' is non-nil."
125   :group 'gnus-group-listing
126   :type '(choice (integer :tag "Level")
127                  (function :tag "Function returning level")))
128
129 (defcustom gnus-group-list-inactive-groups t
130   "*If non-nil, inactive groups will be listed."
131   :group 'gnus-group-listing
132   :group 'gnus-group-levels
133   :type 'boolean)
134
135 (defcustom gnus-group-sort-function 'gnus-group-sort-by-alphabet
136   "*Function used for sorting the group buffer.
137 This function will be called with group info entries as the arguments
138 for the groups to be sorted.  Pre-made functions include
139 `gnus-group-sort-by-alphabet', `gnus-group-sort-by-real-name',
140 `gnus-group-sort-by-unread', `gnus-group-sort-by-level',
141 `gnus-group-sort-by-score', `gnus-group-sort-by-method',
142 `gnus-group-sort-by-server', and `gnus-group-sort-by-rank'.
143
144 This variable can also be a list of sorting functions.  In that case,
145 the most significant sort function should be the last function in the
146 list."
147   :group 'gnus-group-listing
148   :link '(custom-manual "(gnus)Sorting Groups")
149   :type '(repeat :value-to-internal (lambda (widget value)
150                                       (if (listp value) value (list value)))
151                  :match (lambda (widget value)
152                           (or (symbolp value)
153                               (widget-editable-list-match widget value)))
154                  (choice (function-item gnus-group-sort-by-alphabet)
155                          (function-item gnus-group-sort-by-real-name)
156                          (function-item gnus-group-sort-by-unread)
157                          (function-item gnus-group-sort-by-level)
158                          (function-item gnus-group-sort-by-score)
159                          (function-item gnus-group-sort-by-method)
160                          (function-item gnus-group-sort-by-server)
161                          (function-item gnus-group-sort-by-rank)
162                          (function :tag "other" nil))))
163
164 (defcustom gnus-group-line-format "%M\%S\%p\%P\%5y:%B%(%g%)\n"
165   "*Format of group lines.
166 It works along the same lines as a normal formatting string,
167 with some simple extensions.
168
169 %M    Only marked articles (character, \"*\" or \" \")
170 %S    Whether the group is subscribed (character, \"U\", \"K\", \"Z\" or \" \")
171 %L    Level of subscribedness (integer)
172 %N    Number of unread articles (integer)
173 %I    Number of dormant articles (integer)
174 %i    Number of ticked and dormant (integer)
175 %T    Number of ticked articles (integer)
176 %R    Number of read articles (integer)
177 %U    Number of unseen articles (integer)
178 %t    Estimated total number of articles (integer)
179 %y    Number of unread, unticked articles (integer)
180 %G    Group name (string)
181 %g    Qualified group name (string)
182 %c    Short (collapsed) group name.  See `gnus-group-uncollapsed-levels'.
183 %C    Group comment (string)
184 %D    Group description (string)
185 %s    Select method (string)
186 %o    Moderated group (char, \"m\")
187 %p    Process mark (char)
188 %B    Whether a summary buffer for the group is open (char, \"*\")
189 %O    Moderated group (string, \"(m)\" or \"\")
190 %P    Topic indentation (string)
191 %m    Whether there is new(ish) mail in the group (char, \"%\")
192 %n    Select from where (string)
193 %z    A string that look like `<%s:%n>' if a foreign select method is used
194 %d    The date the group was last entered.
195 %E    Icon as defined by `gnus-group-icon-list'.
196 %F    The disk space used by the articles fetched by both the cache and agent.
197 %u    User defined specifier.  The next character in the format string should
198       be a letter.  Gnus will call the function gnus-user-format-function-X,
199       where X is the letter following %u.  The function will be passed a
200       single dummy parameter as argument.  The function should return a
201       string, which will be inserted into the buffer just like information
202       from any other group specifier.
203
204 Note that this format specification is not always respected.  For
205 reasons of efficiency, when listing killed groups, this specification
206 is ignored altogether.  If the spec is changed considerably, your
207 output may end up looking strange when listing both alive and killed
208 groups.
209
210 If you use %o or %O, reading the active file will be slower and quite
211 a bit of extra memory will be used.  %D and %F will also worsen
212 performance.  Also note that if you change the format specification to
213 include any of these specs, you must probably re-start Gnus to see
214 them go into effect.
215
216 General format specifiers can also be used.
217 See Info node `(gnus)Formatting Variables'."
218   :link '(custom-manual "(gnus)Formatting Variables")
219   :group 'gnus-group-visual
220   :type 'string)
221
222 (defcustom gnus-group-mode-line-format "Gnus: %%b {%M\%:%S}"
223   "*The format specification for the group mode line.
224 It works along the same lines as a normal formatting string,
225 with some simple extensions:
226
227 %S   The native news server.
228 %M   The native select method.
229 %:   \":\" if %S isn't \"\"."
230   :group 'gnus-group-visual
231   :type 'string)
232
233 ;; Extracted from gnus-xmas-redefine in order to preserve user settings
234 (when (featurep 'xemacs)
235   (add-hook 'gnus-group-mode-hook 'gnus-xmas-group-menu-add)
236   (add-hook 'gnus-group-mode-hook 'gnus-xmas-setup-group-toolbar))
237
238 (defcustom gnus-group-menu-hook nil
239   "Hook run after the creation of the group mode menu."
240   :group 'gnus-group-various
241   :type 'hook)
242
243 (defcustom gnus-group-catchup-group-hook nil
244   "Hook run when catching up a group from the group buffer."
245   :group 'gnus-group-various
246   :link '(custom-manual "(gnus)Group Data")
247   :type 'hook)
248
249 (defcustom gnus-group-update-group-hook nil
250   "Hook called when updating group lines."
251   :group 'gnus-group-visual
252   :type 'hook)
253
254 (defcustom gnus-group-prepare-function 'gnus-group-prepare-flat
255   "*A function that is called to generate the group buffer.
256 The function is called with three arguments: The first is a number;
257 all group with a level less or equal to that number should be listed,
258 if the second is non-nil, empty groups should also be displayed.  If
259 the third is non-nil, it is a number.  No groups with a level lower
260 than this number should be displayed.
261
262 The only current function implemented is `gnus-group-prepare-flat'."
263   :group 'gnus-group-listing
264   :type 'function)
265
266 (defcustom gnus-group-prepare-hook nil
267   "Hook called after the group buffer has been generated.
268 If you want to modify the group buffer, you can use this hook."
269   :group 'gnus-group-listing
270   :type 'hook)
271
272 (defcustom gnus-suspend-gnus-hook nil
273   "Hook called when suspending (not exiting) Gnus."
274   :group 'gnus-exit
275   :type 'hook)
276
277 (defcustom gnus-exit-gnus-hook nil
278   "Hook called when exiting Gnus."
279   :group 'gnus-exit
280   :type 'hook)
281
282 (defcustom gnus-after-exiting-gnus-hook nil
283   "Hook called after exiting Gnus."
284   :group 'gnus-exit
285   :type 'hook)
286
287 (defcustom gnus-group-update-hook nil
288   "Hook called when a group line is changed."
289   :group 'gnus-group-visual
290   :version "24.1"
291   :type 'hook)
292
293 (defcustom gnus-useful-groups
294   '(("(ding) mailing list mirrored at gmane.org"
295      "gmane.emacs.gnus.general"
296      (nntp "Gmane"
297            (nntp-address "news.gmane.org")))
298     ("Gnus bug archive"
299      "gnus.gnus-bug"
300      (nntp "news.gnus.org"
301            (nntp-address "news.gnus.org")))
302     ("Local Gnus help group"
303      "gnus-help"
304      (nndoc "gnus-help"
305             (nndoc-article-type mbox)
306             (eval `(nndoc-address
307                     ,(let ((file (nnheader-find-etc-directory
308                                   "gnus-tut.txt" t)))
309                        (unless file
310                          (error "Couldn't find doc group"))
311                        file))))))
312   "*Alist of useful group-server pairs."
313   :group 'gnus-group-listing
314   :type '(repeat (list (string :tag "Description")
315                        (string :tag "Name")
316                        (sexp :tag "Method"))))
317
318 (defcustom gnus-group-highlight
319   '(;; Mail.
320     ((and mailp (= unread 0) (eq level 1)) .
321      gnus-group-mail-1-empty)
322     ((and mailp (eq level 1)) .
323      gnus-group-mail-1)
324     ((and mailp (= unread 0) (eq level 2)) .
325      gnus-group-mail-2-empty)
326     ((and mailp (eq level 2)) .
327      gnus-group-mail-2)
328     ((and mailp (= unread 0) (eq level 3)) .
329      gnus-group-mail-3-empty)
330     ((and mailp (eq level 3)) .
331      gnus-group-mail-3)
332     ((and mailp (= unread 0)) .
333      gnus-group-mail-low-empty)
334     ((and mailp) .
335      gnus-group-mail-low)
336     ;; News.
337     ((and (= unread 0) (eq level 1)) .
338      gnus-group-news-1-empty)
339     ((and (eq level 1)) .
340      gnus-group-news-1)
341     ((and (= unread 0) (eq level 2)) .
342      gnus-group-news-2-empty)
343     ((and (eq level 2)) .
344      gnus-group-news-2)
345     ((and (= unread 0) (eq level 3)) .
346      gnus-group-news-3-empty)
347     ((and (eq level 3)) .
348      gnus-group-news-3)
349     ((and (= unread 0) (eq level 4)) .
350      gnus-group-news-4-empty)
351     ((and (eq level 4)) .
352      gnus-group-news-4)
353     ((and (= unread 0) (eq level 5)) .
354      gnus-group-news-5-empty)
355     ((and (eq level 5)) .
356      gnus-group-news-5)
357     ((and (= unread 0) (eq level 6)) .
358      gnus-group-news-6-empty)
359     ((and (eq level 6)) .
360      gnus-group-news-6)
361     ((and (= unread 0)) .
362      gnus-group-news-low-empty)
363     (t .
364      gnus-group-news-low))
365   "*Controls the highlighting of group buffer lines.
366
367 Below is a list of `Form'/`Face' pairs.  When deciding how a a
368 particular group line should be displayed, each form is
369 evaluated.  The content of the face field after the first true form is
370 used.  You can change how those group lines are displayed by
371 editing the face field.
372
373 It is also possible to change and add form fields, but currently that
374 requires an understanding of Lisp expressions.  Hopefully this will
375 change in a future release.  For now, you can use the following
376 variables in the Lisp expression:
377
378 group: The name of the group.
379 unread: The number of unread articles in the group.
380 method: The select method used.
381 mailp: Whether it's a mail group or not.
382 level: The level of the group.
383 score: The score of the group.
384 ticked: The number of ticked articles."
385   :group 'gnus-group-visual
386   :type '(repeat (cons (sexp :tag "Form") face)))
387 (put 'gnus-group-highlight 'risky-local-variable t)
388
389 (defcustom gnus-new-mail-mark ?%
390   "Mark used for groups with new mail."
391   :group 'gnus-group-visual
392   :type 'character)
393
394 (defgroup gnus-group-icons nil
395   "Add Icons to your group buffer."
396   :group 'gnus-group-visual)
397
398 (defcustom gnus-group-icon-list
399   nil
400   "*Controls the insertion of icons into group buffer lines.
401
402 Below is a list of `Form'/`File' pairs.  When deciding how a
403 particular group line should be displayed, each form is evaluated.
404 The icon from the file field after the first true form is used.  You
405 can change how those group lines are displayed by editing the file
406 field.  The File will either be found in the
407 `gnus-group-glyph-directory' or by designating absolute name of the
408 file.
409
410 It is also possible to change and add form fields, but currently that
411 requires an understanding of Lisp expressions.  Hopefully this will
412 change in a future release.  For now, you can use the following
413 variables in the Lisp expression:
414
415 group: The name of the group.
416 unread: The number of unread articles in the group.
417 method: The select method used.
418 mailp: Whether it's a mail group or not.
419 level: The level of the group.
420 score: The score of the group.
421 ticked: The number of ticked articles."
422   :group 'gnus-group-icons
423   :type '(repeat (cons (sexp :tag "Form") file)))
424 (put 'gnus-group-icon-list 'risky-local-variable t)
425
426 (defcustom gnus-group-name-charset-method-alist nil
427   "Alist of method and the charset for group names.
428
429 For example:
430     (((nntp \"news.com.cn\") . cn-gb-2312))"
431   :version "21.1"
432   :group 'gnus-charset
433   :type '(repeat (cons (sexp :tag "Method") (symbol :tag "Charset"))))
434
435 (defcustom gnus-group-name-charset-group-alist
436   (if (or (and (fboundp 'find-coding-system) (find-coding-system 'utf-8))
437           (mm-coding-system-p 'utf-8))
438       '((".*" . utf-8))
439     nil)
440   "Alist of group regexp and the charset for group names.
441
442 For example:
443     ((\"\\.com\\.cn:\" . cn-gb-2312))"
444   :group 'gnus-charset
445   :type '(repeat (cons (regexp :tag "Group") (symbol :tag "Charset"))))
446
447 (defcustom gnus-group-jump-to-group-prompt nil
448   "Default prompt for `gnus-group-jump-to-group'.
449
450 If non-nil, the value should be a string or an alist.  If it is a string,
451 e.g. \"nnml:\", in which case `gnus-group-jump-to-group' offers \"Group:
452 nnml:\" in the minibuffer prompt.
453
454 If it is an alist, it must consist of \(NUMBER .  PROMPT\) pairs, for example:
455 \((1 .  \"\") (2 .  \"nnfolder+archive:\")).  The element with number 0 is
456 used when no prefix argument is given to `gnus-group-jump-to-group'."
457   :version "22.1"
458   :group 'gnus-group-various
459   :type '(choice (string :tag "Prompt string")
460                  (const :tag "Empty" nil)
461                  (repeat (cons (integer :tag "Argument")
462                                (string :tag "Prompt string")))))
463
464 (defvar gnus-group-listing-limit 1000
465   "*A limit of the number of groups when listing.
466 If the number of groups is larger than the limit, list them in a
467 simple manner.")
468
469 ;;; Internal variables
470
471 (defvar gnus-group-is-exiting-p nil)
472 (defvar gnus-group-is-exiting-without-update-p nil)
473 (defvar gnus-group-sort-alist-function 'gnus-group-sort-flat
474   "Function for sorting the group buffer.")
475
476 (defvar gnus-group-sort-selected-function 'gnus-group-sort-selected-flat
477   "Function for sorting the selected groups in the group buffer.")
478
479 (defvar gnus-group-indentation-function nil)
480 (defvar gnus-goto-missing-group-function nil)
481 (defvar gnus-group-update-group-function nil)
482 (defvar gnus-group-goto-next-group-function nil
483   "Function to override finding the next group after listing groups.")
484
485 (defvar gnus-group-edit-buffer nil)
486
487 (defvar gnus-group-line-format-alist
488   `((?M gnus-tmp-marked-mark ?c)
489     (?S gnus-tmp-subscribed ?c)
490     (?L gnus-tmp-level ?d)
491     (?N (cond ((eq number t) "*" )
492               ((numberp number)
493                (int-to-string
494                 (+ number
495                    (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked)))
496                    (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))))))
497               (t number)) ?s)
498     (?R gnus-tmp-number-of-read ?s)
499     (?U (if (gnus-active gnus-tmp-group)
500             (gnus-number-of-unseen-articles-in-group gnus-tmp-group)
501           "*")
502         ?s)
503     (?t gnus-tmp-number-total ?d)
504     (?y gnus-tmp-number-of-unread ?s)
505     (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d)
506     (?T (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))) ?d)
507     (?i (+ (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked)))
508            (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))) ?d)
509     (?g (if (boundp 'gnus-tmp-decoded-group)
510             gnus-tmp-decoded-group
511           gnus-tmp-group)
512         ?s)
513     (?G gnus-tmp-qualified-group ?s)
514     (?c (gnus-short-group-name (if (boundp 'gnus-tmp-decoded-group)
515                                    gnus-tmp-decoded-group
516                                  gnus-tmp-group))
517         ?s)
518     (?C gnus-tmp-comment ?s)
519     (?D gnus-tmp-newsgroup-description ?s)
520     (?o gnus-tmp-moderated ?c)
521     (?O gnus-tmp-moderated-string ?s)
522     (?p gnus-tmp-process-marked ?c)
523     (?s gnus-tmp-news-server ?s)
524     (?n ,(if (featurep 'xemacs)
525              '(symbol-name gnus-tmp-news-method)
526            'gnus-tmp-news-method)
527         ?s)
528     (?P gnus-group-indentation ?s)
529     (?E gnus-tmp-group-icon ?s)
530     (?B gnus-tmp-summary-live ?c)
531     (?z gnus-tmp-news-method-string ?s)
532     (?m (gnus-group-new-mail gnus-tmp-group) ?c)
533     (?d (gnus-group-timestamp-string gnus-tmp-group) ?s)
534     (?u gnus-tmp-user-defined ?s)
535     (?F (gnus-total-fetched-for gnus-tmp-group) ?s)
536     ))
537
538 (defvar gnus-group-mode-line-format-alist
539   `((?S gnus-tmp-news-server ?s)
540     (?M gnus-tmp-news-method ?s)
541     (?u gnus-tmp-user-defined ?s)
542     (?: gnus-tmp-colon ?s)))
543
544 (defvar gnus-topic-topology nil
545   "The complete topic hierarchy.")
546
547 (defvar gnus-topic-alist nil
548   "The complete topic-group alist.")
549
550 (defvar gnus-group-marked nil)
551
552 (defvar gnus-group-list-mode nil)
553
554
555 (defvar gnus-group-listed-groups nil)
556 (defvar gnus-group-list-option nil)
557
558 ;;;
559 ;;; Gnus group mode
560 ;;;
561
562 (put 'gnus-group-mode 'mode-class 'special)
563
564 (gnus-define-keys gnus-group-mode-map
565   " " gnus-group-read-group
566   "=" gnus-group-select-group
567   "\r" gnus-group-select-group
568   "\M-\r" gnus-group-quick-select-group
569   "\M- " gnus-group-visible-select-group
570   [(meta control return)] gnus-group-select-group-ephemerally
571   "j" gnus-group-jump-to-group
572   "n" gnus-group-next-unread-group
573   "p" gnus-group-prev-unread-group
574   "\177" gnus-group-prev-unread-group
575   [delete] gnus-group-prev-unread-group
576   [backspace] gnus-group-prev-unread-group
577   "N" gnus-group-next-group
578   "P" gnus-group-prev-group
579   "\M-n" gnus-group-next-unread-group-same-level
580   "\M-p" gnus-group-prev-unread-group-same-level
581   "," gnus-group-best-unread-group
582   "." gnus-group-first-unread-group
583   "u" gnus-group-unsubscribe-current-group
584   "U" gnus-group-unsubscribe-group
585   "c" gnus-group-catchup-current
586   "C" gnus-group-catchup-current-all
587   "\M-c" gnus-group-clear-data
588   "l" gnus-group-list-groups
589   "L" gnus-group-list-all-groups
590   "m" gnus-group-mail
591   "i" gnus-group-news
592   "g" gnus-group-get-new-news
593   "\M-g" gnus-group-get-new-news-this-group
594   "R" gnus-group-restart
595   "r" gnus-group-read-init-file
596   "B" gnus-group-browse-foreign-server
597   "b" gnus-group-check-bogus-groups
598   "F" gnus-group-find-new-groups
599   "\C-c\C-d" gnus-group-describe-group
600   "\M-d" gnus-group-describe-all-groups
601   "\C-c\C-a" gnus-group-apropos
602   "\C-c\M-\C-a" gnus-group-description-apropos
603   "a" gnus-group-post-news
604   "\ek" gnus-group-edit-local-kill
605   "\eK" gnus-group-edit-global-kill
606   "\C-k" gnus-group-kill-group
607   "\C-y" gnus-group-yank-group
608   "\C-w" gnus-group-kill-region
609   "\C-x\C-t" gnus-group-transpose-groups
610   "\C-c\C-l" gnus-group-list-killed
611   "\C-c\C-x" gnus-group-expire-articles
612   "\C-c\M-\C-x" gnus-group-expire-all-groups
613   "V" gnus-version
614   "s" gnus-group-save-newsrc
615   "z" gnus-group-suspend
616   "q" gnus-group-exit
617   "Q" gnus-group-quit
618   "?" gnus-group-describe-briefly
619   "\C-c\C-i" gnus-info-find-node
620   "\M-e" gnus-group-edit-group-method
621   "^" gnus-group-enter-server-mode
622   gnus-mouse-2 gnus-mouse-pick-group
623   [follow-link] mouse-face
624   "<" beginning-of-buffer
625   ">" end-of-buffer
626   "\C-c\C-b" gnus-bug
627   "\C-c\C-s" gnus-group-sort-groups
628   "t" gnus-topic-mode
629   "\C-c\M-g" gnus-activate-all-groups
630   "\M-&" gnus-group-universal-argument
631   "#" gnus-group-mark-group
632   "\M-#" gnus-group-unmark-group)
633
634 (gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map)
635   "m" gnus-group-mark-group
636   "u" gnus-group-unmark-group
637   "w" gnus-group-mark-region
638   "b" gnus-group-mark-buffer
639   "r" gnus-group-mark-regexp
640   "U" gnus-group-unmark-all-groups)