From be244f4efb094df474691425180abe8c61ff3b1c Mon Sep 17 00:00:00 2001 From: Andrew Cohen Date: Mon, 13 Dec 2010 18:33:02 -0500 Subject: [PATCH] gnus.texi: First very rough pass at nnir documentation. --- texi/ChangeLog | 4 + texi/gnus.texi | 28256 ++++++++++++++++++++++++----------------------- 2 files changed, 14303 insertions(+), 13957 deletions(-) diff --git a/texi/ChangeLog b/texi/ChangeLog index 7b3693520..b839589d9 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,7 @@ +2010-12-13 Andrew Cohen + + * gnus.texi: First pass at adding (rough) nnir documentation. + 2010-12-13 Lars Magne Ingebrigtsen * gnus.texi (Filtering New Groups): Mention diff --git a/texi/gnus.texi b/texi/gnus.texi index 920bc1c63..2e8ae8664 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -407,6 +407,7 @@ This manual corresponds to No Gnus v0.11. * Composing Messages:: Information on sending mail and news. * Select Methods:: Gnus reads all messages from various select methods. * Scoring:: Assigning values to articles. +* Searching:: Mail and News search engines. * Various:: General purpose settings. * The End:: Farewell and goodbye. * Appendices:: Terminology, Emacs intro, @acronym{FAQ}, History, Internals. @@ -785,6 +786,21 @@ Advanced Scoring * Advanced Scoring Examples:: What they look like. * Advanced Scoring Tips:: Getting the most out of it. +Searching + +* nnir:: Searching with various engines. +* nnmairix:: Searching with Mairix. + +nnir + +* What is nnir:: What does nnir do. +* Basic Usage:: How to perform simple searches. +* Setting up nnir:: How to set up nnir. + +Setting up nnir + +* Associating Engines:: How to associate engines. + Various * Process/Prefix:: A convention used by many treatment commands. @@ -1660,7 +1676,6 @@ long as Gnus is active. * Exiting Gnus:: Stop reading news and get some work done. * Group Topics:: A folding group mode divided into topics. * Non-ASCII Group Names:: Accessing groups of non-English names. -* Searching:: Mail search engines. * Misc Group Stuff:: Other stuff that you can to do. @end menu @@ -4282,17414 +4297,17741 @@ names should be the same in both groups. Otherwise the Newsgroups header will be displayed incorrectly in the article buffer. -@node Searching -@section Searching +@node Misc Group Stuff +@section Misc Group Stuff @menu -* nnir:: Searching on IMAP, with swish, namazu, etc. -* nnmairix:: Searching maildir, MH or mbox with Mairix. +* Scanning New Messages:: Asking Gnus to see whether new messages have arrived. +* Group Information:: Information and help on groups and Gnus. +* Group Timestamp:: Making Gnus keep track of when you last read a group. +* File Commands:: Reading and writing the Gnus files. +* Sieve Commands:: Managing Sieve scripts. @end menu -@cindex Searching +@table @kbd -FIXME: This node is a stub. +@item v +@kindex v (Group) +@cindex keys, reserved for users (Group) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. For example: -FIXME: Add a brief overview of Gnus search capabilities. A brief -comparison of nnir, nnmairix, contrib/gnus-namazu would be nice -as well. +@lisp +(define-key gnus-group-mode-map (kbd "v j d") + (lambda () + (interactive) + (gnus-group-jump-to-group "nndraft:drafts"))) +@end lisp -FIXME: Explain difference to @ref{Searching for Articles}, add reference -and back-reference. +On keys reserved for users in Emacs and on keybindings in general +@xref{Keymaps, Keymaps, , emacs, The Emacs Editor}. -@node nnir -@subsection nnir +@item ^ +@kindex ^ (Group) +@findex gnus-group-enter-server-mode +Enter the server buffer (@code{gnus-group-enter-server-mode}). +@xref{Server Buffer}. -FIXME: As a first step, convert the commentary of @file{nnir} to texi. -@cindex nnir +@item a +@kindex a (Group) +@findex gnus-group-post-news +Start composing a message (a news by default) +(@code{gnus-group-post-news}). If given a prefix, post to the group +under the point. If the prefix is 1, prompt for a group to post to. +Contrary to what the name of this function suggests, the prepared +article might be a mail instead of a news, if a mail group is specified +with the prefix argument. @xref{Composing Messages}. -@node nnmairix -@subsection nnmairix +@item m +@kindex m (Group) +@findex gnus-group-mail +Mail a message somewhere (@code{gnus-group-mail}). If given a prefix, +use the posting style of the group under the point. If the prefix is 1, +prompt for a group name to find the posting style. +@xref{Composing Messages}. -@cindex mairix -@cindex nnmairix -This paragraph describes how to set up mairix and the back end -@code{nnmairix} for indexing and searching your mail from within -Gnus. Additionally, you can create permanent ``smart'' groups which are -bound to mairix searches and are automatically updated. +@item i +@kindex i (Group) +@findex gnus-group-news +Start composing a news (@code{gnus-group-news}). If given a prefix, +post to the group under the point. If the prefix is 1, prompt +for group to post to. @xref{Composing Messages}. -@menu -* About mairix:: About the mairix mail search engine -* nnmairix requirements:: What you will need for using nnmairix -* What nnmairix does:: What does nnmairix actually do? -* Setting up mairix:: Set up your mairix installation -* Configuring nnmairix:: Set up the nnmairix back end -* nnmairix keyboard shortcuts:: List of available keyboard shortcuts -* Propagating marks:: How to propagate marks from nnmairix groups -* nnmairix tips and tricks:: Some tips, tricks and examples -* nnmairix caveats:: Some more stuff you might want to know -@end menu +This function actually prepares a news even when using mail groups. +This is useful for ``posting'' messages to mail groups without actually +sending them over the network: they're just saved directly to the group +in question. The corresponding back end must have a request-post method +for this to work though. -@c FIXME: The markup in this section might need improvement. -@c E.g. adding @samp, @var, @file, @command, etc. -@c Cf. (info "(texinfo)Indicating") +@item G z +@kindex G z (Group) +@findex gnus-group-compact-group -@node About mairix -@subsubsection About mairix +Compact the group under point (@code{gnus-group-compact-group}). +Currently implemented only in nnml (@pxref{Mail Spool}). This removes +gaps between article numbers, hence getting a correct total article +count. -Mairix is a tool for indexing and searching words in locally stored -mail. It was written by Richard Curnow and is licensed under the -GPL. Mairix comes with most popular GNU/Linux distributions, but it also -runs under Windows (with cygwin), Mac OS X and Solaris. The homepage can -be found at -@uref{http://www.rpcurnow.force9.co.uk/mairix/index.html} +@end table -Though mairix might not be as flexible as other search tools like -swish++ or namazu, which you can use via the @code{nnir} back end, it -has the prime advantage of being incredibly fast. On current systems, it -can easily search through headers and message bodies of thousands and -thousands of mails in well under a second. Building the database -necessary for searching might take a minute or two, but only has to be -done once fully. Afterwards, the updates are done incrementally and -therefore are really fast, too. Additionally, mairix is very easy to set -up. +Variables for the group buffer: -For maximum speed though, mairix should be used with mails stored in -@code{Maildir} or @code{MH} format (this includes the @code{nnml} back -end), although it also works with mbox. Mairix presents the search -results by populating a @emph{virtual} maildir/MH folder with symlinks -which point to the ``real'' message files (if mbox is used, copies are -made). Since mairix already presents search results in such a virtual -mail folder, it is very well suited for using it as an external program -for creating @emph{smart} mail folders, which represent certain mail -searches. +@table @code -@node nnmairix requirements -@subsubsection nnmairix requirements +@item gnus-group-mode-hook +@vindex gnus-group-mode-hook +is called after the group buffer has been +created. -Mairix searches local mail---that means, mairix absolutely must have -direct access to your mail folders. If your mail resides on another -server (e.g. an @acronym{IMAP} server) and you happen to have shell -access, @code{nnmairix} supports running mairix remotely, e.g. via ssh. +@item gnus-group-prepare-hook +@vindex gnus-group-prepare-hook +is called after the group buffer is +generated. It may be used to modify the buffer in some strange, +unnatural way. -Additionally, @code{nnmairix} only supports the following Gnus back -ends: @code{nnml}, @code{nnmaildir}, and @code{nnimap}. You must use -one of these back ends for using @code{nnmairix}. Other back ends, like -@code{nnmbox}, @code{nnfolder} or @code{nnmh}, won't work. +@item gnus-group-prepared-hook +@vindex gnus-group-prepare-hook +is called as the very last thing after the group buffer has been +generated. It may be used to move point around, for instance. -If you absolutely must use mbox and still want to use @code{nnmairix}, -you can set up a local @acronym{IMAP} server, which you then access via -@code{nnimap}. This is a rather massive setup for accessing some mbox -files, so just change to MH or Maildir already... However, if you're -really, really passionate about using mbox, you might want to look into -the package @file{mairix.el}, which comes with Emacs 23. +@item gnus-permanently-visible-groups +@vindex gnus-permanently-visible-groups +Groups matching this regexp will always be listed in the group buffer, +whether they are empty or not. -@node What nnmairix does -@subsubsection What nnmairix does +@end table -The back end @code{nnmairix} enables you to call mairix from within Gnus, -either to query mairix with a search term or to update the -database. While visiting a message in the summary buffer, you can use -several pre-defined shortcuts for calling mairix, e.g. to quickly -search for all mails from the sender of the current message or to -display the whole thread associated with the message, even if the -mails are in different folders. +@node Scanning New Messages +@subsection Scanning New Messages +@cindex new messages +@cindex scanning new news -Additionally, you can create permanent @code{nnmairix} groups which are bound -to certain mairix searches. This way, you can easily create a group -containing mails from a certain sender, with a certain subject line or -even for one specific thread based on the Message-ID. If you check for -new mail in these folders (e.g. by pressing @kbd{g} or @kbd{M-g}), they -automatically update themselves by calling mairix. +@table @kbd -You might ask why you need @code{nnmairix} at all, since mairix already -creates the group, populates it with links to the mails so that you can -then access it with Gnus, right? Well, this @emph{might} work, but often -does not---at least not without problems. Most probably you will get -strange article counts, and sometimes you might see mails which Gnus -claims have already been canceled and are inaccessible. This is due to -the fact that Gnus isn't really amused when things are happening behind -its back. Another problem can be the mail back end itself, e.g. if you -use mairix with an @acronym{IMAP} server (I had Dovecot complaining -about corrupt index files when mairix changed the contents of the search -group). Using @code{nnmairix} should circumvent these problems. +@item g +@kindex g (Group) +@findex gnus-group-get-new-news +@c @icon{gnus-group-get-new-news} +Check the server(s) for new articles. If the numerical prefix is used, +this command will check only groups of level @var{arg} and lower +(@code{gnus-group-get-new-news}). If given a non-numerical prefix, this +command will force a total re-reading of the active file(s) from the +back end(s). -@code{nnmairix} is not really a mail back end---it's actually more like -a wrapper, sitting between a ``real'' mail back end where mairix stores -the searches and the Gnus front end. You can choose between three -different mail back ends for the mairix folders: @code{nnml}, -@code{nnmaildir} or @code{nnimap}. @code{nnmairix} will call the mairix -binary so that the search results are stored in folders named -@code{zz_mairix--} on this mail back end, but it will -present these folders in the Gnus front end only with @code{}. -You can use an existing mail back end where you already store your mail, -but if you're uncomfortable with @code{nnmairix} creating new mail -groups alongside your other mail, you can also create e.g. a new -@code{nnmaildir} or @code{nnml} server exclusively for mairix, but then -make sure those servers do not accidentally receive your new mail -(@pxref{nnmairix caveats}). A special case exists if you want to use -mairix remotely on an IMAP server with @code{nnimap}---here the mairix -folders and your other mail must be on the same @code{nnimap} back end. +@item M-g +@kindex M-g (Group) +@findex gnus-group-get-new-news-this-group +@vindex gnus-goto-next-group-when-activating +@c @icon{gnus-group-get-new-news-this-group} +Check whether new articles have arrived in the current group +(@code{gnus-group-get-new-news-this-group}). +@code{gnus-goto-next-group-when-activating} says whether this command is +to move point to the next group or not. It is @code{t} by default. -@node Setting up mairix -@subsubsection Setting up mairix +@findex gnus-activate-all-groups +@cindex activating groups +@item C-c M-g +@kindex C-c M-g (Group) +Activate absolutely all groups (@code{gnus-activate-all-groups}). -First: create a backup of your mail folders (@pxref{nnmairix caveats}). +@item R +@kindex R (Group) +@cindex restarting +@findex gnus-group-restart +Restart Gnus (@code{gnus-group-restart}). This saves the @file{.newsrc} +file(s), closes the connection to all servers, clears up all run-time +Gnus variables, and then starts Gnus all over again. -Setting up mairix is easy: simply create a @file{.mairixrc} file with -(at least) the following entries: +@end table -@example -# Your Maildir/MH base folder -base=~/Maildir -@end example +@vindex gnus-get-new-news-hook +@code{gnus-get-new-news-hook} is run just before checking for new news. -This is the base folder for your mails. All the following directories -are relative to this base folder. If you want to use @code{nnmairix} -with @code{nnimap}, this base directory has to point to the mail -directory where the @acronym{IMAP} server stores the mail folders! +@vindex gnus-after-getting-new-news-hook +@code{gnus-after-getting-new-news-hook} is run after checking for new +news. -@example -maildir= ... your maildir folders which should be indexed ... -mh= ... your nnml/mh folders which should be indexed ... -mbox = ... your mbox files which should be indexed ... -@end example -This specifies all your mail folders and mbox files (relative to the -base directory!) you want to index with mairix. Note that the -@code{nnml} back end saves mails in MH format, so you have to put those -directories in the @code{mh} line. See the example at the end of this -section and mairixrc's man-page for further details. +@node Group Information +@subsection Group Information +@cindex group information +@cindex information on groups -@example -omit=zz_mairix-* -@end example +@table @kbd -@vindex nnmairix-group-prefix -This should make sure that you don't accidentally index the mairix -search results. You can change the prefix of these folders with the -variable @code{nnmairix-group-prefix}. -@example -mformat= ... 'maildir' or 'mh' ... -database= ... location of database file ... -@end example +@item H f +@kindex H f (Group) +@findex gnus-group-fetch-faq +@vindex gnus-group-faq-directory +@cindex FAQ +@cindex ange-ftp +Try to fetch the @acronym{FAQ} for the current group +(@code{gnus-group-fetch-faq}). Gnus will try to get the @acronym{FAQ} +from @code{gnus-group-faq-directory}, which is usually a directory on +a remote machine. This variable can also be a list of directories. +In that case, giving a prefix to this command will allow you to choose +between the various sites. @code{ange-ftp} (or @code{efs}) will be +used for fetching the file. -The @code{format} setting specifies the output format for the mairix -search folder. Set this to @code{mh} if you want to access search results -with @code{nnml}. Otherwise choose @code{maildir}. +If fetching from the first site is unsuccessful, Gnus will attempt to go +through @code{gnus-group-faq-directory} and try to open them one by one. -To summarize, here is my shortened @file{.mairixrc} file as an example: +@item H d +@itemx C-c C-d +@c @icon{gnus-group-describe-group} +@kindex H d (Group) +@kindex C-c C-d (Group) +@cindex describing groups +@cindex group description +@findex gnus-group-describe-group +Describe the current group (@code{gnus-group-describe-group}). If given +a prefix, force Gnus to re-read the description from the server. -@example -base=~/Maildir -maildir=.personal:.work:.logcheck:.sent -mh=../Mail/nnml/*... -mbox=../mboxmail/mailarchive_year* -mformat=maildir -omit=zz_mairix-* -database=~/.mairixdatabase -@end example +@item M-d +@kindex M-d (Group) +@findex gnus-group-describe-all-groups +Describe all groups (@code{gnus-group-describe-all-groups}). If given a +prefix, force Gnus to re-read the description file from the server. -In this case, the base directory is @file{~/Maildir}, where all my Maildir -folders are stored. As you can see, the folders are separated by -colons. If you wonder why every folder begins with a dot: this is -because I use Dovecot as @acronym{IMAP} server, which again uses -@code{Maildir++} folders. For testing nnmairix, I also have some -@code{nnml} mail, which is saved in @file{~/Mail/nnml}. Since this has -to be specified relative to the @code{base} directory, the @code{../Mail} -notation is needed. Note that the line ends in @code{*...}, which means -to recursively scan all files under this directory. Without the three -dots, the wildcard @code{*} will not work recursively. I also have some -old mbox files with archived mail lying around in @file{~/mboxmail}. -The other lines should be obvious. +@item H v +@itemx V +@kindex V (Group) +@kindex H v (Group) +@cindex version +@findex gnus-version +Display current Gnus version numbers (@code{gnus-version}). -See the man page for @code{mairixrc} for details and further options, -especially regarding wildcard usage, which may be a little different -than you are used to. +@item ? +@kindex ? (Group) +@findex gnus-group-describe-briefly +Give a very short help message (@code{gnus-group-describe-briefly}). -Now simply call @code{mairix} to create the index for the first time. -Note that this may take a few minutes, but every following index will do -the updates incrementally and hence is very fast. +@item C-c C-i +@kindex C-c C-i (Group) +@cindex info +@cindex manual +@findex gnus-info-find-node +Go to the Gnus info node (@code{gnus-info-find-node}). +@end table -@node Configuring nnmairix -@subsubsection Configuring nnmairix -In group mode, type @kbd{G b c} -(@code{nnmairix-create-server-and-default-group}). This will ask you for all -necessary information and create a @code{nnmairix} server as a foreign -server. You will have to specify the following: +@node Group Timestamp +@subsection Group Timestamp +@cindex timestamps +@cindex group timestamps -@itemize @bullet +It can be convenient to let Gnus keep track of when you last read a +group. To set the ball rolling, you should add +@code{gnus-group-set-timestamp} to @code{gnus-select-group-hook}: -@item -The @strong{name} of the @code{nnmairix} server---choose whatever you -want. +@lisp +(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) +@end lisp -@item -The name of the @strong{back end server} where mairix should store its -searches. This must be a full server name, like @code{nnml:mymail}. -Just hit @kbd{TAB} to see the available servers. Currently, servers -which are accessed through @code{nnmaildir}, @code{nnimap} and -@code{nnml} are supported. As explained above, for locally stored -mails, this can be an existing server where you store your mails. -However, you can also create e.g. a new @code{nnmaildir} or @code{nnml} -server exclusively for @code{nnmairix} in your secondary select methods -(@pxref{Finding the News}). If you use a secondary @code{nnml} server -just for mairix, make sure that you explicitly set the server variable -@code{nnml-get-new-mail} to @code{nil}, or you might lose mail -(@pxref{nnmairix caveats}). If you want to use mairix remotely on an -@acronym{IMAP} server, you have to choose the corresponding -@code{nnimap} server here. +After doing this, each time you enter a group, it'll be recorded. -@item -@vindex nnmairix-mairix-search-options -The @strong{command} to call the mairix binary. This will usually just -be @code{mairix}, but you can also choose something like @code{ssh -SERVER mairix} if you want to call mairix remotely, e.g. on your -@acronym{IMAP} server. If you want to add some default options to -mairix, you could do this here, but better use the variable -@code{nnmairix-mairix-search-options} instead. +This information can be displayed in various ways---the easiest is to +use the @samp{%d} spec in the group line format: -@item -The name of the @strong{default search group}. This will be the group -where all temporary mairix searches are stored, i.e. all searches which -are not bound to permanent @code{nnmairix} groups. Choose whatever you -like. +@lisp +(setq gnus-group-line-format + "%M\%S\%p\%P\%5y: %(%-40,40g%) %d\n") +@end lisp -@item -If the mail back end is @code{nnimap} or @code{nnmaildir}, you will be -asked if you work with @strong{Maildir++}, i.e. with hidden maildir -folders (=beginning with a dot). For example, you have to answer -@samp{yes} here if you work with the Dovecot @acronym{IMAP} -server. Otherwise, you should answer @samp{no} here. +This will result in lines looking like: -@end itemize +@example +* 0: mail.ding 19961002T012943 + 0: custom 19961002T012713 +@end example -@node nnmairix keyboard shortcuts -@subsubsection nnmairix keyboard shortcuts +As you can see, the date is displayed in compact ISO 8601 format. This +may be a bit too much, so to just display the date, you could say +something like: -In group mode: +@lisp +(setq gnus-group-line-format + "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n") +@end lisp -@table @kbd +If you would like greater control of the time format, you can use a +user-defined format spec. Something like the following should do the +trick: -@item G b c -@kindex G b c (Group) -@findex nnmairix-create-server-and-default-group -Creates @code{nnmairix} server and default search group for this server -(@code{nnmairix-create-server-and-default-group}). You should have done -this by now (@pxref{Configuring nnmairix}). +@lisp +(setq gnus-group-line-format + "%M\%S\%p\%P\%5y: %(%-40,40g%) %ud\n") +(defun gnus-user-format-function-d (headers) + (let ((time (gnus-group-timestamp gnus-tmp-group))) + (if time + (format-time-string "%b %d %H:%M" time) + ""))) +@end lisp -@item G b s -@kindex G b s (Group) -@findex nnmairix-search -Prompts for query which is then sent to the mairix binary. Search -results are put into the default search group which is automatically -displayed (@code{nnmairix-search}). -@item G b m -@kindex G b m (Group) -@findex nnmairix-widget-search -Allows you to create a mairix search or a permanent group more -comfortably using graphical widgets, similar to a customization -group. Just try it to see how it works (@code{nnmairix-widget-search}). +@node File Commands +@subsection File Commands +@cindex file commands -@item G b i -@kindex G b i (Group) -@findex nnmairix-search-interactive -Another command for creating a mairix query more comfortably, but uses -only the minibuffer (@code{nnmairix-search-interactive}). +@table @kbd -@item G b g -@kindex G b g (Group) -@findex nnmairix-create-search-group -Creates a permanent group which is associated with a search query -(@code{nnmairix-create-search-group}). The @code{nnmairix} back end -automatically calls mairix when you update this group with @kbd{g} or -@kbd{M-g}. +@item r +@kindex r (Group) +@findex gnus-group-read-init-file +@vindex gnus-init-file +@cindex reading init file +Re-read the init file (@code{gnus-init-file}, which defaults to +@file{~/.gnus.el}) (@code{gnus-group-read-init-file}). -@item G b q -@kindex G b q (Group) -@findex nnmairix-group-change-query-this-group -Changes the search query for the @code{nnmairix} group under cursor -(@code{nnmairix-group-change-query-this-group}). +@item s +@kindex s (Group) +@findex gnus-group-save-newsrc +@cindex saving .newsrc +Save the @file{.newsrc.eld} file (and @file{.newsrc} if wanted) +(@code{gnus-group-save-newsrc}). If given a prefix, force saving the +file(s) whether Gnus thinks it is necessary or not. -@item G b t -@kindex G b t (Group) -@findex nnmairix-group-toggle-threads-this-group -Toggles the 'threads' parameter for the @code{nnmairix} group under cursor, -i.e. if you want see the whole threads of the found messages -(@code{nnmairix-group-toggle-threads-this-group}). +@c @item Z +@c @kindex Z (Group) +@c @findex gnus-group-clear-dribble +@c Clear the dribble buffer (@code{gnus-group-clear-dribble}). -@item G b u -@kindex G b u (Group) -@findex nnmairix-update-database -@vindex nnmairix-mairix-update-options -Calls mairix binary for updating the database -(@code{nnmairix-update-database}). The default parameters are @code{-F} -and @code{-Q} for making this as fast as possible (see variable -@code{nnmairix-mairix-update-options} for defining these default -options). +@end table -@item G b r -@kindex G b r (Group) -@findex nnmairix-group-toggle-readmarks-this-group -Keep articles in this @code{nnmairix} group always read or unread, or leave the -marks unchanged (@code{nnmairix-group-toggle-readmarks-this-group}). -@item G b d -@kindex G b d (Group) -@findex nnmairix-group-delete-recreate-this-group -Recreate @code{nnmairix} group on the ``real'' mail back end -(@code{nnmairix-group-delete-recreate-this-group}). You can do this if -you always get wrong article counts with a @code{nnmairix} group. +@node Sieve Commands +@subsection Sieve Commands +@cindex group sieve commands -@item G b a -@kindex G b a (Group) -@findex nnmairix-group-toggle-allowfast-this-group -Toggles the @code{allow-fast} parameters for group under cursor -(@code{nnmairix-group-toggle-allowfast-this-group}). The default -behavior of @code{nnmairix} is to do a mairix search every time you -update or enter the group. With the @code{allow-fast} parameter set, -mairix will only be called when you explicitly update the group, but not -upon entering. This makes entering the group faster, but it may also -lead to dangling symlinks if something changed between updating and -entering the group which is not yet in the mairix database. +Sieve is a server-side mail filtering language. In Gnus you can use +the @code{sieve} group parameter (@pxref{Group Parameters}) to specify +sieve rules that should apply to each group. Gnus provides two +commands to translate all these group parameters into a proper Sieve +script that can be transfered to the server somehow. -@item G b p -@kindex G b p (Group) -@findex nnmairix-group-toggle-propmarks-this-group -Toggle marks propagation for this group -(@code{nnmairix-group-toggle-propmarks-this-group}). (@pxref{Propagating -marks}). +@vindex gnus-sieve-file +@vindex gnus-sieve-region-start +@vindex gnus-sieve-region-end +The generated Sieve script is placed in @code{gnus-sieve-file} (by +default @file{~/.sieve}). The Sieve code that Gnus generate is placed +between two delimiters, @code{gnus-sieve-region-start} and +@code{gnus-sieve-region-end}, so you may write additional Sieve code +outside these delimiters that will not be removed the next time you +regenerate the Sieve script. -@item G b o -@kindex G b o (Group) -@findex nnmairix-propagate-marks -Manually propagate marks (@code{nnmairix-propagate-marks}); needed only when -@code{nnmairix-propagate-marks-upon-close} is set to @code{nil}. +@vindex gnus-sieve-crosspost +The variable @code{gnus-sieve-crosspost} controls how the Sieve script +is generated. If it is non-@code{nil} (the default) articles is +placed in all groups that have matching rules, otherwise the article +is only placed in the group with the first matching rule. For +example, the group parameter @samp{(sieve address "sender" +"owner-ding@@hpc.uh.edu")} will generate the following piece of Sieve +code if @code{gnus-sieve-crosspost} is @code{nil}. (When +@code{gnus-sieve-crosspost} is non-@code{nil}, it looks the same +except that the line containing the call to @code{stop} is removed.) -@end table +@example +if address "sender" "owner-ding@@hpc.uh.edu" @{ + fileinto "INBOX.ding"; + stop; +@} +@end example -In summary mode: +@xref{Top, Emacs Sieve, Top, sieve, Emacs Sieve}. @table @kbd -@item $ m -@kindex $ m (Summary) -@findex nnmairix-widget-search-from-this-article -Allows you to create a mairix query or group based on the current -message using graphical widgets (same as @code{nnmairix-widget-search}) -(@code{nnmairix-widget-search-from-this-article}). - -@item $ g -@kindex $ g (Summary) -@findex nnmairix-create-search-group-from-message -Interactively creates a new search group with query based on the current -message, but uses the minibuffer instead of graphical widgets -(@code{nnmairix-create-search-group-from-message}). - -@item $ t -@kindex $ t (Summary) -@findex nnmairix-search-thread-this-article -Searches thread for the current article -(@code{nnmairix-search-thread-this-article}). This is effectively a -shortcut for calling @code{nnmairix-search} with @samp{m:msgid} of the -current article and enabled threads. - -@item $ f -@kindex $ f (Summary) -@findex nnmairix-search-from-this-article -Searches all messages from sender of the current article -(@code{nnmairix-search-from-this-article}). This is a shortcut for -calling @code{nnmairix-search} with @samp{f:From}. - -@item $ o -@kindex $ o (Summary) -@findex nnmairix-goto-original-article -(Only in @code{nnmairix} groups!) Tries determine the group this article -originally came from and displays the article in this group, so that -e.g. replying to this article the correct posting styles/group -parameters are applied (@code{nnmairix-goto-original-article}). This -function will use the registry if available, but can also parse the -article file name as a fallback method. +@item D g +@kindex D g (Group) +@findex gnus-sieve-generate +@vindex gnus-sieve-file +@cindex generating sieve script +Regenerate a Sieve script from the @code{sieve} group parameters and +put you into the @code{gnus-sieve-file} without saving it. -@item $ u -@kindex $ u (Summary) -@findex nnmairix-remove-tick-mark-original-article -Remove possibly existing tick mark from original article -(@code{nnmairix-remove-tick-mark-original-article}). (@pxref{nnmairix -tips and tricks}). +@item D u +@kindex D u (Group) +@findex gnus-sieve-update +@vindex gnus-sieve-file +@cindex updating sieve script +Regenerates the Gnus managed part of @code{gnus-sieve-file} using the +@code{sieve} group parameters, save the file and upload it to the +server using the @code{sieveshell} program. @end table -@node Propagating marks -@subsubsection Propagating marks -First of: you really need a patched mairix binary for using the marks -propagation feature efficiently. Otherwise, you would have to update -the mairix database all the time. You can get the patch at +@node Summary Buffer +@chapter Summary Buffer +@cindex summary buffer -@uref{http://www.randomsample.de/mairix-maildir-patch.tar} +A line for each article is displayed in the summary buffer. You can +move around, read articles, post articles and reply to articles. -You need the mairix v0.21 source code for this patch; everything else -is explained in the accompanied readme file. If you don't want to use -marks propagation, you don't have to apply these patches, but they also -fix some annoyances regarding changing maildir flags, so it might still -be useful to you. +The most common way to a summary buffer is to select a group from the +group buffer (@pxref{Selecting a Group}). -With the patched mairix binary, you can use @code{nnmairix} as an -alternative to mail splitting (@pxref{Fancy Mail Splitting}). For -example, instead of splitting all mails from @samp{david@@foobar.com} -into a group, you can simply create a search group with the query -@samp{f:david@@foobar.com}. This is actually what ``smart folders'' are -all about: simply put everything in one mail folder and dynamically -create searches instead of splitting. This is more flexible, since you -can dynamically change your folders any time you want to. This also -implies that you will usually read your mails in the @code{nnmairix} -groups instead of your ``real'' mail groups. +You can have as many summary buffers open as you wish. -There is one problem, though: say you got a new mail from -@samp{david@@foobar.com}; it will now show up in two groups, the -``real'' group (your INBOX, for example) and in the @code{nnmairix} -search group (provided you have updated the mairix database). Now you -enter the @code{nnmairix} group and read the mail. The mail will be -marked as read, but only in the @code{nnmairix} group---in the ``real'' -mail group it will be still shown as unread. +You can customize the Summary Mode tool bar, see @kbd{M-x +customize-apropos RET gnus-summary-tool-bar}. This feature is only +available in Emacs. -You could now catch up the mail group (@pxref{Group Data}), but this is -tedious and error prone, since you may overlook mails you don't have -created @code{nnmairix} groups for. Of course, you could first use -@code{nnmairix-goto-original-article} (@pxref{nnmairix keyboard -shortcuts}) and then read the mail in the original group, but that's -even more cumbersome. +@kindex v (Summary) +@cindex keys, reserved for users (Summary) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. For example: +@lisp +(define-key gnus-summary-mode-map (kbd "v -") "LrS") ;; lower subthread +@end lisp -Clearly, the easiest way would be if marks could somehow be -automatically set for the original article. This is exactly what -@emph{marks propagation} is about. +@menu +* Summary Buffer Format:: Deciding how the summary buffer is to look. +* Summary Maneuvering:: Moving around the summary buffer. +* Choosing Articles:: Reading articles. +* Paging the Article:: Scrolling the current article. +* Reply Followup and Post:: Posting articles. +* Delayed Articles:: Send articles at a later time. +* Marking Articles:: Marking articles as read, expirable, etc. +* Limiting:: You can limit the summary buffer. +* Threading:: How threads are made. +* Sorting the Summary Buffer:: How articles and threads are sorted. +* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. +* Article Caching:: You may store articles in a cache. +* Persistent Articles:: Making articles expiry-resistant. +* Sticky Articles:: Article buffers that are not reused. +* Article Backlog:: Having already read articles hang around. +* Saving Articles:: Ways of customizing article saving. +* Decoding Articles:: Gnus can treat series of (uu)encoded articles. +* Article Treatment:: The article buffer can be mangled at will. +* MIME Commands:: Doing MIMEy things with the articles. +* Charsets:: Character set issues. +* Article Commands:: Doing various things with the article buffer. +* Summary Sorting:: Sorting the summary buffer in various ways. +* Finding the Parent:: No child support? Get the parent. +* Alternative Approaches:: Reading using non-default summaries. +* Tree Display:: A more visual display of threads. +* Mail Group Commands:: Some commands can only be used in mail groups. +* Various Summary Stuff:: What didn't fit anywhere else. +* Exiting the Summary Buffer:: Returning to the Group buffer, + or reselecting the current group. +* Crosspost Handling:: How crossposted articles are dealt with. +* Duplicate Suppression:: An alternative when crosspost handling fails. +* Security:: Decrypt and Verify. +* Mailing List:: Mailing list minor mode. +@end menu -Marks propagation is deactivated by default. You can activate it for a -certain @code{nnmairix} group with -@code{nnmairix-group-toggle-propmarks-this-group} (bound to @kbd{G b -p}). This function will warn you if you try to use it with your default -search group; the reason is that the default search group is used for -temporary searches, and it's easy to accidentally propagate marks from -this group. However, you can ignore this warning if you really want to. -With marks propagation enabled, all the marks you set in a @code{nnmairix} -group should now be propagated to the original article. For example, -you can now tick an article (by default with @kbd{!}) and this mark should -magically be set for the original article, too. +@node Summary Buffer Format +@section Summary Buffer Format +@cindex summary buffer format -A few more remarks which you may or may not want to know: +@iftex +@iflatex +\gnusfigure{The Summary Buffer}{180}{ +\put(0,0){\epsfig{figure=ps/summary,width=7.5cm}} +\put(445,0){\makebox(0,0)[br]{\epsfig{figure=ps/summary-article,width=7.5cm}}} +} +@end iflatex +@end iftex -@vindex nnmairix-propagate-marks-upon-close -Marks will not be set immediately, but only upon closing a group. This -not only makes marks propagation faster, it also avoids problems with -dangling symlinks when dealing with maildir files (since changing flags -will change the file name). You can also control when to propagate marks -via @code{nnmairix-propagate-marks-upon-close} (see the doc-string for -details). +@menu +* Summary Buffer Lines:: You can specify how summary lines should look. +* To From Newsgroups:: How to not display your own name. +* Summary Buffer Mode Line:: You can say how the mode line should look. +* Summary Highlighting:: Making the summary buffer all pretty and nice. +@end menu -Obviously, @code{nnmairix} will have to look up the original group for every -article you want to set marks for. If available, @code{nnmairix} will first use -the registry for determining the original group. The registry is very -fast, hence you should really, really enable the registry when using -marks propagation. If you don't have to worry about RAM and disc space, -set @code{gnus-registry-max-entries} to a large enough value; to be on -the safe side, choose roughly the amount of mails you index with mairix. - -@vindex nnmairix-only-use-registry -If you don't want to use the registry or the registry hasn't seen the -original article yet, @code{nnmairix} will use an additional mairix -search for determining the file name of the article. This, of course, is -way slower than the registry---if you set hundreds or even thousands of -marks this way, it might take some time. You can avoid this situation by -setting @code{nnmairix-only-use-registry} to t. - -Maybe you also want to propagate marks the other way round, i.e. if you -tick an article in a "real" mail group, you'd like to have the same -article in a @code{nnmairix} group ticked, too. For several good -reasons, this can only be done efficiently if you use maildir. To -immediately contradict myself, let me mention that it WON'T work with -@code{nnmaildir}, since @code{nnmaildir} stores the marks externally and -not in the file name. Therefore, propagating marks to @code{nnmairix} -groups will usually only work if you use an IMAP server which uses -maildir as its file format. - -@vindex nnmairix-propagate-marks-to-nnmairix-groups -If you work with this setup, just set -@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t} and see what -happens. If you don't like what you see, just set it to @code{nil} again. One -problem might be that you get a wrong number of unread articles; this -usually happens when you delete or expire articles in the original -groups. When this happens, you can recreate the @code{nnmairix} group on the -back end using @kbd{G b d}. - -@node nnmairix tips and tricks -@subsubsection nnmairix tips and tricks - -@itemize -@item -Checking Mail - -@findex nnmairix-update-groups -I put all my important mail groups at group level 1. The mairix groups -have group level 5, so they do not get checked at start up (@pxref{Group -Levels}). - -I use the following to check for mails: +@findex mail-extract-address-components +@findex gnus-extract-address-components +@vindex gnus-extract-address-components +Gnus will use the value of the @code{gnus-extract-address-components} +variable as a function for getting the name and address parts of a +@code{From} header. Two pre-defined functions exist: +@code{gnus-extract-address-components}, which is the default, quite +fast, and too simplistic solution; and +@code{mail-extract-address-components}, which works very nicely, but is +slower. The default function will return the wrong answer in 5% of the +cases. If this is unacceptable to you, use the other function instead: @lisp -(defun my-check-mail-mairix-update (level) - (interactive "P") - ;; if no prefix given, set level=1 - (gnus-group-get-new-news (or level 1)) - (nnmairix-update-groups "mairixsearch" t t) - (gnus-group-list-groups)) - -(define-key gnus-group-mode-map "g" 'my-check-mail-mairix-update) +(setq gnus-extract-address-components + 'mail-extract-address-components) @end lisp -Instead of @samp{"mairixsearch"} use the name of your @code{nnmairix} -server. See the doc string for @code{nnmairix-update-groups} for -details. - -@item -Example: search group for ticked articles +@vindex gnus-summary-same-subject +@code{gnus-summary-same-subject} is a string indicating that the current +article has the same subject as the previous. This string will be used +with those specs that require it. The default is @code{""}. -For example, you can create a group for all ticked articles, where the -articles always stay unread: -Hit @kbd{G b g}, enter group name (e.g. @samp{important}), use -@samp{F:f} as query and do not include threads. +@node Summary Buffer Lines +@subsection Summary Buffer Lines -Now activate marks propagation for this group by using @kbd{G b p}. Then -activate the always-unread feature by using @kbd{G b r} twice. +@vindex gnus-summary-line-format +You can change the format of the lines in the summary buffer by changing +the @code{gnus-summary-line-format} variable. It works along the same +lines as a normal @code{format} string, with some extensions +(@pxref{Formatting Variables}). -So far so good---but how do you remove the tick marks in the @code{nnmairix} -group? There are two options: You may simply use -@code{nnmairix-remove-tick-mark-original-article} (bound to @kbd{$ u}) to remove -tick marks from the original article. The other possibility is to set -@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t}, but see the above -comments about this option. If it works for you, the tick marks should -also exist in the @code{nnmairix} group and you can remove them as usual, -e.g. by marking an article as read. +There should always be a colon or a point position marker on the line; +the cursor always moves to the point position marker or the colon after +performing an operation. (Of course, Gnus wouldn't be Gnus if it wasn't +possible to change this. Just write a new function +@code{gnus-goto-colon} which does whatever you like with the cursor.) +@xref{Positioning Point}. -When you have removed a tick mark from the original article, this -article should vanish from the @code{nnmairix} group after you have updated the -mairix database and updated the group. Fortunately, there is a function -for doing exactly that: @code{nnmairix-update-groups}. See the previous code -snippet and the doc string for details. +The default string is @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n}. -@item -Dealing with auto-subscription of mail groups +The following format specification characters and extended format +specification(s) are understood: -As described before, all @code{nnmairix} groups are in fact stored on -the mail back end in the form @samp{zz_mairix--}. You can -see them when you enter the back end server in the server buffer. You -should not subscribe these groups! Unfortunately, these groups will -usually get @emph{auto-subscribed} when you use @code{nnmaildir} or -@code{nnml}, i.e. you will suddenly see groups of the form -@samp{zz_mairix*} pop up in your group buffer. If this happens to you, -simply kill these groups with C-k. For avoiding this, turn off -auto-subscription completely by setting the variable -@code{gnus-auto-subscribed-groups} to @code{nil} (@pxref{Filtering New -Groups}), or if you like to keep this feature use the following kludge -for turning it off for all groups beginning with @samp{zz_}: +@table @samp +@item N +Article number. +@item S +Subject string. List identifiers stripped, +@code{gnus-list-identifiers}. @xref{Article Hiding}. +@item s +Subject if the article is the root of the thread or the previous article +had a different subject, @code{gnus-summary-same-subject} otherwise. +(@code{gnus-summary-same-subject} defaults to @code{""}.) +@item F +Full @code{From} header. +@item n +The name (from the @code{From} header). +@item f +The name, @code{To} header or the @code{Newsgroups} header (@pxref{To +From Newsgroups}). +@item a +The name (from the @code{From} header). This differs from the @code{n} +spec in that it uses the function designated by the +@code{gnus-extract-address-components} variable, which is slower, but +may be more thorough. +@item A +The address (from the @code{From} header). This works the same way as +the @code{a} spec. +@item L +Number of lines in the article. +@item c +Number of characters in the article. This specifier is not supported +in some methods (like nnfolder). +@item k +Pretty-printed version of the number of characters in the article; +for example, @samp{1.2k} or @samp{0.4M}. +@item I +Indentation based on thread level (@pxref{Customizing Threading}). +@item B +A complex trn-style thread tree, showing response-connecting trace +lines. A thread could be drawn like this: -@lisp -(setq gnus-auto-subscribed-groups - "^\\(nnml\\|nnfolder\\|nnmbox\\|nnmh\\|nnbabyl\\|nnmaildir\\).*:\\([^z]\\|z$\\|\\z[^z]\\|zz$\\|zz[^_]\\|zz_$\\).*") -@end lisp +@example +> ++-> +| +-> +| | \-> +| | \-> +| \-> ++-> +\-> +@end example -@end itemize +You can customize the appearance with the following options. Note +that it is possible to make the thread display look really neat by +replacing the default @acronym{ASCII} characters with graphic +line-drawing glyphs. +@table @code +@item gnus-sum-thread-tree-root +@vindex gnus-sum-thread-tree-root +Used for the root of a thread. If @code{nil}, use subject +instead. The default is @samp{> }. -@node nnmairix caveats -@subsubsection nnmairix caveats +@item gnus-sum-thread-tree-false-root +@vindex gnus-sum-thread-tree-false-root +Used for the false root of a thread (@pxref{Loose Threads}). If +@code{nil}, use subject instead. The default is @samp{> }. -@itemize -@item -You can create a secondary @code{nnml} server just for nnmairix, but then -you have to explicitly set the corresponding server variable -@code{nnml-get-new-mail} to @code{nil}. Otherwise, new mail might get -put into this secondary server (and would never show up again). Here's -an example server definition: +@item gnus-sum-thread-tree-single-indent +@vindex gnus-sum-thread-tree-single-indent +Used for a thread with just one message. If @code{nil}, use subject +instead. The default is @samp{}. -@lisp -(nnml "mairix" (nnml-directory "mairix") (nnml-get-new-mail nil)) -@end lisp +@item gnus-sum-thread-tree-vertical +@vindex gnus-sum-thread-tree-vertical +Used for drawing a vertical line. The default is @samp{| }. -(The @code{nnmaildir} back end also has a server variabe -@code{get-new-mail}, but its default value is @code{nil}, so you don't -have to explicitly set it if you use a @code{nnmaildir} server just for -mairix.) +@item gnus-sum-thread-tree-indent +@vindex gnus-sum-thread-tree-indent +Used for indenting. The default is @samp{ }. -@item -If you use the Gnus registry: don't use the registry with -@code{nnmairix} groups (put them in -@code{gnus-registry-unfollowed-groups}). Be @emph{extra careful} if -you use @code{gnus-registry-split-fancy-with-parent}; mails which are -split into @code{nnmairix} groups are usually gone for good as soon as -you check the group for new mail (yes, it has happened to me...). +@item gnus-sum-thread-tree-leaf-with-other +@vindex gnus-sum-thread-tree-leaf-with-other +Used for a leaf with brothers. The default is @samp{+-> }. -@item -Therefore: @emph{Never ever} put ``real'' mails into @code{nnmairix} -groups (you shouldn't be able to, anyway). +@item gnus-sum-thread-tree-single-leaf +@vindex gnus-sum-thread-tree-single-leaf +Used for a leaf without brothers. The default is @samp{\-> } -@item -If you use the Gnus agent (@pxref{Gnus Unplugged}): don't agentize -@code{nnmairix} groups (though I have no idea what happens if you do). +@end table -@item -mairix does only support us-ascii characters. +@item T +Nothing if the article is a root and lots of spaces if it isn't (it +pushes everything after it off the screen). +@item [ +Opening bracket, which is normally @samp{[}, but can also be @samp{<} +for adopted articles (@pxref{Customizing Threading}). +@item ] +Closing bracket, which is normally @samp{]}, but can also be @samp{>} +for adopted articles. +@item > +One space for each thread level. +@item < +Twenty minus thread level spaces. +@item U +Unread. @xref{Read Articles}. -@item -@code{nnmairix} uses a rather brute force method to force Gnus to -completely reread the group on the mail back end after mairix was -called---it simply deletes and re-creates the group on the mail -back end. So far, this has worked for me without any problems, and I -don't see how @code{nnmairix} could delete other mail groups than its -own, but anyway: you really should have a backup of your mail -folders. +@item R +This misleadingly named specifier is the @dfn{secondary mark}. This +mark will say whether the article has been replied to, has been cached, +or has been saved. @xref{Other Marks}. -@item -All necessary information is stored in the group parameters -(@pxref{Group Parameters}). This has the advantage that no active file -is needed, but also implies that when you kill a @code{nnmairix} group, -it is gone for good. +@item i +Score as a number (@pxref{Scoring}). +@item z +@vindex gnus-summary-zcore-fuzz +Zcore, @samp{+} if above the default level and @samp{-} if below the +default level. If the difference between +@code{gnus-summary-default-score} and the score is less than +@code{gnus-summary-zcore-fuzz}, this spec will not be used. +@item V +Total thread score. +@item x +@code{Xref}. +@item D +@code{Date}. +@item d +The @code{Date} in @code{DD-MMM} format. +@item o +The @code{Date} in @var{YYYYMMDD}@code{T}@var{HHMMSS} format. +@item M +@code{Message-ID}. +@item r +@code{References}. +@item t +Number of articles in the current sub-thread. Using this spec will slow +down summary buffer generation somewhat. +@item e +An @samp{=} (@code{gnus-not-empty-thread-mark}) will be displayed if the +article has any children. +@item P +The line number. +@item O +Download mark. +@item * +Desired cursor position (instead of after first colon). +@item &user-date; +Age sensitive date format. Various date format is defined in +@code{gnus-user-date-format-alist}. +@item u +User defined specifier. The next character in the format string should +be a letter. Gnus will call the function +@code{gnus-user-format-function-@var{x}}, where @var{x} is the letter +following @samp{%u}. The function will be passed the current header as +argument. The function should return a string, which will be inserted +into the summary just like information from any other summary specifier. +@end table -@item -@findex nnmairix-purge-old-groups -If you create and kill a lot of @code{nnmairix} groups, the -``zz_mairix-*'' groups will accumulate on the mail back end server. To -delete old groups which are no longer needed, call -@code{nnmairix-purge-old-groups}. Note that this assumes that you don't -save any ``real'' mail in folders of the form -@code{zz_mairix--}. You can change the prefix of -@code{nnmairix} groups by changing the variable -@code{nnmairix-group-prefix}. +Text between @samp{%(} and @samp{%)} will be highlighted with +@code{gnus-mouse-face} when the mouse point is placed inside the area. +There can only be one such area. -@item -The following only applies if you @emph{don't} use the mentioned patch -for mairix (@pxref{Propagating marks}): +The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs +have to be handled with care. For reasons of efficiency, Gnus will +compute what column these characters will end up in, and ``hard-code'' +that. This means that it is invalid to have these specs after a +variable-length spec. Well, you might not be arrested, but your summary +buffer will look strange, which is bad enough. -A problem can occur when using @code{nnmairix} with maildir folders and -comes with the fact that maildir stores mail flags like @samp{Seen} or -@samp{Replied} by appending chars @samp{S} and @samp{R} to the message -file name, respectively. This implies that currently you would have to -update the mairix database not only when new mail arrives, but also when -mail flags are changing. The same applies to new mails which are indexed -while they are still in the @samp{new} folder but then get moved to -@samp{cur} when Gnus has seen the mail. If you don't update the database -after this has happened, a mairix query can lead to symlinks pointing to -non-existing files. In Gnus, these messages will usually appear with -``(none)'' entries in the header and can't be accessed. If this happens -to you, using @kbd{G b u} and updating the group will usually fix this. +The smart choice is to have these specs as far to the left as possible. +(Isn't that the case with everything, though? But I digress.) -@end itemize +This restriction may disappear in later versions of Gnus. -@node Misc Group Stuff -@section Misc Group Stuff -@menu -* Scanning New Messages:: Asking Gnus to see whether new messages have arrived. -* Group Information:: Information and help on groups and Gnus. -* Group Timestamp:: Making Gnus keep track of when you last read a group. -* File Commands:: Reading and writing the Gnus files. -* Sieve Commands:: Managing Sieve scripts. -@end menu +@node To From Newsgroups +@subsection To From Newsgroups +@cindex To +@cindex Newsgroups -@table @kbd +In some groups (particularly in archive groups), the @code{From} header +isn't very interesting, since all the articles there are written by +you. To display the information in the @code{To} or @code{Newsgroups} +headers instead, you need to decide three things: What information to +gather; where to display it; and when to display it. -@item v -@kindex v (Group) -@cindex keys, reserved for users (Group) -The key @kbd{v} is reserved for users. You can bind it to some -command or better use it as a prefix key. For example: +@enumerate +@item +@vindex gnus-extra-headers +The reading of extra header information is controlled by the +@code{gnus-extra-headers}. This is a list of header symbols. For +instance: @lisp -(define-key gnus-group-mode-map (kbd "v j d") - (lambda () - (interactive) - (gnus-group-jump-to-group "nndraft:drafts"))) +(setq gnus-extra-headers + '(To Newsgroups X-Newsreader)) @end lisp -On keys reserved for users in Emacs and on keybindings in general -@xref{Keymaps, Keymaps, , emacs, The Emacs Editor}. +This will result in Gnus trying to obtain these three headers, and +storing it in header structures for later easy retrieval. -@item ^ -@kindex ^ (Group) -@findex gnus-group-enter-server-mode -Enter the server buffer (@code{gnus-group-enter-server-mode}). -@xref{Server Buffer}. +@item +@findex gnus-extra-header +The value of these extra headers can be accessed via the +@code{gnus-extra-header} function. Here's a format line spec that will +access the @code{X-Newsreader} header: -@item a -@kindex a (Group) -@findex gnus-group-post-news -Start composing a message (a news by default) -(@code{gnus-group-post-news}). If given a prefix, post to the group -under the point. If the prefix is 1, prompt for a group to post to. -Contrary to what the name of this function suggests, the prepared -article might be a mail instead of a news, if a mail group is specified -with the prefix argument. @xref{Composing Messages}. +@example +"%~(form (gnus-extra-header 'X-Newsreader))@@" +@end example -@item m -@kindex m (Group) -@findex gnus-group-mail -Mail a message somewhere (@code{gnus-group-mail}). If given a prefix, -use the posting style of the group under the point. If the prefix is 1, -prompt for a group name to find the posting style. -@xref{Composing Messages}. +@item +@vindex gnus-ignored-from-addresses +The @code{gnus-ignored-from-addresses} variable says when the @samp{%f} +summary line spec returns the @code{To}, @code{Newsreader} or +@code{From} header. If this regexp matches the contents of the +@code{From} header, the value of the @code{To} or @code{Newsreader} +headers are used instead. -@item i -@kindex i (Group) -@findex gnus-group-news -Start composing a news (@code{gnus-group-news}). If given a prefix, -post to the group under the point. If the prefix is 1, prompt -for group to post to. @xref{Composing Messages}. +To distinguish regular articles from those where the @code{From} field +has been swapped, a string is prefixed to the @code{To} or +@code{Newsgroups} header in the summary line. By default the string is +@samp{-> } for @code{To} and @samp{=> } for @code{Newsgroups}, you can +customize these strings with @code{gnus-summary-to-prefix} and +@code{gnus-summary-newsgroup-prefix}. -This function actually prepares a news even when using mail groups. -This is useful for ``posting'' messages to mail groups without actually -sending them over the network: they're just saved directly to the group -in question. The corresponding back end must have a request-post method -for this to work though. +@end enumerate -@item G z -@kindex G z (Group) -@findex gnus-group-compact-group +@vindex nnmail-extra-headers +A related variable is @code{nnmail-extra-headers}, which controls when +to include extra headers when generating overview (@acronym{NOV}) files. +If you have old overview files, you should regenerate them after +changing this variable, by entering the server buffer using @kbd{^}, +and then @kbd{g} on the appropriate mail server (e.g. nnml) to cause +regeneration. -Compact the group under point (@code{gnus-group-compact-group}). -Currently implemented only in nnml (@pxref{Mail Spool}). This removes -gaps between article numbers, hence getting a correct total article -count. +@vindex gnus-summary-line-format +You also have to instruct Gnus to display the data by changing the +@code{%n} spec to the @code{%f} spec in the +@code{gnus-summary-line-format} variable. -@end table +In summary, you'd typically put something like the following in +@file{~/.gnus.el}: -Variables for the group buffer: +@lisp +(setq gnus-extra-headers + '(To Newsgroups)) +(setq nnmail-extra-headers gnus-extra-headers) +(setq gnus-summary-line-format + "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n") +(setq gnus-ignored-from-addresses + "Your Name Here") +@end lisp -@table @code +(The values listed above are the default values in Gnus. Alter them +to fit your needs.) -@item gnus-group-mode-hook -@vindex gnus-group-mode-hook -is called after the group buffer has been -created. +A note for news server administrators, or for users who wish to try to +convince their news server administrator to provide some additional +support: -@item gnus-group-prepare-hook -@vindex gnus-group-prepare-hook -is called after the group buffer is -generated. It may be used to modify the buffer in some strange, -unnatural way. +The above is mostly useful for mail groups, where you have control over +the @acronym{NOV} files that are created. However, if you can persuade your +nntp admin to add (in the usual implementation, notably INN): -@item gnus-group-prepared-hook -@vindex gnus-group-prepare-hook -is called as the very last thing after the group buffer has been -generated. It may be used to move point around, for instance. +@example +Newsgroups:full +@end example -@item gnus-permanently-visible-groups -@vindex gnus-permanently-visible-groups -Groups matching this regexp will always be listed in the group buffer, -whether they are empty or not. +to the end of her @file{overview.fmt} file, then you can use that just +as you would the extra headers from the mail groups. -@end table -@node Scanning New Messages -@subsection Scanning New Messages -@cindex new messages -@cindex scanning new news +@node Summary Buffer Mode Line +@subsection Summary Buffer Mode Line -@table @kbd +@vindex gnus-summary-mode-line-format +You can also change the format of the summary mode bar (@pxref{Mode Line +Formatting}). Set @code{gnus-summary-mode-line-format} to whatever you +like. The default is @samp{Gnus: %%b [%A] %Z}. + +Here are the elements you can play with: +@table @samp +@item G +Group name. +@item p +Unprefixed group name. +@item A +Current article number. +@item z +Current article score. +@item V +Gnus version. +@item U +Number of unread articles in this group. +@item e +Number of unread articles in this group that aren't displayed in the +summary buffer. +@item Z +A string with the number of unread and unselected articles represented +either as @samp{<%U(+%e) more>} if there are both unread and unselected +articles, and just as @samp{<%U more>} if there are just unread articles +and no unselected ones. @item g -@kindex g (Group) -@findex gnus-group-get-new-news -@c @icon{gnus-group-get-new-news} -Check the server(s) for new articles. If the numerical prefix is used, -this command will check only groups of level @var{arg} and lower -(@code{gnus-group-get-new-news}). If given a non-numerical prefix, this -command will force a total re-reading of the active file(s) from the -back end(s). +Shortish group name. For instance, @samp{rec.arts.anime} will be +shortened to @samp{r.a.anime}. +@item S +Subject of the current article. +@item u +User-defined spec (@pxref{User-Defined Specs}). +@item s +Name of the current score file (@pxref{Scoring}). +@item d +Number of dormant articles (@pxref{Unread Articles}). +@item t +Number of ticked articles (@pxref{Unread Articles}). +@item r +Number of articles that have been marked as read in this session. +@item E +Number of articles expunged by the score files. +@end table -@item M-g -@kindex M-g (Group) -@findex gnus-group-get-new-news-this-group -@vindex gnus-goto-next-group-when-activating -@c @icon{gnus-group-get-new-news-this-group} -Check whether new articles have arrived in the current group -(@code{gnus-group-get-new-news-this-group}). -@code{gnus-goto-next-group-when-activating} says whether this command is -to move point to the next group or not. It is @code{t} by default. -@findex gnus-activate-all-groups -@cindex activating groups -@item C-c M-g -@kindex C-c M-g (Group) -Activate absolutely all groups (@code{gnus-activate-all-groups}). +@node Summary Highlighting +@subsection Summary Highlighting -@item R -@kindex R (Group) -@cindex restarting -@findex gnus-group-restart -Restart Gnus (@code{gnus-group-restart}). This saves the @file{.newsrc} -file(s), closes the connection to all servers, clears up all run-time -Gnus variables, and then starts Gnus all over again. +@table @code + +@item gnus-visual-mark-article-hook +@vindex gnus-visual-mark-article-hook +This hook is run after selecting an article. It is meant to be used for +highlighting the article in some way. It is not run if +@code{gnus-visual} is @code{nil}. + +@item gnus-summary-update-hook +@vindex gnus-summary-update-hook +This hook is called when a summary line is changed. It is not run if +@code{gnus-visual} is @code{nil}. + +@item gnus-summary-selected-face +@vindex gnus-summary-selected-face +This is the face (or @dfn{font} as some people call it) used to +highlight the current article in the summary buffer. +@item gnus-summary-highlight +@vindex gnus-summary-highlight +Summary lines are highlighted according to this variable, which is a +list where the elements are of the format @code{(@var{form} +. @var{face})}. If you would, for instance, like ticked articles to be +italic and high-scored articles to be bold, you could set this variable +to something like +@lisp +(((eq mark gnus-ticked-mark) . italic) + ((> score default) . bold)) +@end lisp +As you may have guessed, if @var{form} returns a non-@code{nil} value, +@var{face} will be applied to the line. @end table -@vindex gnus-get-new-news-hook -@code{gnus-get-new-news-hook} is run just before checking for new news. -@vindex gnus-after-getting-new-news-hook -@code{gnus-after-getting-new-news-hook} is run after checking for new -news. +@node Summary Maneuvering +@section Summary Maneuvering +@cindex summary movement +All the straight movement commands understand the numeric prefix and +behave pretty much as you'd expect. -@node Group Information -@subsection Group Information -@cindex group information -@cindex information on groups +None of these commands select articles. @table @kbd +@item G M-n +@itemx M-n +@kindex M-n (Summary) +@kindex G M-n (Summary) +@findex gnus-summary-next-unread-subject +Go to the next summary line of an unread article +(@code{gnus-summary-next-unread-subject}). +@item G M-p +@itemx M-p +@kindex M-p (Summary) +@kindex G M-p (Summary) +@findex gnus-summary-prev-unread-subject +Go to the previous summary line of an unread article +(@code{gnus-summary-prev-unread-subject}). -@item H f -@kindex H f (Group) -@findex gnus-group-fetch-faq -@vindex gnus-group-faq-directory -@cindex FAQ -@cindex ange-ftp -Try to fetch the @acronym{FAQ} for the current group -(@code{gnus-group-fetch-faq}). Gnus will try to get the @acronym{FAQ} -from @code{gnus-group-faq-directory}, which is usually a directory on -a remote machine. This variable can also be a list of directories. -In that case, giving a prefix to this command will allow you to choose -between the various sites. @code{ange-ftp} (or @code{efs}) will be -used for fetching the file. +@item G g +@kindex G g (Summary) +@findex gnus-summary-goto-subject +Ask for an article number and then go to the summary line of that article +without displaying the article (@code{gnus-summary-goto-subject}). +@end table -If fetching from the first site is unsuccessful, Gnus will attempt to go -through @code{gnus-group-faq-directory} and try to open them one by one. +If Gnus asks you to press a key to confirm going to the next group, you +can use the @kbd{C-n} and @kbd{C-p} keys to move around the group +buffer, searching for the next group to read without actually returning +to the group buffer. -@item H d -@itemx C-c C-d -@c @icon{gnus-group-describe-group} -@kindex H d (Group) -@kindex C-c C-d (Group) -@cindex describing groups -@cindex group description -@findex gnus-group-describe-group -Describe the current group (@code{gnus-group-describe-group}). If given -a prefix, force Gnus to re-read the description from the server. +Variables related to summary movement: -@item M-d -@kindex M-d (Group) -@findex gnus-group-describe-all-groups -Describe all groups (@code{gnus-group-describe-all-groups}). If given a -prefix, force Gnus to re-read the description file from the server. +@table @code -@item H v -@itemx V -@kindex V (Group) -@kindex H v (Group) -@cindex version -@findex gnus-version -Display current Gnus version numbers (@code{gnus-version}). +@vindex gnus-auto-select-next +@item gnus-auto-select-next +If you issue one of the movement commands (like @kbd{n}) and there are +no more unread articles after the current one, Gnus will offer to go to +the next group. If this variable is @code{t} and the next group is +empty, Gnus will exit summary mode and return to the group buffer. If +this variable is neither @code{t} nor @code{nil}, Gnus will select the +next group with unread articles. As a special case, if this variable +is @code{quietly}, Gnus will select the next group without asking for +confirmation. If this variable is @code{almost-quietly}, the same +will happen only if you are located on the last article in the group. +Finally, if this variable is @code{slightly-quietly}, the @kbd{Z n} +command will go to the next group without confirmation. Also +@pxref{Group Levels}. -@item ? -@kindex ? (Group) -@findex gnus-group-describe-briefly -Give a very short help message (@code{gnus-group-describe-briefly}). +@item gnus-auto-select-same +@vindex gnus-auto-select-same +If non-@code{nil}, all the movement commands will try to go to the next +article with the same subject as the current. (@dfn{Same} here might +mean @dfn{roughly equal}. See @code{gnus-summary-gather-subject-limit} +for details (@pxref{Customizing Threading}).) If there are no more +articles with the same subject, go to the first unread article. -@item C-c C-i -@kindex C-c C-i (Group) -@cindex info -@cindex manual -@findex gnus-info-find-node -Go to the Gnus info node (@code{gnus-info-find-node}). -@end table +This variable is not particularly useful if you use a threaded display. +@item gnus-summary-check-current +@vindex gnus-summary-check-current +If non-@code{nil}, all the ``unread'' movement commands will not proceed +to the next (or previous) article if the current article is unread. +Instead, they will choose the current article. -@node Group Timestamp -@subsection Group Timestamp -@cindex timestamps -@cindex group timestamps +@item gnus-auto-center-summary +@vindex gnus-auto-center-summary +If non-@code{nil}, Gnus will keep the point in the summary buffer +centered at all times. This makes things quite tidy, but if you have a +slow network connection, or simply do not like this un-Emacsism, you can +set this variable to @code{nil} to get the normal Emacs scrolling +action. This will also inhibit horizontal re-centering of the summary +buffer, which might make it more inconvenient to read extremely long +threads. -It can be convenient to let Gnus keep track of when you last read a -group. To set the ball rolling, you should add -@code{gnus-group-set-timestamp} to @code{gnus-select-group-hook}: +This variable can also be a number. In that case, center the window at +the given number of lines from the top. -@lisp -(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) -@end lisp +@item gnus-summary-stop-at-end-of-message +@vindex gnus-summary-stop-at-end-of-message +If non-@code{nil}, don't go to the next article when hitting +@kbd{SPC}, and you're at the end of the article. -After doing this, each time you enter a group, it'll be recorded. +@end table -This information can be displayed in various ways---the easiest is to -use the @samp{%d} spec in the group line format: -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %d\n") -@end lisp +@node Choosing Articles +@section Choosing Articles +@cindex selecting articles -This will result in lines looking like: +@menu +* Choosing Commands:: Commands for choosing articles. +* Choosing Variables:: Variables that influence these commands. +@end menu -@example -* 0: mail.ding 19961002T012943 - 0: custom 19961002T012713 -@end example -As you can see, the date is displayed in compact ISO 8601 format. This -may be a bit too much, so to just display the date, you could say -something like: +@node Choosing Commands +@subsection Choosing Commands -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n") -@end lisp +None of the following movement commands understand the numeric prefix, +and they all select and display an article. -If you would like greater control of the time format, you can use a -user-defined format spec. Something like the following should do the -trick: +If you want to fetch new articles or redisplay the group, see +@ref{Exiting the Summary Buffer}. -@lisp -(setq gnus-group-line-format - "%M\%S\%p\%P\%5y: %(%-40,40g%) %ud\n") -(defun gnus-user-format-function-d (headers) - (let ((time (gnus-group-timestamp gnus-tmp-group))) - (if time - (format-time-string "%b %d %H:%M" time) - ""))) -@end lisp +@table @kbd +@item SPACE +@kindex SPACE (Summary) +@findex gnus-summary-next-page +Select the current article, or, if that one's read already, the next +unread article (@code{gnus-summary-next-page}). +If you have an article window open already and you press @kbd{SPACE} +again, the article will be scrolled. This lets you conveniently +@kbd{SPACE} through an entire newsgroup. @xref{Paging the Article}. -@node File Commands -@subsection File Commands -@cindex file commands +@item G n +@itemx n +@kindex n (Summary) +@kindex G n (Summary) +@findex gnus-summary-next-unread-article +@c @icon{gnus-summary-next-unread} +Go to next unread article (@code{gnus-summary-next-unread-article}). -@table @kbd +@item G p +@itemx p +@kindex p (Summary) +@findex gnus-summary-prev-unread-article +@c @icon{gnus-summary-prev-unread} +Go to previous unread article (@code{gnus-summary-prev-unread-article}). -@item r -@kindex r (Group) -@findex gnus-group-read-init-file -@vindex gnus-init-file -@cindex reading init file -Re-read the init file (@code{gnus-init-file}, which defaults to -@file{~/.gnus.el}) (@code{gnus-group-read-init-file}). +@item G N +@itemx N +@kindex N (Summary) +@kindex G N (Summary) +@findex gnus-summary-next-article +Go to the next article (@code{gnus-summary-next-article}). -@item s -@kindex s (Group) -@findex gnus-group-save-newsrc -@cindex saving .newsrc -Save the @file{.newsrc.eld} file (and @file{.newsrc} if wanted) -(@code{gnus-group-save-newsrc}). If given a prefix, force saving the -file(s) whether Gnus thinks it is necessary or not. +@item G P +@itemx P +@kindex P (Summary) +@kindex G P (Summary) +@findex gnus-summary-prev-article +Go to the previous article (@code{gnus-summary-prev-article}). -@c @item Z -@c @kindex Z (Group) -@c @findex gnus-group-clear-dribble -@c Clear the dribble buffer (@code{gnus-group-clear-dribble}). +@item G C-n +@kindex G C-n (Summary) +@findex gnus-summary-next-same-subject +Go to the next article with the same subject +(@code{gnus-summary-next-same-subject}). -@end table +@item G C-p +@kindex G C-p (Summary) +@findex gnus-summary-prev-same-subject +Go to the previous article with the same subject +(@code{gnus-summary-prev-same-subject}). +@item G f +@itemx . +@kindex G f (Summary) +@kindex . (Summary) +@findex gnus-summary-first-unread-article +Go to the first unread article +(@code{gnus-summary-first-unread-article}). -@node Sieve Commands -@subsection Sieve Commands -@cindex group sieve commands +@item G b +@itemx , +@kindex G b (Summary) +@kindex , (Summary) +@findex gnus-summary-best-unread-article +Go to the unread article with the highest score +(@code{gnus-summary-best-unread-article}). If given a prefix argument, +go to the first unread article that has a score over the default score. -Sieve is a server-side mail filtering language. In Gnus you can use -the @code{sieve} group parameter (@pxref{Group Parameters}) to specify -sieve rules that should apply to each group. Gnus provides two -commands to translate all these group parameters into a proper Sieve -script that can be transfered to the server somehow. +@item G l +@itemx l +@kindex l (Summary) +@kindex G l (Summary) +@findex gnus-summary-goto-last-article +Go to the previous article read (@code{gnus-summary-goto-last-article}). -@vindex gnus-sieve-file -@vindex gnus-sieve-region-start -@vindex gnus-sieve-region-end -The generated Sieve script is placed in @code{gnus-sieve-file} (by -default @file{~/.sieve}). The Sieve code that Gnus generate is placed -between two delimiters, @code{gnus-sieve-region-start} and -@code{gnus-sieve-region-end}, so you may write additional Sieve code -outside these delimiters that will not be removed the next time you -regenerate the Sieve script. +@item G o +@kindex G o (Summary) +@findex gnus-summary-pop-article +@cindex history +@cindex article history +Pop an article off the summary history and go to this article +(@code{gnus-summary-pop-article}). This command differs from the +command above in that you can pop as many previous articles off the +history as you like, while @kbd{l} toggles the two last read articles. +For a somewhat related issue (if you use these commands a lot), +@pxref{Article Backlog}. -@vindex gnus-sieve-crosspost -The variable @code{gnus-sieve-crosspost} controls how the Sieve script -is generated. If it is non-@code{nil} (the default) articles is -placed in all groups that have matching rules, otherwise the article -is only placed in the group with the first matching rule. For -example, the group parameter @samp{(sieve address "sender" -"owner-ding@@hpc.uh.edu")} will generate the following piece of Sieve -code if @code{gnus-sieve-crosspost} is @code{nil}. (When -@code{gnus-sieve-crosspost} is non-@code{nil}, it looks the same -except that the line containing the call to @code{stop} is removed.) +@item G j +@itemx j +@kindex j (Summary) +@kindex G j (Summary) +@findex gnus-summary-goto-article +Ask for an article number or @code{Message-ID}, and then go to that +article (@code{gnus-summary-goto-article}). -@example -if address "sender" "owner-ding@@hpc.uh.edu" @{ - fileinto "INBOX.ding"; - stop; -@} -@end example +@end table -@xref{Top, Emacs Sieve, Top, sieve, Emacs Sieve}. -@table @kbd +@node Choosing Variables +@subsection Choosing Variables -@item D g -@kindex D g (Group) -@findex gnus-sieve-generate -@vindex gnus-sieve-file -@cindex generating sieve script -Regenerate a Sieve script from the @code{sieve} group parameters and -put you into the @code{gnus-sieve-file} without saving it. +Some variables relevant for moving and selecting articles: -@item D u -@kindex D u (Group) -@findex gnus-sieve-update -@vindex gnus-sieve-file -@cindex updating sieve script -Regenerates the Gnus managed part of @code{gnus-sieve-file} using the -@code{sieve} group parameters, save the file and upload it to the -server using the @code{sieveshell} program. +@table @code +@item gnus-auto-extend-newsgroup +@vindex gnus-auto-extend-newsgroup +All the movement commands will try to go to the previous (or next) +article, even if that article isn't displayed in the Summary buffer if +this variable is non-@code{nil}. Gnus will then fetch the article from +the server and display it in the article buffer. -@end table +@item gnus-select-article-hook +@vindex gnus-select-article-hook +This hook is called whenever an article is selected. The default is +@code{nil}. If you would like each article to be saved in the Agent as +you read it, putting @code{gnus-agent-fetch-selected-article} on this +hook will do so. +@item gnus-mark-article-hook +@vindex gnus-mark-article-hook +@findex gnus-summary-mark-unread-as-read +@findex gnus-summary-mark-read-and-unread-as-read +@findex gnus-unread-mark +This hook is called whenever an article is selected. It is intended to +be used for marking articles as read. The default value is +@code{gnus-summary-mark-read-and-unread-as-read}, and will change the +mark of almost any article you read to @code{gnus-read-mark}. The only +articles not affected by this function are ticked, dormant, and +expirable articles. If you'd instead like to just have unread articles +marked as read, you can use @code{gnus-summary-mark-unread-as-read} +instead. It will leave marks like @code{gnus-low-score-mark}, +@code{gnus-del-mark} (and so on) alone. -@node Summary Buffer -@chapter Summary Buffer -@cindex summary buffer +@end table -A line for each article is displayed in the summary buffer. You can -move around, read articles, post articles and reply to articles. -The most common way to a summary buffer is to select a group from the -group buffer (@pxref{Selecting a Group}). +@node Paging the Article +@section Scrolling the Article +@cindex article scrolling -You can have as many summary buffers open as you wish. +@table @kbd -You can customize the Summary Mode tool bar, see @kbd{M-x -customize-apropos RET gnus-summary-tool-bar}. This feature is only -available in Emacs. +@item SPACE +@kindex SPACE (Summary) +@findex gnus-summary-next-page +Pressing @kbd{SPACE} will scroll the current article forward one page, +or, if you have come to the end of the current article, will choose the +next article (@code{gnus-summary-next-page}). -@kindex v (Summary) -@cindex keys, reserved for users (Summary) -The key @kbd{v} is reserved for users. You can bind it to some -command or better use it as a prefix key. For example: -@lisp -(define-key gnus-summary-mode-map (kbd "v -") "LrS") ;; lower subthread -@end lisp - -@menu -* Summary Buffer Format:: Deciding how the summary buffer is to look. -* Summary Maneuvering:: Moving around the summary buffer. -* Choosing Articles:: Reading articles. -* Paging the Article:: Scrolling the current article. -* Reply Followup and Post:: Posting articles. -* Delayed Articles:: Send articles at a later time. -* Marking Articles:: Marking articles as read, expirable, etc. -* Limiting:: You can limit the summary buffer. -* Threading:: How threads are made. -* Sorting the Summary Buffer:: How articles and threads are sorted. -* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. -* Article Caching:: You may store articles in a cache. -* Persistent Articles:: Making articles expiry-resistant. -* Sticky Articles:: Article buffers that are not reused. -* Article Backlog:: Having already read articles hang around. -* Saving Articles:: Ways of customizing article saving. -* Decoding Articles:: Gnus can treat series of (uu)encoded articles. -* Article Treatment:: The article buffer can be mangled at will. -* MIME Commands:: Doing MIMEy things with the articles. -* Charsets:: Character set issues. -* Article Commands:: Doing various things with the article buffer. -* Summary Sorting:: Sorting the summary buffer in various ways. -* Finding the Parent:: No child support? Get the parent. -* Alternative Approaches:: Reading using non-default summaries. -* Tree Display:: A more visual display of threads. -* Mail Group Commands:: Some commands can only be used in mail groups. -* Various Summary Stuff:: What didn't fit anywhere else. -* Exiting the Summary Buffer:: Returning to the Group buffer, - or reselecting the current group. -* Crosspost Handling:: How crossposted articles are dealt with. -* Duplicate Suppression:: An alternative when crosspost handling fails. -* Security:: Decrypt and Verify. -* Mailing List:: Mailing list minor mode. -@end menu +@vindex gnus-article-boring-faces +@vindex gnus-article-skip-boring +If @code{gnus-article-skip-boring} is non-@code{nil} and the rest of +the article consists only of citations and signature, then it will be +skipped; the next article will be shown instead. You can customize +what is considered uninteresting with +@code{gnus-article-boring-faces}. You can manually view the article's +pages, no matter how boring, using @kbd{C-M-v}. +@item DEL +@kindex DEL (Summary) +@findex gnus-summary-prev-page +Scroll the current article back one page (@code{gnus-summary-prev-page}). -@node Summary Buffer Format -@section Summary Buffer Format -@cindex summary buffer format +@item RET +@kindex RET (Summary) +@findex gnus-summary-scroll-up +Scroll the current article one line forward +(@code{gnus-summary-scroll-up}). -@iftex -@iflatex -\gnusfigure{The Summary Buffer}{180}{ -\put(0,0){\epsfig{figure=ps/summary,width=7.5cm}} -\put(445,0){\makebox(0,0)[br]{\epsfig{figure=ps/summary-article,width=7.5cm}}} -} -@end iflatex -@end iftex +@item M-RET +@kindex M-RET (Summary) +@findex gnus-summary-scroll-down +Scroll the current article one line backward +(@code{gnus-summary-scroll-down}). -@menu -* Summary Buffer Lines:: You can specify how summary lines should look. -* To From Newsgroups:: How to not display your own name. -* Summary Buffer Mode Line:: You can say how the mode line should look. -* Summary Highlighting:: Making the summary buffer all pretty and nice. -@end menu +@item A g +@itemx g +@kindex A g (Summary) +@kindex g (Summary) +@findex gnus-summary-show-article +@vindex gnus-summary-show-article-charset-alist +(Re)fetch the current article (@code{gnus-summary-show-article}). If +given a prefix, show a completely ``raw'' article, just the way it +came from the server. If given a prefix twice (i.e., @kbd{C-u C-u +g'}), fetch the current article, but don't run any of the article +treatment functions. -@findex mail-extract-address-components -@findex gnus-extract-address-components -@vindex gnus-extract-address-components -Gnus will use the value of the @code{gnus-extract-address-components} -variable as a function for getting the name and address parts of a -@code{From} header. Two pre-defined functions exist: -@code{gnus-extract-address-components}, which is the default, quite -fast, and too simplistic solution; and -@code{mail-extract-address-components}, which works very nicely, but is -slower. The default function will return the wrong answer in 5% of the -cases. If this is unacceptable to you, use the other function instead: +@cindex charset, view article with different charset +If given a numerical prefix, you can do semi-manual charset stuff. +@kbd{C-u 0 g cn-gb-2312 RET} will decode the message as if it were +encoded in the @code{cn-gb-2312} charset. If you have @lisp -(setq gnus-extract-address-components - 'mail-extract-address-components) +(setq gnus-summary-show-article-charset-alist + '((1 . cn-gb-2312) + (2 . big5))) @end lisp -@vindex gnus-summary-same-subject -@code{gnus-summary-same-subject} is a string indicating that the current -article has the same subject as the previous. This string will be used -with those specs that require it. The default is @code{""}. - - -@node Summary Buffer Lines -@subsection Summary Buffer Lines +then you can say @kbd{C-u 1 g} to get the same effect. -@vindex gnus-summary-line-format -You can change the format of the lines in the summary buffer by changing -the @code{gnus-summary-line-format} variable. It works along the same -lines as a normal @code{format} string, with some extensions -(@pxref{Formatting Variables}). +@item A < +@itemx < +@kindex < (Summary) +@kindex A < (Summary) +@findex gnus-summary-beginning-of-article +Scroll to the beginning of the article +(@code{gnus-summary-beginning-of-article}). -There should always be a colon or a point position marker on the line; -the cursor always moves to the point position marker or the colon after -performing an operation. (Of course, Gnus wouldn't be Gnus if it wasn't -possible to change this. Just write a new function -@code{gnus-goto-colon} which does whatever you like with the cursor.) -@xref{Positioning Point}. +@item A > +@itemx > +@kindex > (Summary) +@kindex A > (Summary) +@findex gnus-summary-end-of-article +Scroll to the end of the article (@code{gnus-summary-end-of-article}). -The default string is @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n}. +@item A s +@itemx s +@kindex A s (Summary) +@kindex s (Summary) +@findex gnus-summary-isearch-article +Perform an isearch in the article buffer +(@code{gnus-summary-isearch-article}). -The following format specification characters and extended format -specification(s) are understood: +@item h +@kindex h (Summary) +@findex gnus-summary-select-article-buffer +Select the article buffer (@code{gnus-summary-select-article-buffer}). -@table @samp -@item N -Article number. -@item S -Subject string. List identifiers stripped, -@code{gnus-list-identifiers}. @xref{Article Hiding}. -@item s -Subject if the article is the root of the thread or the previous article -had a different subject, @code{gnus-summary-same-subject} otherwise. -(@code{gnus-summary-same-subject} defaults to @code{""}.) -@item F -Full @code{From} header. -@item n -The name (from the @code{From} header). -@item f -The name, @code{To} header or the @code{Newsgroups} header (@pxref{To -From Newsgroups}). -@item a -The name (from the @code{From} header). This differs from the @code{n} -spec in that it uses the function designated by the -@code{gnus-extract-address-components} variable, which is slower, but -may be more thorough. -@item A -The address (from the @code{From} header). This works the same way as -the @code{a} spec. -@item L -Number of lines in the article. -@item c -Number of characters in the article. This specifier is not supported -in some methods (like nnfolder). -@item k -Pretty-printed version of the number of characters in the article; -for example, @samp{1.2k} or @samp{0.4M}. -@item I -Indentation based on thread level (@pxref{Customizing Threading}). -@item B -A complex trn-style thread tree, showing response-connecting trace -lines. A thread could be drawn like this: +@end table -@example -> -+-> -| +-> -| | \-> -| | \-> -| \-> -+-> -\-> -@end example -You can customize the appearance with the following options. Note -that it is possible to make the thread display look really neat by -replacing the default @acronym{ASCII} characters with graphic -line-drawing glyphs. -@table @code -@item gnus-sum-thread-tree-root -@vindex gnus-sum-thread-tree-root -Used for the root of a thread. If @code{nil}, use subject -instead. The default is @samp{> }. +@node Reply Followup and Post +@section Reply, Followup and Post -@item gnus-sum-thread-tree-false-root -@vindex gnus-sum-thread-tree-false-root -Used for the false root of a thread (@pxref{Loose Threads}). If -@code{nil}, use subject instead. The default is @samp{> }. +@menu +* Summary Mail Commands:: Sending mail. +* Summary Post Commands:: Sending news. +* Summary Message Commands:: Other Message-related commands. +* Canceling and Superseding:: +@end menu -@item gnus-sum-thread-tree-single-indent -@vindex gnus-sum-thread-tree-single-indent -Used for a thread with just one message. If @code{nil}, use subject -instead. The default is @samp{}. -@item gnus-sum-thread-tree-vertical -@vindex gnus-sum-thread-tree-vertical -Used for drawing a vertical line. The default is @samp{| }. +@node Summary Mail Commands +@subsection Summary Mail Commands +@cindex mail +@cindex composing mail -@item gnus-sum-thread-tree-indent -@vindex gnus-sum-thread-tree-indent -Used for indenting. The default is @samp{ }. +Commands for composing a mail message: -@item gnus-sum-thread-tree-leaf-with-other -@vindex gnus-sum-thread-tree-leaf-with-other -Used for a leaf with brothers. The default is @samp{+-> }. +@table @kbd -@item gnus-sum-thread-tree-single-leaf -@vindex gnus-sum-thread-tree-single-leaf -Used for a leaf without brothers. The default is @samp{\-> } +@item S r +@itemx r +@kindex S r (Summary) +@kindex r (Summary) +@findex gnus-summary-reply +@c @icon{gnus-summary-mail-reply} +@c @icon{gnus-summary-reply} +Mail a reply to the author of the current article +(@code{gnus-summary-reply}). -@end table - -@item T -Nothing if the article is a root and lots of spaces if it isn't (it -pushes everything after it off the screen). -@item [ -Opening bracket, which is normally @samp{[}, but can also be @samp{<} -for adopted articles (@pxref{Customizing Threading}). -@item ] -Closing bracket, which is normally @samp{]}, but can also be @samp{>} -for adopted articles. -@item > -One space for each thread level. -@item < -Twenty minus thread level spaces. -@item U -Unread. @xref{Read Articles}. - -@item R -This misleadingly named specifier is the @dfn{secondary mark}. This -mark will say whether the article has been replied to, has been cached, -or has been saved. @xref{Other Marks}. - -@item i -Score as a number (@pxref{Scoring}). -@item z -@vindex gnus-summary-zcore-fuzz -Zcore, @samp{+} if above the default level and @samp{-} if below the -default level. If the difference between -@code{gnus-summary-default-score} and the score is less than -@code{gnus-summary-zcore-fuzz}, this spec will not be used. -@item V -Total thread score. -@item x -@code{Xref}. -@item D -@code{Date}. -@item d -The @code{Date} in @code{DD-MMM} format. -@item o -The @code{Date} in @var{YYYYMMDD}@code{T}@var{HHMMSS} format. -@item M -@code{Message-ID}. -@item r -@code{References}. -@item t -Number of articles in the current sub-thread. Using this spec will slow -down summary buffer generation somewhat. -@item e -An @samp{=} (@code{gnus-not-empty-thread-mark}) will be displayed if the -article has any children. -@item P -The line number. -@item O -Download mark. -@item * -Desired cursor position (instead of after first colon). -@item &user-date; -Age sensitive date format. Various date format is defined in -@code{gnus-user-date-format-alist}. -@item u -User defined specifier. The next character in the format string should -be a letter. Gnus will call the function -@code{gnus-user-format-function-@var{x}}, where @var{x} is the letter -following @samp{%u}. The function will be passed the current header as -argument. The function should return a string, which will be inserted -into the summary just like information from any other summary specifier. -@end table - -Text between @samp{%(} and @samp{%)} will be highlighted with -@code{gnus-mouse-face} when the mouse point is placed inside the area. -There can only be one such area. - -The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs -have to be handled with care. For reasons of efficiency, Gnus will -compute what column these characters will end up in, and ``hard-code'' -that. This means that it is invalid to have these specs after a -variable-length spec. Well, you might not be arrested, but your summary -buffer will look strange, which is bad enough. - -The smart choice is to have these specs as far to the left as possible. -(Isn't that the case with everything, though? But I digress.) - -This restriction may disappear in later versions of Gnus. - - -@node To From Newsgroups -@subsection To From Newsgroups -@cindex To -@cindex Newsgroups - -In some groups (particularly in archive groups), the @code{From} header -isn't very interesting, since all the articles there are written by -you. To display the information in the @code{To} or @code{Newsgroups} -headers instead, you need to decide three things: What information to -gather; where to display it; and when to display it. - -@enumerate -@item -@vindex gnus-extra-headers -The reading of extra header information is controlled by the -@code{gnus-extra-headers}. This is a list of header symbols. For -instance: - -@lisp -(setq gnus-extra-headers - '(To Newsgroups X-Newsreader)) -@end lisp - -This will result in Gnus trying to obtain these three headers, and -storing it in header structures for later easy retrieval. - -@item -@findex gnus-extra-header -The value of these extra headers can be accessed via the -@code{gnus-extra-header} function. Here's a format line spec that will -access the @code{X-Newsreader} header: - -@example -"%~(form (gnus-extra-header 'X-Newsreader))@@" -@end example - -@item -@vindex gnus-ignored-from-addresses -The @code{gnus-ignored-from-addresses} variable says when the @samp{%f} -summary line spec returns the @code{To}, @code{Newsreader} or -@code{From} header. If this regexp matches the contents of the -@code{From} header, the value of the @code{To} or @code{Newsreader} -headers are used instead. - -To distinguish regular articles from those where the @code{From} field -has been swapped, a string is prefixed to the @code{To} or -@code{Newsgroups} header in the summary line. By default the string is -@samp{-> } for @code{To} and @samp{=> } for @code{Newsgroups}, you can -customize these strings with @code{gnus-summary-to-prefix} and -@code{gnus-summary-newsgroup-prefix}. - -@end enumerate - -@vindex nnmail-extra-headers -A related variable is @code{nnmail-extra-headers}, which controls when -to include extra headers when generating overview (@acronym{NOV}) files. -If you have old overview files, you should regenerate them after -changing this variable, by entering the server buffer using @kbd{^}, -and then @kbd{g} on the appropriate mail server (e.g. nnml) to cause -regeneration. - -@vindex gnus-summary-line-format -You also have to instruct Gnus to display the data by changing the -@code{%n} spec to the @code{%f} spec in the -@code{gnus-summary-line-format} variable. +@item S R +@itemx R +@kindex R (Summary) +@kindex S R (Summary) +@findex gnus-summary-reply-with-original +@c @icon{gnus-summary-reply-with-original} +Mail a reply to the author of the current article and include the +original message (@code{gnus-summary-reply-with-original}). This +command uses the process/prefix convention. -In summary, you'd typically put something like the following in -@file{~/.gnus.el}: +@item S w +@kindex S w (Summary) +@findex gnus-summary-wide-reply +Mail a wide reply to the author of the current article +(@code{gnus-summary-wide-reply}). A @dfn{wide reply} is a reply that +goes out to all people listed in the @code{To}, @code{From} (or +@code{Reply-to}) and @code{Cc} headers. If @code{Mail-Followup-To} is +present, that's used instead. -@lisp -(setq gnus-extra-headers - '(To Newsgroups)) -(setq nnmail-extra-headers gnus-extra-headers) -(setq gnus-summary-line-format - "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n") -(setq gnus-ignored-from-addresses - "Your Name Here") -@end lisp +@item S W +@kindex S W (Summary) +@findex gnus-summary-wide-reply-with-original +Mail a wide reply to the current article and include the original +message (@code{gnus-summary-wide-reply-with-original}). This command uses +the process/prefix convention, but only uses the headers from the +first article to determine the recipients. -(The values listed above are the default values in Gnus. Alter them -to fit your needs.) +@item S v +@kindex S v (Summary) +@findex gnus-summary-very-wide-reply +Mail a very wide reply to the author of the current article +(@code{gnus-summary-wide-reply}). A @dfn{very wide reply} is a reply +that goes out to all people listed in the @code{To}, @code{From} (or +@code{Reply-to}) and @code{Cc} headers in all the process/prefixed +articles. This command uses the process/prefix convention. -A note for news server administrators, or for users who wish to try to -convince their news server administrator to provide some additional -support: +@item S V +@kindex S V (Summary) +@findex gnus-summary-very-wide-reply-with-original +Mail a very wide reply to the author of the current article and include the +original message (@code{gnus-summary-very-wide-reply-with-original}). This +command uses the process/prefix convention. -The above is mostly useful for mail groups, where you have control over -the @acronym{NOV} files that are created. However, if you can persuade your -nntp admin to add (in the usual implementation, notably INN): +@item S B r +@kindex S B r (Summary) +@findex gnus-summary-reply-broken-reply-to +Mail a reply to the author of the current article but ignore the +@code{Reply-To} field (@code{gnus-summary-reply-broken-reply-to}). +If you need this because a mailing list incorrectly sets a +@code{Reply-To} header pointing to the list, you probably want to set +the @code{broken-reply-to} group parameter instead, so things will work +correctly. @xref{Group Parameters}. -@example -Newsgroups:full -@end example +@item S B R +@kindex S B R (Summary) +@findex gnus-summary-reply-broken-reply-to-with-original +Mail a reply to the author of the current article and include the +original message but ignore the @code{Reply-To} field +(@code{gnus-summary-reply-broken-reply-to-with-original}). -to the end of her @file{overview.fmt} file, then you can use that just -as you would the extra headers from the mail groups. +@item S o m +@itemx C-c C-f +@kindex S o m (Summary) +@kindex C-c C-f (Summary) +@findex gnus-summary-mail-forward +@c @icon{gnus-summary-mail-forward} +Forward the current article to some other person +(@code{gnus-summary-mail-forward}). If no prefix is given, the message +is forwarded according to the value of (@code{message-forward-as-mime}) +and (@code{message-forward-show-mml}); if the prefix is 1, decode the +message and forward directly inline; if the prefix is 2, forward message +as an rfc822 @acronym{MIME} section; if the prefix is 3, decode message and +forward as an rfc822 @acronym{MIME} section; if the prefix is 4, forward message +directly inline; otherwise, the message is forwarded as no prefix given +but use the flipped value of (@code{message-forward-as-mime}). By +default, the message is decoded and forwarded as an rfc822 @acronym{MIME} +section. +@item S m +@itemx m +@kindex m (Summary) +@kindex S m (Summary) +@findex gnus-summary-mail-other-window +@c @icon{gnus-summary-mail-originate} +Prepare a mail (@code{gnus-summary-mail-other-window}). By default, use +the posting style of the current group. If given a prefix, disable that. +If the prefix is 1, prompt for a group name to find the posting style. -@node Summary Buffer Mode Line -@subsection Summary Buffer Mode Line +@item S i +@kindex S i (Summary) +@findex gnus-summary-news-other-window +Prepare a news (@code{gnus-summary-news-other-window}). By default, +post to the current group. If given a prefix, disable that. If the +prefix is 1, prompt for a group to post to. -@vindex gnus-summary-mode-line-format -You can also change the format of the summary mode bar (@pxref{Mode Line -Formatting}). Set @code{gnus-summary-mode-line-format} to whatever you -like. The default is @samp{Gnus: %%b [%A] %Z}. +This function actually prepares a news even when using mail groups. +This is useful for ``posting'' messages to mail groups without actually +sending them over the network: they're just saved directly to the group +in question. The corresponding back end must have a request-post method +for this to work though. -Here are the elements you can play with: +@item S D b +@kindex S D b (Summary) +@findex gnus-summary-resend-bounced-mail +@cindex bouncing mail +If you have sent a mail, but the mail was bounced back to you for some +reason (wrong address, transient failure), you can use this command to +resend that bounced mail (@code{gnus-summary-resend-bounced-mail}). You +will be popped into a mail buffer where you can edit the headers before +sending the mail off again. If you give a prefix to this command, and +the bounced mail is a reply to some other mail, Gnus will try to fetch +that mail and display it for easy perusal of its headers. This might +very well fail, though. -@table @samp -@item G -Group name. -@item p -Unprefixed group name. -@item A -Current article number. -@item z -Current article score. -@item V -Gnus version. -@item U -Number of unread articles in this group. -@item e -Number of unread articles in this group that aren't displayed in the -summary buffer. -@item Z -A string with the number of unread and unselected articles represented -either as @samp{<%U(+%e) more>} if there are both unread and unselected -articles, and just as @samp{<%U more>} if there are just unread articles -and no unselected ones. -@item g -Shortish group name. For instance, @samp{rec.arts.anime} will be -shortened to @samp{r.a.anime}. -@item S -Subject of the current article. -@item u -User-defined spec (@pxref{User-Defined Specs}). -@item s -Name of the current score file (@pxref{Scoring}). -@item d -Number of dormant articles (@pxref{Unread Articles}). -@item t -Number of ticked articles (@pxref{Unread Articles}). -@item r -Number of articles that have been marked as read in this session. -@item E -Number of articles expunged by the score files. -@end table +@item S D r +@kindex S D r (Summary) +@findex gnus-summary-resend-message +Not to be confused with the previous command, +@code{gnus-summary-resend-message} will prompt you for an address to +send the current message off to, and then send it to that place. The +headers of the message won't be altered---but lots of headers that say +@code{Resent-To}, @code{Resent-From} and so on will be added. This +means that you actually send a mail to someone that has a @code{To} +header that (probably) points to yourself. This will confuse people. +So, natcherly you'll only do that if you're really eVIl. +This command is mainly used if you have several accounts and want to +ship a mail to a different account of yours. (If you're both +@code{root} and @code{postmaster} and get a mail for @code{postmaster} +to the @code{root} account, you may want to resend it to +@code{postmaster}. Ordnung muss sein! -@node Summary Highlighting -@subsection Summary Highlighting +This command understands the process/prefix convention +(@pxref{Process/Prefix}). -@table @code +@item S D e +@kindex S D e (Summary) +@findex gnus-summary-resend-message-edit -@item gnus-visual-mark-article-hook -@vindex gnus-visual-mark-article-hook -This hook is run after selecting an article. It is meant to be used for -highlighting the article in some way. It is not run if -@code{gnus-visual} is @code{nil}. +Like the previous command, but will allow you to edit the message as +if it were a new message before resending. -@item gnus-summary-update-hook -@vindex gnus-summary-update-hook -This hook is called when a summary line is changed. It is not run if -@code{gnus-visual} is @code{nil}. +@item S O m +@kindex S O m (Summary) +@findex gnus-uu-digest-mail-forward +Digest the current series (@pxref{Decoding Articles}) and forward the +result using mail (@code{gnus-uu-digest-mail-forward}). This command +uses the process/prefix convention (@pxref{Process/Prefix}). -@item gnus-summary-selected-face -@vindex gnus-summary-selected-face -This is the face (or @dfn{font} as some people call it) used to -highlight the current article in the summary buffer. +@item S M-c +@kindex S M-c (Summary) +@findex gnus-summary-mail-crosspost-complaint +@cindex crossposting +@cindex excessive crossposting +Send a complaint about excessive crossposting to the author of the +current article (@code{gnus-summary-mail-crosspost-complaint}). + +@findex gnus-crosspost-complaint +This command is provided as a way to fight back against the current +crossposting pandemic that's sweeping Usenet. It will compose a reply +using the @code{gnus-crosspost-complaint} variable as a preamble. This +command understands the process/prefix convention +(@pxref{Process/Prefix}) and will prompt you before sending each mail. -@item gnus-summary-highlight -@vindex gnus-summary-highlight -Summary lines are highlighted according to this variable, which is a -list where the elements are of the format @code{(@var{form} -. @var{face})}. If you would, for instance, like ticked articles to be -italic and high-scored articles to be bold, you could set this variable -to something like -@lisp -(((eq mark gnus-ticked-mark) . italic) - ((> score default) . bold)) -@end lisp -As you may have guessed, if @var{form} returns a non-@code{nil} value, -@var{face} will be applied to the line. @end table +Also @xref{Header Commands, ,Header Commands, message, The Message +Manual}, for more information. -@node Summary Maneuvering -@section Summary Maneuvering -@cindex summary movement -All the straight movement commands understand the numeric prefix and -behave pretty much as you'd expect. +@node Summary Post Commands +@subsection Summary Post Commands +@cindex post +@cindex composing news -None of these commands select articles. +Commands for posting a news article: @table @kbd -@item G M-n -@itemx M-n -@kindex M-n (Summary) -@kindex G M-n (Summary) -@findex gnus-summary-next-unread-subject -Go to the next summary line of an unread article -(@code{gnus-summary-next-unread-subject}). - -@item G M-p -@itemx M-p -@kindex M-p (Summary) -@kindex G M-p (Summary) -@findex gnus-summary-prev-unread-subject -Go to the previous summary line of an unread article -(@code{gnus-summary-prev-unread-subject}). +@item S p +@itemx a +@kindex a (Summary) +@kindex S p (Summary) +@findex gnus-summary-post-news +@c @icon{gnus-summary-post-news} +Prepare for posting an article (@code{gnus-summary-post-news}). By +default, post to the current group. If given a prefix, disable that. +If the prefix is 1, prompt for another group instead. -@item G g -@kindex G g (Summary) -@findex gnus-summary-goto-subject -Ask for an article number and then go to the summary line of that article -without displaying the article (@code{gnus-summary-goto-subject}). -@end table +@item S f +@itemx f +@kindex f (Summary) +@kindex S f (Summary) +@findex gnus-summary-followup +@c @icon{gnus-summary-followup} +Post a followup to the current article (@code{gnus-summary-followup}). -If Gnus asks you to press a key to confirm going to the next group, you -can use the @kbd{C-n} and @kbd{C-p} keys to move around the group -buffer, searching for the next group to read without actually returning -to the group buffer. +@item S F +@itemx F +@kindex S F (Summary) +@kindex F (Summary) +@c @icon{gnus-summary-followup-with-original} +@findex gnus-summary-followup-with-original +Post a followup to the current article and include the original message +(@code{gnus-summary-followup-with-original}). This command uses the +process/prefix convention. -Variables related to summary movement: +@item S n +@kindex S n (Summary) +@findex gnus-summary-followup-to-mail +Post a followup to the current article via news, even if you got the +message through mail (@code{gnus-summary-followup-to-mail}). -@table @code +@item S N +@kindex S N (Summary) +@findex gnus-summary-followup-to-mail-with-original +Post a followup to the current article via news, even if you got the +message through mail and include the original message +(@code{gnus-summary-followup-to-mail-with-original}). This command uses +the process/prefix convention. -@vindex gnus-auto-select-next -@item gnus-auto-select-next -If you issue one of the movement commands (like @kbd{n}) and there are -no more unread articles after the current one, Gnus will offer to go to -the next group. If this variable is @code{t} and the next group is -empty, Gnus will exit summary mode and return to the group buffer. If -this variable is neither @code{t} nor @code{nil}, Gnus will select the -next group with unread articles. As a special case, if this variable -is @code{quietly}, Gnus will select the next group without asking for -confirmation. If this variable is @code{almost-quietly}, the same -will happen only if you are located on the last article in the group. -Finally, if this variable is @code{slightly-quietly}, the @kbd{Z n} -command will go to the next group without confirmation. Also -@pxref{Group Levels}. +@item S o p +@kindex S o p (Summary) +@findex gnus-summary-post-forward +Forward the current article to a newsgroup +(@code{gnus-summary-post-forward}). + If no prefix is given, the message is forwarded according to the value +of (@code{message-forward-as-mime}) and +(@code{message-forward-show-mml}); if the prefix is 1, decode the +message and forward directly inline; if the prefix is 2, forward message +as an rfc822 @acronym{MIME} section; if the prefix is 3, decode message and +forward as an rfc822 @acronym{MIME} section; if the prefix is 4, forward message +directly inline; otherwise, the message is forwarded as no prefix given +but use the flipped value of (@code{message-forward-as-mime}). By +default, the message is decoded and forwarded as an rfc822 @acronym{MIME} section. -@item gnus-auto-select-same -@vindex gnus-auto-select-same -If non-@code{nil}, all the movement commands will try to go to the next -article with the same subject as the current. (@dfn{Same} here might -mean @dfn{roughly equal}. See @code{gnus-summary-gather-subject-limit} -for details (@pxref{Customizing Threading}).) If there are no more -articles with the same subject, go to the first unread article. +@item S O p +@kindex S O p (Summary) +@findex gnus-uu-digest-post-forward +@cindex digests +@cindex making digests +Digest the current series and forward the result to a newsgroup +(@code{gnus-uu-digest-post-forward}). This command uses the +process/prefix convention. -This variable is not particularly useful if you use a threaded display. +@item S u +@kindex S u (Summary) +@findex gnus-uu-post-news +@c @icon{gnus-uu-post-news} +Uuencode a file, split it into parts, and post it as a series +(@code{gnus-uu-post-news}). (@pxref{Uuencoding and Posting}). +@end table -@item gnus-summary-check-current -@vindex gnus-summary-check-current -If non-@code{nil}, all the ``unread'' movement commands will not proceed -to the next (or previous) article if the current article is unread. -Instead, they will choose the current article. +Also @xref{Header Commands, ,Header Commands, message, The Message +Manual}, for more information. -@item gnus-auto-center-summary -@vindex gnus-auto-center-summary -If non-@code{nil}, Gnus will keep the point in the summary buffer -centered at all times. This makes things quite tidy, but if you have a -slow network connection, or simply do not like this un-Emacsism, you can -set this variable to @code{nil} to get the normal Emacs scrolling -action. This will also inhibit horizontal re-centering of the summary -buffer, which might make it more inconvenient to read extremely long -threads. -This variable can also be a number. In that case, center the window at -the given number of lines from the top. +@node Summary Message Commands +@subsection Summary Message Commands -@item gnus-summary-stop-at-end-of-message -@vindex gnus-summary-stop-at-end-of-message -If non-@code{nil}, don't go to the next article when hitting -@kbd{SPC}, and you're at the end of the article. +@table @kbd +@item S y +@kindex S y (Summary) +@findex gnus-summary-yank-message +Yank the current article into an already existing Message composition +buffer (@code{gnus-summary-yank-message}). This command prompts for +what message buffer you want to yank into, and understands the +process/prefix convention (@pxref{Process/Prefix}). @end table -@node Choosing Articles -@section Choosing Articles -@cindex selecting articles +@node Canceling and Superseding +@subsection Canceling Articles +@cindex canceling articles +@cindex superseding articles + +Have you ever written something, and then decided that you really, +really, really wish you hadn't posted that? + +Well, you can't cancel mail, but you can cancel posts. + +@findex gnus-summary-cancel-article +@kindex C (Summary) +@c @icon{gnus-summary-cancel-article} +Find the article you wish to cancel (you can only cancel your own +articles, so don't try any funny stuff). Then press @kbd{C} or @kbd{S +c} (@code{gnus-summary-cancel-article}). Your article will be +canceled---machines all over the world will be deleting your article. +This command uses the process/prefix convention (@pxref{Process/Prefix}). + +Be aware, however, that not all sites honor cancels, so your article may +live on here and there, while most sites will delete the article in +question. -@menu -* Choosing Commands:: Commands for choosing articles. -* Choosing Variables:: Variables that influence these commands. -@end menu +Gnus will use the ``current'' select method when canceling. If you +want to use the standard posting method, use the @samp{a} symbolic +prefix (@pxref{Symbolic Prefixes}). +Gnus ensures that only you can cancel your own messages using a +@code{Cancel-Lock} header (@pxref{Canceling News, Canceling News, , +message, Message Manual}). -@node Choosing Commands -@subsection Choosing Commands +If you discover that you have made some mistakes and want to do some +corrections, you can post a @dfn{superseding} article that will replace +your original article. -None of the following movement commands understand the numeric prefix, -and they all select and display an article. +@findex gnus-summary-supersede-article +@kindex S (Summary) +Go to the original article and press @kbd{S s} +(@code{gnus-summary-supersede-article}). You will be put in a buffer +where you can edit the article all you want before sending it off the +usual way. -If you want to fetch new articles or redisplay the group, see -@ref{Exiting the Summary Buffer}. +The same goes for superseding as for canceling, only more so: Some +sites do not honor superseding. On those sites, it will appear that you +have posted almost the same article twice. -@table @kbd -@item SPACE -@kindex SPACE (Summary) -@findex gnus-summary-next-page -Select the current article, or, if that one's read already, the next -unread article (@code{gnus-summary-next-page}). +If you have just posted the article, and change your mind right away, +there is a trick you can use to cancel/supersede the article without +waiting for the article to appear on your site first. You simply return +to the post buffer (which is called @code{*sent ...*}). There you will +find the article you just posted, with all the headers intact. Change +the @code{Message-ID} header to a @code{Cancel} or @code{Supersedes} +header by substituting one of those words for the word +@code{Message-ID}. Then just press @kbd{C-c C-c} to send the article as +you would do normally. The previous article will be +canceled/superseded. -If you have an article window open already and you press @kbd{SPACE} -again, the article will be scrolled. This lets you conveniently -@kbd{SPACE} through an entire newsgroup. @xref{Paging the Article}. +Just remember, kids: There is no 'c' in 'supersede'. -@item G n -@itemx n -@kindex n (Summary) -@kindex G n (Summary) -@findex gnus-summary-next-unread-article -@c @icon{gnus-summary-next-unread} -Go to next unread article (@code{gnus-summary-next-unread-article}). +@node Delayed Articles +@section Delayed Articles +@cindex delayed sending +@cindex send delayed -@item G p -@itemx p -@kindex p (Summary) -@findex gnus-summary-prev-unread-article -@c @icon{gnus-summary-prev-unread} -Go to previous unread article (@code{gnus-summary-prev-unread-article}). +Sometimes, you might wish to delay the sending of a message. For +example, you might wish to arrange for a message to turn up just in time +to remind your about the birthday of your Significant Other. For this, +there is the @code{gnus-delay} package. Setup is simple: -@item G N -@itemx N -@kindex N (Summary) -@kindex G N (Summary) -@findex gnus-summary-next-article -Go to the next article (@code{gnus-summary-next-article}). +@lisp +(gnus-delay-initialize) +@end lisp -@item G P -@itemx P -@kindex P (Summary) -@kindex G P (Summary) -@findex gnus-summary-prev-article -Go to the previous article (@code{gnus-summary-prev-article}). +@findex gnus-delay-article +Normally, to send a message you use the @kbd{C-c C-c} command from +Message mode. To delay a message, use @kbd{C-c C-j} +(@code{gnus-delay-article}) instead. This will ask you for how long the +message should be delayed. Possible answers are: -@item G C-n -@kindex G C-n (Summary) -@findex gnus-summary-next-same-subject -Go to the next article with the same subject -(@code{gnus-summary-next-same-subject}). +@itemize @bullet +@item +A time span. Consists of an integer and a letter. For example, +@code{42d} means to delay for 42 days. Available letters are @code{m} +(minutes), @code{h} (hours), @code{d} (days), @code{w} (weeks), @code{M} +(months) and @code{Y} (years). -@item G C-p -@kindex G C-p (Summary) -@findex gnus-summary-prev-same-subject -Go to the previous article with the same subject -(@code{gnus-summary-prev-same-subject}). +@item +A specific date. Looks like @code{YYYY-MM-DD}. The message will be +delayed until that day, at a specific time (eight o'clock by default). +See also @code{gnus-delay-default-hour}. -@item G f -@itemx . -@kindex G f (Summary) -@kindex . (Summary) -@findex gnus-summary-first-unread-article -Go to the first unread article -(@code{gnus-summary-first-unread-article}). +@item +A specific time of day. Given in @code{hh:mm} format, 24h, no am/pm +stuff. The deadline will be at that time today, except if that time has +already passed, then it's at the given time tomorrow. So if it's ten +o'clock in the morning and you specify @code{11:15}, then the deadline +is one hour and fifteen minutes hence. But if you specify @code{9:20}, +that means a time tomorrow. +@end itemize -@item G b -@itemx , -@kindex G b (Summary) -@kindex , (Summary) -@findex gnus-summary-best-unread-article -Go to the unread article with the highest score -(@code{gnus-summary-best-unread-article}). If given a prefix argument, -go to the first unread article that has a score over the default score. +The action of the @code{gnus-delay-article} command is influenced by a +couple of variables: -@item G l -@itemx l -@kindex l (Summary) -@kindex G l (Summary) -@findex gnus-summary-goto-last-article -Go to the previous article read (@code{gnus-summary-goto-last-article}). +@table @code +@item gnus-delay-default-hour +@vindex gnus-delay-default-hour +When you specify a specific date, the message will be due on that hour +on the given date. Possible values are integers 0 through 23. -@item G o -@kindex G o (Summary) -@findex gnus-summary-pop-article -@cindex history -@cindex article history -Pop an article off the summary history and go to this article -(@code{gnus-summary-pop-article}). This command differs from the -command above in that you can pop as many previous articles off the -history as you like, while @kbd{l} toggles the two last read articles. -For a somewhat related issue (if you use these commands a lot), -@pxref{Article Backlog}. +@item gnus-delay-default-delay +@vindex gnus-delay-default-delay +This is a string and gives the default delay. It can be of any of the +formats described above. -@item G j -@itemx j -@kindex j (Summary) -@kindex G j (Summary) -@findex gnus-summary-goto-article -Ask for an article number or @code{Message-ID}, and then go to that -article (@code{gnus-summary-goto-article}). +@item gnus-delay-group +@vindex gnus-delay-group +Delayed articles will be kept in this group on the drafts server until +they are due. You probably don't need to change this. The default +value is @code{"delayed"}. +@item gnus-delay-header +@vindex gnus-delay-header +The deadline for each article will be stored in a header. This variable +is a string and gives the header name. You probably don't need to +change this. The default value is @code{"X-Gnus-Delayed"}. @end table +The way delaying works is like this: when you use the +@code{gnus-delay-article} command, you give a certain delay. Gnus +calculates the deadline of the message and stores it in the +@code{X-Gnus-Delayed} header and puts the message in the +@code{nndraft:delayed} group. -@node Choosing Variables -@subsection Choosing Variables - -Some variables relevant for moving and selecting articles: +@findex gnus-delay-send-queue +And whenever you get new news, Gnus looks through the group for articles +which are due and sends them. It uses the @code{gnus-delay-send-queue} +function for this. By default, this function is added to the hook +@code{gnus-get-new-news-hook}. But of course, you can change this. +Maybe you want to use the demon to send drafts? Just tell the demon to +execute the @code{gnus-delay-send-queue} function. @table @code -@item gnus-auto-extend-newsgroup -@vindex gnus-auto-extend-newsgroup -All the movement commands will try to go to the previous (or next) -article, even if that article isn't displayed in the Summary buffer if -this variable is non-@code{nil}. Gnus will then fetch the article from -the server and display it in the article buffer. +@item gnus-delay-initialize +@findex gnus-delay-initialize +By default, this function installs @code{gnus-delay-send-queue} in +@code{gnus-get-new-news-hook}. But it accepts the optional second +argument @code{no-check}. If it is non-@code{nil}, +@code{gnus-get-new-news-hook} is not changed. The optional first +argument is ignored. -@item gnus-select-article-hook -@vindex gnus-select-article-hook -This hook is called whenever an article is selected. The default is -@code{nil}. If you would like each article to be saved in the Agent as -you read it, putting @code{gnus-agent-fetch-selected-article} on this -hook will do so. +For example, @code{(gnus-delay-initialize nil t)} means to do nothing. +Presumably, you want to use the demon for sending due delayed articles. +Just don't forget to set that up :-) +@end table -@item gnus-mark-article-hook -@vindex gnus-mark-article-hook -@findex gnus-summary-mark-unread-as-read -@findex gnus-summary-mark-read-and-unread-as-read -@findex gnus-unread-mark -This hook is called whenever an article is selected. It is intended to -be used for marking articles as read. The default value is -@code{gnus-summary-mark-read-and-unread-as-read}, and will change the -mark of almost any article you read to @code{gnus-read-mark}. The only -articles not affected by this function are ticked, dormant, and -expirable articles. If you'd instead like to just have unread articles -marked as read, you can use @code{gnus-summary-mark-unread-as-read} -instead. It will leave marks like @code{gnus-low-score-mark}, -@code{gnus-del-mark} (and so on) alone. +When delaying an article with @kbd{C-c C-j}, Message mode will +automatically add a @code{"Date"} header with the current time. In +many cases you probably want the @code{"Date"} header to reflect the +time the message is sent instead. To do this, you have to delete +@code{Date} from @code{message-draft-headers}. -@end table +@node Marking Articles +@section Marking Articles +@cindex article marking +@cindex article ticking +@cindex marks + +There are several marks you can set on an article. -@node Paging the Article -@section Scrolling the Article -@cindex article scrolling +You have marks that decide the @dfn{readedness} (whoo, neato-keano +neologism ohoy!) of the article. Alphabetic marks generally mean +@dfn{read}, while non-alphabetic characters generally mean @dfn{unread}. -@table @kbd +In addition, you also have marks that do not affect readedness. + +@ifinfo +There's a plethora of commands for manipulating these marks. +@end ifinfo -@item SPACE -@kindex SPACE (Summary) -@findex gnus-summary-next-page -Pressing @kbd{SPACE} will scroll the current article forward one page, -or, if you have come to the end of the current article, will choose the -next article (@code{gnus-summary-next-page}). +@menu +* Unread Articles:: Marks for unread articles. +* Read Articles:: Marks for read articles. +* Other Marks:: Marks that do not affect readedness. +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. +@end menu -@vindex gnus-article-boring-faces -@vindex gnus-article-skip-boring -If @code{gnus-article-skip-boring} is non-@code{nil} and the rest of -the article consists only of citations and signature, then it will be -skipped; the next article will be shown instead. You can customize -what is considered uninteresting with -@code{gnus-article-boring-faces}. You can manually view the article's -pages, no matter how boring, using @kbd{C-M-v}. -@item DEL -@kindex DEL (Summary) -@findex gnus-summary-prev-page -Scroll the current article back one page (@code{gnus-summary-prev-page}). +@node Unread Articles +@subsection Unread Articles -@item RET -@kindex RET (Summary) -@findex gnus-summary-scroll-up -Scroll the current article one line forward -(@code{gnus-summary-scroll-up}). +The following marks mark articles as (kinda) unread, in one form or +other. -@item M-RET -@kindex M-RET (Summary) -@findex gnus-summary-scroll-down -Scroll the current article one line backward -(@code{gnus-summary-scroll-down}). +@table @samp +@item ! +@vindex gnus-ticked-mark +Marked as ticked (@code{gnus-ticked-mark}). -@item A g -@itemx g -@kindex A g (Summary) -@kindex g (Summary) -@findex gnus-summary-show-article -@vindex gnus-summary-show-article-charset-alist -(Re)fetch the current article (@code{gnus-summary-show-article}). If -given a prefix, show a completely ``raw'' article, just the way it -came from the server. If given a prefix twice (i.e., @kbd{C-u C-u -g'}), fetch the current article, but don't run any of the article -treatment functions. +@dfn{Ticked articles} are articles that will remain visible always. If +you see an article that you find interesting, or you want to put off +reading it, or replying to it, until sometime later, you'd typically +tick it. However, articles can be expired (from news servers by the +news server software, Gnus itself never expires ticked messages), so if +you want to keep an article forever, you'll have to make it persistent +(@pxref{Persistent Articles}). -@cindex charset, view article with different charset -If given a numerical prefix, you can do semi-manual charset stuff. -@kbd{C-u 0 g cn-gb-2312 RET} will decode the message as if it were -encoded in the @code{cn-gb-2312} charset. If you have +@item ? +@vindex gnus-dormant-mark +Marked as dormant (@code{gnus-dormant-mark}). -@lisp -(setq gnus-summary-show-article-charset-alist - '((1 . cn-gb-2312) - (2 . big5))) -@end lisp +@dfn{Dormant articles} will only appear in the summary buffer if there +are followups to it. If you want to see them even if they don't have +followups, you can use the @kbd{/ D} command (@pxref{Limiting}). +Otherwise (except for the visibility issue), they are just like ticked +messages. -then you can say @kbd{C-u 1 g} to get the same effect. +@item SPACE +@vindex gnus-unread-mark +Marked as unread (@code{gnus-unread-mark}). -@item A < -@itemx < -@kindex < (Summary) -@kindex A < (Summary) -@findex gnus-summary-beginning-of-article -Scroll to the beginning of the article -(@code{gnus-summary-beginning-of-article}). +@dfn{Unread articles} are articles that haven't been read at all yet. +@end table -@item A > -@itemx > -@kindex > (Summary) -@kindex A > (Summary) -@findex gnus-summary-end-of-article -Scroll to the end of the article (@code{gnus-summary-end-of-article}). -@item A s -@itemx s -@kindex A s (Summary) -@kindex s (Summary) -@findex gnus-summary-isearch-article -Perform an isearch in the article buffer -(@code{gnus-summary-isearch-article}). +@node Read Articles +@subsection Read Articles +@cindex expirable mark -@item h -@kindex h (Summary) -@findex gnus-summary-select-article-buffer -Select the article buffer (@code{gnus-summary-select-article-buffer}). +All the following marks mark articles as read. -@end table +@table @samp +@item r +@vindex gnus-del-mark +These are articles that the user has marked as read with the @kbd{d} +command manually, more or less (@code{gnus-del-mark}). -@node Reply Followup and Post -@section Reply, Followup and Post +@item R +@vindex gnus-read-mark +Articles that have actually been read (@code{gnus-read-mark}). -@menu -* Summary Mail Commands:: Sending mail. -* Summary Post Commands:: Sending news. -* Summary Message Commands:: Other Message-related commands. -* Canceling and Superseding:: -@end menu +@item O +@vindex gnus-ancient-mark +Articles that were marked as read in previous sessions and are now +@dfn{old} (@code{gnus-ancient-mark}). +@item K +@vindex gnus-killed-mark +Marked as killed (@code{gnus-killed-mark}). -@node Summary Mail Commands -@subsection Summary Mail Commands -@cindex mail -@cindex composing mail +@item X +@vindex gnus-kill-file-mark +Marked as killed by kill files (@code{gnus-kill-file-mark}). -Commands for composing a mail message: +@item Y +@vindex gnus-low-score-mark +Marked as read by having too low a score (@code{gnus-low-score-mark}). -@table @kbd +@item C +@vindex gnus-catchup-mark +Marked as read by a catchup (@code{gnus-catchup-mark}). -@item S r -@itemx r -@kindex S r (Summary) -@kindex r (Summary) -@findex gnus-summary-reply -@c @icon{gnus-summary-mail-reply} -@c @icon{gnus-summary-reply} -Mail a reply to the author of the current article -(@code{gnus-summary-reply}). +@item G +@vindex gnus-canceled-mark +Canceled article (@code{gnus-canceled-mark}) -@item S R -@itemx R -@kindex R (Summary) -@kindex S R (Summary) -@findex gnus-summary-reply-with-original -@c @icon{gnus-summary-reply-with-original} -Mail a reply to the author of the current article and include the -original message (@code{gnus-summary-reply-with-original}). This -command uses the process/prefix convention. +@item Q +@vindex gnus-sparse-mark +Sparsely reffed article (@code{gnus-sparse-mark}). @xref{Customizing +Threading}. -@item S w -@kindex S w (Summary) -@findex gnus-summary-wide-reply -Mail a wide reply to the author of the current article -(@code{gnus-summary-wide-reply}). A @dfn{wide reply} is a reply that -goes out to all people listed in the @code{To}, @code{From} (or -@code{Reply-to}) and @code{Cc} headers. If @code{Mail-Followup-To} is -present, that's used instead. +@item M +@vindex gnus-duplicate-mark +Article marked as read by duplicate suppression +(@code{gnus-duplicate-mark}). @xref{Duplicate Suppression}. -@item S W -@kindex S W (Summary) -@findex gnus-summary-wide-reply-with-original -Mail a wide reply to the current article and include the original -message (@code{gnus-summary-wide-reply-with-original}). This command uses -the process/prefix convention, but only uses the headers from the -first article to determine the recipients. +@end table -@item S v -@kindex S v (Summary) -@findex gnus-summary-very-wide-reply -Mail a very wide reply to the author of the current article -(@code{gnus-summary-wide-reply}). A @dfn{very wide reply} is a reply -that goes out to all people listed in the @code{To}, @code{From} (or -@code{Reply-to}) and @code{Cc} headers in all the process/prefixed -articles. This command uses the process/prefix convention. +All these marks just mean that the article is marked as read, really. +They are interpreted differently when doing adaptive scoring, though. -@item S V -@kindex S V (Summary) -@findex gnus-summary-very-wide-reply-with-original -Mail a very wide reply to the author of the current article and include the -original message (@code{gnus-summary-very-wide-reply-with-original}). This -command uses the process/prefix convention. +One more special mark, though: -@item S B r -@kindex S B r (Summary) -@findex gnus-summary-reply-broken-reply-to -Mail a reply to the author of the current article but ignore the -@code{Reply-To} field (@code{gnus-summary-reply-broken-reply-to}). -If you need this because a mailing list incorrectly sets a -@code{Reply-To} header pointing to the list, you probably want to set -the @code{broken-reply-to} group parameter instead, so things will work -correctly. @xref{Group Parameters}. +@table @samp +@item E +@vindex gnus-expirable-mark +Marked as expirable (@code{gnus-expirable-mark}). -@item S B R -@kindex S B R (Summary) -@findex gnus-summary-reply-broken-reply-to-with-original -Mail a reply to the author of the current article and include the -original message but ignore the @code{Reply-To} field -(@code{gnus-summary-reply-broken-reply-to-with-original}). +Marking articles as @dfn{expirable} (or have them marked as such +automatically) doesn't make much sense in normal groups---a user doesn't +control expiring of news articles, but in mail groups, for instance, +articles marked as @dfn{expirable} can be deleted by Gnus at +any time. +@end table -@item S o m -@itemx C-c C-f -@kindex S o m (Summary) -@kindex C-c C-f (Summary) -@findex gnus-summary-mail-forward -@c @icon{gnus-summary-mail-forward} -Forward the current article to some other person -(@code{gnus-summary-mail-forward}). If no prefix is given, the message -is forwarded according to the value of (@code{message-forward-as-mime}) -and (@code{message-forward-show-mml}); if the prefix is 1, decode the -message and forward directly inline; if the prefix is 2, forward message -as an rfc822 @acronym{MIME} section; if the prefix is 3, decode message and -forward as an rfc822 @acronym{MIME} section; if the prefix is 4, forward message -directly inline; otherwise, the message is forwarded as no prefix given -but use the flipped value of (@code{message-forward-as-mime}). By -default, the message is decoded and forwarded as an rfc822 @acronym{MIME} -section. -@item S m -@itemx m -@kindex m (Summary) -@kindex S m (Summary) -@findex gnus-summary-mail-other-window -@c @icon{gnus-summary-mail-originate} -Prepare a mail (@code{gnus-summary-mail-other-window}). By default, use -the posting style of the current group. If given a prefix, disable that. -If the prefix is 1, prompt for a group name to find the posting style. +@node Other Marks +@subsection Other Marks +@cindex process mark +@cindex bookmarks -@item S i -@kindex S i (Summary) -@findex gnus-summary-news-other-window -Prepare a news (@code{gnus-summary-news-other-window}). By default, -post to the current group. If given a prefix, disable that. If the -prefix is 1, prompt for a group to post to. +There are some marks that have nothing to do with whether the article is +read or not. -This function actually prepares a news even when using mail groups. -This is useful for ``posting'' messages to mail groups without actually -sending them over the network: they're just saved directly to the group -in question. The corresponding back end must have a request-post method -for this to work though. +@itemize @bullet -@item S D b -@kindex S D b (Summary) -@findex gnus-summary-resend-bounced-mail -@cindex bouncing mail -If you have sent a mail, but the mail was bounced back to you for some -reason (wrong address, transient failure), you can use this command to -resend that bounced mail (@code{gnus-summary-resend-bounced-mail}). You -will be popped into a mail buffer where you can edit the headers before -sending the mail off again. If you give a prefix to this command, and -the bounced mail is a reply to some other mail, Gnus will try to fetch -that mail and display it for easy perusal of its headers. This might -very well fail, though. +@item +You can set a bookmark in the current article. Say you are reading a +long thesis on cats' urinary tracts, and have to go home for dinner +before you've finished reading the thesis. You can then set a bookmark +in the article, and Gnus will jump to this bookmark the next time it +encounters the article. @xref{Setting Marks}. -@item S D r -@kindex S D r (Summary) -@findex gnus-summary-resend-message -Not to be confused with the previous command, -@code{gnus-summary-resend-message} will prompt you for an address to -send the current message off to, and then send it to that place. The -headers of the message won't be altered---but lots of headers that say -@code{Resent-To}, @code{Resent-From} and so on will be added. This -means that you actually send a mail to someone that has a @code{To} -header that (probably) points to yourself. This will confuse people. -So, natcherly you'll only do that if you're really eVIl. +@item +@vindex gnus-replied-mark +All articles that you have replied to or made a followup to (i.e., have +answered) will be marked with an @samp{A} in the second column +(@code{gnus-replied-mark}). -This command is mainly used if you have several accounts and want to -ship a mail to a different account of yours. (If you're both -@code{root} and @code{postmaster} and get a mail for @code{postmaster} -to the @code{root} account, you may want to resend it to -@code{postmaster}. Ordnung muss sein! +@item +@vindex gnus-forwarded-mark +All articles that you have forwarded will be marked with an @samp{F} in +the second column (@code{gnus-forwarded-mark}). -This command understands the process/prefix convention -(@pxref{Process/Prefix}). +@item +@vindex gnus-cached-mark +Articles stored in the article cache will be marked with an @samp{*} in +the second column (@code{gnus-cached-mark}). @xref{Article Caching}. -@item S D e -@kindex S D e (Summary) -@findex gnus-summary-resend-message-edit +@item +@vindex gnus-saved-mark +Articles ``saved'' (in some manner or other; not necessarily +religiously) are marked with an @samp{S} in the second column +(@code{gnus-saved-mark}). -Like the previous command, but will allow you to edit the message as -if it were a new message before resending. +@item +@vindex gnus-recent-mark +Articles that according to the server haven't been shown to the user +before are marked with a @samp{N} in the second column +(@code{gnus-recent-mark}). Note that not all servers support this +mark, in which case it simply never appears. Compare with +@code{gnus-unseen-mark}. -@item S O m -@kindex S O m (Summary) -@findex gnus-uu-digest-mail-forward -Digest the current series (@pxref{Decoding Articles}) and forward the -result using mail (@code{gnus-uu-digest-mail-forward}). This command -uses the process/prefix convention (@pxref{Process/Prefix}). +@item +@vindex gnus-unseen-mark +Articles that haven't been seen before in Gnus by the user are marked +with a @samp{.} in the second column (@code{gnus-unseen-mark}). +Compare with @code{gnus-recent-mark}. -@item S M-c -@kindex S M-c (Summary) -@findex gnus-summary-mail-crosspost-complaint -@cindex crossposting -@cindex excessive crossposting -Send a complaint about excessive crossposting to the author of the -current article (@code{gnus-summary-mail-crosspost-complaint}). +@item +@vindex gnus-downloaded-mark +When using the Gnus agent (@pxref{Agent Basics}), articles may be +downloaded for unplugged (offline) viewing. If you are using the +@samp{%O} spec, these articles get the @samp{+} mark in that spec. +(The variable @code{gnus-downloaded-mark} controls which character to +use.) -@findex gnus-crosspost-complaint -This command is provided as a way to fight back against the current -crossposting pandemic that's sweeping Usenet. It will compose a reply -using the @code{gnus-crosspost-complaint} variable as a preamble. This -command understands the process/prefix convention -(@pxref{Process/Prefix}) and will prompt you before sending each mail. +@item +@vindex gnus-undownloaded-mark +When using the Gnus agent (@pxref{Agent Basics}), some articles might +not have been downloaded. Such articles cannot be viewed while you +are unplugged (offline). If you are using the @samp{%O} spec, these +articles get the @samp{-} mark in that spec. (The variable +@code{gnus-undownloaded-mark} controls which character to use.) -@end table +@item +@vindex gnus-downloadable-mark +The Gnus agent (@pxref{Agent Basics}) downloads some articles +automatically, but it is also possible to explicitly mark articles for +download, even if they would not be downloaded automatically. Such +explicitly-marked articles get the @samp{%} mark in the first column. +(The variable @code{gnus-downloadable-mark} controls which character to +use.) -Also @xref{Header Commands, ,Header Commands, message, The Message -Manual}, for more information. +@item +@vindex gnus-not-empty-thread-mark +@vindex gnus-empty-thread-mark +If the @samp{%e} spec is used, the presence of threads or not will be +marked with @code{gnus-not-empty-thread-mark} and +@code{gnus-empty-thread-mark} in the third column, respectively. +@item +@vindex gnus-process-mark +Finally we have the @dfn{process mark} (@code{gnus-process-mark}). A +variety of commands react to the presence of the process mark. For +instance, @kbd{X u} (@code{gnus-uu-decode-uu}) will uudecode and view +all articles that have been marked with the process mark. Articles +marked with the process mark have a @samp{#} in the second column. -@node Summary Post Commands -@subsection Summary Post Commands -@cindex post -@cindex composing news +@end itemize -Commands for posting a news article: +You might have noticed that most of these ``non-readedness'' marks +appear in the second column by default. So if you have a cached, saved, +replied article that you have process-marked, what will that look like? -@table @kbd -@item S p -@itemx a -@kindex a (Summary) -@kindex S p (Summary) -@findex gnus-summary-post-news -@c @icon{gnus-summary-post-news} -Prepare for posting an article (@code{gnus-summary-post-news}). By -default, post to the current group. If given a prefix, disable that. -If the prefix is 1, prompt for another group instead. +Nothing much. The precedence rules go as follows: process -> cache -> +replied -> saved. So if the article is in the cache and is replied, +you'll only see the cache mark and not the replied mark. -@item S f -@itemx f -@kindex f (Summary) -@kindex S f (Summary) -@findex gnus-summary-followup -@c @icon{gnus-summary-followup} -Post a followup to the current article (@code{gnus-summary-followup}). -@item S F -@itemx F -@kindex S F (Summary) -@kindex F (Summary) -@c @icon{gnus-summary-followup-with-original} -@findex gnus-summary-followup-with-original -Post a followup to the current article and include the original message -(@code{gnus-summary-followup-with-original}). This command uses the -process/prefix convention. +@node Setting Marks +@subsection Setting Marks +@cindex setting marks -@item S n -@kindex S n (Summary) -@findex gnus-summary-followup-to-mail -Post a followup to the current article via news, even if you got the -message through mail (@code{gnus-summary-followup-to-mail}). +All the marking commands understand the numeric prefix. -@item S N -@kindex S N (Summary) -@findex gnus-summary-followup-to-mail-with-original -Post a followup to the current article via news, even if you got the -message through mail and include the original message -(@code{gnus-summary-followup-to-mail-with-original}). This command uses -the process/prefix convention. +@table @kbd +@item M c +@itemx M-u +@kindex M c (Summary) +@kindex M-u (Summary) +@findex gnus-summary-clear-mark-forward +@cindex mark as unread +Clear all readedness-marks from the current article +(@code{gnus-summary-clear-mark-forward}). In other words, mark the +article as unread. -@item S o p -@kindex S o p (Summary) -@findex gnus-summary-post-forward -Forward the current article to a newsgroup -(@code{gnus-summary-post-forward}). - If no prefix is given, the message is forwarded according to the value -of (@code{message-forward-as-mime}) and -(@code{message-forward-show-mml}); if the prefix is 1, decode the -message and forward directly inline; if the prefix is 2, forward message -as an rfc822 @acronym{MIME} section; if the prefix is 3, decode message and -forward as an rfc822 @acronym{MIME} section; if the prefix is 4, forward message -directly inline; otherwise, the message is forwarded as no prefix given -but use the flipped value of (@code{message-forward-as-mime}). By -default, the message is decoded and forwarded as an rfc822 @acronym{MIME} section. +@item M t +@itemx ! +@kindex ! (Summary) +@kindex M t (Summary) +@findex gnus-summary-tick-article-forward +Tick the current article (@code{gnus-summary-tick-article-forward}). +@xref{Article Caching}. + +@item M ? +@itemx ? +@kindex ? (Summary) +@kindex M ? (Summary) +@findex gnus-summary-mark-as-dormant +Mark the current article as dormant +(@code{gnus-summary-mark-as-dormant}). @xref{Article Caching}. + +@item M d +@itemx d +@kindex M d (Summary) +@kindex d (Summary) +@findex gnus-summary-mark-as-read-forward +Mark the current article as read +(@code{gnus-summary-mark-as-read-forward}). -@item S O p -@kindex S O p (Summary) -@findex gnus-uu-digest-post-forward -@cindex digests -@cindex making digests -Digest the current series and forward the result to a newsgroup -(@code{gnus-uu-digest-post-forward}). This command uses the -process/prefix convention. +@item D +@kindex D (Summary) +@findex gnus-summary-mark-as-read-backward +Mark the current article as read and move point to the previous line +(@code{gnus-summary-mark-as-read-backward}). -@item S u -@kindex S u (Summary) -@findex gnus-uu-post-news -@c @icon{gnus-uu-post-news} -Uuencode a file, split it into parts, and post it as a series -(@code{gnus-uu-post-news}). (@pxref{Uuencoding and Posting}). -@end table +@item M k +@itemx k +@kindex k (Summary) +@kindex M k (Summary) +@findex gnus-summary-kill-same-subject-and-select +Mark all articles that have the same subject as the current one as read, +and then select the next unread article +(@code{gnus-summary-kill-same-subject-and-select}). -Also @xref{Header Commands, ,Header Commands, message, The Message -Manual}, for more information. +@item M K +@itemx C-k +@kindex M K (Summary) +@kindex C-k (Summary) +@findex gnus-summary-kill-same-subject +Mark all articles that have the same subject as the current one as read +(@code{gnus-summary-kill-same-subject}). +@item M C +@kindex M C (Summary) +@findex gnus-summary-catchup +@c @icon{gnus-summary-catchup} +Mark all unread articles as read (@code{gnus-summary-catchup}). -@node Summary Message Commands -@subsection Summary Message Commands +@item M C-c +@kindex M C-c (Summary) +@findex gnus-summary-catchup-all +Mark all articles in the group as read---even the ticked and dormant +articles (@code{gnus-summary-catchup-all}). -@table @kbd -@item S y -@kindex S y (Summary) -@findex gnus-summary-yank-message -Yank the current article into an already existing Message composition -buffer (@code{gnus-summary-yank-message}). This command prompts for -what message buffer you want to yank into, and understands the -process/prefix convention (@pxref{Process/Prefix}). +@item M H +@kindex M H (Summary) +@findex gnus-summary-catchup-to-here +Catchup the current group to point (before the point) +(@code{gnus-summary-catchup-to-here}). -@end table +@item M h +@kindex M h (Summary) +@findex gnus-summary-catchup-from-here +Catchup the current group from point (after the point) +(@code{gnus-summary-catchup-from-here}). +@item C-w +@kindex C-w (Summary) +@findex gnus-summary-mark-region-as-read +Mark all articles between point and mark as read +(@code{gnus-summary-mark-region-as-read}). -@node Canceling and Superseding -@subsection Canceling Articles -@cindex canceling articles -@cindex superseding articles +@item M V k +@kindex M V k (Summary) +@findex gnus-summary-kill-below +Kill all articles with scores below the default score (or below the +numeric prefix) (@code{gnus-summary-kill-below}). -Have you ever written something, and then decided that you really, -really, really wish you hadn't posted that? +@item M e +@itemx E +@kindex M e (Summary) +@kindex E (Summary) +@findex gnus-summary-mark-as-expirable +Mark the current article as expirable +(@code{gnus-summary-mark-as-expirable}). -Well, you can't cancel mail, but you can cancel posts. +@item M b +@kindex M b (Summary) +@findex gnus-summary-set-bookmark +Set a bookmark in the current article +(@code{gnus-summary-set-bookmark}). -@findex gnus-summary-cancel-article -@kindex C (Summary) -@c @icon{gnus-summary-cancel-article} -Find the article you wish to cancel (you can only cancel your own -articles, so don't try any funny stuff). Then press @kbd{C} or @kbd{S -c} (@code{gnus-summary-cancel-article}). Your article will be -canceled---machines all over the world will be deleting your article. -This command uses the process/prefix convention (@pxref{Process/Prefix}). +@item M B +@kindex M B (Summary) +@findex gnus-summary-remove-bookmark +Remove the bookmark from the current article +(@code{gnus-summary-remove-bookmark}). -Be aware, however, that not all sites honor cancels, so your article may -live on here and there, while most sites will delete the article in -question. +@item M V c +@kindex M V c (Summary) +@findex gnus-summary-clear-above +Clear all marks from articles with scores over the default score (or +over the numeric prefix) (@code{gnus-summary-clear-above}). -Gnus will use the ``current'' select method when canceling. If you -want to use the standard posting method, use the @samp{a} symbolic -prefix (@pxref{Symbolic Prefixes}). +@item M V u +@kindex M V u (Summary) +@findex gnus-summary-tick-above +Tick all articles with scores over the default score (or over the +numeric prefix) (@code{gnus-summary-tick-above}). -Gnus ensures that only you can cancel your own messages using a -@code{Cancel-Lock} header (@pxref{Canceling News, Canceling News, , -message, Message Manual}). +@item M V m +@kindex M V m (Summary) +@findex gnus-summary-mark-above +Prompt for a mark, and mark all articles with scores over the default +score (or over the numeric prefix) with this mark +(@code{gnus-summary-clear-above}). +@end table -If you discover that you have made some mistakes and want to do some -corrections, you can post a @dfn{superseding} article that will replace -your original article. +@vindex gnus-summary-goto-unread +The @code{gnus-summary-goto-unread} variable controls what action should +be taken after setting a mark. If non-@code{nil}, point will move to +the next/previous unread article. If @code{nil}, point will just move +one line up or down. As a special case, if this variable is +@code{never}, all the marking commands as well as other commands (like +@kbd{SPACE}) will move to the next article, whether it is unread or not. +The default is @code{t}. -@findex gnus-summary-supersede-article -@kindex S (Summary) -Go to the original article and press @kbd{S s} -(@code{gnus-summary-supersede-article}). You will be put in a buffer -where you can edit the article all you want before sending it off the -usual way. -The same goes for superseding as for canceling, only more so: Some -sites do not honor superseding. On those sites, it will appear that you -have posted almost the same article twice. +@node Generic Marking Commands +@subsection Generic Marking Commands -If you have just posted the article, and change your mind right away, -there is a trick you can use to cancel/supersede the article without -waiting for the article to appear on your site first. You simply return -to the post buffer (which is called @code{*sent ...*}). There you will -find the article you just posted, with all the headers intact. Change -the @code{Message-ID} header to a @code{Cancel} or @code{Supersedes} -header by substituting one of those words for the word -@code{Message-ID}. Then just press @kbd{C-c C-c} to send the article as -you would do normally. The previous article will be -canceled/superseded. +Some people would like the command that ticks an article (@kbd{!}) go to +the next article. Others would like it to go to the next unread +article. Yet others would like it to stay on the current article. And +even though I haven't heard of anybody wanting it to go to the +previous (unread) article, I'm sure there are people that want that as +well. -Just remember, kids: There is no 'c' in 'supersede'. +Multiply these five behaviors with five different marking commands, and +you get a potentially complex set of variable to control what each +command should do. -@node Delayed Articles -@section Delayed Articles -@cindex delayed sending -@cindex send delayed +To sidestep that mess, Gnus provides commands that do all these +different things. They can be found on the @kbd{M M} map in the summary +buffer. Type @kbd{M M C-h} to see them all---there are too many of them +to list in this manual. -Sometimes, you might wish to delay the sending of a message. For -example, you might wish to arrange for a message to turn up just in time -to remind your about the birthday of your Significant Other. For this, -there is the @code{gnus-delay} package. Setup is simple: +While you can use these commands directly, most users would prefer +altering the summary mode keymap. For instance, if you would like the +@kbd{!} command to go to the next article instead of the next unread +article, you could say something like: @lisp -(gnus-delay-initialize) +@group +(add-hook 'gnus-summary-mode-hook 'my-alter-summary-map) +(defun my-alter-summary-map () + (local-set-key "!" 'gnus-summary-put-mark-as-ticked-next)) +@end group @end lisp -@findex gnus-delay-article -Normally, to send a message you use the @kbd{C-c C-c} command from -Message mode. To delay a message, use @kbd{C-c C-j} -(@code{gnus-delay-article}) instead. This will ask you for how long the -message should be delayed. Possible answers are: +@noindent +or -@itemize @bullet -@item -A time span. Consists of an integer and a letter. For example, -@code{42d} means to delay for 42 days. Available letters are @code{m} -(minutes), @code{h} (hours), @code{d} (days), @code{w} (weeks), @code{M} -(months) and @code{Y} (years). +@lisp +(defun my-alter-summary-map () + (local-set-key "!" "MM!n")) +@end lisp -@item -A specific date. Looks like @code{YYYY-MM-DD}. The message will be -delayed until that day, at a specific time (eight o'clock by default). -See also @code{gnus-delay-default-hour}. -@item -A specific time of day. Given in @code{hh:mm} format, 24h, no am/pm -stuff. The deadline will be at that time today, except if that time has -already passed, then it's at the given time tomorrow. So if it's ten -o'clock in the morning and you specify @code{11:15}, then the deadline -is one hour and fifteen minutes hence. But if you specify @code{9:20}, -that means a time tomorrow. -@end itemize +@node Setting Process Marks +@subsection Setting Process Marks +@cindex setting process marks -The action of the @code{gnus-delay-article} command is influenced by a -couple of variables: +Process marks are displayed as @code{#} in the summary buffer, and are +used for marking articles in such a way that other commands will +process these articles. For instance, if you process mark four +articles and then use the @kbd{*} command, Gnus will enter these four +articles into the cache. For more information, +@pxref{Process/Prefix}. -@table @code -@item gnus-delay-default-hour -@vindex gnus-delay-default-hour -When you specify a specific date, the message will be due on that hour -on the given date. Possible values are integers 0 through 23. +@table @kbd -@item gnus-delay-default-delay -@vindex gnus-delay-default-delay -This is a string and gives the default delay. It can be of any of the -formats described above. +@item M P p +@itemx # +@kindex # (Summary) +@kindex M P p (Summary) +@findex gnus-summary-mark-as-processable +Mark the current article with the process mark +(@code{gnus-summary-mark-as-processable}). +@findex gnus-summary-unmark-as-processable -@item gnus-delay-group -@vindex gnus-delay-group -Delayed articles will be kept in this group on the drafts server until -they are due. You probably don't need to change this. The default -value is @code{"delayed"}. +@item M P u +@itemx M-# +@kindex M P u (Summary) +@kindex M-# (Summary) +Remove the process mark, if any, from the current article +(@code{gnus-summary-unmark-as-processable}). -@item gnus-delay-header -@vindex gnus-delay-header -The deadline for each article will be stored in a header. This variable -is a string and gives the header name. You probably don't need to -change this. The default value is @code{"X-Gnus-Delayed"}. -@end table +@item M P U +@kindex M P U (Summary) +@findex gnus-summary-unmark-all-processable +Remove the process mark from all articles +(@code{gnus-summary-unmark-all-processable}). -The way delaying works is like this: when you use the -@code{gnus-delay-article} command, you give a certain delay. Gnus -calculates the deadline of the message and stores it in the -@code{X-Gnus-Delayed} header and puts the message in the -@code{nndraft:delayed} group. +@item M P i +@kindex M P i (Summary) +@findex gnus-uu-invert-processable +Invert the list of process marked articles +(@code{gnus-uu-invert-processable}). -@findex gnus-delay-send-queue -And whenever you get new news, Gnus looks through the group for articles -which are due and sends them. It uses the @code{gnus-delay-send-queue} -function for this. By default, this function is added to the hook -@code{gnus-get-new-news-hook}. But of course, you can change this. -Maybe you want to use the demon to send drafts? Just tell the demon to -execute the @code{gnus-delay-send-queue} function. +@item M P R +@kindex M P R (Summary) +@findex gnus-uu-mark-by-regexp +Mark articles that have a @code{Subject} header that matches a regular +expression (@code{gnus-uu-mark-by-regexp}). -@table @code -@item gnus-delay-initialize -@findex gnus-delay-initialize -By default, this function installs @code{gnus-delay-send-queue} in -@code{gnus-get-new-news-hook}. But it accepts the optional second -argument @code{no-check}. If it is non-@code{nil}, -@code{gnus-get-new-news-hook} is not changed. The optional first -argument is ignored. +@item M P G +@kindex M P G (Summary) +@findex gnus-uu-unmark-by-regexp +Unmark articles that have a @code{Subject} header that matches a regular +expression (@code{gnus-uu-unmark-by-regexp}). -For example, @code{(gnus-delay-initialize nil t)} means to do nothing. -Presumably, you want to use the demon for sending due delayed articles. -Just don't forget to set that up :-) -@end table +@item M P r +@kindex M P r (Summary) +@findex gnus-uu-mark-region +Mark articles in region (@code{gnus-uu-mark-region}). -When delaying an article with @kbd{C-c C-j}, Message mode will -automatically add a @code{"Date"} header with the current time. In -many cases you probably want the @code{"Date"} header to reflect the -time the message is sent instead. To do this, you have to delete -@code{Date} from @code{message-draft-headers}. +@item M P g +@kindex M P g (Summary) +@findex gnus-uu-unmark-region +Unmark articles in region (@code{gnus-uu-unmark-region}). +@item M P t +@kindex M P t (Summary) +@findex gnus-uu-mark-thread +Mark all articles in the current (sub)thread +(@code{gnus-uu-mark-thread}). -@node Marking Articles -@section Marking Articles -@cindex article marking -@cindex article ticking -@cindex marks +@item M P T +@kindex M P T (Summary) +@findex gnus-uu-unmark-thread +Unmark all articles in the current (sub)thread +(@code{gnus-uu-unmark-thread}). -There are several marks you can set on an article. +@item M P v +@kindex M P v (Summary) +@findex gnus-uu-mark-over +Mark all articles that have a score above the prefix argument +(@code{gnus-uu-mark-over}). -You have marks that decide the @dfn{readedness} (whoo, neato-keano -neologism ohoy!) of the article. Alphabetic marks generally mean -@dfn{read}, while non-alphabetic characters generally mean @dfn{unread}. +@item M P s +@kindex M P s (Summary) +@findex gnus-uu-mark-series +Mark all articles in the current series (@code{gnus-uu-mark-series}). -In addition, you also have marks that do not affect readedness. +@item M P S +@kindex M P S (Summary) +@findex gnus-uu-mark-sparse +Mark all series that have already had some articles marked +(@code{gnus-uu-mark-sparse}). -@ifinfo -There's a plethora of commands for manipulating these marks. -@end ifinfo +@item M P a +@kindex M P a (Summary) +@findex gnus-uu-mark-all +Mark all articles in series order (@code{gnus-uu-mark-all}). -@menu -* Unread Articles:: Marks for unread articles. -* Read Articles:: Marks for read articles. -* Other Marks:: Marks that do not affect readedness. -* Setting Marks:: How to set and remove marks. -* Generic Marking Commands:: How to customize the marking. -* Setting Process Marks:: How to mark articles for later processing. -@end menu +@item M P b +@kindex M P b (Summary) +@findex gnus-uu-mark-buffer +Mark all articles in the buffer in the order they appear +(@code{gnus-uu-mark-buffer}). +@item M P k +@kindex M P k (Summary) +@findex gnus-summary-kill-process-mark +Push the current process mark set onto the stack and unmark all articles +(@code{gnus-summary-kill-process-mark}). -@node Unread Articles -@subsection Unread Articles +@item M P y +@kindex M P y (Summary) +@findex gnus-summary-yank-process-mark +Pop the previous process mark set from the stack and restore it +(@code{gnus-summary-yank-process-mark}). -The following marks mark articles as (kinda) unread, in one form or -other. +@item M P w +@kindex M P w (Summary) +@findex gnus-summary-save-process-mark +Push the current process mark set onto the stack +(@code{gnus-summary-save-process-mark}). -@table @samp -@item ! -@vindex gnus-ticked-mark -Marked as ticked (@code{gnus-ticked-mark}). +@end table -@dfn{Ticked articles} are articles that will remain visible always. If -you see an article that you find interesting, or you want to put off -reading it, or replying to it, until sometime later, you'd typically -tick it. However, articles can be expired (from news servers by the -news server software, Gnus itself never expires ticked messages), so if -you want to keep an article forever, you'll have to make it persistent -(@pxref{Persistent Articles}). +Also see the @kbd{&} command in @ref{Searching for Articles}, for how to +set process marks based on article body contents. -@item ? -@vindex gnus-dormant-mark -Marked as dormant (@code{gnus-dormant-mark}). -@dfn{Dormant articles} will only appear in the summary buffer if there -are followups to it. If you want to see them even if they don't have -followups, you can use the @kbd{/ D} command (@pxref{Limiting}). -Otherwise (except for the visibility issue), they are just like ticked -messages. +@node Limiting +@section Limiting +@cindex limiting -@item SPACE -@vindex gnus-unread-mark -Marked as unread (@code{gnus-unread-mark}). +It can be convenient to limit the summary buffer to just show some +subset of the articles currently in the group. The effect most limit +commands have is to remove a few (or many) articles from the summary +buffer. -@dfn{Unread articles} are articles that haven't been read at all yet. -@end table +Limiting commands work on subsets of the articles already fetched from +the servers. These commands don't query the server for additional +articles. +@table @kbd -@node Read Articles -@subsection Read Articles -@cindex expirable mark +@item / / +@itemx / s +@kindex / / (Summary) +@findex gnus-summary-limit-to-subject +Limit the summary buffer to articles that match some subject +(@code{gnus-summary-limit-to-subject}). If given a prefix, exclude +matching articles. -All the following marks mark articles as read. +@item / a +@kindex / a (Summary) +@findex gnus-summary-limit-to-author +Limit the summary buffer to articles that match some author +(@code{gnus-summary-limit-to-author}). If given a prefix, exclude +matching articles. -@table @samp +@item / R +@kindex / R (Summary) +@findex gnus-summary-limit-to-recipient +Limit the summary buffer to articles that match some recipient +(@code{gnus-summary-limit-to-recipient}). If given a prefix, exclude +matching articles. -@item r -@vindex gnus-del-mark -These are articles that the user has marked as read with the @kbd{d} -command manually, more or less (@code{gnus-del-mark}). +@item / A +@kindex / A (Summary) +@findex gnus-summary-limit-to-address +Limit the summary buffer to articles in which contents of From, To or Cc +header match a given address (@code{gnus-summary-limit-to-address}). If +given a prefix, exclude matching articles. -@item R -@vindex gnus-read-mark -Articles that have actually been read (@code{gnus-read-mark}). +@item / S +@kindex / S (Summary) +@findex gnus-summary-limit-to-singletons +Limit the summary buffer to articles that aren't part of any displayed +threads (@code{gnus-summary-limit-to-singletons}). If given a prefix, +limit to articles that are part of displayed threads. -@item O -@vindex gnus-ancient-mark -Articles that were marked as read in previous sessions and are now -@dfn{old} (@code{gnus-ancient-mark}). +@item / x +@kindex / x (Summary) +@findex gnus-summary-limit-to-extra +Limit the summary buffer to articles that match one of the ``extra'' +headers (@pxref{To From Newsgroups}) +(@code{gnus-summary-limit-to-extra}). If given a prefix, exclude +matching articles. -@item K -@vindex gnus-killed-mark -Marked as killed (@code{gnus-killed-mark}). +@item / u +@itemx x +@kindex / u (Summary) +@kindex x (Summary) +@findex gnus-summary-limit-to-unread +Limit the summary buffer to articles not marked as read +(@code{gnus-summary-limit-to-unread}). If given a prefix, limit the +buffer to articles strictly unread. This means that ticked and +dormant articles will also be excluded. + +@item / m +@kindex / m (Summary) +@findex gnus-summary-limit-to-marks +Ask for a mark and then limit to all articles that have been marked +with that mark (@code{gnus-summary-limit-to-marks}). -@item X -@vindex gnus-kill-file-mark -Marked as killed by kill files (@code{gnus-kill-file-mark}). +@item / t +@kindex / t (Summary) +@findex gnus-summary-limit-to-age +Ask for a number and then limit the summary buffer to articles older than (or equal to) that number of days +(@code{gnus-summary-limit-to-age}). If given a prefix, limit to +articles younger than that number of days. -@item Y -@vindex gnus-low-score-mark -Marked as read by having too low a score (@code{gnus-low-score-mark}). +@item / n +@kindex / n (Summary) +@findex gnus-summary-limit-to-articles +With prefix @samp{n}, limit the summary buffer to the next @samp{n} +articles. If not given a prefix, use the process marked articles +instead. (@code{gnus-summary-limit-to-articles}). -@item C -@vindex gnus-catchup-mark -Marked as read by a catchup (@code{gnus-catchup-mark}). +@item / w +@kindex / w (Summary) +@findex gnus-summary-pop-limit +Pop the previous limit off the stack and restore it +(@code{gnus-summary-pop-limit}). If given a prefix, pop all limits off +the stack. -@item G -@vindex gnus-canceled-mark -Canceled article (@code{gnus-canceled-mark}) +@item / . +@kindex / . (Summary) +@findex gnus-summary-limit-to-unseen +Limit the summary buffer to the unseen articles +(@code{gnus-summary-limit-to-unseen}). -@item Q -@vindex gnus-sparse-mark -Sparsely reffed article (@code{gnus-sparse-mark}). @xref{Customizing -Threading}. +@item / v +@kindex / v (Summary) +@findex gnus-summary-limit-to-score +Limit the summary buffer to articles that have a score at or above some +score (@code{gnus-summary-limit-to-score}). -@item M -@vindex gnus-duplicate-mark -Article marked as read by duplicate suppression -(@code{gnus-duplicate-mark}). @xref{Duplicate Suppression}. +@item / p +@kindex / p (Summary) +@findex gnus-summary-limit-to-display-predicate +Limit the summary buffer to articles that satisfy the @code{display} +group parameter predicate +(@code{gnus-summary-limit-to-display-predicate}). @xref{Group +Parameters}, for more on this predicate. -@end table +@item / r +@kindex / r (Summary) +@findex gnus-summary-limit-to-replied +Limit the summary buffer to replied articles +(@code{gnus-summary-limit-to-replied}). If given a prefix, exclude +replied articles. -All these marks just mean that the article is marked as read, really. -They are interpreted differently when doing adaptive scoring, though. +@item / E +@itemx M S +@kindex M S (Summary) +@kindex / E (Summary) +@findex gnus-summary-limit-include-expunged +Include all expunged articles in the limit +(@code{gnus-summary-limit-include-expunged}). -One more special mark, though: +@item / D +@kindex / D (Summary) +@findex gnus-summary-limit-include-dormant +Include all dormant articles in the limit +(@code{gnus-summary-limit-include-dormant}). -@table @samp -@item E -@vindex gnus-expirable-mark -Marked as expirable (@code{gnus-expirable-mark}). +@item / * +@kindex / * (Summary) +@findex gnus-summary-limit-include-cached +Include all cached articles in the limit +(@code{gnus-summary-limit-include-cached}). -Marking articles as @dfn{expirable} (or have them marked as such -automatically) doesn't make much sense in normal groups---a user doesn't -control expiring of news articles, but in mail groups, for instance, -articles marked as @dfn{expirable} can be deleted by Gnus at -any time. -@end table +@item / d +@kindex / d (Summary) +@findex gnus-summary-limit-exclude-dormant +Exclude all dormant articles from the limit +(@code{gnus-summary-limit-exclude-dormant}). +@item / M +@kindex / M (Summary) +@findex gnus-summary-limit-exclude-marks +Exclude all marked articles (@code{gnus-summary-limit-exclude-marks}). -@node Other Marks -@subsection Other Marks -@cindex process mark -@cindex bookmarks +@item / T +@kindex / T (Summary) +@findex gnus-summary-limit-include-thread +Include all the articles in the current thread in the limit. -There are some marks that have nothing to do with whether the article is -read or not. +@item / c +@kindex / c (Summary) +@findex gnus-summary-limit-exclude-childless-dormant +Exclude all dormant articles that have no children from the limit@* +(@code{gnus-summary-limit-exclude-childless-dormant}). -@itemize @bullet +@item / C +@kindex / C (Summary) +@findex gnus-summary-limit-mark-excluded-as-read +Mark all excluded unread articles as read +(@code{gnus-summary-limit-mark-excluded-as-read}). If given a prefix, +also mark excluded ticked and dormant articles as read. -@item -You can set a bookmark in the current article. Say you are reading a -long thesis on cats' urinary tracts, and have to go home for dinner -before you've finished reading the thesis. You can then set a bookmark -in the article, and Gnus will jump to this bookmark the next time it -encounters the article. @xref{Setting Marks}. +@item / b +@kindex / b (Summary) +@findex gnus-summary-limit-to-bodies +Limit the summary buffer to articles that have bodies that match a +certain regexp (@code{gnus-summary-limit-to-bodies}). If given a +prefix, reverse the limit. This command is quite slow since it +requires selecting each article to find the matches. -@item -@vindex gnus-replied-mark -All articles that you have replied to or made a followup to (i.e., have -answered) will be marked with an @samp{A} in the second column -(@code{gnus-replied-mark}). +@item / h +@kindex / h (Summary) +@findex gnus-summary-limit-to-headers +Like the previous command, only limit to headers instead +(@code{gnus-summary-limit-to-headers}). -@item -@vindex gnus-forwarded-mark -All articles that you have forwarded will be marked with an @samp{F} in -the second column (@code{gnus-forwarded-mark}). +@end table -@item -@vindex gnus-cached-mark -Articles stored in the article cache will be marked with an @samp{*} in -the second column (@code{gnus-cached-mark}). @xref{Article Caching}. -@item -@vindex gnus-saved-mark -Articles ``saved'' (in some manner or other; not necessarily -religiously) are marked with an @samp{S} in the second column -(@code{gnus-saved-mark}). +The following commands aren't limiting commands, but use the @kbd{/} +prefix as well. -@item -@vindex gnus-recent-mark -Articles that according to the server haven't been shown to the user -before are marked with a @samp{N} in the second column -(@code{gnus-recent-mark}). Note that not all servers support this -mark, in which case it simply never appears. Compare with -@code{gnus-unseen-mark}. +@table @kbd +@item / N +@kindex / N (Summary) +@findex gnus-summary-insert-new-articles +Insert all new articles in the summary buffer. It scans for new emails +if @var{back-end}@code{-get-new-mail} is non-@code{nil}. -@item -@vindex gnus-unseen-mark -Articles that haven't been seen before in Gnus by the user are marked -with a @samp{.} in the second column (@code{gnus-unseen-mark}). -Compare with @code{gnus-recent-mark}. +@item / o +@kindex / o (Summary) +@findex gnus-summary-insert-old-articles +Insert all old articles in the summary buffer. If given a numbered +prefix, fetch this number of articles. -@item -@vindex gnus-downloaded-mark -When using the Gnus agent (@pxref{Agent Basics}), articles may be -downloaded for unplugged (offline) viewing. If you are using the -@samp{%O} spec, these articles get the @samp{+} mark in that spec. -(The variable @code{gnus-downloaded-mark} controls which character to -use.) +@end table -@item -@vindex gnus-undownloaded-mark -When using the Gnus agent (@pxref{Agent Basics}), some articles might -not have been downloaded. Such articles cannot be viewed while you -are unplugged (offline). If you are using the @samp{%O} spec, these -articles get the @samp{-} mark in that spec. (The variable -@code{gnus-undownloaded-mark} controls which character to use.) -@item -@vindex gnus-downloadable-mark -The Gnus agent (@pxref{Agent Basics}) downloads some articles -automatically, but it is also possible to explicitly mark articles for -download, even if they would not be downloaded automatically. Such -explicitly-marked articles get the @samp{%} mark in the first column. -(The variable @code{gnus-downloadable-mark} controls which character to -use.) +@node Threading +@section Threading +@cindex threading +@cindex article threading -@item -@vindex gnus-not-empty-thread-mark -@vindex gnus-empty-thread-mark -If the @samp{%e} spec is used, the presence of threads or not will be -marked with @code{gnus-not-empty-thread-mark} and -@code{gnus-empty-thread-mark} in the third column, respectively. +Gnus threads articles by default. @dfn{To thread} is to put responses +to articles directly after the articles they respond to---in a +hierarchical fashion. -@item -@vindex gnus-process-mark -Finally we have the @dfn{process mark} (@code{gnus-process-mark}). A -variety of commands react to the presence of the process mark. For -instance, @kbd{X u} (@code{gnus-uu-decode-uu}) will uudecode and view -all articles that have been marked with the process mark. Articles -marked with the process mark have a @samp{#} in the second column. +Threading is done by looking at the @code{References} headers of the +articles. In a perfect world, this would be enough to build pretty +trees, but unfortunately, the @code{References} header is often broken +or simply missing. Weird news propagation exacerbates the problem, +so one has to employ other heuristics to get pleasing results. A +plethora of approaches exists, as detailed in horrible detail in +@ref{Customizing Threading}. -@end itemize +First, a quick overview of the concepts: -You might have noticed that most of these ``non-readedness'' marks -appear in the second column by default. So if you have a cached, saved, -replied article that you have process-marked, what will that look like? +@table @dfn +@item root +The top-most article in a thread; the first article in the thread. -Nothing much. The precedence rules go as follows: process -> cache -> -replied -> saved. So if the article is in the cache and is replied, -you'll only see the cache mark and not the replied mark. +@item thread +A tree-like article structure. +@item sub-thread +A small(er) section of this tree-like structure. -@node Setting Marks -@subsection Setting Marks -@cindex setting marks +@item loose threads +Threads often lose their roots due to article expiry, or due to the root +already having been read in a previous session, and not displayed in the +summary buffer. We then typically have many sub-threads that really +belong to one thread, but are without connecting roots. These are +called loose threads. -All the marking commands understand the numeric prefix. +@item thread gathering +An attempt to gather loose threads into bigger threads. -@table @kbd -@item M c -@itemx M-u -@kindex M c (Summary) -@kindex M-u (Summary) -@findex gnus-summary-clear-mark-forward -@cindex mark as unread -Clear all readedness-marks from the current article -(@code{gnus-summary-clear-mark-forward}). In other words, mark the -article as unread. +@item sparse threads +A thread where the missing articles have been ``guessed'' at, and are +displayed as empty lines in the summary buffer. -@item M t -@itemx ! -@kindex ! (Summary) -@kindex M t (Summary) -@findex gnus-summary-tick-article-forward -Tick the current article (@code{gnus-summary-tick-article-forward}). -@xref{Article Caching}. +@end table -@item M ? -@itemx ? -@kindex ? (Summary) -@kindex M ? (Summary) -@findex gnus-summary-mark-as-dormant -Mark the current article as dormant -(@code{gnus-summary-mark-as-dormant}). @xref{Article Caching}. -@item M d -@itemx d -@kindex M d (Summary) -@kindex d (Summary) -@findex gnus-summary-mark-as-read-forward -Mark the current article as read -(@code{gnus-summary-mark-as-read-forward}). +@menu +* Customizing Threading:: Variables you can change to affect the threading. +* Thread Commands:: Thread based commands in the summary buffer. +@end menu -@item D -@kindex D (Summary) -@findex gnus-summary-mark-as-read-backward -Mark the current article as read and move point to the previous line -(@code{gnus-summary-mark-as-read-backward}). -@item M k -@itemx k -@kindex k (Summary) -@kindex M k (Summary) -@findex gnus-summary-kill-same-subject-and-select -Mark all articles that have the same subject as the current one as read, -and then select the next unread article -(@code{gnus-summary-kill-same-subject-and-select}). +@node Customizing Threading +@subsection Customizing Threading +@cindex customizing threading -@item M K -@itemx C-k -@kindex M K (Summary) -@kindex C-k (Summary) -@findex gnus-summary-kill-same-subject -Mark all articles that have the same subject as the current one as read -(@code{gnus-summary-kill-same-subject}). +@menu +* Loose Threads:: How Gnus gathers loose threads into bigger threads. +* Filling In Threads:: Making the threads displayed look fuller. +* More Threading:: Even more variables for fiddling with threads. +* Low-Level Threading:: You thought it was over@dots{} but you were wrong! +@end menu -@item M C -@kindex M C (Summary) -@findex gnus-summary-catchup -@c @icon{gnus-summary-catchup} -Mark all unread articles as read (@code{gnus-summary-catchup}). -@item M C-c -@kindex M C-c (Summary) -@findex gnus-summary-catchup-all -Mark all articles in the group as read---even the ticked and dormant -articles (@code{gnus-summary-catchup-all}). +@node Loose Threads +@subsubsection Loose Threads +@cindex < +@cindex > +@cindex loose threads -@item M H -@kindex M H (Summary) -@findex gnus-summary-catchup-to-here -Catchup the current group to point (before the point) -(@code{gnus-summary-catchup-to-here}). +@table @code +@item gnus-summary-make-false-root +@vindex gnus-summary-make-false-root +If non-@code{nil}, Gnus will gather all loose subtrees into one big tree +and create a dummy root at the top. (Wait a minute. Root at the top? +Yup.) Loose subtrees occur when the real root has expired, or you've +read or killed the root in a previous session. -@item M h -@kindex M h (Summary) -@findex gnus-summary-catchup-from-here -Catchup the current group from point (after the point) -(@code{gnus-summary-catchup-from-here}). +When there is no real root of a thread, Gnus will have to fudge +something. This variable says what fudging method Gnus should use. +There are four possible values: -@item C-w -@kindex C-w (Summary) -@findex gnus-summary-mark-region-as-read -Mark all articles between point and mark as read -(@code{gnus-summary-mark-region-as-read}). +@iftex +@iflatex +\gnusfigure{The Summary Buffer}{390}{ +\put(0,0){\epsfig{figure=ps/summary-adopt,width=7.5cm}} +\put(445,0){\makebox(0,0)[br]{\epsfig{figure=ps/summary-empty,width=7.5cm}}} +\put(0,400){\makebox(0,0)[tl]{\epsfig{figure=ps/summary-none,width=7.5cm}}} +\put(445,400){\makebox(0,0)[tr]{\epsfig{figure=ps/summary-dummy,width=7.5cm}}} +} +@end iflatex +@end iftex -@item M V k -@kindex M V k (Summary) -@findex gnus-summary-kill-below -Kill all articles with scores below the default score (or below the -numeric prefix) (@code{gnus-summary-kill-below}). +@cindex adopting articles -@item M e -@itemx E -@kindex M e (Summary) -@kindex E (Summary) -@findex gnus-summary-mark-as-expirable -Mark the current article as expirable -(@code{gnus-summary-mark-as-expirable}). +@table @code -@item M b -@kindex M b (Summary) -@findex gnus-summary-set-bookmark -Set a bookmark in the current article -(@code{gnus-summary-set-bookmark}). +@item adopt +Gnus will make the first of the orphaned articles the parent. This +parent will adopt all the other articles. The adopted articles will be +marked as such by pointy brackets (@samp{<>}) instead of the standard +square brackets (@samp{[]}). This is the default method. -@item M B -@kindex M B (Summary) -@findex gnus-summary-remove-bookmark -Remove the bookmark from the current article -(@code{gnus-summary-remove-bookmark}). +@item dummy +@vindex gnus-summary-dummy-line-format +@vindex gnus-summary-make-false-root-always +Gnus will create a dummy summary line that will pretend to be the +parent. This dummy line does not correspond to any real article, so +selecting it will just select the first real article after the dummy +article. @code{gnus-summary-dummy-line-format} is used to specify the +format of the dummy roots. It accepts only one format spec: @samp{S}, +which is the subject of the article. @xref{Formatting Variables}. +If you want all threads to have a dummy root, even the non-gathered +ones, set @code{gnus-summary-make-false-root-always} to @code{t}. -@item M V c -@kindex M V c (Summary) -@findex gnus-summary-clear-above -Clear all marks from articles with scores over the default score (or -over the numeric prefix) (@code{gnus-summary-clear-above}). +@item empty +Gnus won't actually make any article the parent, but simply leave the +subject field of all orphans except the first empty. (Actually, it will +use @code{gnus-summary-same-subject} as the subject (@pxref{Summary +Buffer Format}).) -@item M V u -@kindex M V u (Summary) -@findex gnus-summary-tick-above -Tick all articles with scores over the default score (or over the -numeric prefix) (@code{gnus-summary-tick-above}). +@item none +Don't make any article parent at all. Just gather the threads and +display them after one another. -@item M V m -@kindex M V m (Summary) -@findex gnus-summary-mark-above -Prompt for a mark, and mark all articles with scores over the default -score (or over the numeric prefix) with this mark -(@code{gnus-summary-clear-above}). +@item nil +Don't gather loose threads. @end table -@vindex gnus-summary-goto-unread -The @code{gnus-summary-goto-unread} variable controls what action should -be taken after setting a mark. If non-@code{nil}, point will move to -the next/previous unread article. If @code{nil}, point will just move -one line up or down. As a special case, if this variable is -@code{never}, all the marking commands as well as other commands (like -@kbd{SPACE}) will move to the next article, whether it is unread or not. -The default is @code{t}. - +@item gnus-summary-gather-subject-limit +@vindex gnus-summary-gather-subject-limit +Loose threads are gathered by comparing subjects of articles. If this +variable is @code{nil}, Gnus requires an exact match between the +subjects of the loose threads before gathering them into one big +super-thread. This might be too strict a requirement, what with the +presence of stupid newsreaders that chop off long subject lines. If +you think so, set this variable to, say, 20 to require that only the +first 20 characters of the subjects have to match. If you set this +variable to a really low number, you'll find that Gnus will gather +everything in sight into one thread, which isn't very helpful. -@node Generic Marking Commands -@subsection Generic Marking Commands +@cindex fuzzy article gathering +If you set this variable to the special value @code{fuzzy}, Gnus will +use a fuzzy string comparison algorithm on the subjects (@pxref{Fuzzy +Matching}). -Some people would like the command that ticks an article (@kbd{!}) go to -the next article. Others would like it to go to the next unread -article. Yet others would like it to stay on the current article. And -even though I haven't heard of anybody wanting it to go to the -previous (unread) article, I'm sure there are people that want that as -well. +@item gnus-simplify-subject-fuzzy-regexp +@vindex gnus-simplify-subject-fuzzy-regexp +This can either be a regular expression or list of regular expressions +that match strings that will be removed from subjects if fuzzy subject +simplification is used. -Multiply these five behaviors with five different marking commands, and -you get a potentially complex set of variable to control what each -command should do. +@item gnus-simplify-ignored-prefixes +@vindex gnus-simplify-ignored-prefixes +If you set @code{gnus-summary-gather-subject-limit} to something as low +as 10, you might consider setting this variable to something sensible: -To sidestep that mess, Gnus provides commands that do all these -different things. They can be found on the @kbd{M M} map in the summary -buffer. Type @kbd{M M C-h} to see them all---there are too many of them -to list in this manual. +@c Written by Michael Ernst +@lisp +(setq gnus-simplify-ignored-prefixes + (concat + "\\`\\[?\\(" + (mapconcat + 'identity + '("looking" + "wanted" "followup" "summary\\( of\\)?" + "help" "query" "problem" "question" + "answer" "reference" "announce" + "How can I" "How to" "Comparison of" + ;; ... + ) + "\\|") + "\\)\\s *\\(" + (mapconcat 'identity + '("for" "for reference" "with" "about") + "\\|") + "\\)?\\]?:?[ \t]*")) +@end lisp -While you can use these commands directly, most users would prefer -altering the summary mode keymap. For instance, if you would like the -@kbd{!} command to go to the next article instead of the next unread -article, you could say something like: +All words that match this regexp will be removed before comparing two +subjects. -@lisp -@group -(add-hook 'gnus-summary-mode-hook 'my-alter-summary-map) -(defun my-alter-summary-map () - (local-set-key "!" 'gnus-summary-put-mark-as-ticked-next)) -@end group -@end lisp +@item gnus-simplify-subject-functions +@vindex gnus-simplify-subject-functions +If non-@code{nil}, this variable overrides +@code{gnus-summary-gather-subject-limit}. This variable should be a +list of functions to apply to the @code{Subject} string iteratively to +arrive at the simplified version of the string. -@noindent -or +Useful functions to put in this list include: -@lisp -(defun my-alter-summary-map () - (local-set-key "!" "MM!n")) -@end lisp +@table @code +@item gnus-simplify-subject-re +@findex gnus-simplify-subject-re +Strip the leading @samp{Re:}. +@item gnus-simplify-subject-fuzzy +@findex gnus-simplify-subject-fuzzy +Simplify fuzzily. -@node Setting Process Marks -@subsection Setting Process Marks -@cindex setting process marks +@item gnus-simplify-whitespace +@findex gnus-simplify-whitespace +Remove excessive whitespace. -Process marks are displayed as @code{#} in the summary buffer, and are -used for marking articles in such a way that other commands will -process these articles. For instance, if you process mark four -articles and then use the @kbd{*} command, Gnus will enter these four -articles into the cache. For more information, -@pxref{Process/Prefix}. +@item gnus-simplify-all-whitespace +@findex gnus-simplify-all-whitespace +Remove all whitespace. +@end table -@table @kbd +You may also write your own functions, of course. -@item M P p -@itemx # -@kindex # (Summary) -@kindex M P p (Summary) -@findex gnus-summary-mark-as-processable -Mark the current article with the process mark -(@code{gnus-summary-mark-as-processable}). -@findex gnus-summary-unmark-as-processable -@item M P u -@itemx M-# -@kindex M P u (Summary) -@kindex M-# (Summary) -Remove the process mark, if any, from the current article -(@code{gnus-summary-unmark-as-processable}). +@item gnus-summary-gather-exclude-subject +@vindex gnus-summary-gather-exclude-subject +Since loose thread gathering is done on subjects only, that might lead +to many false hits, especially with certain common subjects like +@samp{} and @samp{(none)}. To make the situation slightly better, +you can use the regexp @code{gnus-summary-gather-exclude-subject} to say +what subjects should be excluded from the gathering process.@* +The default is @samp{^ *$\\|^(none)$}. -@item M P U -@kindex M P U (Summary) -@findex gnus-summary-unmark-all-processable -Remove the process mark from all articles -(@code{gnus-summary-unmark-all-processable}). +@item gnus-summary-thread-gathering-function +@vindex gnus-summary-thread-gathering-function +Gnus gathers threads by looking at @code{Subject} headers. This means +that totally unrelated articles may end up in the same ``thread'', which +is confusing. An alternate approach is to look at all the +@code{Message-ID}s in all the @code{References} headers to find matches. +This will ensure that no gathered threads ever include unrelated +articles, but it also means that people who have posted with broken +newsreaders won't be gathered properly. The choice is yours---plague or +cholera: -@item M P i -@kindex M P i (Summary) -@findex gnus-uu-invert-processable -Invert the list of process marked articles -(@code{gnus-uu-invert-processable}). +@table @code +@item gnus-gather-threads-by-subject +@findex gnus-gather-threads-by-subject +This function is the default gathering function and looks at +@code{Subject}s exclusively. -@item M P R -@kindex M P R (Summary) -@findex gnus-uu-mark-by-regexp -Mark articles that have a @code{Subject} header that matches a regular -expression (@code{gnus-uu-mark-by-regexp}). +@item gnus-gather-threads-by-references +@findex gnus-gather-threads-by-references +This function looks at @code{References} headers exclusively. +@end table -@item M P G -@kindex M P G (Summary) -@findex gnus-uu-unmark-by-regexp -Unmark articles that have a @code{Subject} header that matches a regular -expression (@code{gnus-uu-unmark-by-regexp}). +If you want to test gathering by @code{References}, you could say +something like: -@item M P r -@kindex M P r (Summary) -@findex gnus-uu-mark-region -Mark articles in region (@code{gnus-uu-mark-region}). +@lisp +(setq gnus-summary-thread-gathering-function + 'gnus-gather-threads-by-references) +@end lisp -@item M P g -@kindex M P g (Summary) -@findex gnus-uu-unmark-region -Unmark articles in region (@code{gnus-uu-unmark-region}). +@end table -@item M P t -@kindex M P t (Summary) -@findex gnus-uu-mark-thread -Mark all articles in the current (sub)thread -(@code{gnus-uu-mark-thread}). -@item M P T -@kindex M P T (Summary) -@findex gnus-uu-unmark-thread -Unmark all articles in the current (sub)thread -(@code{gnus-uu-unmark-thread}). +@node Filling In Threads +@subsubsection Filling In Threads -@item M P v -@kindex M P v (Summary) -@findex gnus-uu-mark-over -Mark all articles that have a score above the prefix argument -(@code{gnus-uu-mark-over}). +@table @code +@item gnus-fetch-old-headers +@vindex gnus-fetch-old-headers +If non-@code{nil}, Gnus will attempt to build old threads by fetching +more old headers---headers to articles marked as read. If you would +like to display as few summary lines as possible, but still connect as +many loose threads as possible, you should set this variable to +@code{some} or a number. If you set it to a number, no more than that +number of extra old headers will be fetched. In either case, fetching +old headers only works if the back end you are using carries overview +files---this would normally be @code{nntp}, @code{nnspool}, +@code{nnml}, and @code{nnmaildir}. Also remember that if the root of +the thread has been expired by the server, there's not much Gnus can +do about that. -@item M P s -@kindex M P s (Summary) -@findex gnus-uu-mark-series -Mark all articles in the current series (@code{gnus-uu-mark-series}). +This variable can also be set to @code{invisible}. This won't have any +visible effects, but is useful if you use the @kbd{A T} command a lot +(@pxref{Finding the Parent}). -@item M P S -@kindex M P S (Summary) -@findex gnus-uu-mark-sparse -Mark all series that have already had some articles marked -(@code{gnus-uu-mark-sparse}). +The server has to support @acronym{NOV} for any of this to work. -@item M P a -@kindex M P a (Summary) -@findex gnus-uu-mark-all -Mark all articles in series order (@code{gnus-uu-mark-all}). +@cindex Gmane, gnus-fetch-old-headers +This feature can seriously impact performance it ignores all locally +cached header entries. Setting it to @code{t} for groups for a server +that doesn't expire articles (such as news.gmane.org), leads to very +slow summary generation. -@item M P b -@kindex M P b (Summary) -@findex gnus-uu-mark-buffer -Mark all articles in the buffer in the order they appear -(@code{gnus-uu-mark-buffer}). +@item gnus-fetch-old-ephemeral-headers +@vindex gnus-fetch-old-ephemeral-headers +Same as @code{gnus-fetch-old-headers}, but only used for ephemeral +newsgroups. -@item M P k -@kindex M P k (Summary) -@findex gnus-summary-kill-process-mark -Push the current process mark set onto the stack and unmark all articles -(@code{gnus-summary-kill-process-mark}). +@item gnus-build-sparse-threads +@vindex gnus-build-sparse-threads +Fetching old headers can be slow. A low-rent similar effect can be +gotten by setting this variable to @code{some}. Gnus will then look at +the complete @code{References} headers of all articles and try to string +together articles that belong in the same thread. This will leave +@dfn{gaps} in the threading display where Gnus guesses that an article +is missing from the thread. (These gaps appear like normal summary +lines. If you select a gap, Gnus will try to fetch the article in +question.) If this variable is @code{t}, Gnus will display all these +``gaps'' without regard for whether they are useful for completing the +thread or not. Finally, if this variable is @code{more}, Gnus won't cut +off sparse leaf nodes that don't lead anywhere. This variable is +@code{nil} by default. -@item M P y -@kindex M P y (Summary) -@findex gnus-summary-yank-process-mark -Pop the previous process mark set from the stack and restore it -(@code{gnus-summary-yank-process-mark}). +@item gnus-read-all-available-headers +@vindex gnus-read-all-available-headers +This is a rather obscure variable that few will find useful. It's +intended for those non-news newsgroups where the back end has to fetch +quite a lot to present the summary buffer, and where it's impossible to +go back to parents of articles. This is mostly the case in the +web-based groups. -@item M P w -@kindex M P w (Summary) -@findex gnus-summary-save-process-mark -Push the current process mark set onto the stack -(@code{gnus-summary-save-process-mark}). +If you don't use those, then it's safe to leave this as the default +@code{nil}. If you want to use this variable, it should be a regexp +that matches the group name, or @code{t} for all groups. @end table -Also see the @kbd{&} command in @ref{Searching for Articles}, for how to -set process marks based on article body contents. +@node More Threading +@subsubsection More Threading -@node Limiting -@section Limiting -@cindex limiting +@table @code +@item gnus-show-threads +@vindex gnus-show-threads +If this variable is @code{nil}, no threading will be done, and all of +the rest of the variables here will have no effect. Turning threading +off will speed group selection up a bit, but it is sure to make reading +slower and more awkward. + +@item gnus-thread-hide-subtree +@vindex gnus-thread-hide-subtree +If non-@code{nil}, all threads will be hidden when the summary buffer is +generated. + +This can also be a predicate specifier (@pxref{Predicate Specifiers}). +Available predicates are @code{gnus-article-unread-p} and +@code{gnus-article-unseen-p}. -It can be convenient to limit the summary buffer to just show some -subset of the articles currently in the group. The effect most limit -commands have is to remove a few (or many) articles from the summary -buffer. +Here's an example: -Limiting commands work on subsets of the articles already fetched from -the servers. These commands don't query the server for additional -articles. +@lisp +(setq gnus-thread-hide-subtree + '(or gnus-article-unread-p + gnus-article-unseen-p)) +@end lisp -@table @kbd +(It's a pretty nonsensical example, since all unseen articles are also +unread, but you get my drift.) -@item / / -@itemx / s -@kindex / / (Summary) -@findex gnus-summary-limit-to-subject -Limit the summary buffer to articles that match some subject -(@code{gnus-summary-limit-to-subject}). If given a prefix, exclude -matching articles. -@item / a -@kindex / a (Summary) -@findex gnus-summary-limit-to-author -Limit the summary buffer to articles that match some author -(@code{gnus-summary-limit-to-author}). If given a prefix, exclude -matching articles. +@item gnus-thread-expunge-below +@vindex gnus-thread-expunge-below +All threads that have a total score (as defined by +@code{gnus-thread-score-function}) less than this number will be +expunged. This variable is @code{nil} by default, which means that no +threads are expunged. -@item / R -@kindex / R (Summary) -@findex gnus-summary-limit-to-recipient -Limit the summary buffer to articles that match some recipient -(@code{gnus-summary-limit-to-recipient}). If given a prefix, exclude -matching articles. +@item gnus-thread-hide-killed +@vindex gnus-thread-hide-killed +if you kill a thread and this variable is non-@code{nil}, the subtree +will be hidden. -@item / A -@kindex / A (Summary) -@findex gnus-summary-limit-to-address -Limit the summary buffer to articles in which contents of From, To or Cc -header match a given address (@code{gnus-summary-limit-to-address}). If -given a prefix, exclude matching articles. +@item gnus-thread-ignore-subject +@vindex gnus-thread-ignore-subject +Sometimes somebody changes the subject in the middle of a thread. If +this variable is non-@code{nil}, which is the default, the subject +change is ignored. If it is @code{nil}, a change in the subject will +result in a new thread. -@item / S -@kindex / S (Summary) -@findex gnus-summary-limit-to-singletons -Limit the summary buffer to articles that aren't part of any displayed -threads (@code{gnus-summary-limit-to-singletons}). If given a prefix, -limit to articles that are part of displayed threads. +@item gnus-thread-indent-level +@vindex gnus-thread-indent-level +This is a number that says how much each sub-thread should be indented. +The default is 4. -@item / x -@kindex / x (Summary) -@findex gnus-summary-limit-to-extra -Limit the summary buffer to articles that match one of the ``extra'' -headers (@pxref{To From Newsgroups}) -(@code{gnus-summary-limit-to-extra}). If given a prefix, exclude -matching articles. +@item gnus-sort-gathered-threads-function +@vindex gnus-sort-gathered-threads-function +Sometimes, particularly with mailing lists, the order in which mails +arrive locally is not necessarily the same as the order in which they +arrived on the mailing list. Consequently, when sorting sub-threads +using the default @code{gnus-thread-sort-by-number}, responses can end +up appearing before the article to which they are responding to. +Setting this variable to an alternate value +(e.g. @code{gnus-thread-sort-by-date}), in a group's parameters or in an +appropriate hook (e.g. @code{gnus-summary-generate-hook}) can produce a +more logical sub-thread ordering in such instances. -@item / u -@itemx x -@kindex / u (Summary) -@kindex x (Summary) -@findex gnus-summary-limit-to-unread -Limit the summary buffer to articles not marked as read -(@code{gnus-summary-limit-to-unread}). If given a prefix, limit the -buffer to articles strictly unread. This means that ticked and -dormant articles will also be excluded. +@end table -@item / m -@kindex / m (Summary) -@findex gnus-summary-limit-to-marks -Ask for a mark and then limit to all articles that have been marked -with that mark (@code{gnus-summary-limit-to-marks}). -@item / t -@kindex / t (Summary) -@findex gnus-summary-limit-to-age -Ask for a number and then limit the summary buffer to articles older than (or equal to) that number of days -(@code{gnus-summary-limit-to-age}). If given a prefix, limit to -articles younger than that number of days. +@node Low-Level Threading +@subsubsection Low-Level Threading -@item / n -@kindex / n (Summary) -@findex gnus-summary-limit-to-articles -With prefix @samp{n}, limit the summary buffer to the next @samp{n} -articles. If not given a prefix, use the process marked articles -instead. (@code{gnus-summary-limit-to-articles}). +@table @code -@item / w -@kindex / w (Summary) -@findex gnus-summary-pop-limit -Pop the previous limit off the stack and restore it -(@code{gnus-summary-pop-limit}). If given a prefix, pop all limits off -the stack. +@item gnus-parse-headers-hook +@vindex gnus-parse-headers-hook +Hook run before parsing any headers. -@item / . -@kindex / . (Summary) -@findex gnus-summary-limit-to-unseen -Limit the summary buffer to the unseen articles -(@code{gnus-summary-limit-to-unseen}). +@item gnus-alter-header-function +@vindex gnus-alter-header-function +If non-@code{nil}, this function will be called to allow alteration of +article header structures. The function is called with one parameter, +the article header vector, which it may alter in any way. For instance, +if you have a mail-to-news gateway which alters the @code{Message-ID}s +in systematic ways (by adding prefixes and such), you can use this +variable to un-scramble the @code{Message-ID}s so that they are more +meaningful. Here's one example: -@item / v -@kindex / v (Summary) -@findex gnus-summary-limit-to-score -Limit the summary buffer to articles that have a score at or above some -score (@code{gnus-summary-limit-to-score}). +@lisp +(setq gnus-alter-header-function 'my-alter-message-id) -@item / p -@kindex / p (Summary) -@findex gnus-summary-limit-to-display-predicate -Limit the summary buffer to articles that satisfy the @code{display} -group parameter predicate -(@code{gnus-summary-limit-to-display-predicate}). @xref{Group -Parameters}, for more on this predicate. +(defun my-alter-message-id (header) + (let ((id (mail-header-id header))) + (when (string-match + "\\(<[^<>@@]*\\)\\.?cygnus\\..*@@\\([^<>@@]*>\\)" id) + (mail-header-set-id + (concat (match-string 1 id) "@@" (match-string 2 id)) + header)))) +@end lisp -@item / r -@kindex / r (Summary) -@findex gnus-summary-limit-to-replied -Limit the summary buffer to replied articles -(@code{gnus-summary-limit-to-replied}). If given a prefix, exclude -replied articles. +@end table -@item / E -@itemx M S -@kindex M S (Summary) -@kindex / E (Summary) -@findex gnus-summary-limit-include-expunged -Include all expunged articles in the limit -(@code{gnus-summary-limit-include-expunged}). -@item / D -@kindex / D (Summary) -@findex gnus-summary-limit-include-dormant -Include all dormant articles in the limit -(@code{gnus-summary-limit-include-dormant}). +@node Thread Commands +@subsection Thread Commands +@cindex thread commands -@item / * -@kindex / * (Summary) -@findex gnus-summary-limit-include-cached -Include all cached articles in the limit -(@code{gnus-summary-limit-include-cached}). +@table @kbd -@item / d -@kindex / d (Summary) -@findex gnus-summary-limit-exclude-dormant -Exclude all dormant articles from the limit -(@code{gnus-summary-limit-exclude-dormant}). +@item T k +@itemx C-M-k +@kindex T k (Summary) +@kindex C-M-k (Summary) +@findex gnus-summary-kill-thread +Mark all articles in the current (sub-)thread as read +(@code{gnus-summary-kill-thread}). If the prefix argument is positive, +remove all marks instead. If the prefix argument is negative, tick +articles instead. -@item / M -@kindex / M (Summary) -@findex gnus-summary-limit-exclude-marks -Exclude all marked articles (@code{gnus-summary-limit-exclude-marks}). +@item T l +@itemx C-M-l +@kindex T l (Summary) +@kindex C-M-l (Summary) +@findex gnus-summary-lower-thread +Lower the score of the current (sub-)thread +(@code{gnus-summary-lower-thread}). -@item / T -@kindex / T (Summary) -@findex gnus-summary-limit-include-thread -Include all the articles in the current thread in the limit. +@item T i +@kindex T i (Summary) +@findex gnus-summary-raise-thread +Increase the score of the current (sub-)thread +(@code{gnus-summary-raise-thread}). -@item / c -@kindex / c (Summary) -@findex gnus-summary-limit-exclude-childless-dormant -Exclude all dormant articles that have no children from the limit@* -(@code{gnus-summary-limit-exclude-childless-dormant}). +@item T # +@kindex T # (Summary) +@findex gnus-uu-mark-thread +Set the process mark on the current (sub-)thread +(@code{gnus-uu-mark-thread}). -@item / C -@kindex / C (Summary) -@findex gnus-summary-limit-mark-excluded-as-read -Mark all excluded unread articles as read -(@code{gnus-summary-limit-mark-excluded-as-read}). If given a prefix, -also mark excluded ticked and dormant articles as read. +@item T M-# +@kindex T M-# (Summary) +@findex gnus-uu-unmark-thread +Remove the process mark from the current (sub-)thread +(@code{gnus-uu-unmark-thread}). -@item / b -@kindex / b (Summary) -@findex gnus-summary-limit-to-bodies -Limit the summary buffer to articles that have bodies that match a -certain regexp (@code{gnus-summary-limit-to-bodies}). If given a -prefix, reverse the limit. This command is quite slow since it -requires selecting each article to find the matches. +@item T T +@kindex T T (Summary) +@findex gnus-summary-toggle-threads +Toggle threading (@code{gnus-summary-toggle-threads}). + +@item T s +@kindex T s (Summary) +@findex gnus-summary-show-thread +Expose the (sub-)thread hidden under the current article, if any@* +(@code{gnus-summary-show-thread}). -@item / h -@kindex / h (Summary) -@findex gnus-summary-limit-to-headers -Like the previous command, only limit to headers instead -(@code{gnus-summary-limit-to-headers}). +@item T h +@kindex T h (Summary) +@findex gnus-summary-hide-thread +Hide the current (sub-)thread (@code{gnus-summary-hide-thread}). -@end table +@item T S +@kindex T S (Summary) +@findex gnus-summary-show-all-threads +Expose all hidden threads (@code{gnus-summary-show-all-threads}). +@item T H +@kindex T H (Summary) +@findex gnus-summary-hide-all-threads +Hide all threads (@code{gnus-summary-hide-all-threads}). -The following commands aren't limiting commands, but use the @kbd{/} -prefix as well. +@item T t +@kindex T t (Summary) +@findex gnus-summary-rethread-current +Re-thread the current article's thread +(@code{gnus-summary-rethread-current}). This works even when the +summary buffer is otherwise unthreaded. -@table @kbd -@item / N -@kindex / N (Summary) -@findex gnus-summary-insert-new-articles -Insert all new articles in the summary buffer. It scans for new emails -if @var{back-end}@code{-get-new-mail} is non-@code{nil}. +@item T ^ +@kindex T ^ (Summary) +@findex gnus-summary-reparent-thread +Make the current article the child of the marked (or previous) article +(@code{gnus-summary-reparent-thread}). -@item / o -@kindex / o (Summary) -@findex gnus-summary-insert-old-articles -Insert all old articles in the summary buffer. If given a numbered -prefix, fetch this number of articles. +@item T M-^ +@kindex T M-^ (Summary) +@findex gnus-summary-reparent-children +Make the current article the parent of the marked articles +(@code{gnus-summary-reparent-children}). @end table +The following commands are thread movement commands. They all +understand the numeric prefix. -@node Threading -@section Threading -@cindex threading -@cindex article threading +@table @kbd -Gnus threads articles by default. @dfn{To thread} is to put responses -to articles directly after the articles they respond to---in a -hierarchical fashion. +@item T n +@kindex T n (Summary) +@itemx C-M-f +@kindex C-M-n (Summary) +@itemx M-down +@kindex M-down (Summary) +@findex gnus-summary-next-thread +Go to the next thread (@code{gnus-summary-next-thread}). -Threading is done by looking at the @code{References} headers of the -articles. In a perfect world, this would be enough to build pretty -trees, but unfortunately, the @code{References} header is often broken -or simply missing. Weird news propagation exacerbates the problem, -so one has to employ other heuristics to get pleasing results. A -plethora of approaches exists, as detailed in horrible detail in -@ref{Customizing Threading}. +@item T p +@kindex T p (Summary) +@itemx C-M-b +@kindex C-M-p (Summary) +@itemx M-up +@kindex M-up (Summary) +@findex gnus-summary-prev-thread +Go to the previous thread (@code{gnus-summary-prev-thread}). -First, a quick overview of the concepts: +@item T d +@kindex T d (Summary) +@findex gnus-summary-down-thread +Descend the thread (@code{gnus-summary-down-thread}). -@table @dfn -@item root -The top-most article in a thread; the first article in the thread. +@item T u +@kindex T u (Summary) +@findex gnus-summary-up-thread +Ascend the thread (@code{gnus-summary-up-thread}). -@item thread -A tree-like article structure. +@item T o +@kindex T o (Summary) +@findex gnus-summary-top-thread +Go to the top of the thread (@code{gnus-summary-top-thread}). +@end table -@item sub-thread -A small(er) section of this tree-like structure. +@vindex gnus-thread-operation-ignore-subject +If you ignore subject while threading, you'll naturally end up with +threads that have several different subjects in them. If you then issue +a command like @kbd{T k} (@code{gnus-summary-kill-thread}) you might not +wish to kill the entire thread, but just those parts of the thread that +have the same subject as the current article. If you like this idea, +you can fiddle with @code{gnus-thread-operation-ignore-subject}. If it +is non-@code{nil} (which it is by default), subjects will be ignored +when doing thread commands. If this variable is @code{nil}, articles in +the same thread with different subjects will not be included in the +operation in question. If this variable is @code{fuzzy}, only articles +that have subjects fuzzily equal will be included (@pxref{Fuzzy +Matching}). -@item loose threads -Threads often lose their roots due to article expiry, or due to the root -already having been read in a previous session, and not displayed in the -summary buffer. We then typically have many sub-threads that really -belong to one thread, but are without connecting roots. These are -called loose threads. -@item thread gathering -An attempt to gather loose threads into bigger threads. +@node Sorting the Summary Buffer +@section Sorting the Summary Buffer -@item sparse threads -A thread where the missing articles have been ``guessed'' at, and are -displayed as empty lines in the summary buffer. +@findex gnus-thread-sort-by-total-score +@findex gnus-thread-sort-by-date +@findex gnus-thread-sort-by-score +@findex gnus-thread-sort-by-subject +@findex gnus-thread-sort-by-author +@findex gnus-thread-sort-by-recipient +@findex gnus-thread-sort-by-number +@findex gnus-thread-sort-by-random +@vindex gnus-thread-sort-functions +@findex gnus-thread-sort-by-most-recent-number +@findex gnus-thread-sort-by-most-recent-date +If you are using a threaded summary display, you can sort the threads by +setting @code{gnus-thread-sort-functions}, which can be either a single +function, a list of functions, or a list containing functions and +@code{(not some-function)} elements. -@end table +By default, sorting is done on article numbers. Ready-made sorting +predicate functions include @code{gnus-thread-sort-by-number}, +@code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-recipient}, +@code{gnus-thread-sort-by-subject}, +@code{gnus-thread-sort-by-date}, +@code{gnus-thread-sort-by-score}, +@code{gnus-thread-sort-by-most-recent-number}, +@code{gnus-thread-sort-by-most-recent-date}, +@code{gnus-thread-sort-by-random} and +@code{gnus-thread-sort-by-total-score}. +Each function takes two threads and returns non-@code{nil} if the first +thread should be sorted before the other. Note that sorting really is +normally done by looking only at the roots of each thread. -@menu -* Customizing Threading:: Variables you can change to affect the threading. -* Thread Commands:: Thread based commands in the summary buffer. -@end menu +If you use more than one function, the primary sort key should be the +last function in the list. You should probably always include +@code{gnus-thread-sort-by-number} in the list of sorting +functions---preferably first. This will ensure that threads that are +equal with respect to the other sort criteria will be displayed in +ascending article order. +If you would like to sort by reverse score, then by subject, and finally +by number, you could do something like: -@node Customizing Threading -@subsection Customizing Threading -@cindex customizing threading +@lisp +(setq gnus-thread-sort-functions + '(gnus-thread-sort-by-number + gnus-thread-sort-by-subject + (not gnus-thread-sort-by-total-score))) +@end lisp -@menu -* Loose Threads:: How Gnus gathers loose threads into bigger threads. -* Filling In Threads:: Making the threads displayed look fuller. -* More Threading:: Even more variables for fiddling with threads. -* Low-Level Threading:: You thought it was over@dots{} but you were wrong! -@end menu +The threads that have highest score will be displayed first in the +summary buffer. When threads have the same score, they will be sorted +alphabetically. The threads that have the same score and the same +subject will be sorted by number, which is (normally) the sequence in +which the articles arrived. +If you want to sort by score and then reverse arrival order, you could +say something like: -@node Loose Threads -@subsubsection Loose Threads -@cindex < -@cindex > -@cindex loose threads +@lisp +(setq gnus-thread-sort-functions + '((not gnus-thread-sort-by-number) + gnus-thread-sort-by-score)) +@end lisp -@table @code -@item gnus-summary-make-false-root -@vindex gnus-summary-make-false-root -If non-@code{nil}, Gnus will gather all loose subtrees into one big tree -and create a dummy root at the top. (Wait a minute. Root at the top? -Yup.) Loose subtrees occur when the real root has expired, or you've -read or killed the root in a previous session. +@vindex gnus-thread-score-function +The function in the @code{gnus-thread-score-function} variable (default +@code{+}) is used for calculating the total score of a thread. Useful +functions might be @code{max}, @code{min}, or squared means, or whatever +tickles your fancy. -When there is no real root of a thread, Gnus will have to fudge -something. This variable says what fudging method Gnus should use. -There are four possible values: +@findex gnus-article-sort-functions +@findex gnus-article-sort-by-date +@findex gnus-article-sort-by-most-recent-date +@findex gnus-article-sort-by-score +@findex gnus-article-sort-by-subject +@findex gnus-article-sort-by-author +@findex gnus-article-sort-by-random +@findex gnus-article-sort-by-number +@findex gnus-article-sort-by-most-recent-number +If you are using an unthreaded display for some strange reason or +other, you have to fiddle with the @code{gnus-article-sort-functions} +variable. It is very similar to the +@code{gnus-thread-sort-functions}, except that it uses slightly +different functions for article comparison. Available sorting +predicate functions are @code{gnus-article-sort-by-number}, +@code{gnus-article-sort-by-author}, +@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date}, +@code{gnus-article-sort-by-random}, and +@code{gnus-article-sort-by-score}. -@iftex -@iflatex -\gnusfigure{The Summary Buffer}{390}{ -\put(0,0){\epsfig{figure=ps/summary-adopt,width=7.5cm}} -\put(445,0){\makebox(0,0)[br]{\epsfig{figure=ps/summary-empty,width=7.5cm}}} -\put(0,400){\makebox(0,0)[tl]{\epsfig{figure=ps/summary-none,width=7.5cm}}} -\put(445,400){\makebox(0,0)[tr]{\epsfig{figure=ps/summary-dummy,width=7.5cm}}} -} -@end iflatex -@end iftex +If you want to sort an unthreaded summary display by subject, you could +say something like: + +@lisp +(setq gnus-article-sort-functions + '(gnus-article-sort-by-number + gnus-article-sort-by-subject)) +@end lisp -@cindex adopting articles +You can define group specific sorting via @code{gnus-parameters}, +@xref{Group Parameters}. -@table @code -@item adopt -Gnus will make the first of the orphaned articles the parent. This -parent will adopt all the other articles. The adopted articles will be -marked as such by pointy brackets (@samp{<>}) instead of the standard -square brackets (@samp{[]}). This is the default method. +@node Asynchronous Fetching +@section Asynchronous Article Fetching +@cindex asynchronous article fetching +@cindex article pre-fetch +@cindex pre-fetch -@item dummy -@vindex gnus-summary-dummy-line-format -@vindex gnus-summary-make-false-root-always -Gnus will create a dummy summary line that will pretend to be the -parent. This dummy line does not correspond to any real article, so -selecting it will just select the first real article after the dummy -article. @code{gnus-summary-dummy-line-format} is used to specify the -format of the dummy roots. It accepts only one format spec: @samp{S}, -which is the subject of the article. @xref{Formatting Variables}. -If you want all threads to have a dummy root, even the non-gathered -ones, set @code{gnus-summary-make-false-root-always} to @code{t}. +If you read your news from an @acronym{NNTP} server that's far away, the +network latencies may make reading articles a chore. You have to wait +for a while after pressing @kbd{n} to go to the next article before the +article appears. Why can't Gnus just go ahead and fetch the article +while you are reading the previous one? Why not, indeed. -@item empty -Gnus won't actually make any article the parent, but simply leave the -subject field of all orphans except the first empty. (Actually, it will -use @code{gnus-summary-same-subject} as the subject (@pxref{Summary -Buffer Format}).) +First, some caveats. There are some pitfalls to using asynchronous +article fetching, especially the way Gnus does it. -@item none -Don't make any article parent at all. Just gather the threads and -display them after one another. +Let's say you are reading article 1, which is short, and article 2 is +quite long, and you are not interested in reading that. Gnus does not +know this, so it goes ahead and fetches article 2. You decide to read +article 3, but since Gnus is in the process of fetching article 2, the +connection is blocked. -@item nil -Don't gather loose threads. -@end table +To avoid these situations, Gnus will open two (count 'em two) +connections to the server. Some people may think this isn't a very nice +thing to do, but I don't see any real alternatives. Setting up that +extra connection takes some time, so Gnus startup will be slower. -@item gnus-summary-gather-subject-limit -@vindex gnus-summary-gather-subject-limit -Loose threads are gathered by comparing subjects of articles. If this -variable is @code{nil}, Gnus requires an exact match between the -subjects of the loose threads before gathering them into one big -super-thread. This might be too strict a requirement, what with the -presence of stupid newsreaders that chop off long subject lines. If -you think so, set this variable to, say, 20 to require that only the -first 20 characters of the subjects have to match. If you set this -variable to a really low number, you'll find that Gnus will gather -everything in sight into one thread, which isn't very helpful. +Gnus will fetch more articles than you will read. This will mean that +the link between your machine and the @acronym{NNTP} server will become more +loaded than if you didn't use article pre-fetch. The server itself will +also become more loaded---both with the extra article requests, and the +extra connection. -@cindex fuzzy article gathering -If you set this variable to the special value @code{fuzzy}, Gnus will -use a fuzzy string comparison algorithm on the subjects (@pxref{Fuzzy -Matching}). +Ok, so now you know that you shouldn't really use this thing@dots{} unless +you really want to. -@item gnus-simplify-subject-fuzzy-regexp -@vindex gnus-simplify-subject-fuzzy-regexp -This can either be a regular expression or list of regular expressions -that match strings that will be removed from subjects if fuzzy subject -simplification is used. +@vindex gnus-asynchronous +Here's how: Set @code{gnus-asynchronous} to @code{t}. The rest should +happen automatically. -@item gnus-simplify-ignored-prefixes -@vindex gnus-simplify-ignored-prefixes -If you set @code{gnus-summary-gather-subject-limit} to something as low -as 10, you might consider setting this variable to something sensible: +@vindex gnus-use-article-prefetch +You can control how many articles are to be pre-fetched by setting +@code{gnus-use-article-prefetch}. This is 30 by default, which means +that when you read an article in the group, the back end will pre-fetch +the next 30 articles. If this variable is @code{t}, the back end will +pre-fetch all the articles it can without bound. If it is +@code{nil}, no pre-fetching will be done. + +@vindex gnus-async-prefetch-article-p +@findex gnus-async-unread-p +There are probably some articles that you don't want to pre-fetch---read +articles, for instance. The @code{gnus-async-prefetch-article-p} +variable controls whether an article is to be pre-fetched. This +function should return non-@code{nil} when the article in question is +to be pre-fetched. The default is @code{gnus-async-unread-p}, which +returns @code{nil} on read articles. The function is called with an +article data structure as the only parameter. + +If, for instance, you wish to pre-fetch only unread articles shorter +than 100 lines, you could say something like: -@c Written by Michael Ernst @lisp -(setq gnus-simplify-ignored-prefixes - (concat - "\\`\\[?\\(" - (mapconcat - 'identity - '("looking" - "wanted" "followup" "summary\\( of\\)?" - "help" "query" "problem" "question" - "answer" "reference" "announce" - "How can I" "How to" "Comparison of" - ;; ... - ) - "\\|") - "\\)\\s *\\(" - (mapconcat 'identity - '("for" "for reference" "with" "about") - "\\|") - "\\)?\\]?:?[ \t]*")) +(defun my-async-short-unread-p (data) + "Return non-nil for short, unread articles." + (and (gnus-data-unread-p data) + (< (mail-header-lines (gnus-data-header data)) + 100))) + +(setq gnus-async-prefetch-article-p 'my-async-short-unread-p) @end lisp -All words that match this regexp will be removed before comparing two -subjects. +These functions will be called many, many times, so they should +preferably be short and sweet to avoid slowing down Gnus too much. +It's probably a good idea to byte-compile things like this. -@item gnus-simplify-subject-functions -@vindex gnus-simplify-subject-functions -If non-@code{nil}, this variable overrides -@code{gnus-summary-gather-subject-limit}. This variable should be a -list of functions to apply to the @code{Subject} string iteratively to -arrive at the simplified version of the string. +@vindex gnus-async-post-fetch-function +@findex gnus-html-prefetch-images +After an article has been prefetched, this +@code{gnus-async-post-fetch-function} will be called. The buffer will +be narrowed to the region of the article that was fetched. A useful +value would be @code{gnus-html-prefetch-images}, which will prefetch +and store images referenced in the article, so that you don't have to +wait for them to be fetched when you read the article. This is useful +for @acronym{HTML} messages that have external images. -Useful functions to put in this list include: +@vindex gnus-prefetched-article-deletion-strategy +Articles have to be removed from the asynch buffer sooner or later. The +@code{gnus-prefetched-article-deletion-strategy} says when to remove +articles. This is a list that may contain the following elements: @table @code -@item gnus-simplify-subject-re -@findex gnus-simplify-subject-re -Strip the leading @samp{Re:}. +@item read +Remove articles when they are read. -@item gnus-simplify-subject-fuzzy -@findex gnus-simplify-subject-fuzzy -Simplify fuzzily. +@item exit +Remove articles when exiting the group. +@end table -@item gnus-simplify-whitespace -@findex gnus-simplify-whitespace -Remove excessive whitespace. +The default value is @code{(read exit)}. -@item gnus-simplify-all-whitespace -@findex gnus-simplify-all-whitespace -Remove all whitespace. -@end table +@c @vindex gnus-use-header-prefetch +@c If @code{gnus-use-header-prefetch} is non-@code{nil}, prefetch articles +@c from the next group. -You may also write your own functions, of course. +@node Article Caching +@section Article Caching +@cindex article caching +@cindex caching -@item gnus-summary-gather-exclude-subject -@vindex gnus-summary-gather-exclude-subject -Since loose thread gathering is done on subjects only, that might lead -to many false hits, especially with certain common subjects like -@samp{} and @samp{(none)}. To make the situation slightly better, -you can use the regexp @code{gnus-summary-gather-exclude-subject} to say -what subjects should be excluded from the gathering process.@* -The default is @samp{^ *$\\|^(none)$}. +If you have an @emph{extremely} slow @acronym{NNTP} connection, you may +consider turning article caching on. Each article will then be stored +locally under your home directory. As you may surmise, this could +potentially use @emph{huge} amounts of disk space, as well as eat up all +your inodes so fast it will make your head swim. In vodka. -@item gnus-summary-thread-gathering-function -@vindex gnus-summary-thread-gathering-function -Gnus gathers threads by looking at @code{Subject} headers. This means -that totally unrelated articles may end up in the same ``thread'', which -is confusing. An alternate approach is to look at all the -@code{Message-ID}s in all the @code{References} headers to find matches. -This will ensure that no gathered threads ever include unrelated -articles, but it also means that people who have posted with broken -newsreaders won't be gathered properly. The choice is yours---plague or -cholera: +Used carefully, though, it could be just an easier way to save articles. -@table @code -@item gnus-gather-threads-by-subject -@findex gnus-gather-threads-by-subject -This function is the default gathering function and looks at -@code{Subject}s exclusively. +@vindex gnus-use-long-file-name +@vindex gnus-cache-directory +@vindex gnus-use-cache +To turn caching on, set @code{gnus-use-cache} to @code{t}. By default, +all articles ticked or marked as dormant will then be copied +over to your local cache (@code{gnus-cache-directory}). Whether this +cache is flat or hierarchical is controlled by the +@code{gnus-use-long-file-name} variable, as usual. -@item gnus-gather-threads-by-references -@findex gnus-gather-threads-by-references -This function looks at @code{References} headers exclusively. -@end table +When re-selecting a ticked or dormant article, it will be fetched from the +cache instead of from the server. As articles in your cache will never +expire, this might serve as a method of saving articles while still +keeping them where they belong. Just mark all articles you want to save +as dormant, and don't worry. -If you want to test gathering by @code{References}, you could say -something like: +When an article is marked as read, is it removed from the cache. -@lisp -(setq gnus-summary-thread-gathering-function - 'gnus-gather-threads-by-references) -@end lisp +@vindex gnus-cache-remove-articles +@vindex gnus-cache-enter-articles +The entering/removal of articles from the cache is controlled by the +@code{gnus-cache-enter-articles} and @code{gnus-cache-remove-articles} +variables. Both are lists of symbols. The first is @code{(ticked +dormant)} by default, meaning that ticked and dormant articles will be +put in the cache. The latter is @code{(read)} by default, meaning that +articles marked as read are removed from the cache. Possibly +symbols in these two lists are @code{ticked}, @code{dormant}, +@code{unread} and @code{read}. -@end table +@findex gnus-jog-cache +So where does the massive article-fetching and storing come into the +picture? The @code{gnus-jog-cache} command will go through all +subscribed newsgroups, request all unread articles, score them, and +store them in the cache. You should only ever, ever ever ever, use this +command if 1) your connection to the @acronym{NNTP} server is really, really, +really slow and 2) you have a really, really, really huge disk. +Seriously. One way to cut down on the number of articles downloaded is +to score unwanted articles down and have them marked as read. They will +not then be downloaded by this command. +@vindex gnus-uncacheable-groups +@vindex gnus-cacheable-groups +It is likely that you do not want caching on all groups. For instance, +if your @code{nnml} mail is located under your home directory, it makes no +sense to cache it somewhere else under your home directory. Unless you +feel that it's neat to use twice as much space. -@node Filling In Threads -@subsubsection Filling In Threads +To limit the caching, you could set @code{gnus-cacheable-groups} to a +regexp of groups to cache, @samp{^nntp} for instance, or set the +@code{gnus-uncacheable-groups} regexp to @samp{^nnml}, for instance. +Both variables are @code{nil} by default. If a group matches both +variables, the group is not cached. -@table @code -@item gnus-fetch-old-headers -@vindex gnus-fetch-old-headers -If non-@code{nil}, Gnus will attempt to build old threads by fetching -more old headers---headers to articles marked as read. If you would -like to display as few summary lines as possible, but still connect as -many loose threads as possible, you should set this variable to -@code{some} or a number. If you set it to a number, no more than that -number of extra old headers will be fetched. In either case, fetching -old headers only works if the back end you are using carries overview -files---this would normally be @code{nntp}, @code{nnspool}, -@code{nnml}, and @code{nnmaildir}. Also remember that if the root of -the thread has been expired by the server, there's not much Gnus can -do about that. +@findex gnus-cache-generate-nov-databases +@findex gnus-cache-generate-active +@vindex gnus-cache-active-file +The cache stores information on what articles it contains in its active +file (@code{gnus-cache-active-file}). If this file (or any other parts +of the cache) becomes all messed up for some reason or other, Gnus +offers two functions that will try to set things right. @kbd{M-x +gnus-cache-generate-nov-databases} will (re)build all the @acronym{NOV} +files, and @kbd{gnus-cache-generate-active} will (re)generate the active +file. -This variable can also be set to @code{invisible}. This won't have any -visible effects, but is useful if you use the @kbd{A T} command a lot -(@pxref{Finding the Parent}). +@findex gnus-cache-move-cache +@code{gnus-cache-move-cache} will move your whole +@code{gnus-cache-directory} to some other location. You get asked to +where, isn't that cool? -The server has to support @acronym{NOV} for any of this to work. +@node Persistent Articles +@section Persistent Articles +@cindex persistent articles -@cindex Gmane, gnus-fetch-old-headers -This feature can seriously impact performance it ignores all locally -cached header entries. Setting it to @code{t} for groups for a server -that doesn't expire articles (such as news.gmane.org), leads to very -slow summary generation. +Closely related to article caching, we have @dfn{persistent articles}. +In fact, it's just a different way of looking at caching, and much more +useful in my opinion. -@item gnus-fetch-old-ephemeral-headers -@vindex gnus-fetch-old-ephemeral-headers -Same as @code{gnus-fetch-old-headers}, but only used for ephemeral -newsgroups. +Say you're reading a newsgroup, and you happen on to some valuable gem +that you want to keep and treasure forever. You'd normally just save it +(using one of the many saving commands) in some file. The problem with +that is that it's just, well, yucky. Ideally you'd prefer just having +the article remain in the group where you found it forever; untouched by +the expiry going on at the news server. -@item gnus-build-sparse-threads -@vindex gnus-build-sparse-threads -Fetching old headers can be slow. A low-rent similar effect can be -gotten by setting this variable to @code{some}. Gnus will then look at -the complete @code{References} headers of all articles and try to string -together articles that belong in the same thread. This will leave -@dfn{gaps} in the threading display where Gnus guesses that an article -is missing from the thread. (These gaps appear like normal summary -lines. If you select a gap, Gnus will try to fetch the article in -question.) If this variable is @code{t}, Gnus will display all these -``gaps'' without regard for whether they are useful for completing the -thread or not. Finally, if this variable is @code{more}, Gnus won't cut -off sparse leaf nodes that don't lead anywhere. This variable is -@code{nil} by default. +This is what a @dfn{persistent article} is---an article that just won't +be deleted. It's implemented using the normal cache functions, but +you use two explicit commands for managing persistent articles: -@item gnus-read-all-available-headers -@vindex gnus-read-all-available-headers -This is a rather obscure variable that few will find useful. It's -intended for those non-news newsgroups where the back end has to fetch -quite a lot to present the summary buffer, and where it's impossible to -go back to parents of articles. This is mostly the case in the -web-based groups. +@table @kbd -If you don't use those, then it's safe to leave this as the default -@code{nil}. If you want to use this variable, it should be a regexp -that matches the group name, or @code{t} for all groups. +@item * +@kindex * (Summary) +@findex gnus-cache-enter-article +Make the current article persistent (@code{gnus-cache-enter-article}). +@item M-* +@kindex M-* (Summary) +@findex gnus-cache-remove-article +Remove the current article from the persistent articles +(@code{gnus-cache-remove-article}). This will normally delete the +article. @end table +Both these commands understand the process/prefix convention. -@node More Threading -@subsubsection More Threading +To avoid having all ticked articles (and stuff) entered into the cache, +you should set @code{gnus-use-cache} to @code{passive} if you're just +interested in persistent articles: -@table @code -@item gnus-show-threads -@vindex gnus-show-threads -If this variable is @code{nil}, no threading will be done, and all of -the rest of the variables here will have no effect. Turning threading -off will speed group selection up a bit, but it is sure to make reading -slower and more awkward. +@lisp +(setq gnus-use-cache 'passive) +@end lisp -@item gnus-thread-hide-subtree -@vindex gnus-thread-hide-subtree -If non-@code{nil}, all threads will be hidden when the summary buffer is -generated. +@node Sticky Articles +@section Sticky Articles +@cindex sticky articles -This can also be a predicate specifier (@pxref{Predicate Specifiers}). -Available predicates are @code{gnus-article-unread-p} and -@code{gnus-article-unseen-p}. +When you select an article the current article buffer will be reused +according to the value of the variable +@code{gnus-single-article-buffer}. If its value is non-@code{nil} (the +default) all articles reuse the same article buffer. Else each group +has its own article buffer. -Here's an example: +This implies that it's not possible to have more than one article buffer +in a group at a time. But sometimes you might want to display all the +latest emails from your mother, your father, your aunt, your uncle and +your 17 cousins to coordinate the next christmas party. -@lisp -(setq gnus-thread-hide-subtree - '(or gnus-article-unread-p - gnus-article-unseen-p)) -@end lisp +That's where sticky articles come in handy. A sticky article buffer +basically is a normal article buffer, but it won't be reused when you +select another article. You can make an article sticky with: -(It's a pretty nonsensical example, since all unseen articles are also -unread, but you get my drift.) +@table @kbd +@item A S +@kindex A S (Summary) +@findex gnus-sticky-article +Make the current article sticky. If a prefix arg is given, ask for a +name for this sticky article buffer. +@end table +To close a sticky article buffer you can use these commands: -@item gnus-thread-expunge-below -@vindex gnus-thread-expunge-below -All threads that have a total score (as defined by -@code{gnus-thread-score-function}) less than this number will be -expunged. This variable is @code{nil} by default, which means that no -threads are expunged. +@table @kbd +@item q +@kindex q (Article) +@findex bury-buffer +Puts this sticky article buffer at the end of the list of all buffers. -@item gnus-thread-hide-killed -@vindex gnus-thread-hide-killed -if you kill a thread and this variable is non-@code{nil}, the subtree -will be hidden. +@item k +@kindex k (Article) +@findex gnus-kill-sticky-article-buffer +Kills this sticky article buffer. +@end table -@item gnus-thread-ignore-subject -@vindex gnus-thread-ignore-subject -Sometimes somebody changes the subject in the middle of a thread. If -this variable is non-@code{nil}, which is the default, the subject -change is ignored. If it is @code{nil}, a change in the subject will -result in a new thread. +To kill all sticky article buffers you can use: -@item gnus-thread-indent-level -@vindex gnus-thread-indent-level -This is a number that says how much each sub-thread should be indented. -The default is 4. +@defun gnus-kill-sticky-article-buffers ARG +Kill all sticky article buffers. +If a prefix ARG is given, ask for confirmation. +@end defun -@item gnus-sort-gathered-threads-function -@vindex gnus-sort-gathered-threads-function -Sometimes, particularly with mailing lists, the order in which mails -arrive locally is not necessarily the same as the order in which they -arrived on the mailing list. Consequently, when sorting sub-threads -using the default @code{gnus-thread-sort-by-number}, responses can end -up appearing before the article to which they are responding to. -Setting this variable to an alternate value -(e.g. @code{gnus-thread-sort-by-date}), in a group's parameters or in an -appropriate hook (e.g. @code{gnus-summary-generate-hook}) can produce a -more logical sub-thread ordering in such instances. +@node Article Backlog +@section Article Backlog +@cindex backlog +@cindex article backlog -@end table +If you have a slow connection, but the idea of using caching seems +unappealing to you (and it is, really), you can help the situation some +by switching on the @dfn{backlog}. This is where Gnus will buffer +already read articles so that it doesn't have to re-fetch articles +you've already read. This only helps if you are in the habit of +re-selecting articles you've recently read, of course. If you never do +that, turning the backlog on will slow Gnus down a little bit, and +increase memory usage some. + +@vindex gnus-keep-backlog +If you set @code{gnus-keep-backlog} to a number @var{n}, Gnus will store +at most @var{n} old articles in a buffer for later re-fetching. If this +variable is non-@code{nil} and is not a number, Gnus will store +@emph{all} read articles, which means that your Emacs will grow without +bound before exploding and taking your machine down with you. I put +that in there just to keep y'all on your toes. +The default value is 20. -@node Low-Level Threading -@subsubsection Low-Level Threading -@table @code +@node Saving Articles +@section Saving Articles +@cindex saving articles -@item gnus-parse-headers-hook -@vindex gnus-parse-headers-hook -Hook run before parsing any headers. +Gnus can save articles in a number of ways. Below is the documentation +for saving articles in a fairly straight-forward fashion (i.e., little +processing of the article is done before it is saved). For a different +approach (uudecoding, unsharing) you should use @code{gnus-uu} +(@pxref{Decoding Articles}). -@item gnus-alter-header-function -@vindex gnus-alter-header-function -If non-@code{nil}, this function will be called to allow alteration of -article header structures. The function is called with one parameter, -the article header vector, which it may alter in any way. For instance, -if you have a mail-to-news gateway which alters the @code{Message-ID}s -in systematic ways (by adding prefixes and such), you can use this -variable to un-scramble the @code{Message-ID}s so that they are more -meaningful. Here's one example: +For the commands listed here, the target is a file. If you want to +save to a group, see the @kbd{B c} (@code{gnus-summary-copy-article}) +command (@pxref{Mail Group Commands}). + +@vindex gnus-save-all-headers +If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete +unwanted headers before saving the article. -@lisp -(setq gnus-alter-header-function 'my-alter-message-id) +@vindex gnus-saved-headers +If the preceding variable is @code{nil}, all headers that match the +@code{gnus-saved-headers} regexp will be kept, while the rest will be +deleted before saving. -(defun my-alter-message-id (header) - (let ((id (mail-header-id header))) - (when (string-match - "\\(<[^<>@@]*\\)\\.?cygnus\\..*@@\\([^<>@@]*>\\)" id) - (mail-header-set-id - (concat (match-string 1 id) "@@" (match-string 2 id)) - header)))) -@end lisp +@table @kbd -@end table +@item O o +@itemx o +@kindex O o (Summary) +@kindex o (Summary) +@findex gnus-summary-save-article +@c @icon{gnus-summary-save-article} +Save the current article using the default article saver +(@code{gnus-summary-save-article}). +@item O m +@kindex O m (Summary) +@findex gnus-summary-save-article-mail +Save the current article in a Unix mail box (mbox) file +(@code{gnus-summary-save-article-mail}). -@node Thread Commands -@subsection Thread Commands -@cindex thread commands +@item O r +@kindex O r (Summary) +@findex gnus-summary-save-article-rmail +Save the current article in Rmail format +(@code{gnus-summary-save-article-rmail}). This is mbox since Emacs 23, +Babyl in older versions. -@table @kbd +@item O f +@kindex O f (Summary) +@findex gnus-summary-save-article-file +@c @icon{gnus-summary-save-article-file} +Save the current article in plain file format +(@code{gnus-summary-save-article-file}). -@item T k -@itemx C-M-k -@kindex T k (Summary) -@kindex C-M-k (Summary) -@findex gnus-summary-kill-thread -Mark all articles in the current (sub-)thread as read -(@code{gnus-summary-kill-thread}). If the prefix argument is positive, -remove all marks instead. If the prefix argument is negative, tick -articles instead. +@item O F +@kindex O F (Summary) +@findex gnus-summary-write-article-file +Write the current article in plain file format, overwriting any previous +file contents (@code{gnus-summary-write-article-file}). -@item T l -@itemx C-M-l -@kindex T l (Summary) -@kindex C-M-l (Summary) -@findex gnus-summary-lower-thread -Lower the score of the current (sub-)thread -(@code{gnus-summary-lower-thread}). +@item O b +@kindex O b (Summary) +@findex gnus-summary-save-article-body-file +Save the current article body in plain file format +(@code{gnus-summary-save-article-body-file}). -@item T i -@kindex T i (Summary) -@findex gnus-summary-raise-thread -Increase the score of the current (sub-)thread -(@code{gnus-summary-raise-thread}). +@item O h +@kindex O h (Summary) +@findex gnus-summary-save-article-folder +Save the current article in mh folder format +(@code{gnus-summary-save-article-folder}). -@item T # -@kindex T # (Summary) -@findex gnus-uu-mark-thread -Set the process mark on the current (sub-)thread -(@code{gnus-uu-mark-thread}). +@item O v +@kindex O v (Summary) +@findex gnus-summary-save-article-vm +Save the current article in a VM folder +(@code{gnus-summary-save-article-vm}). -@item T M-# -@kindex T M-# (Summary) -@findex gnus-uu-unmark-thread -Remove the process mark from the current (sub-)thread -(@code{gnus-uu-unmark-thread}). +@item O p +@itemx | +@kindex O p (Summary) +@kindex | (Summary) +@findex gnus-summary-pipe-output +@vindex gnus-summary-pipe-output-default-command +Save the current article in a pipe. Uhm, like, what I mean is---Pipe +the current article to a process (@code{gnus-summary-pipe-output}). +If given a symbolic prefix (@pxref{Symbolic Prefixes}), include the +complete headers in the piped output. The symbolic prefix @code{r} is +special; it lets this command pipe a raw article including all headers. +The @code{gnus-summary-pipe-output-default-command} variable can be set +to a string containing the default command and options (default +@code{nil}). -@item T T -@kindex T T (Summary) -@findex gnus-summary-toggle-threads -Toggle threading (@code{gnus-summary-toggle-threads}). +@item O P +@kindex O P (Summary) +@findex gnus-summary-muttprint +@vindex gnus-summary-muttprint-program +Save the current article into muttprint. That is, print it using the +external program @uref{http://muttprint.sourceforge.net/, +Muttprint}. The program name and options to use is controlled by the +variable @code{gnus-summary-muttprint-program}. +(@code{gnus-summary-muttprint}). -@item T s -@kindex T s (Summary) -@findex gnus-summary-show-thread -Expose the (sub-)thread hidden under the current article, if any@* -(@code{gnus-summary-show-thread}). +@end table -@item T h -@kindex T h (Summary) -@findex gnus-summary-hide-thread -Hide the current (sub-)thread (@code{gnus-summary-hide-thread}). +@vindex gnus-prompt-before-saving +All these commands use the process/prefix convention +(@pxref{Process/Prefix}). If you save bunches of articles using these +functions, you might get tired of being prompted for files to save each +and every article in. The prompting action is controlled by +the @code{gnus-prompt-before-saving} variable, which is @code{always} by +default, giving you that excessive prompting action you know and +loathe. If you set this variable to @code{t} instead, you'll be prompted +just once for each series of articles you save. If you like to really +have Gnus do all your thinking for you, you can even set this variable +to @code{nil}, which means that you will never be prompted for files to +save articles in. Gnus will simply save all the articles in the default +files. -@item T S -@kindex T S (Summary) -@findex gnus-summary-show-all-threads -Expose all hidden threads (@code{gnus-summary-show-all-threads}). -@item T H -@kindex T H (Summary) -@findex gnus-summary-hide-all-threads -Hide all threads (@code{gnus-summary-hide-all-threads}). +@vindex gnus-default-article-saver +You can customize the @code{gnus-default-article-saver} variable to make +Gnus do what you want it to. You can use any of the eight ready-made +functions below, or you can create your own. -@item T t -@kindex T t (Summary) -@findex gnus-summary-rethread-current -Re-thread the current article's thread -(@code{gnus-summary-rethread-current}). This works even when the -summary buffer is otherwise unthreaded. +@table @code -@item T ^ -@kindex T ^ (Summary) -@findex gnus-summary-reparent-thread -Make the current article the child of the marked (or previous) article -(@code{gnus-summary-reparent-thread}). +@item gnus-summary-save-in-rmail +@findex gnus-summary-save-in-rmail +@vindex gnus-rmail-save-name +@findex gnus-plain-save-name +This is the default format, that used by the Rmail package. Since Emacs +23, Rmail uses standard mbox format. Before this, it used the +@dfn{Babyl} format. Accordingly, this command writes mbox format since +Emacs 23, unless appending to an existing Babyl file. In older versions +of Emacs, it always uses Babyl format. Uses the function in the +@code{gnus-rmail-save-name} variable to get a file name to save the +article in. The default is @code{gnus-plain-save-name}. -@item T M-^ -@kindex T M-^ (Summary) -@findex gnus-summary-reparent-children -Make the current article the parent of the marked articles -(@code{gnus-summary-reparent-children}). +@item gnus-summary-save-in-mail +@findex gnus-summary-save-in-mail +@vindex gnus-mail-save-name +Save in a Unix mail (mbox) file. Uses the function in the +@code{gnus-mail-save-name} variable to get a file name to save the +article in. The default is @code{gnus-plain-save-name}. -@end table +@item gnus-summary-save-in-file +@findex gnus-summary-save-in-file +@vindex gnus-file-save-name +@findex gnus-numeric-save-name +Append the article straight to an ordinary file. Uses the function in +the @code{gnus-file-save-name} variable to get a file name to save the +article in. The default is @code{gnus-numeric-save-name}. -The following commands are thread movement commands. They all -understand the numeric prefix. +@item gnus-summary-write-to-file +@findex gnus-summary-write-to-file +Write the article straight to an ordinary file. The file is +overwritten if it exists. Uses the function in the +@code{gnus-file-save-name} variable to get a file name to save the +article in. The default is @code{gnus-numeric-save-name}. -@table @kbd +@item gnus-summary-save-body-in-file +@findex gnus-summary-save-body-in-file +Append the article body to an ordinary file. Uses the function in the +@code{gnus-file-save-name} variable to get a file name to save the +article in. The default is @code{gnus-numeric-save-name}. -@item T n -@kindex T n (Summary) -@itemx C-M-f -@kindex C-M-n (Summary) -@itemx M-down -@kindex M-down (Summary) -@findex gnus-summary-next-thread -Go to the next thread (@code{gnus-summary-next-thread}). +@item gnus-summary-write-body-to-file +@findex gnus-summary-write-body-to-file +Write the article body straight to an ordinary file. The file is +overwritten if it exists. Uses the function in the +@code{gnus-file-save-name} variable to get a file name to save the +article in. The default is @code{gnus-numeric-save-name}. -@item T p -@kindex T p (Summary) -@itemx C-M-b -@kindex C-M-p (Summary) -@itemx M-up -@kindex M-up (Summary) -@findex gnus-summary-prev-thread -Go to the previous thread (@code{gnus-summary-prev-thread}). +@item gnus-summary-save-in-folder +@findex gnus-summary-save-in-folder +@findex gnus-folder-save-name +@findex gnus-Folder-save-name +@vindex gnus-folder-save-name +@cindex rcvstore +@cindex MH folders +Save the article to an MH folder using @code{rcvstore} from the MH +library. Uses the function in the @code{gnus-folder-save-name} variable +to get a file name to save the article in. The default is +@code{gnus-folder-save-name}, but you can also use +@code{gnus-Folder-save-name}, which creates capitalized names. + +@item gnus-summary-save-in-vm +@findex gnus-summary-save-in-vm +Save the article in a VM folder. You have to have the VM mail +reader to use this setting. -@item T d -@kindex T d (Summary) -@findex gnus-summary-down-thread -Descend the thread (@code{gnus-summary-down-thread}). +@item gnus-summary-save-in-pipe +@findex gnus-summary-save-in-pipe +Pipe the article to a shell command. This function takes optional two +arguments COMMAND and RAW. Valid values for COMMAND include: -@item T u -@kindex T u (Summary) -@findex gnus-summary-up-thread -Ascend the thread (@code{gnus-summary-up-thread}). +@itemize @bullet +@item a string@* +The executable command name and possibly arguments. +@item @code{nil}@* +You will be prompted for the command in the minibuffer. +@item the symbol @code{default}@* +It will be replaced with the command which the variable +@code{gnus-summary-pipe-output-default-command} holds or the command +last used for saving. +@end itemize -@item T o -@kindex T o (Summary) -@findex gnus-summary-top-thread -Go to the top of the thread (@code{gnus-summary-top-thread}). +Non-@code{nil} value for RAW overrides @code{:decode} and +@code{:headers} properties (see below) and the raw article including all +headers will be piped. @end table -@vindex gnus-thread-operation-ignore-subject -If you ignore subject while threading, you'll naturally end up with -threads that have several different subjects in them. If you then issue -a command like @kbd{T k} (@code{gnus-summary-kill-thread}) you might not -wish to kill the entire thread, but just those parts of the thread that -have the same subject as the current article. If you like this idea, -you can fiddle with @code{gnus-thread-operation-ignore-subject}. If it -is non-@code{nil} (which it is by default), subjects will be ignored -when doing thread commands. If this variable is @code{nil}, articles in -the same thread with different subjects will not be included in the -operation in question. If this variable is @code{fuzzy}, only articles -that have subjects fuzzily equal will be included (@pxref{Fuzzy -Matching}). +The symbol of each function may have the following properties: +@table @code +@item :decode +The value non-@code{nil} means save decoded articles. This is +meaningful only with @code{gnus-summary-save-in-file}, +@code{gnus-summary-save-body-in-file}, +@code{gnus-summary-write-to-file}, +@code{gnus-summary-write-body-to-file}, and +@code{gnus-summary-save-in-pipe}. -@node Sorting the Summary Buffer -@section Sorting the Summary Buffer +@item :function +The value specifies an alternative function which appends, not +overwrites, articles to a file. This implies that when saving many +articles at a time, @code{gnus-prompt-before-saving} is bound to +@code{t} and all articles are saved in a single file. This is +meaningful only with @code{gnus-summary-write-to-file} and +@code{gnus-summary-write-body-to-file}. -@findex gnus-thread-sort-by-total-score -@findex gnus-thread-sort-by-date -@findex gnus-thread-sort-by-score -@findex gnus-thread-sort-by-subject -@findex gnus-thread-sort-by-author -@findex gnus-thread-sort-by-recipient -@findex gnus-thread-sort-by-number -@findex gnus-thread-sort-by-random -@vindex gnus-thread-sort-functions -@findex gnus-thread-sort-by-most-recent-number -@findex gnus-thread-sort-by-most-recent-date -If you are using a threaded summary display, you can sort the threads by -setting @code{gnus-thread-sort-functions}, which can be either a single -function, a list of functions, or a list containing functions and -@code{(not some-function)} elements. +@item :headers +The value specifies the symbol of a variable of which the value +specifies headers to be saved. If it is omitted, +@code{gnus-save-all-headers} and @code{gnus-saved-headers} control what +headers should be saved. +@end table -By default, sorting is done on article numbers. Ready-made sorting -predicate functions include @code{gnus-thread-sort-by-number}, -@code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-recipient}, -@code{gnus-thread-sort-by-subject}, -@code{gnus-thread-sort-by-date}, -@code{gnus-thread-sort-by-score}, -@code{gnus-thread-sort-by-most-recent-number}, -@code{gnus-thread-sort-by-most-recent-date}, -@code{gnus-thread-sort-by-random} and -@code{gnus-thread-sort-by-total-score}. +@vindex gnus-article-save-directory +All of these functions, except for the last one, will save the article +in the @code{gnus-article-save-directory}, which is initialized from the +@env{SAVEDIR} environment variable. This is @file{~/News/} by +default. -Each function takes two threads and returns non-@code{nil} if the first -thread should be sorted before the other. Note that sorting really is -normally done by looking only at the roots of each thread. +As you can see above, the functions use different functions to find a +suitable name of a file to save the article in. Below is a list of +available functions that generate names: -If you use more than one function, the primary sort key should be the -last function in the list. You should probably always include -@code{gnus-thread-sort-by-number} in the list of sorting -functions---preferably first. This will ensure that threads that are -equal with respect to the other sort criteria will be displayed in -ascending article order. +@table @code -If you would like to sort by reverse score, then by subject, and finally -by number, you could do something like: +@item gnus-Numeric-save-name +@findex gnus-Numeric-save-name +File names like @file{~/News/Alt.andrea-dworkin/45}. -@lisp -(setq gnus-thread-sort-functions - '(gnus-thread-sort-by-number - gnus-thread-sort-by-subject - (not gnus-thread-sort-by-total-score))) -@end lisp +@item gnus-numeric-save-name +@findex gnus-numeric-save-name +File names like @file{~/News/alt.andrea-dworkin/45}. -The threads that have highest score will be displayed first in the -summary buffer. When threads have the same score, they will be sorted -alphabetically. The threads that have the same score and the same -subject will be sorted by number, which is (normally) the sequence in -which the articles arrived. +@item gnus-Plain-save-name +@findex gnus-Plain-save-name +File names like @file{~/News/Alt.andrea-dworkin}. -If you want to sort by score and then reverse arrival order, you could -say something like: +@item gnus-plain-save-name +@findex gnus-plain-save-name +File names like @file{~/News/alt.andrea-dworkin}. + +@item gnus-sender-save-name +@findex gnus-sender-save-name +File names like @file{~/News/larsi}. +@end table + +@vindex gnus-split-methods +You can have Gnus suggest where to save articles by plonking a regexp into +the @code{gnus-split-methods} alist. For instance, if you would like to +save articles related to Gnus in the file @file{gnus-stuff}, and articles +related to VM in @file{vm-stuff}, you could set this variable to something +like: @lisp -(setq gnus-thread-sort-functions - '((not gnus-thread-sort-by-number) - gnus-thread-sort-by-score)) +(("^Subject:.*gnus\\|^Newsgroups:.*gnus" "gnus-stuff") + ("^Subject:.*vm\\|^Xref:.*vm" "vm-stuff") + (my-choosing-function "../other-dir/my-stuff") + ((equal gnus-newsgroup-name "mail.misc") "mail-stuff")) @end lisp -@vindex gnus-thread-score-function -The function in the @code{gnus-thread-score-function} variable (default -@code{+}) is used for calculating the total score of a thread. Useful -functions might be @code{max}, @code{min}, or squared means, or whatever -tickles your fancy. +We see that this is a list where each element is a list that has two +elements---the @dfn{match} and the @dfn{file}. The match can either be +a string (in which case it is used as a regexp to match on the article +head); it can be a symbol (which will be called as a function with the +group name as a parameter); or it can be a list (which will be +@code{eval}ed). If any of these actions have a non-@code{nil} result, +the @dfn{file} will be used as a default prompt. In addition, the +result of the operation itself will be used if the function or form +called returns a string or a list of strings. -@findex gnus-article-sort-functions -@findex gnus-article-sort-by-date -@findex gnus-article-sort-by-most-recent-date -@findex gnus-article-sort-by-score -@findex gnus-article-sort-by-subject -@findex gnus-article-sort-by-author -@findex gnus-article-sort-by-random -@findex gnus-article-sort-by-number -@findex gnus-article-sort-by-most-recent-number -If you are using an unthreaded display for some strange reason or -other, you have to fiddle with the @code{gnus-article-sort-functions} -variable. It is very similar to the -@code{gnus-thread-sort-functions}, except that it uses slightly -different functions for article comparison. Available sorting -predicate functions are @code{gnus-article-sort-by-number}, -@code{gnus-article-sort-by-author}, -@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date}, -@code{gnus-article-sort-by-random}, and -@code{gnus-article-sort-by-score}. +You basically end up with a list of file names that might be used when +saving the current article. (All ``matches'' will be used.) You will +then be prompted for what you really want to use as a name, with file +name completion over the results from applying this variable. -If you want to sort an unthreaded summary display by subject, you could -say something like: +This variable is @code{((gnus-article-archive-name))} by default, which +means that Gnus will look at the articles it saves for an +@code{Archive-name} line and use that as a suggestion for the file +name. + +Here's an example function to clean up file names somewhat. If you have +lots of mail groups called things like +@samp{nnml:mail.whatever}, you may want to chop off the beginning of +these group names before creating the file name to save to. The +following will do just that: @lisp -(setq gnus-article-sort-functions - '(gnus-article-sort-by-number - gnus-article-sort-by-subject)) +(defun my-save-name (group) + (when (string-match "^nnml:mail." group) + (substring group (match-end 0)))) + +(setq gnus-split-methods + '((gnus-article-archive-name) + (my-save-name))) @end lisp -You can define group specific sorting via @code{gnus-parameters}, -@xref{Group Parameters}. +@vindex gnus-use-long-file-name +Finally, you have the @code{gnus-use-long-file-name} variable. If it is +@code{nil}, all the preceding functions will replace all periods +(@samp{.}) in the group names with slashes (@samp{/})---which means that +the functions will generate hierarchies of directories instead of having +all the files in the top level directory +(@file{~/News/alt/andrea-dworkin} instead of +@file{~/News/alt.andrea-dworkin}.) This variable is @code{t} by default +on most systems. However, for historical reasons, this is @code{nil} on +Xenix and usg-unix-v machines by default. + +This function also affects kill and score file names. If this variable +is a list, and the list contains the element @code{not-score}, long file +names will not be used for score files, if it contains the element +@code{not-save}, long file names will not be used for saving, and if it +contains the element @code{not-kill}, long file names will not be used +for kill files. -@node Asynchronous Fetching -@section Asynchronous Article Fetching -@cindex asynchronous article fetching -@cindex article pre-fetch -@cindex pre-fetch +If you'd like to save articles in a hierarchy that looks something like +a spool, you could -If you read your news from an @acronym{NNTP} server that's far away, the -network latencies may make reading articles a chore. You have to wait -for a while after pressing @kbd{n} to go to the next article before the -article appears. Why can't Gnus just go ahead and fetch the article -while you are reading the previous one? Why not, indeed. +@lisp +(setq gnus-use-long-file-name '(not-save)) ; @r{to get a hierarchy} +(setq gnus-default-article-saver + 'gnus-summary-save-in-file) ; @r{no encoding} +@end lisp -First, some caveats. There are some pitfalls to using asynchronous -article fetching, especially the way Gnus does it. +Then just save with @kbd{o}. You'd then read this hierarchy with +ephemeral @code{nneething} groups---@kbd{G D} in the group buffer, and +the top level directory as the argument (@file{~/News/}). Then just walk +around to the groups/directories with @code{nneething}. -Let's say you are reading article 1, which is short, and article 2 is -quite long, and you are not interested in reading that. Gnus does not -know this, so it goes ahead and fetches article 2. You decide to read -article 3, but since Gnus is in the process of fetching article 2, the -connection is blocked. -To avoid these situations, Gnus will open two (count 'em two) -connections to the server. Some people may think this isn't a very nice -thing to do, but I don't see any real alternatives. Setting up that -extra connection takes some time, so Gnus startup will be slower. +@node Decoding Articles +@section Decoding Articles +@cindex decoding articles -Gnus will fetch more articles than you will read. This will mean that -the link between your machine and the @acronym{NNTP} server will become more -loaded than if you didn't use article pre-fetch. The server itself will -also become more loaded---both with the extra article requests, and the -extra connection. +Sometime users post articles (or series of articles) that have been +encoded in some way or other. Gnus can decode them for you. -Ok, so now you know that you shouldn't really use this thing@dots{} unless -you really want to. +@menu +* Uuencoded Articles:: Uudecode articles. +* Shell Archives:: Unshar articles. +* PostScript Files:: Split PostScript. +* Other Files:: Plain save and binhex. +* Decoding Variables:: Variables for a happy decoding. +* Viewing Files:: You want to look at the result of the decoding? +@end menu -@vindex gnus-asynchronous -Here's how: Set @code{gnus-asynchronous} to @code{t}. The rest should -happen automatically. +@cindex series +@cindex article series +All these functions use the process/prefix convention +(@pxref{Process/Prefix}) for finding out what articles to work on, with +the extension that a ``single article'' means ``a single series''. Gnus +can find out by itself what articles belong to a series, decode all the +articles and unpack/view/save the resulting file(s). -@vindex gnus-use-article-prefetch -You can control how many articles are to be pre-fetched by setting -@code{gnus-use-article-prefetch}. This is 30 by default, which means -that when you read an article in the group, the back end will pre-fetch -the next 30 articles. If this variable is @code{t}, the back end will -pre-fetch all the articles it can without bound. If it is -@code{nil}, no pre-fetching will be done. +Gnus guesses what articles are in the series according to the following +simplish rule: The subjects must be (nearly) identical, except for the +last two numbers of the line. (Spaces are largely ignored, however.) -@vindex gnus-async-prefetch-article-p -@findex gnus-async-unread-p -There are probably some articles that you don't want to pre-fetch---read -articles, for instance. The @code{gnus-async-prefetch-article-p} -variable controls whether an article is to be pre-fetched. This -function should return non-@code{nil} when the article in question is -to be pre-fetched. The default is @code{gnus-async-unread-p}, which -returns @code{nil} on read articles. The function is called with an -article data structure as the only parameter. +For example: If you choose a subject called @samp{cat.gif (2/3)}, Gnus +will find all the articles that match the regexp @samp{^cat.gif +([0-9]+/[0-9]+).*$}. -If, for instance, you wish to pre-fetch only unread articles shorter -than 100 lines, you could say something like: +Subjects that are non-standard, like @samp{cat.gif (2/3) Part 6 of a +series}, will not be properly recognized by any of the automatic viewing +commands, and you have to mark the articles manually with @kbd{#}. -@lisp -(defun my-async-short-unread-p (data) - "Return non-nil for short, unread articles." - (and (gnus-data-unread-p data) - (< (mail-header-lines (gnus-data-header data)) - 100))) -(setq gnus-async-prefetch-article-p 'my-async-short-unread-p) -@end lisp +@node Uuencoded Articles +@subsection Uuencoded Articles +@cindex uudecode +@cindex uuencoded articles -These functions will be called many, many times, so they should -preferably be short and sweet to avoid slowing down Gnus too much. -It's probably a good idea to byte-compile things like this. +@table @kbd -@vindex gnus-async-post-fetch-function -@findex gnus-html-prefetch-images -After an article has been prefetched, this -@code{gnus-async-post-fetch-function} will be called. The buffer will -be narrowed to the region of the article that was fetched. A useful -value would be @code{gnus-html-prefetch-images}, which will prefetch -and store images referenced in the article, so that you don't have to -wait for them to be fetched when you read the article. This is useful -for @acronym{HTML} messages that have external images. +@item X u +@kindex X u (Summary) +@findex gnus-uu-decode-uu +@c @icon{gnus-uu-decode-uu} +Uudecodes the current series (@code{gnus-uu-decode-uu}). -@vindex gnus-prefetched-article-deletion-strategy -Articles have to be removed from the asynch buffer sooner or later. The -@code{gnus-prefetched-article-deletion-strategy} says when to remove -articles. This is a list that may contain the following elements: +@item X U +@kindex X U (Summary) +@findex gnus-uu-decode-uu-and-save +Uudecodes and saves the current series +(@code{gnus-uu-decode-uu-and-save}). -@table @code -@item read -Remove articles when they are read. +@item X v u +@kindex X v u (Summary) +@findex gnus-uu-decode-uu-view +Uudecodes and views the current series (@code{gnus-uu-decode-uu-view}). + +@item X v U +@kindex X v U (Summary) +@findex gnus-uu-decode-uu-and-save-view +Uudecodes, views and saves the current series +(@code{gnus-uu-decode-uu-and-save-view}). -@item exit -Remove articles when exiting the group. @end table -The default value is @code{(read exit)}. +Remember that these all react to the presence of articles marked with +the process mark. If, for instance, you'd like to decode and save an +entire newsgroup, you'd typically do @kbd{M P a} +(@code{gnus-uu-mark-all}) and then @kbd{X U} +(@code{gnus-uu-decode-uu-and-save}). -@c @vindex gnus-use-header-prefetch -@c If @code{gnus-use-header-prefetch} is non-@code{nil}, prefetch articles -@c from the next group. +All this is very much different from how @code{gnus-uu} worked with +@sc{gnus 4.1}, where you had explicit keystrokes for everything under +the sun. This version of @code{gnus-uu} generally assumes that you mark +articles in some way (@pxref{Setting Process Marks}) and then press +@kbd{X u}. +@vindex gnus-uu-notify-files +Note: When trying to decode articles that have names matching +@code{gnus-uu-notify-files}, which is hard-coded to +@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}, @code{gnus-uu} will +automatically post an article on @samp{comp.unix.wizards} saying that +you have just viewed the file in question. This feature can't be turned +off. -@node Article Caching -@section Article Caching -@cindex article caching -@cindex caching -If you have an @emph{extremely} slow @acronym{NNTP} connection, you may -consider turning article caching on. Each article will then be stored -locally under your home directory. As you may surmise, this could -potentially use @emph{huge} amounts of disk space, as well as eat up all -your inodes so fast it will make your head swim. In vodka. +@node Shell Archives +@subsection Shell Archives +@cindex unshar +@cindex shell archives +@cindex shared articles -Used carefully, though, it could be just an easier way to save articles. +Shell archives (``shar files'') used to be a popular way to distribute +sources, but it isn't used all that much today. In any case, we have +some commands to deal with these: -@vindex gnus-use-long-file-name -@vindex gnus-cache-directory -@vindex gnus-use-cache -To turn caching on, set @code{gnus-use-cache} to @code{t}. By default, -all articles ticked or marked as dormant will then be copied -over to your local cache (@code{gnus-cache-directory}). Whether this -cache is flat or hierarchical is controlled by the -@code{gnus-use-long-file-name} variable, as usual. +@table @kbd -When re-selecting a ticked or dormant article, it will be fetched from the -cache instead of from the server. As articles in your cache will never -expire, this might serve as a method of saving articles while still -keeping them where they belong. Just mark all articles you want to save -as dormant, and don't worry. +@item X s +@kindex X s (Summary) +@findex gnus-uu-decode-unshar +Unshars the current series (@code{gnus-uu-decode-unshar}). -When an article is marked as read, is it removed from the cache. +@item X S +@kindex X S (Summary) +@findex gnus-uu-decode-unshar-and-save +Unshars and saves the current series (@code{gnus-uu-decode-unshar-and-save}). -@vindex gnus-cache-remove-articles -@vindex gnus-cache-enter-articles -The entering/removal of articles from the cache is controlled by the -@code{gnus-cache-enter-articles} and @code{gnus-cache-remove-articles} -variables. Both are lists of symbols. The first is @code{(ticked -dormant)} by default, meaning that ticked and dormant articles will be -put in the cache. The latter is @code{(read)} by default, meaning that -articles marked as read are removed from the cache. Possibly -symbols in these two lists are @code{ticked}, @code{dormant}, -@code{unread} and @code{read}. +@item X v s +@kindex X v s (Summary) +@findex gnus-uu-decode-unshar-view +Unshars and views the current series (@code{gnus-uu-decode-unshar-view}). -@findex gnus-jog-cache -So where does the massive article-fetching and storing come into the -picture? The @code{gnus-jog-cache} command will go through all -subscribed newsgroups, request all unread articles, score them, and -store them in the cache. You should only ever, ever ever ever, use this -command if 1) your connection to the @acronym{NNTP} server is really, really, -really slow and 2) you have a really, really, really huge disk. -Seriously. One way to cut down on the number of articles downloaded is -to score unwanted articles down and have them marked as read. They will -not then be downloaded by this command. +@item X v S +@kindex X v S (Summary) +@findex gnus-uu-decode-unshar-and-save-view +Unshars, views and saves the current series +(@code{gnus-uu-decode-unshar-and-save-view}). +@end table -@vindex gnus-uncacheable-groups -@vindex gnus-cacheable-groups -It is likely that you do not want caching on all groups. For instance, -if your @code{nnml} mail is located under your home directory, it makes no -sense to cache it somewhere else under your home directory. Unless you -feel that it's neat to use twice as much space. -To limit the caching, you could set @code{gnus-cacheable-groups} to a -regexp of groups to cache, @samp{^nntp} for instance, or set the -@code{gnus-uncacheable-groups} regexp to @samp{^nnml}, for instance. -Both variables are @code{nil} by default. If a group matches both -variables, the group is not cached. +@node PostScript Files +@subsection PostScript Files +@cindex PostScript -@findex gnus-cache-generate-nov-databases -@findex gnus-cache-generate-active -@vindex gnus-cache-active-file -The cache stores information on what articles it contains in its active -file (@code{gnus-cache-active-file}). If this file (or any other parts -of the cache) becomes all messed up for some reason or other, Gnus -offers two functions that will try to set things right. @kbd{M-x -gnus-cache-generate-nov-databases} will (re)build all the @acronym{NOV} -files, and @kbd{gnus-cache-generate-active} will (re)generate the active -file. +@table @kbd -@findex gnus-cache-move-cache -@code{gnus-cache-move-cache} will move your whole -@code{gnus-cache-directory} to some other location. You get asked to -where, isn't that cool? +@item X p +@kindex X p (Summary) +@findex gnus-uu-decode-postscript +Unpack the current PostScript series (@code{gnus-uu-decode-postscript}). -@node Persistent Articles -@section Persistent Articles -@cindex persistent articles +@item X P +@kindex X P (Summary) +@findex gnus-uu-decode-postscript-and-save +Unpack and save the current PostScript series +(@code{gnus-uu-decode-postscript-and-save}). + +@item X v p +@kindex X v p (Summary) +@findex gnus-uu-decode-postscript-view +View the current PostScript series +(@code{gnus-uu-decode-postscript-view}). -Closely related to article caching, we have @dfn{persistent articles}. -In fact, it's just a different way of looking at caching, and much more -useful in my opinion. +@item X v P +@kindex X v P (Summary) +@findex gnus-uu-decode-postscript-and-save-view +View and save the current PostScript series +(@code{gnus-uu-decode-postscript-and-save-view}). +@end table -Say you're reading a newsgroup, and you happen on to some valuable gem -that you want to keep and treasure forever. You'd normally just save it -(using one of the many saving commands) in some file. The problem with -that is that it's just, well, yucky. Ideally you'd prefer just having -the article remain in the group where you found it forever; untouched by -the expiry going on at the news server. -This is what a @dfn{persistent article} is---an article that just won't -be deleted. It's implemented using the normal cache functions, but -you use two explicit commands for managing persistent articles: +@node Other Files +@subsection Other Files @table @kbd +@item X o +@kindex X o (Summary) +@findex gnus-uu-decode-save +Save the current series +(@code{gnus-uu-decode-save}). -@item * -@kindex * (Summary) -@findex gnus-cache-enter-article -Make the current article persistent (@code{gnus-cache-enter-article}). +@item X b +@kindex X b (Summary) +@findex gnus-uu-decode-binhex +Unbinhex the current series (@code{gnus-uu-decode-binhex}). This +doesn't really work yet. -@item M-* -@kindex M-* (Summary) -@findex gnus-cache-remove-article -Remove the current article from the persistent articles -(@code{gnus-cache-remove-article}). This will normally delete the -article. +@item X Y +@kindex X Y (Summary) +@findex gnus-uu-decode-yenc +yEnc-decode the current series and save it (@code{gnus-uu-decode-yenc}). @end table -Both these commands understand the process/prefix convention. -To avoid having all ticked articles (and stuff) entered into the cache, -you should set @code{gnus-use-cache} to @code{passive} if you're just -interested in persistent articles: +@node Decoding Variables +@subsection Decoding Variables + +Adjective, not verb. + +@menu +* Rule Variables:: Variables that say how a file is to be viewed. +* Other Decode Variables:: Other decode variables. +* Uuencoding and Posting:: Variables for customizing uuencoding. +@end menu + + +@node Rule Variables +@subsubsection Rule Variables +@cindex rule variables + +Gnus uses @dfn{rule variables} to decide how to view a file. All these +variables are of the form @lisp -(setq gnus-use-cache 'passive) + (list '(regexp1 command2) + '(regexp2 command2) + ...) @end lisp -@node Sticky Articles -@section Sticky Articles -@cindex sticky articles - -When you select an article the current article buffer will be reused -according to the value of the variable -@code{gnus-single-article-buffer}. If its value is non-@code{nil} (the -default) all articles reuse the same article buffer. Else each group -has its own article buffer. +@table @code -This implies that it's not possible to have more than one article buffer -in a group at a time. But sometimes you might want to display all the -latest emails from your mother, your father, your aunt, your uncle and -your 17 cousins to coordinate the next christmas party. +@item gnus-uu-user-view-rules +@vindex gnus-uu-user-view-rules +@cindex sox +This variable is consulted first when viewing files. If you wish to use, +for instance, @code{sox} to convert an @file{.au} sound file, you could +say something like: +@lisp +(setq gnus-uu-user-view-rules + (list '("\\\\.au$" "sox %s -t .aiff > /dev/audio"))) +@end lisp -That's where sticky articles come in handy. A sticky article buffer -basically is a normal article buffer, but it won't be reused when you -select another article. You can make an article sticky with: +@item gnus-uu-user-view-rules-end +@vindex gnus-uu-user-view-rules-end +This variable is consulted if Gnus couldn't make any matches from the +user and default view rules. -@table @kbd -@item A S -@kindex A S (Summary) -@findex gnus-sticky-article -Make the current article sticky. If a prefix arg is given, ask for a -name for this sticky article buffer. +@item gnus-uu-user-archive-rules +@vindex gnus-uu-user-archive-rules +This variable can be used to say what commands should be used to unpack +archives. @end table -To close a sticky article buffer you can use these commands: -@table @kbd -@item q -@kindex q (Article) -@findex bury-buffer -Puts this sticky article buffer at the end of the list of all buffers. +@node Other Decode Variables +@subsubsection Other Decode Variables -@item k -@kindex k (Article) -@findex gnus-kill-sticky-article-buffer -Kills this sticky article buffer. -@end table +@table @code +@vindex gnus-uu-grabbed-file-functions -To kill all sticky article buffers you can use: +@item gnus-uu-grabbed-file-functions +All functions in this list will be called right after each file has been +successfully decoded---so that you can move or view files right away, +and don't have to wait for all files to be decoded before you can do +anything. Ready-made functions you can put in this list are: -@defun gnus-kill-sticky-article-buffers ARG -Kill all sticky article buffers. -If a prefix ARG is given, ask for confirmation. -@end defun +@table @code -@node Article Backlog -@section Article Backlog -@cindex backlog -@cindex article backlog +@item gnus-uu-grab-view +@findex gnus-uu-grab-view +View the file. -If you have a slow connection, but the idea of using caching seems -unappealing to you (and it is, really), you can help the situation some -by switching on the @dfn{backlog}. This is where Gnus will buffer -already read articles so that it doesn't have to re-fetch articles -you've already read. This only helps if you are in the habit of -re-selecting articles you've recently read, of course. If you never do -that, turning the backlog on will slow Gnus down a little bit, and -increase memory usage some. +@item gnus-uu-grab-move +@findex gnus-uu-grab-move +Move the file (if you're using a saving function.) +@end table -@vindex gnus-keep-backlog -If you set @code{gnus-keep-backlog} to a number @var{n}, Gnus will store -at most @var{n} old articles in a buffer for later re-fetching. If this -variable is non-@code{nil} and is not a number, Gnus will store -@emph{all} read articles, which means that your Emacs will grow without -bound before exploding and taking your machine down with you. I put -that in there just to keep y'all on your toes. +@item gnus-uu-be-dangerous +@vindex gnus-uu-be-dangerous +Specifies what to do if unusual situations arise during decoding. If +@code{nil}, be as conservative as possible. If @code{t}, ignore things +that didn't work, and overwrite existing files. Otherwise, ask each +time. -The default value is 20. +@item gnus-uu-ignore-files-by-name +@vindex gnus-uu-ignore-files-by-name +Files with name matching this regular expression won't be viewed. +@item gnus-uu-ignore-files-by-type +@vindex gnus-uu-ignore-files-by-type +Files with a @acronym{MIME} type matching this variable won't be viewed. +Note that Gnus tries to guess what type the file is based on the name. +@code{gnus-uu} is not a @acronym{MIME} package (yet), so this is slightly +kludgey. -@node Saving Articles -@section Saving Articles -@cindex saving articles +@item gnus-uu-tmp-dir +@vindex gnus-uu-tmp-dir +Where @code{gnus-uu} does its work. -Gnus can save articles in a number of ways. Below is the documentation -for saving articles in a fairly straight-forward fashion (i.e., little -processing of the article is done before it is saved). For a different -approach (uudecoding, unsharing) you should use @code{gnus-uu} -(@pxref{Decoding Articles}). +@item gnus-uu-do-not-unpack-archives +@vindex gnus-uu-do-not-unpack-archives +Non-@code{nil} means that @code{gnus-uu} won't peek inside archives +looking for files to display. -For the commands listed here, the target is a file. If you want to -save to a group, see the @kbd{B c} (@code{gnus-summary-copy-article}) -command (@pxref{Mail Group Commands}). +@item gnus-uu-view-and-save +@vindex gnus-uu-view-and-save +Non-@code{nil} means that the user will always be asked to save a file +after viewing it. -@vindex gnus-save-all-headers -If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete -unwanted headers before saving the article. +@item gnus-uu-ignore-default-view-rules +@vindex gnus-uu-ignore-default-view-rules +Non-@code{nil} means that @code{gnus-uu} will ignore the default viewing +rules. -@vindex gnus-saved-headers -If the preceding variable is @code{nil}, all headers that match the -@code{gnus-saved-headers} regexp will be kept, while the rest will be -deleted before saving. +@item gnus-uu-ignore-default-archive-rules +@vindex gnus-uu-ignore-default-archive-rules +Non-@code{nil} means that @code{gnus-uu} will ignore the default archive +unpacking commands. -@table @kbd +@item gnus-uu-kill-carriage-return +@vindex gnus-uu-kill-carriage-return +Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns +from articles. -@item O o -@itemx o -@kindex O o (Summary) -@kindex o (Summary) -@findex gnus-summary-save-article -@c @icon{gnus-summary-save-article} -Save the current article using the default article saver -(@code{gnus-summary-save-article}). +@item gnus-uu-unmark-articles-not-decoded +@vindex gnus-uu-unmark-articles-not-decoded +Non-@code{nil} means that @code{gnus-uu} will mark unsuccessfully +decoded articles as unread. -@item O m -@kindex O m (Summary) -@findex gnus-summary-save-article-mail -Save the current article in a Unix mail box (mbox) file -(@code{gnus-summary-save-article-mail}). +@item gnus-uu-correct-stripped-uucode +@vindex gnus-uu-correct-stripped-uucode +Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix +uuencoded files that have had trailing spaces deleted. + +@item gnus-uu-pre-uudecode-hook +@vindex gnus-uu-pre-uudecode-hook +Hook run before sending a message to @code{uudecode}. + +@item gnus-uu-view-with-metamail +@vindex gnus-uu-view-with-metamail +@cindex metamail +Non-@code{nil} means that @code{gnus-uu} will ignore the viewing +commands defined by the rule variables and just fudge a @acronym{MIME} +content type based on the file name. The result will be fed to +@code{metamail} for viewing. -@item O r -@kindex O r (Summary) -@findex gnus-summary-save-article-rmail -Save the current article in Rmail format -(@code{gnus-summary-save-article-rmail}). This is mbox since Emacs 23, -Babyl in older versions. +@item gnus-uu-save-in-digest +@vindex gnus-uu-save-in-digest +Non-@code{nil} means that @code{gnus-uu}, when asked to save without +decoding, will save in digests. If this variable is @code{nil}, +@code{gnus-uu} will just save everything in a file without any +embellishments. The digesting almost conforms to RFC 1153---no easy way +to specify any meaningful volume and issue numbers were found, so I +simply dropped them. -@item O f -@kindex O f (Summary) -@findex gnus-summary-save-article-file -@c @icon{gnus-summary-save-article-file} -Save the current article in plain file format -(@code{gnus-summary-save-article-file}). +@end table -@item O F -@kindex O F (Summary) -@findex gnus-summary-write-article-file -Write the current article in plain file format, overwriting any previous -file contents (@code{gnus-summary-write-article-file}). -@item O b -@kindex O b (Summary) -@findex gnus-summary-save-article-body-file -Save the current article body in plain file format -(@code{gnus-summary-save-article-body-file}). +@node Uuencoding and Posting +@subsubsection Uuencoding and Posting -@item O h -@kindex O h (Summary) -@findex gnus-summary-save-article-folder -Save the current article in mh folder format -(@code{gnus-summary-save-article-folder}). +@table @code -@item O v -@kindex O v (Summary) -@findex gnus-summary-save-article-vm -Save the current article in a VM folder -(@code{gnus-summary-save-article-vm}). +@item gnus-uu-post-include-before-composing +@vindex gnus-uu-post-include-before-composing +Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode +before you compose the article. If this variable is @code{t}, you can +either include an encoded file with @kbd{C-c C-i} or have one included +for you when you post the article. -@item O p -@itemx | -@kindex O p (Summary) -@kindex | (Summary) -@findex gnus-summary-pipe-output -@vindex gnus-summary-pipe-output-default-command -Save the current article in a pipe. Uhm, like, what I mean is---Pipe -the current article to a process (@code{gnus-summary-pipe-output}). -If given a symbolic prefix (@pxref{Symbolic Prefixes}), include the -complete headers in the piped output. The symbolic prefix @code{r} is -special; it lets this command pipe a raw article including all headers. -The @code{gnus-summary-pipe-output-default-command} variable can be set -to a string containing the default command and options (default -@code{nil}). +@item gnus-uu-post-length +@vindex gnus-uu-post-length +Maximum length of an article. The encoded file will be split into how +many articles it takes to post the entire file. -@item O P -@kindex O P (Summary) -@findex gnus-summary-muttprint -@vindex gnus-summary-muttprint-program -Save the current article into muttprint. That is, print it using the -external program @uref{http://muttprint.sourceforge.net/, -Muttprint}. The program name and options to use is controlled by the -variable @code{gnus-summary-muttprint-program}. -(@code{gnus-summary-muttprint}). +@item gnus-uu-post-threaded +@vindex gnus-uu-post-threaded +Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a +thread. This may not be smart, as no other decoder I have seen is able +to follow threads when collecting uuencoded articles. (Well, I have +seen one package that does that---@code{gnus-uu}, but somehow, I don't +think that counts@dots{}) Default is @code{nil}. + +@item gnus-uu-post-separate-description +@vindex gnus-uu-post-separate-description +Non-@code{nil} means that the description will be posted in a separate +article. The first article will typically be numbered (0/x). If this +variable is @code{nil}, the description the user enters will be included +at the beginning of the first article, which will be numbered (1/x). +Default is @code{t}. @end table -@vindex gnus-prompt-before-saving -All these commands use the process/prefix convention -(@pxref{Process/Prefix}). If you save bunches of articles using these -functions, you might get tired of being prompted for files to save each -and every article in. The prompting action is controlled by -the @code{gnus-prompt-before-saving} variable, which is @code{always} by -default, giving you that excessive prompting action you know and -loathe. If you set this variable to @code{t} instead, you'll be prompted -just once for each series of articles you save. If you like to really -have Gnus do all your thinking for you, you can even set this variable -to @code{nil}, which means that you will never be prompted for files to -save articles in. Gnus will simply save all the articles in the default -files. +@node Viewing Files +@subsection Viewing Files +@cindex viewing files +@cindex pseudo-articles -@vindex gnus-default-article-saver -You can customize the @code{gnus-default-article-saver} variable to make -Gnus do what you want it to. You can use any of the eight ready-made -functions below, or you can create your own. +After decoding, if the file is some sort of archive, Gnus will attempt +to unpack the archive and see if any of the files in the archive can be +viewed. For instance, if you have a gzipped tar file @file{pics.tar.gz} +containing the files @file{pic1.jpg} and @file{pic2.gif}, Gnus will +uncompress and de-tar the main file, and then view the two pictures. +This unpacking process is recursive, so if the archive contains archives +of archives, it'll all be unpacked. -@table @code +Finally, Gnus will normally insert a @dfn{pseudo-article} for each +extracted file into the summary buffer. If you go to these +``articles'', you will be prompted for a command to run (usually Gnus +will make a suggestion), and then the command will be run. -@item gnus-summary-save-in-rmail -@findex gnus-summary-save-in-rmail -@vindex gnus-rmail-save-name -@findex gnus-plain-save-name -This is the default format, that used by the Rmail package. Since Emacs -23, Rmail uses standard mbox format. Before this, it used the -@dfn{Babyl} format. Accordingly, this command writes mbox format since -Emacs 23, unless appending to an existing Babyl file. In older versions -of Emacs, it always uses Babyl format. Uses the function in the -@code{gnus-rmail-save-name} variable to get a file name to save the -article in. The default is @code{gnus-plain-save-name}. +@vindex gnus-view-pseudo-asynchronously +If @code{gnus-view-pseudo-asynchronously} is @code{nil}, Emacs will wait +until the viewing is done before proceeding. -@item gnus-summary-save-in-mail -@findex gnus-summary-save-in-mail -@vindex gnus-mail-save-name -Save in a Unix mail (mbox) file. Uses the function in the -@code{gnus-mail-save-name} variable to get a file name to save the -article in. The default is @code{gnus-plain-save-name}. +@vindex gnus-view-pseudos +If @code{gnus-view-pseudos} is @code{automatic}, Gnus will not insert +the pseudo-articles into the summary buffer, but view them +immediately. If this variable is @code{not-confirm}, the user won't even +be asked for a confirmation before viewing is done. -@item gnus-summary-save-in-file -@findex gnus-summary-save-in-file -@vindex gnus-file-save-name -@findex gnus-numeric-save-name -Append the article straight to an ordinary file. Uses the function in -the @code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. +@vindex gnus-view-pseudos-separately +If @code{gnus-view-pseudos-separately} is non-@code{nil}, one +pseudo-article will be created for each file to be viewed. If +@code{nil}, all files that use the same viewing command will be given as +a list of parameters to that command. -@item gnus-summary-write-to-file -@findex gnus-summary-write-to-file -Write the article straight to an ordinary file. The file is -overwritten if it exists. Uses the function in the -@code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. +@vindex gnus-insert-pseudo-articles +If @code{gnus-insert-pseudo-articles} is non-@code{nil}, insert +pseudo-articles when decoding. It is @code{t} by default. -@item gnus-summary-save-body-in-file -@findex gnus-summary-save-body-in-file -Append the article body to an ordinary file. Uses the function in the -@code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. +So; there you are, reading your @emph{pseudo-articles} in your +@emph{virtual newsgroup} from the @emph{virtual server}; and you think: +Why isn't anything real anymore? How did we get here? -@item gnus-summary-write-body-to-file -@findex gnus-summary-write-body-to-file -Write the article body straight to an ordinary file. The file is -overwritten if it exists. Uses the function in the -@code{gnus-file-save-name} variable to get a file name to save the -article in. The default is @code{gnus-numeric-save-name}. -@item gnus-summary-save-in-folder -@findex gnus-summary-save-in-folder -@findex gnus-folder-save-name -@findex gnus-Folder-save-name -@vindex gnus-folder-save-name -@cindex rcvstore -@cindex MH folders -Save the article to an MH folder using @code{rcvstore} from the MH -library. Uses the function in the @code{gnus-folder-save-name} variable -to get a file name to save the article in. The default is -@code{gnus-folder-save-name}, but you can also use -@code{gnus-Folder-save-name}, which creates capitalized names. +@node Article Treatment +@section Article Treatment -@item gnus-summary-save-in-vm -@findex gnus-summary-save-in-vm -Save the article in a VM folder. You have to have the VM mail -reader to use this setting. +Reading through this huge manual, you may have quite forgotten that the +object of newsreaders is to actually, like, read what people have +written. Reading articles. Unfortunately, people are quite bad at +writing, so there are tons of functions and variables to make reading +these articles easier. -@item gnus-summary-save-in-pipe -@findex gnus-summary-save-in-pipe -Pipe the article to a shell command. This function takes optional two -arguments COMMAND and RAW. Valid values for COMMAND include: +@menu +* Article Highlighting:: You want to make the article look like fruit salad. +* Article Fontisizing:: Making emphasized text look nice. +* Article Hiding:: You also want to make certain info go away. +* Article Washing:: Lots of way-neat functions to make life better. +* Article Header:: Doing various header transformations. +* Article Buttons:: Click on URLs, Message-IDs, addresses and the like. +* Article Button Levels:: Controlling appearance of buttons. +* Article Date:: Grumble, UT! +* Article Display:: Display various stuff: + X-Face, Picons, Gravatars, Smileys. +* Article Signature:: What is a signature? +* Article Miscellanea:: Various other stuff. +@end menu -@itemize @bullet -@item a string@* -The executable command name and possibly arguments. -@item @code{nil}@* -You will be prompted for the command in the minibuffer. -@item the symbol @code{default}@* -It will be replaced with the command which the variable -@code{gnus-summary-pipe-output-default-command} holds or the command -last used for saving. -@end itemize -Non-@code{nil} value for RAW overrides @code{:decode} and -@code{:headers} properties (see below) and the raw article including all -headers will be piped. -@end table +@node Article Highlighting +@subsection Article Highlighting +@cindex highlighting -The symbol of each function may have the following properties: +Not only do you want your article buffer to look like fruit salad, but +you want it to look like technicolor fruit salad. -@table @code -@item :decode -The value non-@code{nil} means save decoded articles. This is -meaningful only with @code{gnus-summary-save-in-file}, -@code{gnus-summary-save-body-in-file}, -@code{gnus-summary-write-to-file}, -@code{gnus-summary-write-body-to-file}, and -@code{gnus-summary-save-in-pipe}. +@table @kbd -@item :function -The value specifies an alternative function which appends, not -overwrites, articles to a file. This implies that when saving many -articles at a time, @code{gnus-prompt-before-saving} is bound to -@code{t} and all articles are saved in a single file. This is -meaningful only with @code{gnus-summary-write-to-file} and -@code{gnus-summary-write-body-to-file}. +@item W H a +@kindex W H a (Summary) +@findex gnus-article-highlight +@findex gnus-article-maybe-highlight +Do much highlighting of the current article +(@code{gnus-article-highlight}). This function highlights header, cited +text, the signature, and adds buttons to the body and the head. -@item :headers -The value specifies the symbol of a variable of which the value -specifies headers to be saved. If it is omitted, -@code{gnus-save-all-headers} and @code{gnus-saved-headers} control what -headers should be saved. -@end table +@item W H h +@kindex W H h (Summary) +@findex gnus-article-highlight-headers +@vindex gnus-header-face-alist +Highlight the headers (@code{gnus-article-highlight-headers}). The +highlighting will be done according to the @code{gnus-header-face-alist} +variable, which is a list where each element has the form +@code{(@var{regexp} @var{name} @var{content})}. +@var{regexp} is a regular expression for matching the +header, @var{name} is the face used for highlighting the header name +(@pxref{Faces and Fonts}) and @var{content} is the face for highlighting +the header value. The first match made will be used. Note that +@var{regexp} shouldn't have @samp{^} prepended---Gnus will add one. -@vindex gnus-article-save-directory -All of these functions, except for the last one, will save the article -in the @code{gnus-article-save-directory}, which is initialized from the -@env{SAVEDIR} environment variable. This is @file{~/News/} by -default. +@item W H c +@kindex W H c (Summary) +@findex gnus-article-highlight-citation +Highlight cited text (@code{gnus-article-highlight-citation}). -As you can see above, the functions use different functions to find a -suitable name of a file to save the article in. Below is a list of -available functions that generate names: +Some variables to customize the citation highlights: @table @code +@vindex gnus-cite-parse-max-size -@item gnus-Numeric-save-name -@findex gnus-Numeric-save-name -File names like @file{~/News/Alt.andrea-dworkin/45}. +@item gnus-cite-parse-max-size +If the article size in bytes is bigger than this variable (which is +25000 by default), no citation highlighting will be performed. -@item gnus-numeric-save-name -@findex gnus-numeric-save-name -File names like @file{~/News/alt.andrea-dworkin/45}. +@item gnus-cite-max-prefix +@vindex gnus-cite-max-prefix +Maximum possible length for a citation prefix (default 20). -@item gnus-Plain-save-name -@findex gnus-Plain-save-name -File names like @file{~/News/Alt.andrea-dworkin}. +@item gnus-cite-face-list +@vindex gnus-cite-face-list +List of faces used for highlighting citations (@pxref{Faces and Fonts}). +When there are citations from multiple articles in the same message, +Gnus will try to give each citation from each article its own face. +This should make it easier to see who wrote what. -@item gnus-plain-save-name -@findex gnus-plain-save-name -File names like @file{~/News/alt.andrea-dworkin}. +@item gnus-supercite-regexp +@vindex gnus-supercite-regexp +Regexp matching normal Supercite attribution lines. -@item gnus-sender-save-name -@findex gnus-sender-save-name -File names like @file{~/News/larsi}. -@end table +@item gnus-supercite-secondary-regexp +@vindex gnus-supercite-secondary-regexp +Regexp matching mangled Supercite attribution lines. -@vindex gnus-split-methods -You can have Gnus suggest where to save articles by plonking a regexp into -the @code{gnus-split-methods} alist. For instance, if you would like to -save articles related to Gnus in the file @file{gnus-stuff}, and articles -related to VM in @file{vm-stuff}, you could set this variable to something -like: +@item gnus-cite-minimum-match-count +@vindex gnus-cite-minimum-match-count +Minimum number of identical prefixes we have to see before we believe +that it's a citation. -@lisp -(("^Subject:.*gnus\\|^Newsgroups:.*gnus" "gnus-stuff") - ("^Subject:.*vm\\|^Xref:.*vm" "vm-stuff") - (my-choosing-function "../other-dir/my-stuff") - ((equal gnus-newsgroup-name "mail.misc") "mail-stuff")) -@end lisp +@item gnus-cite-attribution-prefix +@vindex gnus-cite-attribution-prefix +Regexp matching the beginning of an attribution line. -We see that this is a list where each element is a list that has two -elements---the @dfn{match} and the @dfn{file}. The match can either be -a string (in which case it is used as a regexp to match on the article -head); it can be a symbol (which will be called as a function with the -group name as a parameter); or it can be a list (which will be -@code{eval}ed). If any of these actions have a non-@code{nil} result, -the @dfn{file} will be used as a default prompt. In addition, the -result of the operation itself will be used if the function or form -called returns a string or a list of strings. +@item gnus-cite-attribution-suffix +@vindex gnus-cite-attribution-suffix +Regexp matching the end of an attribution line. -You basically end up with a list of file names that might be used when -saving the current article. (All ``matches'' will be used.) You will -then be prompted for what you really want to use as a name, with file -name completion over the results from applying this variable. +@item gnus-cite-attribution-face +@vindex gnus-cite-attribution-face +Face used for attribution lines. It is merged with the face for the +cited text belonging to the attribution. -This variable is @code{((gnus-article-archive-name))} by default, which -means that Gnus will look at the articles it saves for an -@code{Archive-name} line and use that as a suggestion for the file -name. +@item gnus-cite-ignore-quoted-from +@vindex gnus-cite-ignore-quoted-from +If non-@code{nil}, no citation highlighting will be performed on lines +beginning with @samp{>From }. Those lines may have been quoted by MTAs +in order not to mix up with the envelope From line. The default value +is @code{t}. -Here's an example function to clean up file names somewhat. If you have -lots of mail groups called things like -@samp{nnml:mail.whatever}, you may want to chop off the beginning of -these group names before creating the file name to save to. The -following will do just that: +@end table -@lisp -(defun my-save-name (group) - (when (string-match "^nnml:mail." group) - (substring group (match-end 0)))) -(setq gnus-split-methods - '((gnus-article-archive-name) - (my-save-name))) -@end lisp +@item W H s +@kindex W H s (Summary) +@vindex gnus-signature-separator +@vindex gnus-signature-face +@findex gnus-article-highlight-signature +Highlight the signature (@code{gnus-article-highlight-signature}). +Everything after @code{gnus-signature-separator} (@pxref{Article +Signature}) in an article will be considered a signature and will be +highlighted with @code{gnus-signature-face}, which is @code{italic} by +default. +@end table -@vindex gnus-use-long-file-name -Finally, you have the @code{gnus-use-long-file-name} variable. If it is -@code{nil}, all the preceding functions will replace all periods -(@samp{.}) in the group names with slashes (@samp{/})---which means that -the functions will generate hierarchies of directories instead of having -all the files in the top level directory -(@file{~/News/alt/andrea-dworkin} instead of -@file{~/News/alt.andrea-dworkin}.) This variable is @code{t} by default -on most systems. However, for historical reasons, this is @code{nil} on -Xenix and usg-unix-v machines by default. +@xref{Customizing Articles}, for how to highlight articles automatically. -This function also affects kill and score file names. If this variable -is a list, and the list contains the element @code{not-score}, long file -names will not be used for score files, if it contains the element -@code{not-save}, long file names will not be used for saving, and if it -contains the element @code{not-kill}, long file names will not be used -for kill files. -If you'd like to save articles in a hierarchy that looks something like -a spool, you could +@node Article Fontisizing +@subsection Article Fontisizing +@cindex emphasis +@cindex article emphasis + +@findex gnus-article-emphasize +@kindex W e (Summary) +People commonly add emphasis to words in news articles by writing things +like @samp{_this_} or @samp{*this*} or @samp{/this/}. Gnus can make +this look nicer by running the article through the @kbd{W e} +(@code{gnus-article-emphasize}) command. + +@vindex gnus-emphasis-alist +How the emphasis is computed is controlled by the +@code{gnus-emphasis-alist} variable. This is an alist where the first +element is a regular expression to be matched. The second is a number +that says what regular expression grouping is used to find the entire +emphasized word. The third is a number that says what regexp grouping +should be displayed and highlighted. (The text between these two +groupings will be hidden.) The fourth is the face used for +highlighting. @lisp -(setq gnus-use-long-file-name '(not-save)) ; @r{to get a hierarchy} -(setq gnus-default-article-saver - 'gnus-summary-save-in-file) ; @r{no encoding} +(setq gnus-emphasis-alist + '(("_\\(\\w+\\)_" 0 1 gnus-emphasis-underline) + ("\\*\\(\\w+\\)\\*" 0 1 gnus-emphasis-bold))) @end lisp -Then just save with @kbd{o}. You'd then read this hierarchy with -ephemeral @code{nneething} groups---@kbd{G D} in the group buffer, and -the top level directory as the argument (@file{~/News/}). Then just walk -around to the groups/directories with @code{nneething}. - +@cindex slash +@cindex asterisk +@cindex underline +@cindex / +@cindex * -@node Decoding Articles -@section Decoding Articles -@cindex decoding articles +@vindex gnus-emphasis-underline +@vindex gnus-emphasis-bold +@vindex gnus-emphasis-italic +@vindex gnus-emphasis-underline-bold +@vindex gnus-emphasis-underline-italic +@vindex gnus-emphasis-bold-italic +@vindex gnus-emphasis-underline-bold-italic +By default, there are seven rules, and they use the following faces: +@code{gnus-emphasis-bold}, @code{gnus-emphasis-italic}, +@code{gnus-emphasis-underline}, @code{gnus-emphasis-bold-italic}, +@code{gnus-emphasis-underline-italic}, +@code{gnus-emphasis-underline-bold}, and +@code{gnus-emphasis-underline-bold-italic}. -Sometime users post articles (or series of articles) that have been -encoded in some way or other. Gnus can decode them for you. +If you want to change these faces, you can either use @kbd{M-x +customize}, or you can use @code{copy-face}. For instance, if you want +to make @code{gnus-emphasis-italic} use a red face instead, you could +say something like: -@menu -* Uuencoded Articles:: Uudecode articles. -* Shell Archives:: Unshar articles. -* PostScript Files:: Split PostScript. -* Other Files:: Plain save and binhex. -* Decoding Variables:: Variables for a happy decoding. -* Viewing Files:: You want to look at the result of the decoding? -@end menu +@lisp +(copy-face 'red 'gnus-emphasis-italic) +@end lisp -@cindex series -@cindex article series -All these functions use the process/prefix convention -(@pxref{Process/Prefix}) for finding out what articles to work on, with -the extension that a ``single article'' means ``a single series''. Gnus -can find out by itself what articles belong to a series, decode all the -articles and unpack/view/save the resulting file(s). +@vindex gnus-group-highlight-words-alist -Gnus guesses what articles are in the series according to the following -simplish rule: The subjects must be (nearly) identical, except for the -last two numbers of the line. (Spaces are largely ignored, however.) +If you want to highlight arbitrary words, you can use the +@code{gnus-group-highlight-words-alist} variable, which uses the same +syntax as @code{gnus-emphasis-alist}. The @code{highlight-words} group +parameter (@pxref{Group Parameters}) can also be used. -For example: If you choose a subject called @samp{cat.gif (2/3)}, Gnus -will find all the articles that match the regexp @samp{^cat.gif -([0-9]+/[0-9]+).*$}. +@xref{Customizing Articles}, for how to fontize articles automatically. -Subjects that are non-standard, like @samp{cat.gif (2/3) Part 6 of a -series}, will not be properly recognized by any of the automatic viewing -commands, and you have to mark the articles manually with @kbd{#}. +@node Article Hiding +@subsection Article Hiding +@cindex article hiding -@node Uuencoded Articles -@subsection Uuencoded Articles -@cindex uudecode -@cindex uuencoded articles +Or rather, hiding certain things in each article. There usually is much +too much cruft in most articles. @table @kbd -@item X u -@kindex X u (Summary) -@findex gnus-uu-decode-uu -@c @icon{gnus-uu-decode-uu} -Uudecodes the current series (@code{gnus-uu-decode-uu}). +@item W W a +@kindex W W a (Summary) +@findex gnus-article-hide +Do quite a lot of hiding on the article buffer +(@kbd{gnus-article-hide}). In particular, this function will hide +headers, @acronym{PGP}, cited text and the signature. -@item X U -@kindex X U (Summary) -@findex gnus-uu-decode-uu-and-save -Uudecodes and saves the current series -(@code{gnus-uu-decode-uu-and-save}). +@item W W h +@kindex W W h (Summary) +@findex gnus-article-hide-headers +Hide headers (@code{gnus-article-hide-headers}). @xref{Hiding +Headers}. -@item X v u -@kindex X v u (Summary) -@findex gnus-uu-decode-uu-view -Uudecodes and views the current series (@code{gnus-uu-decode-uu-view}). +@item W W b +@kindex W W b (Summary) +@findex gnus-article-hide-boring-headers +Hide headers that aren't particularly interesting +(@code{gnus-article-hide-boring-headers}). @xref{Hiding Headers}. -@item X v U -@kindex X v U (Summary) -@findex gnus-uu-decode-uu-and-save-view -Uudecodes, views and saves the current series -(@code{gnus-uu-decode-uu-and-save-view}). +@item W W s +@kindex W W s (Summary) +@findex gnus-article-hide-signature +Hide signature (@code{gnus-article-hide-signature}). @xref{Article +Signature}. -@end table +@item W W l +@kindex W W l (Summary) +@findex gnus-article-hide-list-identifiers +@vindex gnus-list-identifiers +Strip list identifiers specified in @code{gnus-list-identifiers}. These +are strings some mailing list servers add to the beginning of all +@code{Subject} headers---for example, @samp{[zebra 4711]}. Any leading +@samp{Re: } is skipped before stripping. @code{gnus-list-identifiers} +may not contain @code{\\(..\\)}. -Remember that these all react to the presence of articles marked with -the process mark. If, for instance, you'd like to decode and save an -entire newsgroup, you'd typically do @kbd{M P a} -(@code{gnus-uu-mark-all}) and then @kbd{X U} -(@code{gnus-uu-decode-uu-and-save}). +@table @code -All this is very much different from how @code{gnus-uu} worked with -@sc{gnus 4.1}, where you had explicit keystrokes for everything under -the sun. This version of @code{gnus-uu} generally assumes that you mark -articles in some way (@pxref{Setting Process Marks}) and then press -@kbd{X u}. +@item gnus-list-identifiers +@vindex gnus-list-identifiers +A regular expression that matches list identifiers to be removed from +subject. This can also be a list of regular expressions. -@vindex gnus-uu-notify-files -Note: When trying to decode articles that have names matching -@code{gnus-uu-notify-files}, which is hard-coded to -@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}, @code{gnus-uu} will -automatically post an article on @samp{comp.unix.wizards} saying that -you have just viewed the file in question. This feature can't be turned -off. +@end table +@item W W P +@kindex W W P (Summary) +@findex gnus-article-hide-pem +Hide @acronym{PEM} (privacy enhanced messages) cruft +(@code{gnus-article-hide-pem}). -@node Shell Archives -@subsection Shell Archives -@cindex unshar -@cindex shell archives -@cindex shared articles +@item W W B +@kindex W W B (Summary) +@findex gnus-article-strip-banner +@vindex gnus-article-banner-alist +@vindex gnus-article-address-banner-alist +@cindex banner +@cindex OneList +@cindex stripping advertisements +@cindex advertisements +Strip the banner specified by the @code{banner} group parameter +(@code{gnus-article-strip-banner}). This is mainly used to hide those +annoying banners and/or signatures that some mailing lists and moderated +groups adds to all the messages. The way to use this function is to add +the @code{banner} group parameter (@pxref{Group Parameters}) to the +group you want banners stripped from. The parameter either be a string, +which will be interpreted as a regular expression matching text to be +removed, or the symbol @code{signature}, meaning that the (last) +signature should be removed, or other symbol, meaning that the +corresponding regular expression in @code{gnus-article-banner-alist} is +used. -Shell archives (``shar files'') used to be a popular way to distribute -sources, but it isn't used all that much today. In any case, we have -some commands to deal with these: +For instance: -@table @kbd +@lisp +(setq gnus-article-banner-alist + ((googleGroups . + "^\n*--~--~---------\\(.+\n\\)+"))) +@end lisp -@item X s -@kindex X s (Summary) -@findex gnus-uu-decode-unshar -Unshars the current series (@code{gnus-uu-decode-unshar}). +Regardless of a group, you can hide things like advertisements only when +the sender of an article has a certain mail address specified in +@code{gnus-article-address-banner-alist}. -@item X S -@kindex X S (Summary) -@findex gnus-uu-decode-unshar-and-save -Unshars and saves the current series (@code{gnus-uu-decode-unshar-and-save}). +@table @code -@item X v s -@kindex X v s (Summary) -@findex gnus-uu-decode-unshar-view -Unshars and views the current series (@code{gnus-uu-decode-unshar-view}). +@item gnus-article-address-banner-alist +@vindex gnus-article-address-banner-alist +Alist of mail addresses and banners. Each element has the form +@code{(@var{address} . @var{banner})}, where @var{address} is a regexp +matching a mail address in the From header, @var{banner} is one of a +symbol @code{signature}, an item in @code{gnus-article-banner-alist}, +a regexp and @code{nil}. If @var{address} matches author's mail +address, it will remove things like advertisements. For example, if a +sender has the mail address @samp{hail@@yoo-hoo.co.jp} and there is a +banner something like @samp{Do You Yoo-hoo!?} in all articles he +sends, you can use the following element to remove them: -@item X v S -@kindex X v S (Summary) -@findex gnus-uu-decode-unshar-and-save-view -Unshars, views and saves the current series -(@code{gnus-uu-decode-unshar-and-save-view}). -@end table +@lisp +("@@yoo-hoo\\.co\\.jp\\'" . + "\n_+\nDo You Yoo-hoo!\\?\n.*\n.*\n") +@end lisp +@end table -@node PostScript Files -@subsection PostScript Files -@cindex PostScript +@item W W c +@kindex W W c (Summary) +@findex gnus-article-hide-citation +Hide citation (@code{gnus-article-hide-citation}). Some variables for +customizing the hiding: -@table @kbd +@table @code -@item X p -@kindex X p (Summary) -@findex gnus-uu-decode-postscript -Unpack the current PostScript series (@code{gnus-uu-decode-postscript}). +@item gnus-cited-opened-text-button-line-format +@itemx gnus-cited-closed-text-button-line-format +@vindex gnus-cited-closed-text-button-line-format +@vindex gnus-cited-opened-text-button-line-format +Gnus adds buttons to show where the cited text has been hidden, and to +allow toggle hiding the text. The format of the variable is specified +by these format-like variable (@pxref{Formatting Variables}). These +specs are valid: -@item X P -@kindex X P (Summary) -@findex gnus-uu-decode-postscript-and-save -Unpack and save the current PostScript series -(@code{gnus-uu-decode-postscript-and-save}). +@table @samp +@item b +Starting point of the hidden text. +@item e +Ending point of the hidden text. +@item l +Number of characters in the hidden region. +@item n +Number of lines of hidden text. +@end table -@item X v p -@kindex X v p (Summary) -@findex gnus-uu-decode-postscript-view -View the current PostScript series -(@code{gnus-uu-decode-postscript-view}). +@item gnus-cited-lines-visible +@vindex gnus-cited-lines-visible +The number of lines at the beginning of the cited text to leave +shown. This can also be a cons cell with the number of lines at the top +and bottom of the text, respectively, to remain visible. -@item X v P -@kindex X v P (Summary) -@findex gnus-uu-decode-postscript-and-save-view -View and save the current PostScript series -(@code{gnus-uu-decode-postscript-and-save-view}). @end table +@item W W C-c +@kindex W W C-c (Summary) +@findex gnus-article-hide-citation-maybe + +Hide citation (@code{gnus-article-hide-citation-maybe}) depending on the +following two variables: -@node Other Files -@subsection Other Files +@table @code +@item gnus-cite-hide-percentage +@vindex gnus-cite-hide-percentage +If the cited text is of a bigger percentage than this variable (default +50), hide the cited text. -@table @kbd -@item X o -@kindex X o (Summary) -@findex gnus-uu-decode-save -Save the current series -(@code{gnus-uu-decode-save}). +@item gnus-cite-hide-absolute +@vindex gnus-cite-hide-absolute +The cited text must have at least this length (default 10) before it +is hidden. +@end table -@item X b -@kindex X b (Summary) -@findex gnus-uu-decode-binhex -Unbinhex the current series (@code{gnus-uu-decode-binhex}). This -doesn't really work yet. +@item W W C +@kindex W W C (Summary) +@findex gnus-article-hide-citation-in-followups +Hide cited text in articles that aren't roots +(@code{gnus-article-hide-citation-in-followups}). This isn't very +useful as an interactive command, but might be a handy function to stick +have happen automatically (@pxref{Customizing Articles}). -@item X Y -@kindex X Y (Summary) -@findex gnus-uu-decode-yenc -yEnc-decode the current series and save it (@code{gnus-uu-decode-yenc}). @end table +All these ``hiding'' commands are toggles, but if you give a negative +prefix to these commands, they will show what they have previously +hidden. If you give a positive prefix, they will always hide. -@node Decoding Variables -@subsection Decoding Variables +Also @pxref{Article Highlighting} for further variables for +citation customization. -Adjective, not verb. +@xref{Customizing Articles}, for how to hide article elements +automatically. -@menu -* Rule Variables:: Variables that say how a file is to be viewed. -* Other Decode Variables:: Other decode variables. -* Uuencoding and Posting:: Variables for customizing uuencoding. -@end menu +@node Article Washing +@subsection Article Washing +@cindex washing +@cindex article washing -@node Rule Variables -@subsubsection Rule Variables -@cindex rule variables +We call this ``article washing'' for a really good reason. Namely, the +@kbd{A} key was taken, so we had to use the @kbd{W} key instead. -Gnus uses @dfn{rule variables} to decide how to view a file. All these -variables are of the form +@dfn{Washing} is defined by us as ``changing something from something to +something else'', but normally results in something looking better. +Cleaner, perhaps. -@lisp - (list '(regexp1 command2) - '(regexp2 command2) - ...) -@end lisp +@xref{Customizing Articles}, if you want to change how Gnus displays +articles by default. -@table @code +@table @kbd -@item gnus-uu-user-view-rules -@vindex gnus-uu-user-view-rules -@cindex sox -This variable is consulted first when viewing files. If you wish to use, -for instance, @code{sox} to convert an @file{.au} sound file, you could -say something like: -@lisp -(setq gnus-uu-user-view-rules - (list '("\\\\.au$" "sox %s -t .aiff > /dev/audio"))) -@end lisp +@item C-u g +This is not really washing, it's sort of the opposite of washing. If +you type this, you see the article exactly as it exists on disk or on +the server. -@item gnus-uu-user-view-rules-end -@vindex gnus-uu-user-view-rules-end -This variable is consulted if Gnus couldn't make any matches from the -user and default view rules. +@item g +Force redisplaying of the current article +(@code{gnus-summary-show-article}). This is also not really washing. +If you type this, you see the article without any previously applied +interactive Washing functions but with all default treatments +(@pxref{Customizing Articles}). -@item gnus-uu-user-archive-rules -@vindex gnus-uu-user-archive-rules -This variable can be used to say what commands should be used to unpack -archives. -@end table +@item W l +@kindex W l (Summary) +@findex gnus-summary-stop-page-breaking +Remove page breaks from the current article +(@code{gnus-summary-stop-page-breaking}). @xref{Misc Article}, for page +delimiters. +@item W r +@kindex W r (Summary) +@findex gnus-summary-caesar-message +@c @icon{gnus-summary-caesar-message} +Do a Caesar rotate (rot13) on the article buffer +(@code{gnus-summary-caesar-message}). +Unreadable articles that tell you to read them with Caesar rotate or rot13. +(Typically offensive jokes and such.) -@node Other Decode Variables -@subsubsection Other Decode Variables +It's commonly called ``rot13'' because each letter is rotated 13 +positions in the alphabet, e. g. @samp{B} (letter #2) -> @samp{O} (letter +#15). It is sometimes referred to as ``Caesar rotate'' because Caesar +is rumored to have employed this form of, uh, somewhat weak encryption. -@table @code -@vindex gnus-uu-grabbed-file-functions +@item W m +@kindex W m (Summary) +@findex gnus-summary-morse-message +Morse decode the article buffer (@code{gnus-summary-morse-message}). -@item gnus-uu-grabbed-file-functions -All functions in this list will be called right after each file has been -successfully decoded---so that you can move or view files right away, -and don't have to wait for all files to be decoded before you can do -anything. Ready-made functions you can put in this list are: +@item W i +@kindex W i (Summary) +@findex gnus-summary-idna-message +Decode IDNA encoded domain names in the current articles. IDNA +encoded domain names looks like @samp{xn--bar}. If a string remain +unencoded after running invoking this, it is likely an invalid IDNA +string (@samp{xn--bar} is invalid). You must have GNU Libidn +(@url{http://www.gnu.org/software/libidn/}) installed for this command +to work. -@table @code +@item W t +@item t +@kindex W t (Summary) +@kindex t (Summary) +@findex gnus-summary-toggle-header +Toggle whether to display all headers in the article buffer +(@code{gnus-summary-toggle-header}). -@item gnus-uu-grab-view -@findex gnus-uu-grab-view -View the file. +@item W v +@kindex W v (Summary) +@findex gnus-summary-verbose-headers +Toggle whether to display all headers in the article buffer permanently +(@code{gnus-summary-verbose-headers}). -@item gnus-uu-grab-move -@findex gnus-uu-grab-move -Move the file (if you're using a saving function.) -@end table +@item W o +@kindex W o (Summary) +@findex gnus-article-treat-overstrike +Treat overstrike (@code{gnus-article-treat-overstrike}). -@item gnus-uu-be-dangerous -@vindex gnus-uu-be-dangerous -Specifies what to do if unusual situations arise during decoding. If -@code{nil}, be as conservative as possible. If @code{t}, ignore things -that didn't work, and overwrite existing files. Otherwise, ask each -time. +@item W d +@kindex W d (Summary) +@findex gnus-article-treat-dumbquotes +@vindex gnus-article-dumbquotes-map +@cindex Smartquotes +@cindex M****s*** sm*rtq**t*s +@cindex Latin 1 +Treat M****s*** sm*rtq**t*s according to +@code{gnus-article-dumbquotes-map} +(@code{gnus-article-treat-dumbquotes}). Note that this function guesses +whether a character is a sm*rtq**t* or not, so it should only be used +interactively. -@item gnus-uu-ignore-files-by-name -@vindex gnus-uu-ignore-files-by-name -Files with name matching this regular expression won't be viewed. +Sm*rtq**t*s are M****s***'s unilateral extension to the character map in +an attempt to provide more quoting characters. If you see something +like @code{\222} or @code{\264} where you're expecting some kind of +apostrophe or quotation mark, then try this wash. -@item gnus-uu-ignore-files-by-type -@vindex gnus-uu-ignore-files-by-type -Files with a @acronym{MIME} type matching this variable won't be viewed. -Note that Gnus tries to guess what type the file is based on the name. -@code{gnus-uu} is not a @acronym{MIME} package (yet), so this is slightly -kludgey. +@item W U +@kindex W U (Summary) +@findex gnus-article-treat-non-ascii +@cindex Unicode +@cindex Non-@acronym{ASCII} +Translate many non-@acronym{ASCII} characters into their +@acronym{ASCII} equivalents (@code{gnus-article-treat-non-ascii}). +This is mostly useful if you're on a terminal that has a limited font +and does't show accented characters, ``advanced'' punctuation, and the +like. For instance, @samp{»} is tranlated into @samp{>>}, and so on. -@item gnus-uu-tmp-dir -@vindex gnus-uu-tmp-dir -Where @code{gnus-uu} does its work. +@item W Y f +@kindex W Y f (Summary) +@findex gnus-article-outlook-deuglify-article +@cindex Outlook Express +Full deuglify of broken Outlook (Express) articles: Treat dumbquotes, +unwrap lines, repair attribution and rearrange citation. +(@code{gnus-article-outlook-deuglify-article}). -@item gnus-uu-do-not-unpack-archives -@vindex gnus-uu-do-not-unpack-archives -Non-@code{nil} means that @code{gnus-uu} won't peek inside archives -looking for files to display. +@item W Y u +@kindex W Y u (Summary) +@findex gnus-article-outlook-unwrap-lines +@vindex gnus-outlook-deuglify-unwrap-min +@vindex gnus-outlook-deuglify-unwrap-max +Unwrap lines that appear to be wrapped citation lines. You can control +what lines will be unwrapped by frobbing +@code{gnus-outlook-deuglify-unwrap-min} and +@code{gnus-outlook-deuglify-unwrap-max}, indicating the minimum and +maximum length of an unwrapped citation line. +(@code{gnus-article-outlook-unwrap-lines}). -@item gnus-uu-view-and-save -@vindex gnus-uu-view-and-save -Non-@code{nil} means that the user will always be asked to save a file -after viewing it. +@item W Y a +@kindex W Y a (Summary) +@findex gnus-article-outlook-repair-attribution +Repair a broken attribution line.@* +(@code{gnus-article-outlook-repair-attribution}). -@item gnus-uu-ignore-default-view-rules -@vindex gnus-uu-ignore-default-view-rules -Non-@code{nil} means that @code{gnus-uu} will ignore the default viewing -rules. +@item W Y c +@kindex W Y c (Summary) +@findex gnus-article-outlook-rearrange-citation +Repair broken citations by rearranging the text. +(@code{gnus-article-outlook-rearrange-citation}). -@item gnus-uu-ignore-default-archive-rules -@vindex gnus-uu-ignore-default-archive-rules -Non-@code{nil} means that @code{gnus-uu} will ignore the default archive -unpacking commands. +@item W w +@kindex W w (Summary) +@findex gnus-article-fill-cited-article +Do word wrap (@code{gnus-article-fill-cited-article}). -@item gnus-uu-kill-carriage-return -@vindex gnus-uu-kill-carriage-return -Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns -from articles. +You can give the command a numerical prefix to specify the width to use +when filling. -@item gnus-uu-unmark-articles-not-decoded -@vindex gnus-uu-unmark-articles-not-decoded -Non-@code{nil} means that @code{gnus-uu} will mark unsuccessfully -decoded articles as unread. +@item W Q +@kindex W Q (Summary) +@findex gnus-article-fill-long-lines +Fill long lines (@code{gnus-article-fill-long-lines}). -@item gnus-uu-correct-stripped-uucode -@vindex gnus-uu-correct-stripped-uucode -Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix -uuencoded files that have had trailing spaces deleted. +@item W C +@kindex W C (Summary) +@findex gnus-article-capitalize-sentences +Capitalize the first word in each sentence +(@code{gnus-article-capitalize-sentences}). -@item gnus-uu-pre-uudecode-hook -@vindex gnus-uu-pre-uudecode-hook -Hook run before sending a message to @code{uudecode}. +@item W c +@kindex W c (Summary) +@findex gnus-article-remove-cr +Translate CRLF pairs (i. e., @samp{^M}s on the end of the lines) into LF +(this takes care of DOS line endings), and then translate any remaining +CRs into LF (this takes care of Mac line endings) +(@code{gnus-article-remove-cr}). -@item gnus-uu-view-with-metamail -@vindex gnus-uu-view-with-metamail -@cindex metamail -Non-@code{nil} means that @code{gnus-uu} will ignore the viewing -commands defined by the rule variables and just fudge a @acronym{MIME} -content type based on the file name. The result will be fed to -@code{metamail} for viewing. +@item W q +@kindex W q (Summary) +@findex gnus-article-de-quoted-unreadable +Treat quoted-printable (@code{gnus-article-de-quoted-unreadable}). +Quoted-Printable is one common @acronym{MIME} encoding employed when +sending non-@acronym{ASCII} (i.e., 8-bit) articles. It typically +makes strings like @samp{d@'ej@`a vu} look like @samp{d=E9j=E0 vu}, +which doesn't look very readable to me. Note that this is usually +done automatically by Gnus if the message in question has a +@code{Content-Transfer-Encoding} header that says that this encoding +has been done. If a prefix is given, a charset will be asked for. -@item gnus-uu-save-in-digest -@vindex gnus-uu-save-in-digest -Non-@code{nil} means that @code{gnus-uu}, when asked to save without -decoding, will save in digests. If this variable is @code{nil}, -@code{gnus-uu} will just save everything in a file without any -embellishments. The digesting almost conforms to RFC 1153---no easy way -to specify any meaningful volume and issue numbers were found, so I -simply dropped them. +@item W 6 +@kindex W 6 (Summary) +@findex gnus-article-de-base64-unreadable +Treat base64 (@code{gnus-article-de-base64-unreadable}). Base64 is +one common @acronym{MIME} encoding employed when sending +non-@acronym{ASCII} (i.e., 8-bit) articles. Note that this is +usually done automatically by Gnus if the message in question has a +@code{Content-Transfer-Encoding} header that says that this encoding +has been done. If a prefix is given, a charset will be asked for. -@end table +@item W Z +@kindex W Z (Summary) +@findex gnus-article-decode-HZ +Treat HZ or HZP (@code{gnus-article-decode-HZ}). HZ (or HZP) is one +common encoding employed when sending Chinese articles. It typically +makes strings look like @samp{~@{<:Ky2;S@{#,NpJ)l6HK!#~@}}. +@item W A +@kindex W A (Summary) +@findex gnus-article-treat-ansi-sequences +@cindex @acronym{ANSI} control sequences +Translate @acronym{ANSI} SGR control sequences into overlays or +extents (@code{gnus-article-treat-ansi-sequences}). @acronym{ANSI} +sequences are used in some Chinese hierarchies for highlighting. -@node Uuencoding and Posting -@subsubsection Uuencoding and Posting +@item W u +@kindex W u (Summary) +@findex gnus-article-unsplit-urls +Remove newlines from within URLs. Some mailers insert newlines into +outgoing email messages to keep lines short. This reformatting can +split long URLs onto multiple lines. Repair those URLs by removing +the newlines (@code{gnus-article-unsplit-urls}). -@table @code +@item W h +@kindex W h (Summary) +@findex gnus-article-wash-html +Treat @acronym{HTML} (@code{gnus-article-wash-html}). Note that this is +usually done automatically by Gnus if the message in question has a +@code{Content-Type} header that says that the message is @acronym{HTML}. -@item gnus-uu-post-include-before-composing -@vindex gnus-uu-post-include-before-composing -Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode -before you compose the article. If this variable is @code{t}, you can -either include an encoded file with @kbd{C-c C-i} or have one included -for you when you post the article. +If a prefix is given, a charset will be asked for. If it is a number, +the charset defined in @code{gnus-summary-show-article-charset-alist} +(@pxref{Paging the Article}) will be used. -@item gnus-uu-post-length -@vindex gnus-uu-post-length -Maximum length of an article. The encoded file will be split into how -many articles it takes to post the entire file. +The default is to use the function specified by +@code{mm-text-html-renderer} (@pxref{Display Customization, ,Display +Customization, emacs-mime, The Emacs MIME Manual}) to convert the +@acronym{HTML}. Pre-defined functions you can use include: -@item gnus-uu-post-threaded -@vindex gnus-uu-post-threaded -Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a -thread. This may not be smart, as no other decoder I have seen is able -to follow threads when collecting uuencoded articles. (Well, I have -seen one package that does that---@code{gnus-uu}, but somehow, I don't -think that counts@dots{}) Default is @code{nil}. +@table @code +@item shr +Use Gnus simple html renderer. -@item gnus-uu-post-separate-description -@vindex gnus-uu-post-separate-description -Non-@code{nil} means that the description will be posted in a separate -article. The first article will typically be numbered (0/x). If this -variable is @code{nil}, the description the user enters will be included -at the beginning of the first article, which will be numbered (1/x). -Default is @code{t}. +@item gnus-w3m +Use Gnus rendered based on w3m. -@end table +@item w3 +Use Emacs/W3. +@item w3m +Use @uref{http://emacs-w3m.namazu.org/, emacs-w3m}. -@node Viewing Files -@subsection Viewing Files -@cindex viewing files -@cindex pseudo-articles +@item w3m-standalone +Use @uref{http://w3m.sourceforge.net/, w3m}. -After decoding, if the file is some sort of archive, Gnus will attempt -to unpack the archive and see if any of the files in the archive can be -viewed. For instance, if you have a gzipped tar file @file{pics.tar.gz} -containing the files @file{pic1.jpg} and @file{pic2.gif}, Gnus will -uncompress and de-tar the main file, and then view the two pictures. -This unpacking process is recursive, so if the archive contains archives -of archives, it'll all be unpacked. +@item links +Use @uref{http://links.sf.net/, Links}. -Finally, Gnus will normally insert a @dfn{pseudo-article} for each -extracted file into the summary buffer. If you go to these -``articles'', you will be prompted for a command to run (usually Gnus -will make a suggestion), and then the command will be run. +@item lynx +Use @uref{http://lynx.isc.org/, Lynx}. -@vindex gnus-view-pseudo-asynchronously -If @code{gnus-view-pseudo-asynchronously} is @code{nil}, Emacs will wait -until the viewing is done before proceeding. +@item html2text +Use html2text---a simple @acronym{HTML} converter included with Gnus. -@vindex gnus-view-pseudos -If @code{gnus-view-pseudos} is @code{automatic}, Gnus will not insert -the pseudo-articles into the summary buffer, but view them -immediately. If this variable is @code{not-confirm}, the user won't even -be asked for a confirmation before viewing is done. +@end table -@vindex gnus-view-pseudos-separately -If @code{gnus-view-pseudos-separately} is non-@code{nil}, one -pseudo-article will be created for each file to be viewed. If -@code{nil}, all files that use the same viewing command will be given as -a list of parameters to that command. +@item W b +@kindex W b (Summary) +@findex gnus-article-add-buttons +Add clickable buttons to the article (@code{gnus-article-add-buttons}). +@xref{Article Buttons}. -@vindex gnus-insert-pseudo-articles -If @code{gnus-insert-pseudo-articles} is non-@code{nil}, insert -pseudo-articles when decoding. It is @code{t} by default. +@item W B +@kindex W B (Summary) +@findex gnus-article-add-buttons-to-head +Add clickable buttons to the article headers +(@code{gnus-article-add-buttons-to-head}). -So; there you are, reading your @emph{pseudo-articles} in your -@emph{virtual newsgroup} from the @emph{virtual server}; and you think: -Why isn't anything real anymore? How did we get here? +@item W p +@kindex W p (Summary) +@findex gnus-article-verify-x-pgp-sig +Verify a signed control message +(@code{gnus-article-verify-x-pgp-sig}). Control messages such as +@code{newgroup} and @code{checkgroups} are usually signed by the +hierarchy maintainer. You need to add the @acronym{PGP} public key of +the maintainer to your keyring to verify the +message.@footnote{@acronym{PGP} keys for many hierarchies are +available at @uref{ftp://ftp.isc.org/pub/pgpcontrol/README.html}} +@item W s +@kindex W s (Summary) +@findex gnus-summary-force-verify-and-decrypt +Verify a signed (@acronym{PGP}, @acronym{PGP/MIME} or +@acronym{S/MIME}) message +(@code{gnus-summary-force-verify-and-decrypt}). @xref{Security}. -@node Article Treatment -@section Article Treatment +@item W a +@kindex W a (Summary) +@findex gnus-article-strip-headers-in-body +Strip headers like the @code{X-No-Archive} header from the beginning of +article bodies (@code{gnus-article-strip-headers-in-body}). -Reading through this huge manual, you may have quite forgotten that the -object of newsreaders is to actually, like, read what people have -written. Reading articles. Unfortunately, people are quite bad at -writing, so there are tons of functions and variables to make reading -these articles easier. +@item W E l +@kindex W E l (Summary) +@findex gnus-article-strip-leading-blank-lines +Remove all blank lines from the beginning of the article +(@code{gnus-article-strip-leading-blank-lines}). -@menu -* Article Highlighting:: You want to make the article look like fruit salad. -* Article Fontisizing:: Making emphasized text look nice. -* Article Hiding:: You also want to make certain info go away. -* Article Washing:: Lots of way-neat functions to make life better. -* Article Header:: Doing various header transformations. -* Article Buttons:: Click on URLs, Message-IDs, addresses and the like. -* Article Button Levels:: Controlling appearance of buttons. -* Article Date:: Grumble, UT! -* Article Display:: Display various stuff: - X-Face, Picons, Gravatars, Smileys. -* Article Signature:: What is a signature? -* Article Miscellanea:: Various other stuff. -@end menu +@item W E m +@kindex W E m (Summary) +@findex gnus-article-strip-multiple-blank-lines +Replace all blank lines with empty lines and then all multiple empty +lines with a single empty line. +(@code{gnus-article-strip-multiple-blank-lines}). +@item W E t +@kindex W E t (Summary) +@findex gnus-article-remove-trailing-blank-lines +Remove all blank lines at the end of the article +(@code{gnus-article-remove-trailing-blank-lines}). -@node Article Highlighting -@subsection Article Highlighting -@cindex highlighting +@item W E a +@kindex W E a (Summary) +@findex gnus-article-strip-blank-lines +Do all the three commands above +(@code{gnus-article-strip-blank-lines}). -Not only do you want your article buffer to look like fruit salad, but -you want it to look like technicolor fruit salad. +@item W E A +@kindex W E A (Summary) +@findex gnus-article-strip-all-blank-lines +Remove all blank lines +(@code{gnus-article-strip-all-blank-lines}). -@table @kbd +@item W E s +@kindex W E s (Summary) +@findex gnus-article-strip-leading-space +Remove all white space from the beginning of all lines of the article +body (@code{gnus-article-strip-leading-space}). -@item W H a -@kindex W H a (Summary) -@findex gnus-article-highlight -@findex gnus-article-maybe-highlight -Do much highlighting of the current article -(@code{gnus-article-highlight}). This function highlights header, cited -text, the signature, and adds buttons to the body and the head. +@item W E e +@kindex W E e (Summary) +@findex gnus-article-strip-trailing-space +Remove all white space from the end of all lines of the article +body (@code{gnus-article-strip-trailing-space}). -@item W H h -@kindex W H h (Summary) -@findex gnus-article-highlight-headers -@vindex gnus-header-face-alist -Highlight the headers (@code{gnus-article-highlight-headers}). The -highlighting will be done according to the @code{gnus-header-face-alist} -variable, which is a list where each element has the form -@code{(@var{regexp} @var{name} @var{content})}. -@var{regexp} is a regular expression for matching the -header, @var{name} is the face used for highlighting the header name -(@pxref{Faces and Fonts}) and @var{content} is the face for highlighting -the header value. The first match made will be used. Note that -@var{regexp} shouldn't have @samp{^} prepended---Gnus will add one. +@end table -@item W H c -@kindex W H c (Summary) -@findex gnus-article-highlight-citation -Highlight cited text (@code{gnus-article-highlight-citation}). +@xref{Customizing Articles}, for how to wash articles automatically. -Some variables to customize the citation highlights: -@table @code -@vindex gnus-cite-parse-max-size +@node Article Header +@subsection Article Header -@item gnus-cite-parse-max-size -If the article size in bytes is bigger than this variable (which is -25000 by default), no citation highlighting will be performed. +These commands perform various transformations of article header. -@item gnus-cite-max-prefix -@vindex gnus-cite-max-prefix -Maximum possible length for a citation prefix (default 20). +@table @kbd -@item gnus-cite-face-list -@vindex gnus-cite-face-list -List of faces used for highlighting citations (@pxref{Faces and Fonts}). -When there are citations from multiple articles in the same message, -Gnus will try to give each citation from each article its own face. -This should make it easier to see who wrote what. +@item W G u +@kindex W G u (Summary) +@findex gnus-article-treat-unfold-headers +Unfold folded header lines (@code{gnus-article-treat-unfold-headers}). -@item gnus-supercite-regexp -@vindex gnus-supercite-regexp -Regexp matching normal Supercite attribution lines. +@item W G n +@kindex W G n (Summary) +@findex gnus-article-treat-fold-newsgroups +Fold the @code{Newsgroups} and @code{Followup-To} headers +(@code{gnus-article-treat-fold-newsgroups}). -@item gnus-supercite-secondary-regexp -@vindex gnus-supercite-secondary-regexp -Regexp matching mangled Supercite attribution lines. +@item W G f +@kindex W G f (Summary) +@findex gnus-article-treat-fold-headers +Fold all the message headers +(@code{gnus-article-treat-fold-headers}). -@item gnus-cite-minimum-match-count -@vindex gnus-cite-minimum-match-count -Minimum number of identical prefixes we have to see before we believe -that it's a citation. +@item W E w +@kindex W E w (Summary) +@findex gnus-article-remove-leading-whitespace +Remove excessive whitespace from all headers +(@code{gnus-article-remove-leading-whitespace}). -@item gnus-cite-attribution-prefix -@vindex gnus-cite-attribution-prefix -Regexp matching the beginning of an attribution line. +@end table -@item gnus-cite-attribution-suffix -@vindex gnus-cite-attribution-suffix -Regexp matching the end of an attribution line. -@item gnus-cite-attribution-face -@vindex gnus-cite-attribution-face -Face used for attribution lines. It is merged with the face for the -cited text belonging to the attribution. +@node Article Buttons +@subsection Article Buttons +@cindex buttons -@item gnus-cite-ignore-quoted-from -@vindex gnus-cite-ignore-quoted-from -If non-@code{nil}, no citation highlighting will be performed on lines -beginning with @samp{>From }. Those lines may have been quoted by MTAs -in order not to mix up with the envelope From line. The default value -is @code{t}. +People often include references to other stuff in articles, and it would +be nice if Gnus could just fetch whatever it is that people talk about +with the minimum of fuzz when you hit @kbd{RET} or use the middle mouse +button on these references. -@end table +@vindex gnus-button-man-handler +Gnus adds @dfn{buttons} to certain standard references by default: +Well-formed URLs, mail addresses, Message-IDs, Info links, man pages and +Emacs or Gnus related references. This is controlled by two variables, +one that handles article bodies and one that handles article heads: +@table @code -@item W H s -@kindex W H s (Summary) -@vindex gnus-signature-separator -@vindex gnus-signature-face -@findex gnus-article-highlight-signature -Highlight the signature (@code{gnus-article-highlight-signature}). -Everything after @code{gnus-signature-separator} (@pxref{Article -Signature}) in an article will be considered a signature and will be -highlighted with @code{gnus-signature-face}, which is @code{italic} by -default. +@item gnus-button-alist +@vindex gnus-button-alist +This is an alist where each entry has this form: -@end table +@lisp +(@var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par}) +@end lisp -@xref{Customizing Articles}, for how to highlight articles automatically. +@table @var +@item regexp +All text that match this regular expression (case insensitive) will be +considered an external reference. Here's a typical regexp that matches +embedded URLs: @samp{]*\\)>}. This can also be a +variable containing a regexp, useful variables to use include +@code{gnus-button-url-regexp} and @code{gnus-button-mid-or-mail-regexp}. -@node Article Fontisizing -@subsection Article Fontisizing -@cindex emphasis -@cindex article emphasis +@item button-par +Gnus has to know which parts of the matches is to be highlighted. This +is a number that says what sub-expression of the regexp is to be +highlighted. If you want it all highlighted, you use 0 here. -@findex gnus-article-emphasize -@kindex W e (Summary) -People commonly add emphasis to words in news articles by writing things -like @samp{_this_} or @samp{*this*} or @samp{/this/}. Gnus can make -this look nicer by running the article through the @kbd{W e} -(@code{gnus-article-emphasize}) command. +@item use-p +This form will be @code{eval}ed, and if the result is non-@code{nil}, +this is considered a match. This is useful if you want extra sifting to +avoid false matches. Often variables named +@code{gnus-button-@var{*}-level} are used here, @xref{Article Button +Levels}, but any other form may be used too. -@vindex gnus-emphasis-alist -How the emphasis is computed is controlled by the -@code{gnus-emphasis-alist} variable. This is an alist where the first -element is a regular expression to be matched. The second is a number -that says what regular expression grouping is used to find the entire -emphasized word. The third is a number that says what regexp grouping -should be displayed and highlighted. (The text between these two -groupings will be hidden.) The fourth is the face used for -highlighting. +@c @code{use-p} is @code{eval}ed only if @code{regexp} matches. -@lisp -(setq gnus-emphasis-alist - '(("_\\(\\w+\\)_" 0 1 gnus-emphasis-underline) - ("\\*\\(\\w+\\)\\*" 0 1 gnus-emphasis-bold))) -@end lisp +@item function +This function will be called when you click on this button. -@cindex slash -@cindex asterisk -@cindex underline -@cindex / -@cindex * +@item data-par +As with @var{button-par}, this is a sub-expression number, but this one +says which part of the match is to be sent as data to @var{function}. -@vindex gnus-emphasis-underline -@vindex gnus-emphasis-bold -@vindex gnus-emphasis-italic -@vindex gnus-emphasis-underline-bold -@vindex gnus-emphasis-underline-italic -@vindex gnus-emphasis-bold-italic -@vindex gnus-emphasis-underline-bold-italic -By default, there are seven rules, and they use the following faces: -@code{gnus-emphasis-bold}, @code{gnus-emphasis-italic}, -@code{gnus-emphasis-underline}, @code{gnus-emphasis-bold-italic}, -@code{gnus-emphasis-underline-italic}, -@code{gnus-emphasis-underline-bold}, and -@code{gnus-emphasis-underline-bold-italic}. +@end table -If you want to change these faces, you can either use @kbd{M-x -customize}, or you can use @code{copy-face}. For instance, if you want -to make @code{gnus-emphasis-italic} use a red face instead, you could -say something like: +So the full entry for buttonizing URLs is then @lisp -(copy-face 'red 'gnus-emphasis-italic) +("]*\\)>" 0 t gnus-button-url 1) @end lisp -@vindex gnus-group-highlight-words-alist +@item gnus-header-button-alist +@vindex gnus-header-button-alist +This is just like the other alist, except that it is applied to the +article head only, and that each entry has an additional element that is +used to say what headers to apply the buttonize coding to: -If you want to highlight arbitrary words, you can use the -@code{gnus-group-highlight-words-alist} variable, which uses the same -syntax as @code{gnus-emphasis-alist}. The @code{highlight-words} group -parameter (@pxref{Group Parameters}) can also be used. +@lisp +(@var{header} @var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par}) +@end lisp -@xref{Customizing Articles}, for how to fontize articles automatically. +@var{header} is a regular expression. +@end table +@subsubsection Related variables and functions -@node Article Hiding -@subsection Article Hiding -@cindex article hiding +@table @code +@item gnus-button-@var{*}-level +@xref{Article Button Levels}. -Or rather, hiding certain things in each article. There usually is much -too much cruft in most articles. +@c Stuff related to gnus-button-browse-level -@table @kbd +@item gnus-button-url-regexp +@vindex gnus-button-url-regexp +A regular expression that matches embedded URLs. It is used in the +default values of the variables above. -@item W W a -@kindex W W a (Summary) -@findex gnus-article-hide -Do quite a lot of hiding on the article buffer -(@kbd{gnus-article-hide}). In particular, this function will hide -headers, @acronym{PGP}, cited text and the signature. +@c Stuff related to gnus-button-man-level -@item W W h -@kindex W W h (Summary) -@findex gnus-article-hide-headers -Hide headers (@code{gnus-article-hide-headers}). @xref{Hiding -Headers}. +@item gnus-button-man-handler +@vindex gnus-button-man-handler +The function to use for displaying man pages. It must take at least one +argument with a string naming the man page. -@item W W b -@kindex W W b (Summary) -@findex gnus-article-hide-boring-headers -Hide headers that aren't particularly interesting -(@code{gnus-article-hide-boring-headers}). @xref{Hiding Headers}. +@c Stuff related to gnus-button-message-level + +@item gnus-button-mid-or-mail-regexp +@vindex gnus-button-mid-or-mail-regexp +Regular expression that matches a message ID or a mail address. + +@item gnus-button-prefer-mid-or-mail +@vindex gnus-button-prefer-mid-or-mail +This variable determines what to do when the button on a string as +@samp{foo123@@bar.invalid} is pushed. Strings like this can be either a +message ID or a mail address. If it is one of the symbols @code{mid} or +@code{mail}, Gnus will always assume that the string is a message ID or +a mail address, respectively. If this variable is set to the symbol +@code{ask}, always query the user what to do. If it is a function, this +function will be called with the string as its only argument. The +function must return @code{mid}, @code{mail}, @code{invalid} or +@code{ask}. The default value is the function +@code{gnus-button-mid-or-mail-heuristic}. -@item W W s -@kindex W W s (Summary) -@findex gnus-article-hide-signature -Hide signature (@code{gnus-article-hide-signature}). @xref{Article -Signature}. +@item gnus-button-mid-or-mail-heuristic +@findex gnus-button-mid-or-mail-heuristic +Function that guesses whether its argument is a message ID or a mail +address. Returns @code{mid} if it's a message IDs, @code{mail} if +it's a mail address, @code{ask} if unsure and @code{invalid} if the +string is invalid. -@item W W l -@kindex W W l (Summary) -@findex gnus-article-hide-list-identifiers -@vindex gnus-list-identifiers -Strip list identifiers specified in @code{gnus-list-identifiers}. These -are strings some mailing list servers add to the beginning of all -@code{Subject} headers---for example, @samp{[zebra 4711]}. Any leading -@samp{Re: } is skipped before stripping. @code{gnus-list-identifiers} -may not contain @code{\\(..\\)}. +@item gnus-button-mid-or-mail-heuristic-alist +@vindex gnus-button-mid-or-mail-heuristic-alist +An alist of @code{(RATE . REGEXP)} pairs used by the function +@code{gnus-button-mid-or-mail-heuristic}. -@table @code +@c Misc stuff -@item gnus-list-identifiers -@vindex gnus-list-identifiers -A regular expression that matches list identifiers to be removed from -subject. This can also be a list of regular expressions. +@item gnus-article-button-face +@vindex gnus-article-button-face +Face used on buttons. + +@item gnus-article-mouse-face +@vindex gnus-article-mouse-face +Face used when the mouse cursor is over a button. @end table -@item W W P -@kindex W W P (Summary) -@findex gnus-article-hide-pem -Hide @acronym{PEM} (privacy enhanced messages) cruft -(@code{gnus-article-hide-pem}). +@xref{Customizing Articles}, for how to buttonize articles automatically. -@item W W B -@kindex W W B (Summary) -@findex gnus-article-strip-banner -@vindex gnus-article-banner-alist -@vindex gnus-article-address-banner-alist -@cindex banner -@cindex OneList -@cindex stripping advertisements -@cindex advertisements -Strip the banner specified by the @code{banner} group parameter -(@code{gnus-article-strip-banner}). This is mainly used to hide those -annoying banners and/or signatures that some mailing lists and moderated -groups adds to all the messages. The way to use this function is to add -the @code{banner} group parameter (@pxref{Group Parameters}) to the -group you want banners stripped from. The parameter either be a string, -which will be interpreted as a regular expression matching text to be -removed, or the symbol @code{signature}, meaning that the (last) -signature should be removed, or other symbol, meaning that the -corresponding regular expression in @code{gnus-article-banner-alist} is -used. -For instance: +@node Article Button Levels +@subsection Article button levels +@cindex button levels +The higher the value of the variables @code{gnus-button-@var{*}-level}, +the more buttons will appear. If the level is zero, no corresponding +buttons are displayed. With the default value (which is 5) you should +already see quite a lot of buttons. With higher levels, you will see +more buttons, but you may also get more false positives. To avoid them, +you can set the variables @code{gnus-button-@var{*}-level} local to +specific groups (@pxref{Group Parameters}). Here's an example for the +variable @code{gnus-parameters}: @lisp -(setq gnus-article-banner-alist - ((googleGroups . - "^\n*--~--~---------\\(.+\n\\)+"))) +;; @r{increase @code{gnus-button-*-level} in some groups:} +(setq gnus-parameters + '(("\\<\\(emacs\\|gnus\\)\\>" (gnus-button-emacs-level 10)) + ("\\" (gnus-button-man-level 10)) + ("\\" (gnus-button-tex-level 10)))) @end lisp -Regardless of a group, you can hide things like advertisements only when -the sender of an article has a certain mail address specified in -@code{gnus-article-address-banner-alist}. - @table @code -@item gnus-article-address-banner-alist -@vindex gnus-article-address-banner-alist -Alist of mail addresses and banners. Each element has the form -@code{(@var{address} . @var{banner})}, where @var{address} is a regexp -matching a mail address in the From header, @var{banner} is one of a -symbol @code{signature}, an item in @code{gnus-article-banner-alist}, -a regexp and @code{nil}. If @var{address} matches author's mail -address, it will remove things like advertisements. For example, if a -sender has the mail address @samp{hail@@yoo-hoo.co.jp} and there is a -banner something like @samp{Do You Yoo-hoo!?} in all articles he -sends, you can use the following element to remove them: +@item gnus-button-browse-level +@vindex gnus-button-browse-level +Controls the display of references to message IDs, mail addresses and +news URLs. Related variables and functions include +@code{gnus-button-url-regexp}, @code{browse-url}, and +@code{browse-url-browser-function}. -@lisp -("@@yoo-hoo\\.co\\.jp\\'" . - "\n_+\nDo You Yoo-hoo!\\?\n.*\n.*\n") -@end lisp +@item gnus-button-emacs-level +@vindex gnus-button-emacs-level +Controls the display of Emacs or Gnus references. Related functions are +@code{gnus-button-handle-custom}, +@code{gnus-button-handle-describe-function}, +@code{gnus-button-handle-describe-variable}, +@code{gnus-button-handle-symbol}, +@code{gnus-button-handle-describe-key}, +@code{gnus-button-handle-apropos}, +@code{gnus-button-handle-apropos-command}, +@code{gnus-button-handle-apropos-variable}, +@code{gnus-button-handle-apropos-documentation}, and +@code{gnus-button-handle-library}. + +@item gnus-button-man-level +@vindex gnus-button-man-level +Controls the display of references to (Unix) man pages. +See @code{gnus-button-man-handler}. + +@item gnus-button-message-level +@vindex gnus-button-message-level +Controls the display of message IDs, mail addresses and news URLs. +Related variables and functions include +@code{gnus-button-mid-or-mail-regexp}, +@code{gnus-button-prefer-mid-or-mail}, +@code{gnus-button-mid-or-mail-heuristic}, and +@code{gnus-button-mid-or-mail-heuristic-alist}. @end table -@item W W c -@kindex W W c (Summary) -@findex gnus-article-hide-citation -Hide citation (@code{gnus-article-hide-citation}). Some variables for -customizing the hiding: -@table @code +@node Article Date +@subsection Article Date -@item gnus-cited-opened-text-button-line-format -@itemx gnus-cited-closed-text-button-line-format -@vindex gnus-cited-closed-text-button-line-format -@vindex gnus-cited-opened-text-button-line-format -Gnus adds buttons to show where the cited text has been hidden, and to -allow toggle hiding the text. The format of the variable is specified -by these format-like variable (@pxref{Formatting Variables}). These -specs are valid: +The date is most likely generated in some obscure timezone you've never +heard of, so it's quite nice to be able to find out what the time was +when the article was sent. -@table @samp -@item b -Starting point of the hidden text. -@item e -Ending point of the hidden text. -@item l -Number of characters in the hidden region. -@item n -Number of lines of hidden text. -@end table +@table @kbd -@item gnus-cited-lines-visible -@vindex gnus-cited-lines-visible -The number of lines at the beginning of the cited text to leave -shown. This can also be a cons cell with the number of lines at the top -and bottom of the text, respectively, to remain visible. +@item W T u +@kindex W T u (Summary) +@findex gnus-article-date-ut +Display the date in UT (aka. GMT, aka ZULU) +(@code{gnus-article-date-ut}). -@end table +@item W T i +@kindex W T i (Summary) +@findex gnus-article-date-iso8601 +@cindex ISO 8601 +Display the date in international format, aka. ISO 8601 +(@code{gnus-article-date-iso8601}). -@item W W C-c -@kindex W W C-c (Summary) -@findex gnus-article-hide-citation-maybe +@item W T l +@kindex W T l (Summary) +@findex gnus-article-date-local +Display the date in the local timezone (@code{gnus-article-date-local}). -Hide citation (@code{gnus-article-hide-citation-maybe}) depending on the -following two variables: +@item W T p +@kindex W T p (Summary) +@findex gnus-article-date-english +Display the date in a format that's easily pronounceable in English +(@code{gnus-article-date-english}). -@table @code -@item gnus-cite-hide-percentage -@vindex gnus-cite-hide-percentage -If the cited text is of a bigger percentage than this variable (default -50), hide the cited text. +@item W T s +@kindex W T s (Summary) +@vindex gnus-article-time-format +@findex gnus-article-date-user +@findex format-time-string +Display the date using a user-defined format +(@code{gnus-article-date-user}). The format is specified by the +@code{gnus-article-time-format} variable, and is a string that's passed +to @code{format-time-string}. See the documentation of that variable +for a list of possible format specs. -@item gnus-cite-hide-absolute -@vindex gnus-cite-hide-absolute -The cited text must have at least this length (default 10) before it -is hidden. -@end table +@item W T e +@kindex W T e (Summary) +@findex gnus-article-date-lapsed +@findex gnus-start-date-timer +@findex gnus-stop-date-timer +Say how much time has elapsed between the article was posted and now +(@code{gnus-article-date-lapsed}). It looks something like: -@item W W C -@kindex W W C (Summary) -@findex gnus-article-hide-citation-in-followups -Hide cited text in articles that aren't roots -(@code{gnus-article-hide-citation-in-followups}). This isn't very -useful as an interactive command, but might be a handy function to stick -have happen automatically (@pxref{Customizing Articles}). +@example +X-Sent: 6 weeks, 4 days, 1 hour, 3 minutes, 8 seconds ago +@end example -@end table +@vindex gnus-article-date-lapsed-new-header +The value of @code{gnus-article-date-lapsed-new-header} determines +whether this header will just be added below the old Date one, or will +replace it. -All these ``hiding'' commands are toggles, but if you give a negative -prefix to these commands, they will show what they have previously -hidden. If you give a positive prefix, they will always hide. +An advantage of using Gnus to read mail is that it converts simple bugs +into wonderful absurdities. + +If you want to have this line updated continually, you can put + +@lisp +(gnus-start-date-timer) +@end lisp + +in your @file{~/.gnus.el} file, or you can run it off of some hook. If +you want to stop the timer, you can use the @code{gnus-stop-date-timer} +command. -Also @pxref{Article Highlighting} for further variables for -citation customization. +@item W T o +@kindex W T o (Summary) +@findex gnus-article-date-original +Display the original date (@code{gnus-article-date-original}). This can +be useful if you normally use some other conversion function and are +worried that it might be doing something totally wrong. Say, claiming +that the article was posted in 1854. Although something like that is +@emph{totally} impossible. Don't you trust me? *titter* -@xref{Customizing Articles}, for how to hide article elements -automatically. +@end table +@xref{Customizing Articles}, for how to display the date in your +preferred format automatically. -@node Article Washing -@subsection Article Washing -@cindex washing -@cindex article washing -We call this ``article washing'' for a really good reason. Namely, the -@kbd{A} key was taken, so we had to use the @kbd{W} key instead. +@node Article Display +@subsection Article Display +@cindex picons +@cindex x-face +@cindex smileys +@cindex gravatars -@dfn{Washing} is defined by us as ``changing something from something to -something else'', but normally results in something looking better. -Cleaner, perhaps. +These commands add various frivolous display gimmicks to the article +buffer in Emacs versions that support them. -@xref{Customizing Articles}, if you want to change how Gnus displays -articles by default. +@code{X-Face} headers are small black-and-white images supplied by the +message headers (@pxref{X-Face}). -@table @kbd +@code{Face} headers are small colored images supplied by the message +headers (@pxref{Face}). -@item C-u g -This is not really washing, it's sort of the opposite of washing. If -you type this, you see the article exactly as it exists on disk or on -the server. +Smileys are those little @samp{:-)} symbols that people like to litter +their messages with (@pxref{Smileys}). -@item g -Force redisplaying of the current article -(@code{gnus-summary-show-article}). This is also not really washing. -If you type this, you see the article without any previously applied -interactive Washing functions but with all default treatments -(@pxref{Customizing Articles}). +Picons, on the other hand, reside on your own system, and Gnus will +try to match the headers to what you have (@pxref{Picons}). -@item W l -@kindex W l (Summary) -@findex gnus-summary-stop-page-breaking -Remove page breaks from the current article -(@code{gnus-summary-stop-page-breaking}). @xref{Misc Article}, for page -delimiters. +Gravatars reside on-line and are fetched from +@uref{http://www.gravatar.com/} (@pxref{Gravatars}). -@item W r -@kindex W r (Summary) -@findex gnus-summary-caesar-message -@c @icon{gnus-summary-caesar-message} -Do a Caesar rotate (rot13) on the article buffer -(@code{gnus-summary-caesar-message}). -Unreadable articles that tell you to read them with Caesar rotate or rot13. -(Typically offensive jokes and such.) +All these functions are toggles---if the elements already exist, +they'll be removed. -It's commonly called ``rot13'' because each letter is rotated 13 -positions in the alphabet, e. g. @samp{B} (letter #2) -> @samp{O} (letter -#15). It is sometimes referred to as ``Caesar rotate'' because Caesar -is rumored to have employed this form of, uh, somewhat weak encryption. +@table @kbd +@item W D x +@kindex W D x (Summary) +@findex gnus-article-display-x-face +Display an @code{X-Face} in the @code{From} header. +(@code{gnus-article-display-x-face}). -@item W m -@kindex W m (Summary) -@findex gnus-summary-morse-message -Morse decode the article buffer (@code{gnus-summary-morse-message}). +@item W D d +@kindex W D d (Summary) +@findex gnus-article-display-face +Display a @code{Face} in the @code{From} header. +(@code{gnus-article-display-face}). -@item W i -@kindex W i (Summary) -@findex gnus-summary-idna-message -Decode IDNA encoded domain names in the current articles. IDNA -encoded domain names looks like @samp{xn--bar}. If a string remain -unencoded after running invoking this, it is likely an invalid IDNA -string (@samp{xn--bar} is invalid). You must have GNU Libidn -(@url{http://www.gnu.org/software/libidn/}) installed for this command -to work. +@item W D s +@kindex W D s (Summary) +@findex gnus-treat-smiley +Display smileys (@code{gnus-treat-smiley}). -@item W t -@item t -@kindex W t (Summary) -@kindex t (Summary) -@findex gnus-summary-toggle-header -Toggle whether to display all headers in the article buffer -(@code{gnus-summary-toggle-header}). +@item W D f +@kindex W D f (Summary) +@findex gnus-treat-from-picon +Piconify the @code{From} header (@code{gnus-treat-from-picon}). -@item W v -@kindex W v (Summary) -@findex gnus-summary-verbose-headers -Toggle whether to display all headers in the article buffer permanently -(@code{gnus-summary-verbose-headers}). +@item W D m +@kindex W D m (Summary) +@findex gnus-treat-mail-picon +Piconify all mail headers (i. e., @code{Cc}, @code{To}) +(@code{gnus-treat-mail-picon}). -@item W o -@kindex W o (Summary) -@findex gnus-article-treat-overstrike -Treat overstrike (@code{gnus-article-treat-overstrike}). +@item W D n +@kindex W D n (Summary) +@findex gnus-treat-newsgroups-picon +Piconify all news headers (i. e., @code{Newsgroups} and +@code{Followup-To}) (@code{gnus-treat-newsgroups-picon}). -@item W d -@kindex W d (Summary) -@findex gnus-article-treat-dumbquotes -@vindex gnus-article-dumbquotes-map -@cindex Smartquotes -@cindex M****s*** sm*rtq**t*s -@cindex Latin 1 -Treat M****s*** sm*rtq**t*s according to -@code{gnus-article-dumbquotes-map} -(@code{gnus-article-treat-dumbquotes}). Note that this function guesses -whether a character is a sm*rtq**t* or not, so it should only be used -interactively. +@item W D g +@kindex W D g (Summary) +@findex gnus-treat-from-gravatar +Gravatarify the @code{From} header (@code{gnus-treat-from-gravatar}). -Sm*rtq**t*s are M****s***'s unilateral extension to the character map in -an attempt to provide more quoting characters. If you see something -like @code{\222} or @code{\264} where you're expecting some kind of -apostrophe or quotation mark, then try this wash. +@item W D h +@kindex W D h (Summary) +@findex gnus-treat-mail-gravatar +Gravatarify all mail headers (i. e., @code{Cc}, @code{To}) +(@code{gnus-treat-from-gravatar}). -@item W U -@kindex W U (Summary) -@findex gnus-article-treat-non-ascii -@cindex Unicode -@cindex Non-@acronym{ASCII} -Translate many non-@acronym{ASCII} characters into their -@acronym{ASCII} equivalents (@code{gnus-article-treat-non-ascii}). -This is mostly useful if you're on a terminal that has a limited font -and does't show accented characters, ``advanced'' punctuation, and the -like. For instance, @samp{»} is tranlated into @samp{>>}, and so on. +@item W D D +@kindex W D D (Summary) +@findex gnus-article-remove-images +Remove all images from the article buffer +(@code{gnus-article-remove-images}). -@item W Y f -@kindex W Y f (Summary) -@findex gnus-article-outlook-deuglify-article -@cindex Outlook Express -Full deuglify of broken Outlook (Express) articles: Treat dumbquotes, -unwrap lines, repair attribution and rearrange citation. -(@code{gnus-article-outlook-deuglify-article}). +@item W D W +@kindex W D W (Summary) +@findex gnus-html-show-images +If you're reading an @acronym{HTML} article rendered with +@code{gnus-article-html}, then you can insert any blocked images in +the buffer with this command. +(@code{gnus-html-show-images}). -@item W Y u -@kindex W Y u (Summary) -@findex gnus-article-outlook-unwrap-lines -@vindex gnus-outlook-deuglify-unwrap-min -@vindex gnus-outlook-deuglify-unwrap-max -Unwrap lines that appear to be wrapped citation lines. You can control -what lines will be unwrapped by frobbing -@code{gnus-outlook-deuglify-unwrap-min} and -@code{gnus-outlook-deuglify-unwrap-max}, indicating the minimum and -maximum length of an unwrapped citation line. -(@code{gnus-article-outlook-unwrap-lines}). +@end table -@item W Y a -@kindex W Y a (Summary) -@findex gnus-article-outlook-repair-attribution -Repair a broken attribution line.@* -(@code{gnus-article-outlook-repair-attribution}). -@item W Y c -@kindex W Y c (Summary) -@findex gnus-article-outlook-rearrange-citation -Repair broken citations by rearranging the text. -(@code{gnus-article-outlook-rearrange-citation}). -@item W w -@kindex W w (Summary) -@findex gnus-article-fill-cited-article -Do word wrap (@code{gnus-article-fill-cited-article}). +@node Article Signature +@subsection Article Signature +@cindex signatures +@cindex article signature -You can give the command a numerical prefix to specify the width to use -when filling. +@vindex gnus-signature-separator +Each article is divided into two parts---the head and the body. The +body can be divided into a signature part and a text part. The variable +that says what is to be considered a signature is +@code{gnus-signature-separator}. This is normally the standard +@samp{^-- $} as mandated by son-of-RFC 1036. However, many people use +non-standard signature separators, so this variable can also be a list +of regular expressions to be tested, one by one. (Searches are done +from the end of the body towards the beginning.) One likely value is: -@item W Q -@kindex W Q (Summary) -@findex gnus-article-fill-long-lines -Fill long lines (@code{gnus-article-fill-long-lines}). +@lisp +(setq gnus-signature-separator + '("^-- $" ; @r{The standard} + "^-- *$" ; @r{A common mangling} + "^-------*$" ; @r{Many people just use a looong} + ; @r{line of dashes. Shame!} + "^ *--------*$" ; @r{Double-shame!} + "^________*$" ; @r{Underscores are also popular} + "^========*$")) ; @r{Pervert!} +@end lisp -@item W C -@kindex W C (Summary) -@findex gnus-article-capitalize-sentences -Capitalize the first word in each sentence -(@code{gnus-article-capitalize-sentences}). +The more permissive you are, the more likely it is that you'll get false +positives. -@item W c -@kindex W c (Summary) -@findex gnus-article-remove-cr -Translate CRLF pairs (i. e., @samp{^M}s on the end of the lines) into LF -(this takes care of DOS line endings), and then translate any remaining -CRs into LF (this takes care of Mac line endings) -(@code{gnus-article-remove-cr}). +@vindex gnus-signature-limit +@code{gnus-signature-limit} provides a limit to what is considered a +signature when displaying articles. -@item W q -@kindex W q (Summary) -@findex gnus-article-de-quoted-unreadable -Treat quoted-printable (@code{gnus-article-de-quoted-unreadable}). -Quoted-Printable is one common @acronym{MIME} encoding employed when -sending non-@acronym{ASCII} (i.e., 8-bit) articles. It typically -makes strings like @samp{d@'ej@`a vu} look like @samp{d=E9j=E0 vu}, -which doesn't look very readable to me. Note that this is usually -done automatically by Gnus if the message in question has a -@code{Content-Transfer-Encoding} header that says that this encoding -has been done. If a prefix is given, a charset will be asked for. +@enumerate +@item +If it is an integer, no signature may be longer (in characters) than +that integer. +@item +If it is a floating point number, no signature may be longer (in lines) +than that number. +@item +If it is a function, the function will be called without any parameters, +and if it returns @code{nil}, there is no signature in the buffer. +@item +If it is a string, it will be used as a regexp. If it matches, the text +in question is not a signature. +@end enumerate -@item W 6 -@kindex W 6 (Summary) -@findex gnus-article-de-base64-unreadable -Treat base64 (@code{gnus-article-de-base64-unreadable}). Base64 is -one common @acronym{MIME} encoding employed when sending -non-@acronym{ASCII} (i.e., 8-bit) articles. Note that this is -usually done automatically by Gnus if the message in question has a -@code{Content-Transfer-Encoding} header that says that this encoding -has been done. If a prefix is given, a charset will be asked for. +This variable can also be a list where the elements may be of the types +listed above. Here's an example: -@item W Z -@kindex W Z (Summary) -@findex gnus-article-decode-HZ -Treat HZ or HZP (@code{gnus-article-decode-HZ}). HZ (or HZP) is one -common encoding employed when sending Chinese articles. It typically -makes strings look like @samp{~@{<:Ky2;S@{#,NpJ)l6HK!#~@}}. +@lisp +(setq gnus-signature-limit + '(200.0 "^---*Forwarded article")) +@end lisp -@item W A -@kindex W A (Summary) -@findex gnus-article-treat-ansi-sequences -@cindex @acronym{ANSI} control sequences -Translate @acronym{ANSI} SGR control sequences into overlays or -extents (@code{gnus-article-treat-ansi-sequences}). @acronym{ANSI} -sequences are used in some Chinese hierarchies for highlighting. +This means that if there are more than 200 lines after the signature +separator, or the text after the signature separator is matched by +the regular expression @samp{^---*Forwarded article}, then it isn't a +signature after all. -@item W u -@kindex W u (Summary) -@findex gnus-article-unsplit-urls -Remove newlines from within URLs. Some mailers insert newlines into -outgoing email messages to keep lines short. This reformatting can -split long URLs onto multiple lines. Repair those URLs by removing -the newlines (@code{gnus-article-unsplit-urls}). -@item W h -@kindex W h (Summary) -@findex gnus-article-wash-html -Treat @acronym{HTML} (@code{gnus-article-wash-html}). Note that this is -usually done automatically by Gnus if the message in question has a -@code{Content-Type} header that says that the message is @acronym{HTML}. +@node Article Miscellanea +@subsection Article Miscellanea -If a prefix is given, a charset will be asked for. If it is a number, -the charset defined in @code{gnus-summary-show-article-charset-alist} -(@pxref{Paging the Article}) will be used. +@table @kbd +@item A t +@kindex A t (Summary) +@findex gnus-article-babel +Translate the article from one language to another +(@code{gnus-article-babel}). -The default is to use the function specified by -@code{mm-text-html-renderer} (@pxref{Display Customization, ,Display -Customization, emacs-mime, The Emacs MIME Manual}) to convert the -@acronym{HTML}. Pre-defined functions you can use include: +@end table -@table @code -@item shr -Use Gnus simple html renderer. -@item gnus-w3m -Use Gnus rendered based on w3m. +@node MIME Commands +@section MIME Commands +@cindex MIME decoding +@cindex attachments +@cindex viewing attachments -@item w3 -Use Emacs/W3. +The following commands all understand the numerical prefix. For +instance, @kbd{3 K v} means ``view the third @acronym{MIME} part''. -@item w3m -Use @uref{http://emacs-w3m.namazu.org/, emacs-w3m}. +@table @kbd +@item b +@itemx K v +@kindex b (Summary) +@kindex K v (Summary) +View the @acronym{MIME} part. -@item w3m-standalone -Use @uref{http://w3m.sourceforge.net/, w3m}. +@item K o +@kindex K o (Summary) +Save the @acronym{MIME} part. -@item links -Use @uref{http://links.sf.net/, Links}. +@item K O +@kindex K O (Summary) +Prompt for a file name, then save the @acronym{MIME} part and strip it +from the article. The stripped @acronym{MIME} object will be referred +via the message/external-body @acronym{MIME} type. -@item lynx -Use @uref{http://lynx.isc.org/, Lynx}. +@item K r +@kindex K r (Summary) +Replace the @acronym{MIME} part with an external body. -@item html2text -Use html2text---a simple @acronym{HTML} converter included with Gnus. +@item K d +@kindex K d (Summary) +Delete the @acronym{MIME} part and add some information about the +removed part. -@end table +@item K c +@kindex K c (Summary) +Copy the @acronym{MIME} part. -@item W b -@kindex W b (Summary) -@findex gnus-article-add-buttons -Add clickable buttons to the article (@code{gnus-article-add-buttons}). -@xref{Article Buttons}. +@item K e +@kindex K e (Summary) +View the @acronym{MIME} part externally. -@item W B -@kindex W B (Summary) -@findex gnus-article-add-buttons-to-head -Add clickable buttons to the article headers -(@code{gnus-article-add-buttons-to-head}). +@item K i +@kindex K i (Summary) +View the @acronym{MIME} part internally. -@item W p -@kindex W p (Summary) -@findex gnus-article-verify-x-pgp-sig -Verify a signed control message -(@code{gnus-article-verify-x-pgp-sig}). Control messages such as -@code{newgroup} and @code{checkgroups} are usually signed by the -hierarchy maintainer. You need to add the @acronym{PGP} public key of -the maintainer to your keyring to verify the -message.@footnote{@acronym{PGP} keys for many hierarchies are -available at @uref{ftp://ftp.isc.org/pub/pgpcontrol/README.html}} +@item K | +@kindex K | (Summary) +Pipe the @acronym{MIME} part to an external command. +@end table -@item W s -@kindex W s (Summary) -@findex gnus-summary-force-verify-and-decrypt -Verify a signed (@acronym{PGP}, @acronym{PGP/MIME} or -@acronym{S/MIME}) message -(@code{gnus-summary-force-verify-and-decrypt}). @xref{Security}. +The rest of these @acronym{MIME} commands do not use the numerical prefix in +the same manner: -@item W a -@kindex W a (Summary) -@findex gnus-article-strip-headers-in-body -Strip headers like the @code{X-No-Archive} header from the beginning of -article bodies (@code{gnus-article-strip-headers-in-body}). +@table @kbd +@item K H +@kindex K H (Summary) +@findex gnus-article-browse-html-article +View @samp{text/html} parts of the current article with a WWW browser. +Inline images embedded in a message using the @code{cid} scheme, as they +are generally considered to be safe, will be processed properly. The +message header is added to the beginning of every @acronym{HTML} part +unless the prefix argument is given. -@item W E l -@kindex W E l (Summary) -@findex gnus-article-strip-leading-blank-lines -Remove all blank lines from the beginning of the article -(@code{gnus-article-strip-leading-blank-lines}). +Warning: Spammers use links to images (using the @code{http} scheme) in +@acronym{HTML} articles to verify whether you have read the message. As +this command passes the @acronym{HTML} content to the browser without +eliminating these ``web bugs'' you should only use it for mails from +trusted senders. -@item W E m -@kindex W E m (Summary) -@findex gnus-article-strip-multiple-blank-lines -Replace all blank lines with empty lines and then all multiple empty -lines with a single empty line. -(@code{gnus-article-strip-multiple-blank-lines}). +If you always want to display @acronym{HTML} parts in the browser, set +@code{mm-text-html-renderer} to @code{nil}. -@item W E t -@kindex W E t (Summary) -@findex gnus-article-remove-trailing-blank-lines -Remove all blank lines at the end of the article -(@code{gnus-article-remove-trailing-blank-lines}). +This command creates temporary files to pass @acronym{HTML} contents +including images if any to the browser, and deletes them when exiting +the group (if you want). -@item W E a -@kindex W E a (Summary) -@findex gnus-article-strip-blank-lines -Do all the three commands above -(@code{gnus-article-strip-blank-lines}). +@item K b +@kindex K b (Summary) +Make all the @acronym{MIME} parts have buttons in front of them. This is +mostly useful if you wish to save (or perform other actions) on inlined +parts. -@item W E A -@kindex W E A (Summary) -@findex gnus-article-strip-all-blank-lines -Remove all blank lines -(@code{gnus-article-strip-all-blank-lines}). +@item K m +@kindex K m (Summary) +@findex gnus-summary-repair-multipart +Some multipart messages are transmitted with missing or faulty headers. +This command will attempt to ``repair'' these messages so that they can +be viewed in a more pleasant manner +(@code{gnus-summary-repair-multipart}). -@item W E s -@kindex W E s (Summary) -@findex gnus-article-strip-leading-space -Remove all white space from the beginning of all lines of the article -body (@code{gnus-article-strip-leading-space}). +@item X m +@kindex X m (Summary) +@findex gnus-summary-save-parts +Save all parts matching a @acronym{MIME} type to a directory +(@code{gnus-summary-save-parts}). Understands the process/prefix +convention (@pxref{Process/Prefix}). -@item W E e -@kindex W E e (Summary) -@findex gnus-article-strip-trailing-space -Remove all white space from the end of all lines of the article -body (@code{gnus-article-strip-trailing-space}). +@item M-t +@kindex M-t (Summary) +@findex gnus-summary-toggle-display-buttonized +Toggle the buttonized display of the article buffer +(@code{gnus-summary-toggle-display-buttonized}). -@end table +@item W M w +@kindex W M w (Summary) +@findex gnus-article-decode-mime-words +Decode RFC 2047-encoded words in the article headers +(@code{gnus-article-decode-mime-words}). -@xref{Customizing Articles}, for how to wash articles automatically. +@item W M c +@kindex W M c (Summary) +@findex gnus-article-decode-charset +Decode encoded article bodies as well as charsets +(@code{gnus-article-decode-charset}). +This command looks in the @code{Content-Type} header to determine the +charset. If there is no such header in the article, you can give it a +prefix, which will prompt for the charset to decode as. In regional +groups where people post using some common encoding (but do not +include @acronym{MIME} headers), you can set the @code{charset} group/topic +parameter to the required charset (@pxref{Group Parameters}). -@node Article Header -@subsection Article Header +@item W M v +@kindex W M v (Summary) +@findex gnus-mime-view-all-parts +View all the @acronym{MIME} parts in the current article +(@code{gnus-mime-view-all-parts}). -These commands perform various transformations of article header. +@end table -@table @kbd +Relevant variables: -@item W G u -@kindex W G u (Summary) -@findex gnus-article-treat-unfold-headers -Unfold folded header lines (@code{gnus-article-treat-unfold-headers}). +@table @code +@item gnus-ignored-mime-types +@vindex gnus-ignored-mime-types +This is a list of regexps. @acronym{MIME} types that match a regexp from +this list will be completely ignored by Gnus. The default value is +@code{nil}. -@item W G n -@kindex W G n (Summary) -@findex gnus-article-treat-fold-newsgroups -Fold the @code{Newsgroups} and @code{Followup-To} headers -(@code{gnus-article-treat-fold-newsgroups}). +To have all Vcards be ignored, you'd say something like this: -@item W G f -@kindex W G f (Summary) -@findex gnus-article-treat-fold-headers -Fold all the message headers -(@code{gnus-article-treat-fold-headers}). +@lisp +(setq gnus-ignored-mime-types + '("text/x-vcard")) +@end lisp -@item W E w -@kindex W E w (Summary) -@findex gnus-article-remove-leading-whitespace -Remove excessive whitespace from all headers -(@code{gnus-article-remove-leading-whitespace}). +@item gnus-article-loose-mime +@vindex gnus-article-loose-mime +If non-@code{nil}, Gnus won't require the @samp{MIME-Version} header +before interpreting the message as a @acronym{MIME} message. This helps +when reading messages from certain broken mail user agents. The +default is @code{t}. -@end table +@item gnus-article-emulate-mime +@vindex gnus-article-emulate-mime +@cindex uuencode +@cindex yEnc +There are other, non-@acronym{MIME} encoding methods used. The most common +is @samp{uuencode}, but yEncode is also getting to be popular. If +this variable is non-@code{nil}, Gnus will look in message bodies to +see if it finds these encodings, and if so, it'll run them through the +Gnus @acronym{MIME} machinery. The default is @code{t}. Only +single-part yEnc encoded attachments can be decoded. There's no support +for encoding in Gnus. +@item gnus-unbuttonized-mime-types +@vindex gnus-unbuttonized-mime-types +This is a list of regexps. @acronym{MIME} types that match a regexp from +this list won't have @acronym{MIME} buttons inserted unless they aren't +displayed or this variable is overridden by +@code{gnus-buttonized-mime-types}. The default value is +@code{(".*/.*")}. This variable is only used when +@code{gnus-inhibit-mime-unbuttonizing} is @code{nil}. -@node Article Buttons -@subsection Article Buttons -@cindex buttons +@item gnus-buttonized-mime-types +@vindex gnus-buttonized-mime-types +This is a list of regexps. @acronym{MIME} types that match a regexp from +this list will have @acronym{MIME} buttons inserted unless they aren't +displayed. This variable overrides +@code{gnus-unbuttonized-mime-types}. The default value is @code{nil}. +This variable is only used when @code{gnus-inhibit-mime-unbuttonizing} +is @code{nil}. -People often include references to other stuff in articles, and it would -be nice if Gnus could just fetch whatever it is that people talk about -with the minimum of fuzz when you hit @kbd{RET} or use the middle mouse -button on these references. +To see e.g. security buttons but no other buttons, you could set this +variable to @code{("multipart/signed")} and leave +@code{gnus-unbuttonized-mime-types} at the default value. -@vindex gnus-button-man-handler -Gnus adds @dfn{buttons} to certain standard references by default: -Well-formed URLs, mail addresses, Message-IDs, Info links, man pages and -Emacs or Gnus related references. This is controlled by two variables, -one that handles article bodies and one that handles article heads: +You could also add @code{"multipart/alternative"} to this list to +display radio buttons that allow you to choose one of two media types +those mails include. See also @code{mm-discouraged-alternatives} +(@pxref{Display Customization, ,Display Customization, emacs-mime, The +Emacs MIME Manual}). -@table @code +@item gnus-inhibit-mime-unbuttonizing +@vindex gnus-inhibit-mime-unbuttonizing +If this is non-@code{nil}, then all @acronym{MIME} parts get buttons. The +default value is @code{nil}. -@item gnus-button-alist -@vindex gnus-button-alist -This is an alist where each entry has this form: +@item gnus-article-mime-part-function +@vindex gnus-article-mime-part-function +For each @acronym{MIME} part, this function will be called with the @acronym{MIME} +handle as the parameter. The function is meant to be used to allow +users to gather information from the article (e. g., add Vcard info to +the bbdb database) or to do actions based on parts (e. g., automatically +save all jpegs into some directory). + +Here's an example function the does the latter: @lisp -(@var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par}) +(defun my-save-all-jpeg-parts (handle) + (when (equal (car (mm-handle-type handle)) "image/jpeg") + (with-temp-buffer + (insert (mm-get-part handle)) + (write-region (point-min) (point-max) + (read-file-name "Save jpeg to: "))))) +(setq gnus-article-mime-part-function + 'my-save-all-jpeg-parts) @end lisp -@table @var +@vindex gnus-mime-multipart-functions +@item gnus-mime-multipart-functions +Alist of @acronym{MIME} multipart types and functions to handle them. -@item regexp -All text that match this regular expression (case insensitive) will be -considered an external reference. Here's a typical regexp that matches -embedded URLs: @samp{]*\\)>}. This can also be a -variable containing a regexp, useful variables to use include -@code{gnus-button-url-regexp} and @code{gnus-button-mid-or-mail-regexp}. +@vindex gnus-mime-display-multipart-alternative-as-mixed +@item gnus-mime-display-multipart-alternative-as-mixed +Display "multipart/alternative" parts as "multipart/mixed". -@item button-par -Gnus has to know which parts of the matches is to be highlighted. This -is a number that says what sub-expression of the regexp is to be -highlighted. If you want it all highlighted, you use 0 here. +@vindex gnus-mime-display-multipart-related-as-mixed +@item gnus-mime-display-multipart-related-as-mixed +Display "multipart/related" parts as "multipart/mixed". -@item use-p -This form will be @code{eval}ed, and if the result is non-@code{nil}, -this is considered a match. This is useful if you want extra sifting to -avoid false matches. Often variables named -@code{gnus-button-@var{*}-level} are used here, @xref{Article Button -Levels}, but any other form may be used too. +If displaying @samp{text/html} is discouraged, see +@code{mm-discouraged-alternatives}, images or other material inside a +"multipart/related" part might be overlooked when this variable is +@code{nil}. @ref{Display Customization, Display Customization, , +emacs-mime, Emacs-Mime Manual}. -@c @code{use-p} is @code{eval}ed only if @code{regexp} matches. +@vindex gnus-mime-display-multipart-as-mixed +@item gnus-mime-display-multipart-as-mixed +Display "multipart" parts as "multipart/mixed". If @code{t}, it +overrides @code{nil} values of +@code{gnus-mime-display-multipart-alternative-as-mixed} and +@code{gnus-mime-display-multipart-related-as-mixed}. -@item function -This function will be called when you click on this button. +@vindex mm-file-name-rewrite-functions +@item mm-file-name-rewrite-functions +List of functions used for rewriting file names of @acronym{MIME} parts. +Each function takes a file name as input and returns a file name. -@item data-par -As with @var{button-par}, this is a sub-expression number, but this one -says which part of the match is to be sent as data to @var{function}. +Ready-made functions include@* +@code{mm-file-name-delete-whitespace}, +@code{mm-file-name-trim-whitespace}, +@code{mm-file-name-collapse-whitespace}, and +@code{mm-file-name-replace-whitespace}. The later uses the value of +the variable @code{mm-file-name-replace-whitespace} to replace each +whitespace character in a file name with that string; default value +is @code{"_"} (a single underscore). +@findex mm-file-name-delete-whitespace +@findex mm-file-name-trim-whitespace +@findex mm-file-name-collapse-whitespace +@findex mm-file-name-replace-whitespace +@vindex mm-file-name-replace-whitespace -@end table +The standard functions @code{capitalize}, @code{downcase}, +@code{upcase}, and @code{upcase-initials} may be useful, too. -So the full entry for buttonizing URLs is then +Everybody knows that whitespace characters in file names are evil, +except those who don't know. If you receive lots of attachments from +such unenlightened users, you can make live easier by adding @lisp -("]*\\)>" 0 t gnus-button-url 1) +(setq mm-file-name-rewrite-functions + '(mm-file-name-trim-whitespace + mm-file-name-collapse-whitespace + mm-file-name-replace-whitespace)) @end lisp -@item gnus-header-button-alist -@vindex gnus-header-button-alist -This is just like the other alist, except that it is applied to the -article head only, and that each entry has an additional element that is -used to say what headers to apply the buttonize coding to: - -@lisp -(@var{header} @var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par}) -@end lisp +@noindent +to your @file{~/.gnus.el} file. -@var{header} is a regular expression. @end table -@subsubsection Related variables and functions -@table @code -@item gnus-button-@var{*}-level -@xref{Article Button Levels}. +@node Charsets +@section Charsets +@cindex charsets -@c Stuff related to gnus-button-browse-level +People use different charsets, and we have @acronym{MIME} to let us know what +charsets they use. Or rather, we wish we had. Many people use +newsreaders and mailers that do not understand or use @acronym{MIME}, and +just send out messages without saying what character sets they use. To +help a bit with this, some local news hierarchies have policies that say +what character set is the default. For instance, the @samp{fj} +hierarchy uses @code{iso-2022-jp}. -@item gnus-button-url-regexp -@vindex gnus-button-url-regexp -A regular expression that matches embedded URLs. It is used in the -default values of the variables above. +@vindex gnus-group-charset-alist +This knowledge is encoded in the @code{gnus-group-charset-alist} +variable, which is an alist of regexps (use the first item to match full +group names) and default charsets to be used when reading these groups. -@c Stuff related to gnus-button-man-level +@vindex gnus-newsgroup-ignored-charsets +In addition, some people do use soi-disant @acronym{MIME}-aware agents that +aren't. These blithely mark messages as being in @code{iso-8859-1} +even if they really are in @code{koi-8}. To help here, the +@code{gnus-newsgroup-ignored-charsets} variable can be used. The +charsets that are listed here will be ignored. The variable can be +set on a group-by-group basis using the group parameters (@pxref{Group +Parameters}). The default value is @code{(unknown-8bit x-unknown)}, +which includes values some agents insist on having in there. -@item gnus-button-man-handler -@vindex gnus-button-man-handler -The function to use for displaying man pages. It must take at least one -argument with a string naming the man page. +@vindex gnus-group-posting-charset-alist +When posting, @code{gnus-group-posting-charset-alist} is used to +determine which charsets should not be encoded using the @acronym{MIME} +encodings. For instance, some hierarchies discourage using +quoted-printable header encoding. -@c Stuff related to gnus-button-message-level +This variable is an alist of regexps and permitted unencoded charsets +for posting. Each element of the alist has the form @code{(}@var{test +header body-list}@code{)}, where: -@item gnus-button-mid-or-mail-regexp -@vindex gnus-button-mid-or-mail-regexp -Regular expression that matches a message ID or a mail address. +@table @var +@item test +is either a regular expression matching the newsgroup header or a +variable to query, +@item header +is the charset which may be left unencoded in the header (@code{nil} +means encode all charsets), +@item body-list +is a list of charsets which may be encoded using 8bit content-transfer +encoding in the body, or one of the special values @code{nil} (always +encode using quoted-printable) or @code{t} (always use 8bit). +@end table -@item gnus-button-prefer-mid-or-mail -@vindex gnus-button-prefer-mid-or-mail -This variable determines what to do when the button on a string as -@samp{foo123@@bar.invalid} is pushed. Strings like this can be either a -message ID or a mail address. If it is one of the symbols @code{mid} or -@code{mail}, Gnus will always assume that the string is a message ID or -a mail address, respectively. If this variable is set to the symbol -@code{ask}, always query the user what to do. If it is a function, this -function will be called with the string as its only argument. The -function must return @code{mid}, @code{mail}, @code{invalid} or -@code{ask}. The default value is the function -@code{gnus-button-mid-or-mail-heuristic}. +@cindex Russian +@cindex koi8-r +@cindex koi8-u +@cindex iso-8859-5 +@cindex coding system aliases +@cindex preferred charset -@item gnus-button-mid-or-mail-heuristic -@findex gnus-button-mid-or-mail-heuristic -Function that guesses whether its argument is a message ID or a mail -address. Returns @code{mid} if it's a message IDs, @code{mail} if -it's a mail address, @code{ask} if unsure and @code{invalid} if the -string is invalid. +@xref{Encoding Customization, , Encoding Customization, emacs-mime, +The Emacs MIME Manual}, for additional variables that control which +MIME charsets are used when sending messages. -@item gnus-button-mid-or-mail-heuristic-alist -@vindex gnus-button-mid-or-mail-heuristic-alist -An alist of @code{(RATE . REGEXP)} pairs used by the function -@code{gnus-button-mid-or-mail-heuristic}. +Other charset tricks that may be useful, although not Gnus-specific: -@c Misc stuff +If there are several @acronym{MIME} charsets that encode the same Emacs +charset, you can choose what charset to use by saying the following: -@item gnus-article-button-face -@vindex gnus-article-button-face -Face used on buttons. +@lisp +(put-charset-property 'cyrillic-iso8859-5 + 'preferred-coding-system 'koi8-r) +@end lisp -@item gnus-article-mouse-face -@vindex gnus-article-mouse-face -Face used when the mouse cursor is over a button. +This means that Russian will be encoded using @code{koi8-r} instead of +the default @code{iso-8859-5} @acronym{MIME} charset. -@end table +If you want to read messages in @code{koi8-u}, you can cheat and say -@xref{Customizing Articles}, for how to buttonize articles automatically. +@lisp +(define-coding-system-alias 'koi8-u 'koi8-r) +@end lisp +This will almost do the right thing. -@node Article Button Levels -@subsection Article button levels -@cindex button levels -The higher the value of the variables @code{gnus-button-@var{*}-level}, -the more buttons will appear. If the level is zero, no corresponding -buttons are displayed. With the default value (which is 5) you should -already see quite a lot of buttons. With higher levels, you will see -more buttons, but you may also get more false positives. To avoid them, -you can set the variables @code{gnus-button-@var{*}-level} local to -specific groups (@pxref{Group Parameters}). Here's an example for the -variable @code{gnus-parameters}: +And finally, to read charsets like @code{windows-1251}, you can say +something like @lisp -;; @r{increase @code{gnus-button-*-level} in some groups:} -(setq gnus-parameters - '(("\\<\\(emacs\\|gnus\\)\\>" (gnus-button-emacs-level 10)) - ("\\" (gnus-button-man-level 10)) - ("\\" (gnus-button-tex-level 10)))) +(codepage-setup 1251) +(define-coding-system-alias 'windows-1251 'cp1251) @end lisp -@table @code -@item gnus-button-browse-level -@vindex gnus-button-browse-level -Controls the display of references to message IDs, mail addresses and -news URLs. Related variables and functions include -@code{gnus-button-url-regexp}, @code{browse-url}, and -@code{browse-url-browser-function}. +@node Article Commands +@section Article Commands -@item gnus-button-emacs-level -@vindex gnus-button-emacs-level -Controls the display of Emacs or Gnus references. Related functions are -@code{gnus-button-handle-custom}, -@code{gnus-button-handle-describe-function}, -@code{gnus-button-handle-describe-variable}, -@code{gnus-button-handle-symbol}, -@code{gnus-button-handle-describe-key}, -@code{gnus-button-handle-apropos}, -@code{gnus-button-handle-apropos-command}, -@code{gnus-button-handle-apropos-variable}, -@code{gnus-button-handle-apropos-documentation}, and -@code{gnus-button-handle-library}. +@table @kbd -@item gnus-button-man-level -@vindex gnus-button-man-level -Controls the display of references to (Unix) man pages. -See @code{gnus-button-man-handler}. +@item A P +@cindex PostScript +@cindex printing +@kindex A P (Summary) +@vindex gnus-ps-print-hook +@findex gnus-summary-print-article +Generate and print a PostScript image of the article buffer +(@code{gnus-summary-print-article}). @code{gnus-ps-print-hook} will +be run just before printing the buffer. An alternative way to print +article is to use Muttprint (@pxref{Saving Articles}). -@item gnus-button-message-level -@vindex gnus-button-message-level -Controls the display of message IDs, mail addresses and news URLs. -Related variables and functions include -@code{gnus-button-mid-or-mail-regexp}, -@code{gnus-button-prefer-mid-or-mail}, -@code{gnus-button-mid-or-mail-heuristic}, and -@code{gnus-button-mid-or-mail-heuristic-alist}. +@item A C +@vindex gnus-fetch-partial-articles +@findex gnus-summary-show-complete-article +If @code{-fetch-partial-articles} is non-@code{nil}, Gnus will +fetch partial articles, if the backend it fetches them from supports +it. Currently only @code{nnimap} does. If you're looking at a +partial article, and want to see the complete article instead, then +the @kbd{A C} command (@code{gnus-summary-show-complete-article}) will +do so. @end table -@node Article Date -@subsection Article Date +@node Summary Sorting +@section Summary Sorting +@cindex summary sorting -The date is most likely generated in some obscure timezone you've never -heard of, so it's quite nice to be able to find out what the time was -when the article was sent. +You can have the summary buffer sorted in various ways, even though I +can't really see why you'd want that. @table @kbd -@item W T u -@kindex W T u (Summary) -@findex gnus-article-date-ut -Display the date in UT (aka. GMT, aka ZULU) -(@code{gnus-article-date-ut}). - -@item W T i -@kindex W T i (Summary) -@findex gnus-article-date-iso8601 -@cindex ISO 8601 -Display the date in international format, aka. ISO 8601 -(@code{gnus-article-date-iso8601}). - -@item W T l -@kindex W T l (Summary) -@findex gnus-article-date-local -Display the date in the local timezone (@code{gnus-article-date-local}). +@item C-c C-s C-n +@kindex C-c C-s C-n (Summary) +@findex gnus-summary-sort-by-number +Sort by article number (@code{gnus-summary-sort-by-number}). -@item W T p -@kindex W T p (Summary) -@findex gnus-article-date-english -Display the date in a format that's easily pronounceable in English -(@code{gnus-article-date-english}). +@item C-c C-s C-m C-n +@kindex C-c C-s C-n (Summary) +@findex gnus-summary-sort-by-most-recent-number +Sort by most recent article number +(@code{gnus-summary-sort-by-most-recent-number}). -@item W T s -@kindex W T s (Summary) -@vindex gnus-article-time-format -@findex gnus-article-date-user -@findex format-time-string -Display the date using a user-defined format -(@code{gnus-article-date-user}). The format is specified by the -@code{gnus-article-time-format} variable, and is a string that's passed -to @code{format-time-string}. See the documentation of that variable -for a list of possible format specs. +@item C-c C-s C-a +@kindex C-c C-s C-a (Summary) +@findex gnus-summary-sort-by-author +Sort by author (@code{gnus-summary-sort-by-author}). -@item W T e -@kindex W T e (Summary) -@findex gnus-article-date-lapsed -@findex gnus-start-date-timer -@findex gnus-stop-date-timer -Say how much time has elapsed between the article was posted and now -(@code{gnus-article-date-lapsed}). It looks something like: +@item C-c C-s C-t +@kindex C-c C-s C-t (Summary) +@findex gnus-summary-sort-by-recipient +Sort by recipient (@code{gnus-summary-sort-by-recipient}). -@example -X-Sent: 6 weeks, 4 days, 1 hour, 3 minutes, 8 seconds ago -@end example +@item C-c C-s C-s +@kindex C-c C-s C-s (Summary) +@findex gnus-summary-sort-by-subject +Sort by subject (@code{gnus-summary-sort-by-subject}). -@vindex gnus-article-date-lapsed-new-header -The value of @code{gnus-article-date-lapsed-new-header} determines -whether this header will just be added below the old Date one, or will -replace it. +@item C-c C-s C-d +@kindex C-c C-s C-d (Summary) +@findex gnus-summary-sort-by-date +Sort by date (@code{gnus-summary-sort-by-date}). -An advantage of using Gnus to read mail is that it converts simple bugs -into wonderful absurdities. +@item C-c C-s C-m C-d +@kindex C-c C-s C-m C-d (Summary) +@findex gnus-summary-sort-by-most-recent-date +Sort by most recent date (@code{gnus-summary-sort-by-most-recent-date}). -If you want to have this line updated continually, you can put +@item C-c C-s C-l +@kindex C-c C-s C-l (Summary) +@findex gnus-summary-sort-by-lines +Sort by lines (@code{gnus-summary-sort-by-lines}). -@lisp -(gnus-start-date-timer) -@end lisp +@item C-c C-s C-c +@kindex C-c C-s C-c (Summary) +@findex gnus-summary-sort-by-chars +Sort by article length (@code{gnus-summary-sort-by-chars}). -in your @file{~/.gnus.el} file, or you can run it off of some hook. If -you want to stop the timer, you can use the @code{gnus-stop-date-timer} -command. +@item C-c C-s C-i +@kindex C-c C-s C-i (Summary) +@findex gnus-summary-sort-by-score +Sort by score (@code{gnus-summary-sort-by-score}). -@item W T o -@kindex W T o (Summary) -@findex gnus-article-date-original -Display the original date (@code{gnus-article-date-original}). This can -be useful if you normally use some other conversion function and are -worried that it might be doing something totally wrong. Say, claiming -that the article was posted in 1854. Although something like that is -@emph{totally} impossible. Don't you trust me? *titter* +@item C-c C-s C-r +@kindex C-c C-s C-r (Summary) +@findex gnus-summary-sort-by-random +Randomize (@code{gnus-summary-sort-by-random}). +@item C-c C-s C-o +@kindex C-c C-s C-o (Summary) +@findex gnus-summary-sort-by-original +Sort using the default sorting method +(@code{gnus-summary-sort-by-original}). @end table -@xref{Customizing Articles}, for how to display the date in your -preferred format automatically. +These functions will work both when you use threading and when you don't +use threading. In the latter case, all summary lines will be sorted, +line by line. In the former case, sorting will be done on a +root-by-root basis, which might not be what you were looking for. To +toggle whether to use threading, type @kbd{T T} (@pxref{Thread +Commands}). +If a prefix argument if given, the sort order is reversed. -@node Article Display -@subsection Article Display -@cindex picons -@cindex x-face -@cindex smileys -@cindex gravatars -These commands add various frivolous display gimmicks to the article -buffer in Emacs versions that support them. +@node Finding the Parent +@section Finding the Parent +@cindex parent articles +@cindex referring articles -@code{X-Face} headers are small black-and-white images supplied by the -message headers (@pxref{X-Face}). +@table @kbd +@item ^ +@kindex ^ (Summary) +@findex gnus-summary-refer-parent-article +If you'd like to read the parent of the current article, and it is not +displayed in the summary buffer, you might still be able to. That is, +if the current group is fetched by @acronym{NNTP}, the parent hasn't expired +and the @code{References} in the current article are not mangled, you +can just press @kbd{^} or @kbd{A r} +(@code{gnus-summary-refer-parent-article}). If everything goes well, +you'll get the parent. If the parent is already displayed in the +summary buffer, point will just move to this article. -@code{Face} headers are small colored images supplied by the message -headers (@pxref{Face}). +If given a positive numerical prefix, fetch that many articles back into +the ancestry. If given a negative numerical prefix, fetch just that +ancestor. So if you say @kbd{3 ^}, Gnus will fetch the parent, the +grandparent and the grandgrandparent of the current article. If you say +@kbd{-3 ^}, Gnus will only fetch the grandgrandparent of the current +article. -Smileys are those little @samp{:-)} symbols that people like to litter -their messages with (@pxref{Smileys}). +@item A R (Summary) +@findex gnus-summary-refer-references +@kindex A R (Summary) +Fetch all articles mentioned in the @code{References} header of the +article (@code{gnus-summary-refer-references}). -Picons, on the other hand, reside on your own system, and Gnus will -try to match the headers to what you have (@pxref{Picons}). +@item A T (Summary) +@findex gnus-summary-refer-thread +@kindex A T (Summary) +Display the full thread where the current article appears +(@code{gnus-summary-refer-thread}). This command has to fetch all the +headers in the current group to work, so it usually takes a while. If +you do it often, you may consider setting @code{gnus-fetch-old-headers} +to @code{invisible} (@pxref{Filling In Threads}). This won't have any +visible effects normally, but it'll make this command work a whole lot +faster. Of course, it'll make group entry somewhat slow. -Gravatars reside on-line and are fetched from -@uref{http://www.gravatar.com/} (@pxref{Gravatars}). +@vindex gnus-refer-thread-limit +The @code{gnus-refer-thread-limit} variable says how many old (i. e., +articles before the first displayed in the current group) headers to +fetch when doing this command. The default is 200. If @code{t}, all +the available headers will be fetched. This variable can be overridden +by giving the @kbd{A T} command a numerical prefix. -All these functions are toggles---if the elements already exist, -they'll be removed. +@item M-^ (Summary) +@findex gnus-summary-refer-article +@kindex M-^ (Summary) +@cindex Message-ID +@cindex fetching by Message-ID +You can also ask Gnus for an arbitrary article, no matter what group it +belongs to. @kbd{M-^} (@code{gnus-summary-refer-article}) will ask you +for a @code{Message-ID}, which is one of those long, hard-to-read +thingies that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. +You have to get it all exactly right. No fuzzy searches, I'm afraid. -@table @kbd -@item W D x -@kindex W D x (Summary) -@findex gnus-article-display-x-face -Display an @code{X-Face} in the @code{From} header. -(@code{gnus-article-display-x-face}). +Gnus looks for the @code{Message-ID} in the headers that have already +been fetched, but also tries all the select methods specified by +@code{gnus-refer-article-method} if it is not found. +@end table -@item W D d -@kindex W D d (Summary) -@findex gnus-article-display-face -Display a @code{Face} in the @code{From} header. -(@code{gnus-article-display-face}). +@vindex gnus-refer-article-method +If the group you are reading is located on a back end that does not +support fetching by @code{Message-ID} very well (like @code{nnspool}), +you can set @code{gnus-refer-article-method} to an @acronym{NNTP} method. It +would, perhaps, be best if the @acronym{NNTP} server you consult is the one +updating the spool you are reading from, but that's not really +necessary. -@item W D s -@kindex W D s (Summary) -@findex gnus-treat-smiley -Display smileys (@code{gnus-treat-smiley}). +It can also be a list of select methods, as well as the special symbol +@code{current}, which means to use the current select method. If it +is a list, Gnus will try all the methods in the list until it finds a +match. -@item W D f -@kindex W D f (Summary) -@findex gnus-treat-from-picon -Piconify the @code{From} header (@code{gnus-treat-from-picon}). +Here's an example setting that will first try the current method, and +then ask Google if that fails: -@item W D m -@kindex W D m (Summary) -@findex gnus-treat-mail-picon -Piconify all mail headers (i. e., @code{Cc}, @code{To}) -(@code{gnus-treat-mail-picon}). +@lisp +(setq gnus-refer-article-method + '(current + (nnweb "google" (nnweb-type google)))) +@end lisp -@item W D n -@kindex W D n (Summary) -@findex gnus-treat-newsgroups-picon -Piconify all news headers (i. e., @code{Newsgroups} and -@code{Followup-To}) (@code{gnus-treat-newsgroups-picon}). +Most of the mail back ends support fetching by @code{Message-ID}, but +do not do a particularly excellent job at it. That is, @code{nnmbox}, +@code{nnbabyl}, @code{nnmaildir}, @code{nnml}, are able to locate +articles from any groups, while @code{nnfolder}, and @code{nnimap} are +only able to locate articles that have been posted to the current +group. @code{nnmh} does not support this at all. -@item W D g -@kindex W D g (Summary) -@findex gnus-treat-from-gravatar -Gravatarify the @code{From} header (@code{gnus-treat-from-gravatar}). +Fortunately, the special @code{nnregistry} back end is able to locate +articles in any groups, regardless of their back end (@pxref{Registry +Article Refer Method, fetching by @code{Message-ID} using the +registry}). -@item W D h -@kindex W D h (Summary) -@findex gnus-treat-mail-gravatar -Gravatarify all mail headers (i. e., @code{Cc}, @code{To}) -(@code{gnus-treat-from-gravatar}). +@node Alternative Approaches +@section Alternative Approaches -@item W D D -@kindex W D D (Summary) -@findex gnus-article-remove-images -Remove all images from the article buffer -(@code{gnus-article-remove-images}). +Different people like to read news using different methods. This being +Gnus, we offer a small selection of minor modes for the summary buffers. -@item W D W -@kindex W D W (Summary) -@findex gnus-html-show-images -If you're reading an @acronym{HTML} article rendered with -@code{gnus-article-html}, then you can insert any blocked images in -the buffer with this command. -(@code{gnus-html-show-images}). +@menu +* Pick and Read:: First mark articles and then read them. +* Binary Groups:: Auto-decode all articles. +@end menu -@end table +@node Pick and Read +@subsection Pick and Read +@cindex pick and read +Some newsreaders (like @code{nn} and, uhm, @code{Netnews} on VM/CMS) use +a two-phased reading interface. The user first marks in a summary +buffer the articles she wants to read. Then she starts reading the +articles with just an article buffer displayed. -@node Article Signature -@subsection Article Signature -@cindex signatures -@cindex article signature +@findex gnus-pick-mode +@kindex M-x gnus-pick-mode +Gnus provides a summary buffer minor mode that allows +this---@code{gnus-pick-mode}. This basically means that a few process +mark commands become one-keystroke commands to allow easy marking, and +it provides one additional command for switching to the summary buffer. -@vindex gnus-signature-separator -Each article is divided into two parts---the head and the body. The -body can be divided into a signature part and a text part. The variable -that says what is to be considered a signature is -@code{gnus-signature-separator}. This is normally the standard -@samp{^-- $} as mandated by son-of-RFC 1036. However, many people use -non-standard signature separators, so this variable can also be a list -of regular expressions to be tested, one by one. (Searches are done -from the end of the body towards the beginning.) One likely value is: +Here are the available keystrokes when using pick mode: -@lisp -(setq gnus-signature-separator - '("^-- $" ; @r{The standard} - "^-- *$" ; @r{A common mangling} - "^-------*$" ; @r{Many people just use a looong} - ; @r{line of dashes. Shame!} - "^ *--------*$" ; @r{Double-shame!} - "^________*$" ; @r{Underscores are also popular} - "^========*$")) ; @r{Pervert!} -@end lisp +@table @kbd +@item . +@kindex . (Pick) +@findex gnus-pick-article-or-thread +Pick the article or thread on the current line +(@code{gnus-pick-article-or-thread}). If the variable +@code{gnus-thread-hide-subtree} is true, then this key selects the +entire thread when used at the first article of the thread. Otherwise, +it selects just the article. If given a numerical prefix, go to that +thread or article and pick it. (The line number is normally displayed +at the beginning of the summary pick lines.) + +@item SPACE +@kindex SPACE (Pick) +@findex gnus-pick-next-page +Scroll the summary buffer up one page (@code{gnus-pick-next-page}). If +at the end of the buffer, start reading the picked articles. + +@item u +@kindex u (Pick) +@findex gnus-pick-unmark-article-or-thread. +Unpick the thread or article +(@code{gnus-pick-unmark-article-or-thread}). If the variable +@code{gnus-thread-hide-subtree} is true, then this key unpicks the +thread if used at the first article of the thread. Otherwise it unpicks +just the article. You can give this key a numerical prefix to unpick +the thread or article at that line. -The more permissive you are, the more likely it is that you'll get false -positives. +@item RET +@kindex RET (Pick) +@findex gnus-pick-start-reading +@vindex gnus-pick-display-summary +Start reading the picked articles (@code{gnus-pick-start-reading}). If +given a prefix, mark all unpicked articles as read first. If +@code{gnus-pick-display-summary} is non-@code{nil}, the summary buffer +will still be visible when you are reading. -@vindex gnus-signature-limit -@code{gnus-signature-limit} provides a limit to what is considered a -signature when displaying articles. +@end table -@enumerate -@item -If it is an integer, no signature may be longer (in characters) than -that integer. -@item -If it is a floating point number, no signature may be longer (in lines) -than that number. -@item -If it is a function, the function will be called without any parameters, -and if it returns @code{nil}, there is no signature in the buffer. -@item -If it is a string, it will be used as a regexp. If it matches, the text -in question is not a signature. -@end enumerate +All the normal summary mode commands are still available in the +pick-mode, with the exception of @kbd{u}. However @kbd{!} is available +which is mapped to the same function +@code{gnus-summary-tick-article-forward}. -This variable can also be a list where the elements may be of the types -listed above. Here's an example: +If this sounds like a good idea to you, you could say: @lisp -(setq gnus-signature-limit - '(200.0 "^---*Forwarded article")) +(add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) @end lisp -This means that if there are more than 200 lines after the signature -separator, or the text after the signature separator is matched by -the regular expression @samp{^---*Forwarded article}, then it isn't a -signature after all. - - -@node Article Miscellanea -@subsection Article Miscellanea - -@table @kbd -@item A t -@kindex A t (Summary) -@findex gnus-article-babel -Translate the article from one language to another -(@code{gnus-article-babel}). - -@end table +@vindex gnus-pick-mode-hook +@code{gnus-pick-mode-hook} is run in pick minor mode buffers. +@vindex gnus-mark-unpicked-articles-as-read +If @code{gnus-mark-unpicked-articles-as-read} is non-@code{nil}, mark +all unpicked articles as read. The default is @code{nil}. -@node MIME Commands -@section MIME Commands -@cindex MIME decoding -@cindex attachments -@cindex viewing attachments +@vindex gnus-summary-pick-line-format +The summary line format in pick mode is slightly different from the +standard format. At the beginning of each line the line number is +displayed. The pick mode line format is controlled by the +@code{gnus-summary-pick-line-format} variable (@pxref{Formatting +Variables}). It accepts the same format specs that +@code{gnus-summary-line-format} does (@pxref{Summary Buffer Lines}). -The following commands all understand the numerical prefix. For -instance, @kbd{3 K v} means ``view the third @acronym{MIME} part''. -@table @kbd -@item b -@itemx K v -@kindex b (Summary) -@kindex K v (Summary) -View the @acronym{MIME} part. +@node Binary Groups +@subsection Binary Groups +@cindex binary groups -@item K o -@kindex K o (Summary) -Save the @acronym{MIME} part. +@findex gnus-binary-mode +@kindex M-x gnus-binary-mode +If you spend much time in binary groups, you may grow tired of hitting +@kbd{X u}, @kbd{n}, @kbd{RET} all the time. @kbd{M-x gnus-binary-mode} +is a minor mode for summary buffers that makes all ordinary Gnus article +selection functions uudecode series of articles and display the result +instead of just displaying the articles the normal way. -@item K O -@kindex K O (Summary) -Prompt for a file name, then save the @acronym{MIME} part and strip it -from the article. The stripped @acronym{MIME} object will be referred -via the message/external-body @acronym{MIME} type. +@kindex g (Binary) +@findex gnus-binary-show-article +The only way, in fact, to see the actual articles is the @kbd{g} +command, when you have turned on this mode +(@code{gnus-binary-show-article}). -@item K r -@kindex K r (Summary) -Replace the @acronym{MIME} part with an external body. +@vindex gnus-binary-mode-hook +@code{gnus-binary-mode-hook} is called in binary minor mode buffers. -@item K d -@kindex K d (Summary) -Delete the @acronym{MIME} part and add some information about the -removed part. -@item K c -@kindex K c (Summary) -Copy the @acronym{MIME} part. +@node Tree Display +@section Tree Display +@cindex trees -@item K e -@kindex K e (Summary) -View the @acronym{MIME} part externally. +@vindex gnus-use-trees +If you don't like the normal Gnus summary display, you might try setting +@code{gnus-use-trees} to @code{t}. This will create (by default) an +additional @dfn{tree buffer}. You can execute all summary mode commands +in the tree buffer. -@item K i -@kindex K i (Summary) -View the @acronym{MIME} part internally. +There are a few variables to customize the tree display, of course: -@item K | -@kindex K | (Summary) -Pipe the @acronym{MIME} part to an external command. -@end table +@table @code +@item gnus-tree-mode-hook +@vindex gnus-tree-mode-hook +A hook called in all tree mode buffers. -The rest of these @acronym{MIME} commands do not use the numerical prefix in -the same manner: +@item gnus-tree-mode-line-format +@vindex gnus-tree-mode-line-format +A format string for the mode bar in the tree mode buffers (@pxref{Mode +Line Formatting}). The default is @samp{Gnus: %%b %S %Z}. For a list +of valid specs, @pxref{Summary Buffer Mode Line}. -@table @kbd -@item K H -@kindex K H (Summary) -@findex gnus-article-browse-html-article -View @samp{text/html} parts of the current article with a WWW browser. -Inline images embedded in a message using the @code{cid} scheme, as they -are generally considered to be safe, will be processed properly. The -message header is added to the beginning of every @acronym{HTML} part -unless the prefix argument is given. +@item gnus-selected-tree-face +@vindex gnus-selected-tree-face +Face used for highlighting the selected article in the tree buffer. The +default is @code{modeline}. -Warning: Spammers use links to images (using the @code{http} scheme) in -@acronym{HTML} articles to verify whether you have read the message. As -this command passes the @acronym{HTML} content to the browser without -eliminating these ``web bugs'' you should only use it for mails from -trusted senders. +@item gnus-tree-line-format +@vindex gnus-tree-line-format +A format string for the tree nodes. The name is a bit of a misnomer, +though---it doesn't define a line, but just the node. The default value +is @samp{%(%[%3,3n%]%)}, which displays the first three characters of +the name of the poster. It is vital that all nodes are of the same +length, so you @emph{must} use @samp{%4,4n}-like specifiers. -If you always want to display @acronym{HTML} parts in the browser, set -@code{mm-text-html-renderer} to @code{nil}. +Valid specs are: -This command creates temporary files to pass @acronym{HTML} contents -including images if any to the browser, and deletes them when exiting -the group (if you want). +@table @samp +@item n +The name of the poster. +@item f +The @code{From} header. +@item N +The number of the article. +@item [ +The opening bracket. +@item ] +The closing bracket. +@item s +The subject. +@end table -@item K b -@kindex K b (Summary) -Make all the @acronym{MIME} parts have buttons in front of them. This is -mostly useful if you wish to save (or perform other actions) on inlined -parts. +@xref{Formatting Variables}. -@item K m -@kindex K m (Summary) -@findex gnus-summary-repair-multipart -Some multipart messages are transmitted with missing or faulty headers. -This command will attempt to ``repair'' these messages so that they can -be viewed in a more pleasant manner -(@code{gnus-summary-repair-multipart}). +Variables related to the display are: -@item X m -@kindex X m (Summary) -@findex gnus-summary-save-parts -Save all parts matching a @acronym{MIME} type to a directory -(@code{gnus-summary-save-parts}). Understands the process/prefix -convention (@pxref{Process/Prefix}). +@table @code +@item gnus-tree-brackets +@vindex gnus-tree-brackets +This is used for differentiating between ``real'' articles and +``sparse'' articles. The format is +@example +((@var{real-open} . @var{real-close}) + (@var{sparse-open} . @var{sparse-close}) + (@var{dummy-open} . @var{dummy-close})) +@end example +and the default is @code{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))}. -@item M-t -@kindex M-t (Summary) -@findex gnus-summary-toggle-display-buttonized -Toggle the buttonized display of the article buffer -(@code{gnus-summary-toggle-display-buttonized}). +@item gnus-tree-parent-child-edges +@vindex gnus-tree-parent-child-edges +This is a list that contains the characters used for connecting parent +nodes to their children. The default is @code{(?- ?\\ ?|)}. -@item W M w -@kindex W M w (Summary) -@findex gnus-article-decode-mime-words -Decode RFC 2047-encoded words in the article headers -(@code{gnus-article-decode-mime-words}). +@end table -@item W M c -@kindex W M c (Summary) -@findex gnus-article-decode-charset -Decode encoded article bodies as well as charsets -(@code{gnus-article-decode-charset}). +@item gnus-tree-minimize-window +@vindex gnus-tree-minimize-window +If this variable is non-@code{nil}, Gnus will try to keep the tree +buffer as small as possible to allow more room for the other Gnus +windows. If this variable is a number, the tree buffer will never be +higher than that number. The default is @code{t}. Note that if you +have several windows displayed side-by-side in a frame and the tree +buffer is one of these, minimizing the tree window will also resize all +other windows displayed next to it. -This command looks in the @code{Content-Type} header to determine the -charset. If there is no such header in the article, you can give it a -prefix, which will prompt for the charset to decode as. In regional -groups where people post using some common encoding (but do not -include @acronym{MIME} headers), you can set the @code{charset} group/topic -parameter to the required charset (@pxref{Group Parameters}). +You may also wish to add the following hook to keep the window minimized +at all times: -@item W M v -@kindex W M v (Summary) -@findex gnus-mime-view-all-parts -View all the @acronym{MIME} parts in the current article -(@code{gnus-mime-view-all-parts}). +@lisp +(add-hook 'gnus-configure-windows-hook + 'gnus-tree-perhaps-minimize) +@end lisp + +@item gnus-generate-tree-function +@vindex gnus-generate-tree-function +@findex gnus-generate-horizontal-tree +@findex gnus-generate-vertical-tree +The function that actually generates the thread tree. Two predefined +functions are available: @code{gnus-generate-horizontal-tree} and +@code{gnus-generate-vertical-tree} (which is the default). @end table -Relevant variables: +Here's an example from a horizontal tree buffer: -@table @code -@item gnus-ignored-mime-types -@vindex gnus-ignored-mime-types -This is a list of regexps. @acronym{MIME} types that match a regexp from -this list will be completely ignored by Gnus. The default value is -@code{nil}. +@example +@{***@}-(***)-[odd]-[Gun] + | \[Jan] + | \[odd]-[Eri] + | \(***)-[Eri] + | \[odd]-[Paa] + \[Bjo] + \[Gun] + \[Gun]-[Jor] +@end example -To have all Vcards be ignored, you'd say something like this: +Here's the same thread displayed in a vertical tree buffer: + +@example +@group +@{***@} + |--------------------------\-----\-----\ +(***) [Bjo] [Gun] [Gun] + |--\-----\-----\ | +[odd] [Jan] [odd] (***) [Jor] + | | |--\ +[Gun] [Eri] [Eri] [odd] + | + [Paa] +@end group +@end example + +If you're using horizontal trees, it might be nice to display the trees +side-by-side with the summary buffer. You could add something like the +following to your @file{~/.gnus.el} file: @lisp -(setq gnus-ignored-mime-types - '("text/x-vcard")) +(setq gnus-use-trees t + gnus-generate-tree-function 'gnus-generate-horizontal-tree + gnus-tree-minimize-window nil) +(gnus-add-configuration + '(article + (vertical 1.0 + (horizontal 0.25 + (summary 0.75 point) + (tree 1.0)) + (article 1.0)))) @end lisp -@item gnus-article-loose-mime -@vindex gnus-article-loose-mime -If non-@code{nil}, Gnus won't require the @samp{MIME-Version} header -before interpreting the message as a @acronym{MIME} message. This helps -when reading messages from certain broken mail user agents. The -default is @code{t}. +@xref{Window Layout}. -@item gnus-article-emulate-mime -@vindex gnus-article-emulate-mime -@cindex uuencode -@cindex yEnc -There are other, non-@acronym{MIME} encoding methods used. The most common -is @samp{uuencode}, but yEncode is also getting to be popular. If -this variable is non-@code{nil}, Gnus will look in message bodies to -see if it finds these encodings, and if so, it'll run them through the -Gnus @acronym{MIME} machinery. The default is @code{t}. Only -single-part yEnc encoded attachments can be decoded. There's no support -for encoding in Gnus. -@item gnus-unbuttonized-mime-types -@vindex gnus-unbuttonized-mime-types -This is a list of regexps. @acronym{MIME} types that match a regexp from -this list won't have @acronym{MIME} buttons inserted unless they aren't -displayed or this variable is overridden by -@code{gnus-buttonized-mime-types}. The default value is -@code{(".*/.*")}. This variable is only used when -@code{gnus-inhibit-mime-unbuttonizing} is @code{nil}. +@node Mail Group Commands +@section Mail Group Commands +@cindex mail group commands -@item gnus-buttonized-mime-types -@vindex gnus-buttonized-mime-types -This is a list of regexps. @acronym{MIME} types that match a regexp from -this list will have @acronym{MIME} buttons inserted unless they aren't -displayed. This variable overrides -@code{gnus-unbuttonized-mime-types}. The default value is @code{nil}. -This variable is only used when @code{gnus-inhibit-mime-unbuttonizing} -is @code{nil}. +Some commands only make sense in mail groups. If these commands are +invalid in the current group, they will raise a hell and let you know. -To see e.g. security buttons but no other buttons, you could set this -variable to @code{("multipart/signed")} and leave -@code{gnus-unbuttonized-mime-types} at the default value. +All these commands (except the expiry and edit commands) use the +process/prefix convention (@pxref{Process/Prefix}). -You could also add @code{"multipart/alternative"} to this list to -display radio buttons that allow you to choose one of two media types -those mails include. See also @code{mm-discouraged-alternatives} -(@pxref{Display Customization, ,Display Customization, emacs-mime, The -Emacs MIME Manual}). +@table @kbd -@item gnus-inhibit-mime-unbuttonizing -@vindex gnus-inhibit-mime-unbuttonizing -If this is non-@code{nil}, then all @acronym{MIME} parts get buttons. The -default value is @code{nil}. +@item B e +@kindex B e (Summary) +@findex gnus-summary-expire-articles +@cindex expiring mail +Run all expirable articles in the current group through the expiry +process (@code{gnus-summary-expire-articles}). That is, delete all +expirable articles in the group that have been around for a while. +(@pxref{Expiring Mail}). -@item gnus-article-mime-part-function -@vindex gnus-article-mime-part-function -For each @acronym{MIME} part, this function will be called with the @acronym{MIME} -handle as the parameter. The function is meant to be used to allow -users to gather information from the article (e. g., add Vcard info to -the bbdb database) or to do actions based on parts (e. g., automatically -save all jpegs into some directory). +@item B C-M-e +@kindex B C-M-e (Summary) +@findex gnus-summary-expire-articles-now +@cindex expiring mail +Delete all the expirable articles in the group +(@code{gnus-summary-expire-articles-now}). This means that @strong{all} +articles eligible for expiry in the current group will +disappear forever into that big @file{/dev/null} in the sky. -Here's an example function the does the latter: +@item B DEL +@kindex B DEL (Summary) +@cindex deleting mail +@findex gnus-summary-delete-article +@c @icon{gnus-summary-mail-delete} +Delete the mail article. This is ``delete'' as in ``delete it from your +disk forever and ever, never to return again.'' Use with caution. +(@code{gnus-summary-delete-article}). -@lisp -(defun my-save-all-jpeg-parts (handle) - (when (equal (car (mm-handle-type handle)) "image/jpeg") - (with-temp-buffer - (insert (mm-get-part handle)) - (write-region (point-min) (point-max) - (read-file-name "Save jpeg to: "))))) -(setq gnus-article-mime-part-function - 'my-save-all-jpeg-parts) -@end lisp +@item B m +@kindex B m (Summary) +@cindex move mail +@findex gnus-summary-move-article +@vindex gnus-preserve-marks +Move the article from one mail group to another +(@code{gnus-summary-move-article}). Marks will be preserved if +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). -@vindex gnus-mime-multipart-functions -@item gnus-mime-multipart-functions -Alist of @acronym{MIME} multipart types and functions to handle them. +@item B c +@kindex B c (Summary) +@cindex copy mail +@findex gnus-summary-copy-article +@c @icon{gnus-summary-mail-copy} +Copy the article from one group (mail group or not) to a mail group +(@code{gnus-summary-copy-article}). Marks will be preserved if +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). -@vindex gnus-mime-display-multipart-alternative-as-mixed -@item gnus-mime-display-multipart-alternative-as-mixed -Display "multipart/alternative" parts as "multipart/mixed". +@item B B +@kindex B B (Summary) +@cindex crosspost mail +@findex gnus-summary-crosspost-article +Crosspost the current article to some other group +(@code{gnus-summary-crosspost-article}). This will create a new copy of +the article in the other group, and the Xref headers of the article will +be properly updated. -@vindex gnus-mime-display-multipart-related-as-mixed -@item gnus-mime-display-multipart-related-as-mixed -Display "multipart/related" parts as "multipart/mixed". +@item B i +@kindex B i (Summary) +@findex gnus-summary-import-article +Import an arbitrary file into the current mail newsgroup +(@code{gnus-summary-import-article}). You will be prompted for a file +name, a @code{From} header and a @code{Subject} header. -If displaying @samp{text/html} is discouraged, see -@code{mm-discouraged-alternatives}, images or other material inside a -"multipart/related" part might be overlooked when this variable is -@code{nil}. @ref{Display Customization, Display Customization, , -emacs-mime, Emacs-Mime Manual}. +@item B I +@kindex B I (Summary) +@findex gnus-summary-create-article +Create an empty article in the current mail newsgroups +(@code{gnus-summary-create-article}). You will be prompted for a +@code{From} header and a @code{Subject} header. -@vindex gnus-mime-display-multipart-as-mixed -@item gnus-mime-display-multipart-as-mixed -Display "multipart" parts as "multipart/mixed". If @code{t}, it -overrides @code{nil} values of -@code{gnus-mime-display-multipart-alternative-as-mixed} and -@code{gnus-mime-display-multipart-related-as-mixed}. +@item B r +@kindex B r (Summary) +@findex gnus-summary-respool-article +@vindex gnus-summary-respool-default-method +Respool the mail article (@code{gnus-summary-respool-article}). +@code{gnus-summary-respool-default-method} will be used as the default +select method when respooling. This variable is @code{nil} by default, +which means that the current group select method will be used instead. +Marks will be preserved if @code{gnus-preserve-marks} is non-@code{nil} +(which is the default). + +@item B w +@itemx e +@kindex B w (Summary) +@kindex e (Summary) +@findex gnus-summary-edit-article +@kindex C-c C-c (Article) +@findex gnus-summary-edit-article-done +Edit the current article (@code{gnus-summary-edit-article}). To finish +editing and make the changes permanent, type @kbd{C-c C-c} +(@code{gnus-summary-edit-article-done}). If you give a prefix to the +@kbd{C-c C-c} command, Gnus won't re-highlight the article. + +@item B q +@kindex B q (Summary) +@findex gnus-summary-respool-query +If you want to re-spool an article, you might be curious as to what group +the article will end up in before you do the re-spooling. This command +will tell you (@code{gnus-summary-respool-query}). -@vindex mm-file-name-rewrite-functions -@item mm-file-name-rewrite-functions -List of functions used for rewriting file names of @acronym{MIME} parts. -Each function takes a file name as input and returns a file name. +@item B t +@kindex B t (Summary) +@findex gnus-summary-respool-trace +Similarly, this command will display all fancy splitting patterns used +when respooling, if any (@code{gnus-summary-respool-trace}). -Ready-made functions include@* -@code{mm-file-name-delete-whitespace}, -@code{mm-file-name-trim-whitespace}, -@code{mm-file-name-collapse-whitespace}, and -@code{mm-file-name-replace-whitespace}. The later uses the value of -the variable @code{mm-file-name-replace-whitespace} to replace each -whitespace character in a file name with that string; default value -is @code{"_"} (a single underscore). -@findex mm-file-name-delete-whitespace -@findex mm-file-name-trim-whitespace -@findex mm-file-name-collapse-whitespace -@findex mm-file-name-replace-whitespace -@vindex mm-file-name-replace-whitespace +@item B p +@kindex B p (Summary) +@findex gnus-summary-article-posted-p +Some people have a tendency to send you ``courtesy'' copies when they +follow up to articles you have posted. These usually have a +@code{Newsgroups} header in them, but not always. This command +(@code{gnus-summary-article-posted-p}) will try to fetch the current +article from your news server (or rather, from +@code{gnus-refer-article-method} or @code{gnus-select-method}) and will +report back whether it found the article or not. Even if it says that +it didn't find the article, it may have been posted anyway---mail +propagation is much faster than news propagation, and the news copy may +just not have arrived yet. -The standard functions @code{capitalize}, @code{downcase}, -@code{upcase}, and @code{upcase-initials} may be useful, too. +@item K E +@kindex K E (Summary) +@findex gnus-article-encrypt-body +@vindex gnus-article-encrypt-protocol +Encrypt the body of an article (@code{gnus-article-encrypt-body}). +The body is encrypted with the encryption protocol specified by the +variable @code{gnus-article-encrypt-protocol}. -Everybody knows that whitespace characters in file names are evil, -except those who don't know. If you receive lots of attachments from -such unenlightened users, you can make live easier by adding +@end table + +@vindex gnus-move-split-methods +@cindex moving articles +If you move (or copy) articles regularly, you might wish to have Gnus +suggest where to put the articles. @code{gnus-move-split-methods} is a +variable that uses the same syntax as @code{gnus-split-methods} +(@pxref{Saving Articles}). You may customize that variable to create +suggestions you find reasonable. (Note that +@code{gnus-move-split-methods} uses group names where +@code{gnus-split-methods} uses file names.) @lisp -(setq mm-file-name-rewrite-functions - '(mm-file-name-trim-whitespace - mm-file-name-collapse-whitespace - mm-file-name-replace-whitespace)) +(setq gnus-move-split-methods + '(("^From:.*Lars Magne" "nnml:junk") + ("^Subject:.*gnus" "nnfolder:important") + (".*" "nnml:misc"))) @end lisp -@noindent -to your @file{~/.gnus.el} file. - -@end table - -@node Charsets -@section Charsets -@cindex charsets +@node Various Summary Stuff +@section Various Summary Stuff -People use different charsets, and we have @acronym{MIME} to let us know what -charsets they use. Or rather, we wish we had. Many people use -newsreaders and mailers that do not understand or use @acronym{MIME}, and -just send out messages without saying what character sets they use. To -help a bit with this, some local news hierarchies have policies that say -what character set is the default. For instance, the @samp{fj} -hierarchy uses @code{iso-2022-jp}. +@menu +* Summary Group Information:: Information oriented commands. +* Searching for Articles:: Multiple article commands. +* Summary Generation Commands:: +* Really Various Summary Commands:: Those pesky non-conformant commands. +@end menu -@vindex gnus-group-charset-alist -This knowledge is encoded in the @code{gnus-group-charset-alist} -variable, which is an alist of regexps (use the first item to match full -group names) and default charsets to be used when reading these groups. +@table @code +@vindex gnus-summary-display-while-building +@item gnus-summary-display-while-building +If non-@code{nil}, show and update the summary buffer as it's being +built. If @code{t}, update the buffer after every line is inserted. +If the value is an integer, @var{n}, update the display every @var{n} +lines. The default is @code{nil}. -@vindex gnus-newsgroup-ignored-charsets -In addition, some people do use soi-disant @acronym{MIME}-aware agents that -aren't. These blithely mark messages as being in @code{iso-8859-1} -even if they really are in @code{koi-8}. To help here, the -@code{gnus-newsgroup-ignored-charsets} variable can be used. The -charsets that are listed here will be ignored. The variable can be -set on a group-by-group basis using the group parameters (@pxref{Group -Parameters}). The default value is @code{(unknown-8bit x-unknown)}, -which includes values some agents insist on having in there. +@vindex gnus-summary-display-arrow +@item gnus-summary-display-arrow +If non-@code{nil}, display an arrow in the fringe to indicate the +current article. -@vindex gnus-group-posting-charset-alist -When posting, @code{gnus-group-posting-charset-alist} is used to -determine which charsets should not be encoded using the @acronym{MIME} -encodings. For instance, some hierarchies discourage using -quoted-printable header encoding. +@vindex gnus-summary-mode-hook +@item gnus-summary-mode-hook +This hook is called when creating a summary mode buffer. -This variable is an alist of regexps and permitted unencoded charsets -for posting. Each element of the alist has the form @code{(}@var{test -header body-list}@code{)}, where: +@vindex gnus-summary-generate-hook +@item gnus-summary-generate-hook +This is called as the last thing before doing the threading and the +generation of the summary buffer. It's quite convenient for customizing +the threading variables based on what data the newsgroup has. This hook +is called from the summary buffer after most summary buffer variables +have been set. -@table @var -@item test -is either a regular expression matching the newsgroup header or a -variable to query, -@item header -is the charset which may be left unencoded in the header (@code{nil} -means encode all charsets), -@item body-list -is a list of charsets which may be encoded using 8bit content-transfer -encoding in the body, or one of the special values @code{nil} (always -encode using quoted-printable) or @code{t} (always use 8bit). -@end table +@vindex gnus-summary-prepare-hook +@item gnus-summary-prepare-hook +It is called after the summary buffer has been generated. You might use +it to, for instance, highlight lines or modify the look of the buffer in +some other ungodly manner. I don't care. -@cindex Russian -@cindex koi8-r -@cindex koi8-u -@cindex iso-8859-5 -@cindex coding system aliases -@cindex preferred charset +@vindex gnus-summary-prepared-hook +@item gnus-summary-prepared-hook +A hook called as the very last thing after the summary buffer has been +generated. -@xref{Encoding Customization, , Encoding Customization, emacs-mime, -The Emacs MIME Manual}, for additional variables that control which -MIME charsets are used when sending messages. +@vindex gnus-summary-ignore-duplicates +@item gnus-summary-ignore-duplicates +When Gnus discovers two articles that have the same @code{Message-ID}, +it has to do something drastic. No articles are allowed to have the +same @code{Message-ID}, but this may happen when reading mail from some +sources. Gnus allows you to customize what happens with this variable. +If it is @code{nil} (which is the default), Gnus will rename the +@code{Message-ID} (for display purposes only) and display the article as +any other article. If this variable is @code{t}, it won't display the +article---it'll be as if it never existed. -Other charset tricks that may be useful, although not Gnus-specific: +@vindex gnus-alter-articles-to-read-function +@item gnus-alter-articles-to-read-function +This function, which takes two parameters (the group name and the list +of articles to be selected), is called to allow the user to alter the +list of articles to be selected. -If there are several @acronym{MIME} charsets that encode the same Emacs -charset, you can choose what charset to use by saying the following: +For instance, the following function adds the list of cached articles to +the list in one particular group: @lisp -(put-charset-property 'cyrillic-iso8859-5 - 'preferred-coding-system 'koi8-r) +(defun my-add-cached-articles (group articles) + (if (string= group "some.group") + (append gnus-newsgroup-cached articles) + articles)) @end lisp -This means that Russian will be encoded using @code{koi8-r} instead of -the default @code{iso-8859-5} @acronym{MIME} charset. +@vindex gnus-newsgroup-variables +@item gnus-newsgroup-variables +A list of newsgroup (summary buffer) local variables, or cons of +variables and their default expressions to be evalled (when the default +values are not @code{nil}), that should be made global while the summary +buffer is active. -If you want to read messages in @code{koi8-u}, you can cheat and say +Note: The default expressions will be evaluated (using function +@code{eval}) before assignment to the local variable rather than just +assigned to it. If the default expression is the symbol @code{global}, +that symbol will not be evaluated but the global value of the local +variable will be used instead. + +These variables can be used to set variables in the group parameters +while still allowing them to affect operations done in other +buffers. For example: @lisp -(define-coding-system-alias 'koi8-u 'koi8-r) +(setq gnus-newsgroup-variables + '(message-use-followup-to + (gnus-visible-headers . + "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:"))) @end lisp -This will almost do the right thing. +Also @pxref{Group Parameters}. -And finally, to read charsets like @code{windows-1251}, you can say -something like +@vindex gnus-propagate-marks +@item gnus-propagate-marks +If non-@code{nil}, propagate marks to the backends for possible +storing. @xref{NNTP marks}, and friends, for a more fine-grained +sieve. -@lisp -(codepage-setup 1251) -(define-coding-system-alias 'windows-1251 'cp1251) -@end lisp +@end table -@node Article Commands -@section Article Commands +@node Summary Group Information +@subsection Summary Group Information @table @kbd -@item A P -@cindex PostScript -@cindex printing -@kindex A P (Summary) -@vindex gnus-ps-print-hook -@findex gnus-summary-print-article -Generate and print a PostScript image of the article buffer -(@code{gnus-summary-print-article}). @code{gnus-ps-print-hook} will -be run just before printing the buffer. An alternative way to print -article is to use Muttprint (@pxref{Saving Articles}). +@item H d +@kindex H d (Summary) +@findex gnus-summary-describe-group +Give a brief description of the current group +(@code{gnus-summary-describe-group}). If given a prefix, force +rereading the description from the server. -@item A C -@vindex gnus-fetch-partial-articles -@findex gnus-summary-show-complete-article -If @code{-fetch-partial-articles} is non-@code{nil}, Gnus will -fetch partial articles, if the backend it fetches them from supports -it. Currently only @code{nnimap} does. If you're looking at a -partial article, and want to see the complete article instead, then -the @kbd{A C} command (@code{gnus-summary-show-complete-article}) will -do so. +@item H h +@kindex H h (Summary) +@findex gnus-summary-describe-briefly +Give an extremely brief description of the most important summary +keystrokes (@code{gnus-summary-describe-briefly}). +@item H i +@kindex H i (Summary) +@findex gnus-info-find-node +Go to the Gnus info node (@code{gnus-info-find-node}). @end table -@node Summary Sorting -@section Summary Sorting -@cindex summary sorting - -You can have the summary buffer sorted in various ways, even though I -can't really see why you'd want that. +@node Searching for Articles +@subsection Searching for Articles @table @kbd -@item C-c C-s C-n -@kindex C-c C-s C-n (Summary) -@findex gnus-summary-sort-by-number -Sort by article number (@code{gnus-summary-sort-by-number}). +@item M-s +@kindex M-s (Summary) +@findex gnus-summary-search-article-forward +Search through all subsequent (raw) articles for a regexp +(@code{gnus-summary-search-article-forward}). -@item C-c C-s C-m C-n -@kindex C-c C-s C-n (Summary) -@findex gnus-summary-sort-by-most-recent-number -Sort by most recent article number -(@code{gnus-summary-sort-by-most-recent-number}). +@item M-r +@kindex M-r (Summary) +@findex gnus-summary-search-article-backward +Search through all previous (raw) articles for a regexp +(@code{gnus-summary-search-article-backward}). -@item C-c C-s C-a -@kindex C-c C-s C-a (Summary) -@findex gnus-summary-sort-by-author -Sort by author (@code{gnus-summary-sort-by-author}). +@item M-S +@kindex M-S (Summary) +@findex gnus-summary-repeat-search-article-forward +Repeat the previous search forwards +(@code{gnus-summary-repeat-search-article-forward}). -@item C-c C-s C-t -@kindex C-c C-s C-t (Summary) -@findex gnus-summary-sort-by-recipient -Sort by recipient (@code{gnus-summary-sort-by-recipient}). +@item M-R +@kindex M-R (Summary) +@findex gnus-summary-repeat-search-article-backward +Repeat the previous search backwards +(@code{gnus-summary-repeat-search-article-backward}). -@item C-c C-s C-s -@kindex C-c C-s C-s (Summary) -@findex gnus-summary-sort-by-subject -Sort by subject (@code{gnus-summary-sort-by-subject}). +@item & +@kindex & (Summary) +@findex gnus-summary-execute-command +This command will prompt you for a header, a regular expression to match +on this field, and a command to be executed if the match is made +(@code{gnus-summary-execute-command}). If the header is an empty +string, the match is done on the entire article. If given a prefix, +search backward instead. -@item C-c C-s C-d -@kindex C-c C-s C-d (Summary) -@findex gnus-summary-sort-by-date -Sort by date (@code{gnus-summary-sort-by-date}). +For instance, @kbd{& RET some.*string RET #} will put the process mark on +all articles that have heads or bodies that match @samp{some.*string}. -@item C-c C-s C-m C-d -@kindex C-c C-s C-m C-d (Summary) -@findex gnus-summary-sort-by-most-recent-date -Sort by most recent date (@code{gnus-summary-sort-by-most-recent-date}). +@item M-& +@kindex M-& (Summary) +@findex gnus-summary-universal-argument +Perform any operation on all articles that have been marked with +the process mark (@code{gnus-summary-universal-argument}). +@end table -@item C-c C-s C-l -@kindex C-c C-s C-l (Summary) -@findex gnus-summary-sort-by-lines -Sort by lines (@code{gnus-summary-sort-by-lines}). +@node Summary Generation Commands +@subsection Summary Generation Commands -@item C-c C-s C-c -@kindex C-c C-s C-c (Summary) -@findex gnus-summary-sort-by-chars -Sort by article length (@code{gnus-summary-sort-by-chars}). +@table @kbd -@item C-c C-s C-i -@kindex C-c C-s C-i (Summary) -@findex gnus-summary-sort-by-score -Sort by score (@code{gnus-summary-sort-by-score}). +@item Y g +@kindex Y g (Summary) +@findex gnus-summary-prepare +Regenerate the current summary buffer (@code{gnus-summary-prepare}). -@item C-c C-s C-r -@kindex C-c C-s C-r (Summary) -@findex gnus-summary-sort-by-random -Randomize (@code{gnus-summary-sort-by-random}). +@item Y c +@kindex Y c (Summary) +@findex gnus-summary-insert-cached-articles +Pull all cached articles (for the current group) into the summary buffer +(@code{gnus-summary-insert-cached-articles}). -@item C-c C-s C-o -@kindex C-c C-s C-o (Summary) -@findex gnus-summary-sort-by-original -Sort using the default sorting method -(@code{gnus-summary-sort-by-original}). -@end table +@item Y d +@kindex Y d (Summary) +@findex gnus-summary-insert-dormant-articles +Pull all dormant articles (for the current group) into the summary buffer +(@code{gnus-summary-insert-dormant-articles}). -These functions will work both when you use threading and when you don't -use threading. In the latter case, all summary lines will be sorted, -line by line. In the former case, sorting will be done on a -root-by-root basis, which might not be what you were looking for. To -toggle whether to use threading, type @kbd{T T} (@pxref{Thread -Commands}). +@item Y t +@kindex Y t (Summary) +@findex gnus-summary-insert-ticked-articles +Pull all ticked articles (for the current group) into the summary buffer +(@code{gnus-summary-insert-ticked-articles}). -If a prefix argument if given, the sort order is reversed. +@end table -@node Finding the Parent -@section Finding the Parent -@cindex parent articles -@cindex referring articles +@node Really Various Summary Commands +@subsection Really Various Summary Commands @table @kbd -@item ^ -@kindex ^ (Summary) -@findex gnus-summary-refer-parent-article -If you'd like to read the parent of the current article, and it is not -displayed in the summary buffer, you might still be able to. That is, -if the current group is fetched by @acronym{NNTP}, the parent hasn't expired -and the @code{References} in the current article are not mangled, you -can just press @kbd{^} or @kbd{A r} -(@code{gnus-summary-refer-parent-article}). If everything goes well, -you'll get the parent. If the parent is already displayed in the -summary buffer, point will just move to this article. -If given a positive numerical prefix, fetch that many articles back into -the ancestry. If given a negative numerical prefix, fetch just that -ancestor. So if you say @kbd{3 ^}, Gnus will fetch the parent, the -grandparent and the grandgrandparent of the current article. If you say -@kbd{-3 ^}, Gnus will only fetch the grandgrandparent of the current -article. +@item A D +@itemx C-d +@kindex C-d (Summary) +@kindex A D (Summary) +@findex gnus-summary-enter-digest-group +If the current article is a collection of other articles (for instance, +a digest), you might use this command to enter a group based on the that +article (@code{gnus-summary-enter-digest-group}). Gnus will try to +guess what article type is currently displayed unless you give a prefix +to this command, which forces a ``digest'' interpretation. Basically, +whenever you see a message that is a collection of other messages of +some format, you @kbd{C-d} and read these messages in a more convenient +fashion. -@item A R (Summary) -@findex gnus-summary-refer-references -@kindex A R (Summary) -Fetch all articles mentioned in the @code{References} header of the -article (@code{gnus-summary-refer-references}). +@vindex gnus-auto-select-on-ephemeral-exit +The variable @code{gnus-auto-select-on-ephemeral-exit} controls what +article should be selected after exiting a digest group. Valid values +include: -@item A T (Summary) -@findex gnus-summary-refer-thread -@kindex A T (Summary) -Display the full thread where the current article appears -(@code{gnus-summary-refer-thread}). This command has to fetch all the -headers in the current group to work, so it usually takes a while. If -you do it often, you may consider setting @code{gnus-fetch-old-headers} -to @code{invisible} (@pxref{Filling In Threads}). This won't have any -visible effects normally, but it'll make this command work a whole lot -faster. Of course, it'll make group entry somewhat slow. +@table @code +@item next +Select the next article. -@vindex gnus-refer-thread-limit -The @code{gnus-refer-thread-limit} variable says how many old (i. e., -articles before the first displayed in the current group) headers to -fetch when doing this command. The default is 200. If @code{t}, all -the available headers will be fetched. This variable can be overridden -by giving the @kbd{A T} command a numerical prefix. +@item next-unread +Select the next unread article. -@item M-^ (Summary) -@findex gnus-summary-refer-article -@kindex M-^ (Summary) -@cindex Message-ID -@cindex fetching by Message-ID -You can also ask Gnus for an arbitrary article, no matter what group it -belongs to. @kbd{M-^} (@code{gnus-summary-refer-article}) will ask you -for a @code{Message-ID}, which is one of those long, hard-to-read -thingies that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. -You have to get it all exactly right. No fuzzy searches, I'm afraid. +@item next-noselect +Move the cursor to the next article. This is the default. + +@item next-unread-noselect +Move the cursor to the next unread article. +@end table + +If it has any other value or there is no next (unread) article, the +article selected before entering to the digest group will appear. + +@item C-M-d +@kindex C-M-d (Summary) +@findex gnus-summary-read-document +This command is very similar to the one above, but lets you gather +several documents into one biiig group +(@code{gnus-summary-read-document}). It does this by opening several +@code{nndoc} groups for each document, and then opening an +@code{nnvirtual} group on top of these @code{nndoc} groups. This +command understands the process/prefix convention +(@pxref{Process/Prefix}). + +@item C-t +@kindex C-t (Summary) +@findex gnus-summary-toggle-truncation +Toggle truncation of summary lines +(@code{gnus-summary-toggle-truncation}). This will probably confuse the +line centering function in the summary buffer, so it's not a good idea +to have truncation switched off while reading articles. + +@item = +@kindex = (Summary) +@findex gnus-summary-expand-window +Expand the summary buffer window (@code{gnus-summary-expand-window}). +If given a prefix, force an @code{article} window configuration. + +@item C-M-e +@kindex C-M-e (Summary) +@findex gnus-summary-edit-parameters +Edit the group parameters (@pxref{Group Parameters}) of the current +group (@code{gnus-summary-edit-parameters}). + +@item C-M-a +@kindex C-M-a (Summary) +@findex gnus-summary-customize-parameters +Customize the group parameters (@pxref{Group Parameters}) of the current +group (@code{gnus-summary-customize-parameters}). -Gnus looks for the @code{Message-ID} in the headers that have already -been fetched, but also tries all the select methods specified by -@code{gnus-refer-article-method} if it is not found. @end table -@vindex gnus-refer-article-method -If the group you are reading is located on a back end that does not -support fetching by @code{Message-ID} very well (like @code{nnspool}), -you can set @code{gnus-refer-article-method} to an @acronym{NNTP} method. It -would, perhaps, be best if the @acronym{NNTP} server you consult is the one -updating the spool you are reading from, but that's not really -necessary. -It can also be a list of select methods, as well as the special symbol -@code{current}, which means to use the current select method. If it -is a list, Gnus will try all the methods in the list until it finds a -match. +@node Exiting the Summary Buffer +@section Exiting the Summary Buffer +@cindex summary exit +@cindex exiting groups -Here's an example setting that will first try the current method, and -then ask Google if that fails: +Exiting from the summary buffer will normally update all info on the +group and return you to the group buffer. -@lisp -(setq gnus-refer-article-method - '(current - (nnweb "google" (nnweb-type google)))) -@end lisp +@table @kbd -Most of the mail back ends support fetching by @code{Message-ID}, but -do not do a particularly excellent job at it. That is, @code{nnmbox}, -@code{nnbabyl}, @code{nnmaildir}, @code{nnml}, are able to locate -articles from any groups, while @code{nnfolder}, and @code{nnimap} are -only able to locate articles that have been posted to the current -group. @code{nnmh} does not support this at all. +@item Z Z +@itemx Z Q +@itemx q +@kindex Z Z (Summary) +@kindex Z Q (Summary) +@kindex q (Summary) +@findex gnus-summary-exit +@vindex gnus-summary-exit-hook +@vindex gnus-summary-prepare-exit-hook +@vindex gnus-group-no-more-groups-hook +@c @icon{gnus-summary-exit} +Exit the current group and update all information on the group +(@code{gnus-summary-exit}). @code{gnus-summary-prepare-exit-hook} is +called before doing much of the exiting, which calls +@code{gnus-summary-expire-articles} by default. +@code{gnus-summary-exit-hook} is called after finishing the exit +process. @code{gnus-group-no-more-groups-hook} is run when returning to +group mode having no more (unread) groups. -Fortunately, the special @code{nnregistry} back end is able to locate -articles in any groups, regardless of their back end (@pxref{Registry -Article Refer Method, fetching by @code{Message-ID} using the -registry}). +@item Z E +@itemx Q +@kindex Z E (Summary) +@kindex Q (Summary) +@findex gnus-summary-exit-no-update +Exit the current group without updating any information on the group +(@code{gnus-summary-exit-no-update}). -@node Alternative Approaches -@section Alternative Approaches +@item Z c +@itemx c +@kindex Z c (Summary) +@kindex c (Summary) +@findex gnus-summary-catchup-and-exit +@c @icon{gnus-summary-catchup-and-exit} +Mark all unticked articles in the group as read and then exit +(@code{gnus-summary-catchup-and-exit}). -Different people like to read news using different methods. This being -Gnus, we offer a small selection of minor modes for the summary buffers. +@item Z C +@kindex Z C (Summary) +@findex gnus-summary-catchup-all-and-exit +Mark all articles, even the ticked ones, as read and then exit +(@code{gnus-summary-catchup-all-and-exit}). -@menu -* Pick and Read:: First mark articles and then read them. -* Binary Groups:: Auto-decode all articles. -@end menu +@item Z n +@kindex Z n (Summary) +@findex gnus-summary-catchup-and-goto-next-group +Mark all articles as read and go to the next group +(@code{gnus-summary-catchup-and-goto-next-group}). +@item Z p +@kindex Z p (Summary) +@findex gnus-summary-catchup-and-goto-prev-group +Mark all articles as read and go to the previous group +(@code{gnus-summary-catchup-and-goto-prev-group}). -@node Pick and Read -@subsection Pick and Read -@cindex pick and read +@item Z R +@itemx C-x C-s +@kindex Z R (Summary) +@kindex C-x C-s (Summary) +@findex gnus-summary-reselect-current-group +Exit this group, and then enter it again +(@code{gnus-summary-reselect-current-group}). If given a prefix, select +all articles, both read and unread. -Some newsreaders (like @code{nn} and, uhm, @code{Netnews} on VM/CMS) use -a two-phased reading interface. The user first marks in a summary -buffer the articles she wants to read. Then she starts reading the -articles with just an article buffer displayed. +@item Z G +@itemx M-g +@kindex Z G (Summary) +@kindex M-g (Summary) +@findex gnus-summary-rescan-group +@c @icon{gnus-summary-mail-get} +Exit the group, check for new articles in the group, and select the +group (@code{gnus-summary-rescan-group}). If given a prefix, select all +articles, both read and unread. -@findex gnus-pick-mode -@kindex M-x gnus-pick-mode -Gnus provides a summary buffer minor mode that allows -this---@code{gnus-pick-mode}. This basically means that a few process -mark commands become one-keystroke commands to allow easy marking, and -it provides one additional command for switching to the summary buffer. +@item Z N +@kindex Z N (Summary) +@findex gnus-summary-next-group +Exit the group and go to the next group +(@code{gnus-summary-next-group}). -Here are the available keystrokes when using pick mode: +@item Z P +@kindex Z P (Summary) +@findex gnus-summary-prev-group +Exit the group and go to the previous group +(@code{gnus-summary-prev-group}). -@table @kbd -@item . -@kindex . (Pick) -@findex gnus-pick-article-or-thread -Pick the article or thread on the current line -(@code{gnus-pick-article-or-thread}). If the variable -@code{gnus-thread-hide-subtree} is true, then this key selects the -entire thread when used at the first article of the thread. Otherwise, -it selects just the article. If given a numerical prefix, go to that -thread or article and pick it. (The line number is normally displayed -at the beginning of the summary pick lines.) +@item Z s +@kindex Z s (Summary) +@findex gnus-summary-save-newsrc +Save the current number of read/marked articles in the dribble buffer +and then save the dribble buffer (@code{gnus-summary-save-newsrc}). If +given a prefix, also save the @file{.newsrc} file(s). Using this +command will make exit without updating (the @kbd{Q} command) worthless. +@end table -@item SPACE -@kindex SPACE (Pick) -@findex gnus-pick-next-page -Scroll the summary buffer up one page (@code{gnus-pick-next-page}). If -at the end of the buffer, start reading the picked articles. +@vindex gnus-exit-group-hook +@code{gnus-exit-group-hook} is called when you exit the current group +with an ``updating'' exit. For instance @kbd{Q} +(@code{gnus-summary-exit-no-update}) does not call this hook. -@item u -@kindex u (Pick) -@findex gnus-pick-unmark-article-or-thread. -Unpick the thread or article -(@code{gnus-pick-unmark-article-or-thread}). If the variable -@code{gnus-thread-hide-subtree} is true, then this key unpicks the -thread if used at the first article of the thread. Otherwise it unpicks -just the article. You can give this key a numerical prefix to unpick -the thread or article at that line. +@findex gnus-summary-wake-up-the-dead +@findex gnus-dead-summary-mode +@vindex gnus-kill-summary-on-exit +If you're in the habit of exiting groups, and then changing your mind +about it, you might set @code{gnus-kill-summary-on-exit} to @code{nil}. +If you do that, Gnus won't kill the summary buffer when you exit it. +(Quelle surprise!) Instead it will change the name of the buffer to +something like @samp{*Dead Summary ... *} and install a minor mode +called @code{gnus-dead-summary-mode}. Now, if you switch back to this +buffer, you'll find that all keys are mapped to a function called +@code{gnus-summary-wake-up-the-dead}. So tapping any keys in a dead +summary buffer will result in a live, normal summary buffer. -@item RET -@kindex RET (Pick) -@findex gnus-pick-start-reading -@vindex gnus-pick-display-summary -Start reading the picked articles (@code{gnus-pick-start-reading}). If -given a prefix, mark all unpicked articles as read first. If -@code{gnus-pick-display-summary} is non-@code{nil}, the summary buffer -will still be visible when you are reading. +There will never be more than one dead summary buffer at any one time. -@end table +@vindex gnus-use-cross-reference +The data on the current group will be updated (which articles you have +read, which articles you have replied to, etc.) when you exit the +summary buffer. If the @code{gnus-use-cross-reference} variable is +@code{t} (which is the default), articles that are cross-referenced to +this group and are marked as read, will also be marked as read in the +other subscribed groups they were cross-posted to. If this variable is +neither @code{nil} nor @code{t}, the article will be marked as read in +both subscribed and unsubscribed groups (@pxref{Crosspost Handling}). -All the normal summary mode commands are still available in the -pick-mode, with the exception of @kbd{u}. However @kbd{!} is available -which is mapped to the same function -@code{gnus-summary-tick-article-forward}. -If this sounds like a good idea to you, you could say: +@node Crosspost Handling +@section Crosspost Handling -@lisp -(add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) -@end lisp +@cindex velveeta +@cindex spamming +Marking cross-posted articles as read ensures that you'll never have to +read the same article more than once. Unless, of course, somebody has +posted it to several groups separately. Posting the same article to +several groups (not cross-posting) is called @dfn{spamming}, and you are +by law required to send nasty-grams to anyone who perpetrates such a +heinous crime. -@vindex gnus-pick-mode-hook -@code{gnus-pick-mode-hook} is run in pick minor mode buffers. +Remember: Cross-posting is kinda ok, but posting the same article +separately to several groups is not. Massive cross-posting (aka. +@dfn{velveeta}) is to be avoided at all costs, and you can even use the +@code{gnus-summary-mail-crosspost-complaint} command to complain about +excessive crossposting (@pxref{Summary Mail Commands}). + +@cindex cross-posting +@cindex Xref +@cindex @acronym{NOV} +One thing that may cause Gnus to not do the cross-posting thing +correctly is if you use an @acronym{NNTP} server that supports @sc{xover} +(which is very nice, because it speeds things up considerably) which +does not include the @code{Xref} header in its @acronym{NOV} lines. This is +Evil, but all too common, alas, alack. Gnus tries to Do The Right Thing +even with @sc{xover} by registering the @code{Xref} lines of all +articles you actually read, but if you kill the articles, or just mark +them as read without reading them, Gnus will not get a chance to snoop +the @code{Xref} lines out of these articles, and will be unable to use +the cross reference mechanism. + +@cindex LIST overview.fmt +@cindex overview.fmt +To check whether your @acronym{NNTP} server includes the @code{Xref} header +in its overview files, try @samp{telnet your.nntp.server nntp}, +@samp{MODE READER} on @code{inn} servers, and then say @samp{LIST +overview.fmt}. This may not work, but if it does, and the last line you +get does not read @samp{Xref:full}, then you should shout and whine at +your news admin until she includes the @code{Xref} header in the +overview files. + +If you want Gnus to get the @code{Xref}s right all the time, you have to +set @code{nntp-nov-is-evil} to @code{t}, which slows things down +considerably. Also @pxref{Slow/Expensive Connection}. + +C'est la vie. -@vindex gnus-mark-unpicked-articles-as-read -If @code{gnus-mark-unpicked-articles-as-read} is non-@code{nil}, mark -all unpicked articles as read. The default is @code{nil}. +For an alternative approach, @pxref{Duplicate Suppression}. -@vindex gnus-summary-pick-line-format -The summary line format in pick mode is slightly different from the -standard format. At the beginning of each line the line number is -displayed. The pick mode line format is controlled by the -@code{gnus-summary-pick-line-format} variable (@pxref{Formatting -Variables}). It accepts the same format specs that -@code{gnus-summary-line-format} does (@pxref{Summary Buffer Lines}). +@node Duplicate Suppression +@section Duplicate Suppression -@node Binary Groups -@subsection Binary Groups -@cindex binary groups +By default, Gnus tries to make sure that you don't have to read the same +article more than once by utilizing the crossposting mechanism +(@pxref{Crosspost Handling}). However, that simple and efficient +approach may not work satisfactory for some users for various +reasons. -@findex gnus-binary-mode -@kindex M-x gnus-binary-mode -If you spend much time in binary groups, you may grow tired of hitting -@kbd{X u}, @kbd{n}, @kbd{RET} all the time. @kbd{M-x gnus-binary-mode} -is a minor mode for summary buffers that makes all ordinary Gnus article -selection functions uudecode series of articles and display the result -instead of just displaying the articles the normal way. +@enumerate +@item +The @acronym{NNTP} server may fail to generate the @code{Xref} header. This +is evil and not very common. -@kindex g (Binary) -@findex gnus-binary-show-article -The only way, in fact, to see the actual articles is the @kbd{g} -command, when you have turned on this mode -(@code{gnus-binary-show-article}). +@item +The @acronym{NNTP} server may fail to include the @code{Xref} header in the +@file{.overview} data bases. This is evil and all too common, alas. -@vindex gnus-binary-mode-hook -@code{gnus-binary-mode-hook} is called in binary minor mode buffers. +@item +You may be reading the same group (or several related groups) from +different @acronym{NNTP} servers. +@item +You may be getting mail that duplicates articles posted to groups. +@end enumerate -@node Tree Display -@section Tree Display -@cindex trees +I'm sure there are other situations where @code{Xref} handling fails as +well, but these four are the most common situations. -@vindex gnus-use-trees -If you don't like the normal Gnus summary display, you might try setting -@code{gnus-use-trees} to @code{t}. This will create (by default) an -additional @dfn{tree buffer}. You can execute all summary mode commands -in the tree buffer. +If, and only if, @code{Xref} handling fails for you, then you may +consider switching on @dfn{duplicate suppression}. If you do so, Gnus +will remember the @code{Message-ID}s of all articles you have read or +otherwise marked as read, and then, as if by magic, mark them as read +all subsequent times you see them---in @emph{all} groups. Using this +mechanism is quite likely to be somewhat inefficient, but not overly +so. It's certainly preferable to reading the same articles more than +once. -There are a few variables to customize the tree display, of course: +Duplicate suppression is not a very subtle instrument. It's more like a +sledge hammer than anything else. It works in a very simple +fashion---if you have marked an article as read, it adds this Message-ID +to a cache. The next time it sees this Message-ID, it will mark the +article as read with the @samp{M} mark. It doesn't care what group it +saw the article in. @table @code -@item gnus-tree-mode-hook -@vindex gnus-tree-mode-hook -A hook called in all tree mode buffers. +@item gnus-suppress-duplicates +@vindex gnus-suppress-duplicates +If non-@code{nil}, suppress duplicates. -@item gnus-tree-mode-line-format -@vindex gnus-tree-mode-line-format -A format string for the mode bar in the tree mode buffers (@pxref{Mode -Line Formatting}). The default is @samp{Gnus: %%b %S %Z}. For a list -of valid specs, @pxref{Summary Buffer Mode Line}. +@item gnus-save-duplicate-list +@vindex gnus-save-duplicate-list +If non-@code{nil}, save the list of duplicates to a file. This will +make startup and shutdown take longer, so the default is @code{nil}. +However, this means that only duplicate articles read in a single Gnus +session are suppressed. -@item gnus-selected-tree-face -@vindex gnus-selected-tree-face -Face used for highlighting the selected article in the tree buffer. The -default is @code{modeline}. +@item gnus-duplicate-list-length +@vindex gnus-duplicate-list-length +This variable says how many @code{Message-ID}s to keep in the duplicate +suppression list. The default is 10000. -@item gnus-tree-line-format -@vindex gnus-tree-line-format -A format string for the tree nodes. The name is a bit of a misnomer, -though---it doesn't define a line, but just the node. The default value -is @samp{%(%[%3,3n%]%)}, which displays the first three characters of -the name of the poster. It is vital that all nodes are of the same -length, so you @emph{must} use @samp{%4,4n}-like specifiers. +@item gnus-duplicate-file +@vindex gnus-duplicate-file +The name of the file to store the duplicate suppression list in. The +default is @file{~/News/suppression}. +@end table -Valid specs are: +If you have a tendency to stop and start Gnus often, setting +@code{gnus-save-duplicate-list} to @code{t} is probably a good idea. If +you leave Gnus running for weeks on end, you may have it @code{nil}. On +the other hand, saving the list makes startup and shutdown much slower, +so that means that if you stop and start Gnus often, you should set +@code{gnus-save-duplicate-list} to @code{nil}. Uhm. I'll leave this up +to you to figure out, I think. -@table @samp -@item n -The name of the poster. -@item f -The @code{From} header. -@item N -The number of the article. -@item [ -The opening bracket. -@item ] -The closing bracket. -@item s -The subject. -@end table +@node Security +@section Security -@xref{Formatting Variables}. +Gnus is able to verify signed messages or decrypt encrypted messages. +The formats that are supported are @acronym{PGP}, @acronym{PGP/MIME} +and @acronym{S/MIME}, however you need some external programs to get +things to work: -Variables related to the display are: +@enumerate +@item +To handle @acronym{PGP} and @acronym{PGP/MIME} messages, you have to +install an OpenPGP implementation such as GnuPG. The Lisp interface +to GnuPG included with Emacs is called EasyPG (@pxref{Top, ,EasyPG, +epa, EasyPG Assistant user's manual}), but PGG (@pxref{Top, ,PGG, pgg, +PGG Manual}), and Mailcrypt are also supported. -@table @code -@item gnus-tree-brackets -@vindex gnus-tree-brackets -This is used for differentiating between ``real'' articles and -``sparse'' articles. The format is -@example -((@var{real-open} . @var{real-close}) - (@var{sparse-open} . @var{sparse-close}) - (@var{dummy-open} . @var{dummy-close})) -@end example -and the default is @code{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))}. +@item +To handle @acronym{S/MIME} message, you need to install OpenSSL. OpenSSL 0.9.6 +or newer is recommended. -@item gnus-tree-parent-child-edges -@vindex gnus-tree-parent-child-edges -This is a list that contains the characters used for connecting parent -nodes to their children. The default is @code{(?- ?\\ ?|)}. +@end enumerate -@end table +The variables that control security functionality on reading/composing +messages include: -@item gnus-tree-minimize-window -@vindex gnus-tree-minimize-window -If this variable is non-@code{nil}, Gnus will try to keep the tree -buffer as small as possible to allow more room for the other Gnus -windows. If this variable is a number, the tree buffer will never be -higher than that number. The default is @code{t}. Note that if you -have several windows displayed side-by-side in a frame and the tree -buffer is one of these, minimizing the tree window will also resize all -other windows displayed next to it. +@table @code +@item mm-verify-option +@vindex mm-verify-option +Option of verifying signed parts. @code{never}, not verify; +@code{always}, always verify; @code{known}, only verify known +protocols. Otherwise, ask user. -You may also wish to add the following hook to keep the window minimized -at all times: +@item mm-decrypt-option +@vindex mm-decrypt-option +Option of decrypting encrypted parts. @code{never}, no decryption; +@code{always}, always decrypt; @code{known}, only decrypt known +protocols. Otherwise, ask user. -@lisp -(add-hook 'gnus-configure-windows-hook - 'gnus-tree-perhaps-minimize) -@end lisp +@item mm-sign-option +@vindex mm-sign-option +Option of creating signed parts. @code{nil}, use default signing +keys; @code{guided}, ask user to select signing keys from the menu. -@item gnus-generate-tree-function -@vindex gnus-generate-tree-function -@findex gnus-generate-horizontal-tree -@findex gnus-generate-vertical-tree -The function that actually generates the thread tree. Two predefined -functions are available: @code{gnus-generate-horizontal-tree} and -@code{gnus-generate-vertical-tree} (which is the default). +@item mm-encrypt-option +@vindex mm-encrypt-option +Option of creating encrypted parts. @code{nil}, use the first +public-key matching the @samp{From:} header as the recipient; +@code{guided}, ask user to select recipient keys from the menu. -@end table +@item mml1991-use +@vindex mml1991-use +Symbol indicating elisp interface to OpenPGP implementation for +@acronym{PGP} messages. The default is @code{epg}, but @code{pgg}, +and @code{mailcrypt} are also supported although +deprecated. By default, Gnus uses the first available interface in +this order. -Here's an example from a horizontal tree buffer: +@item mml2015-use +@vindex mml2015-use +Symbol indicating elisp interface to OpenPGP implementation for +@acronym{PGP/MIME} messages. The default is @code{epg}, but +@code{pgg}, and @code{mailcrypt} are also supported +although deprecated. By default, Gnus uses the first available +interface in this order. -@example -@{***@}-(***)-[odd]-[Gun] - | \[Jan] - | \[odd]-[Eri] - | \(***)-[Eri] - | \[odd]-[Paa] - \[Bjo] - \[Gun] - \[Gun]-[Jor] -@end example +@end table -Here's the same thread displayed in a vertical tree buffer: +By default the buttons that display security information are not +shown, because they clutter reading the actual e-mail. You can type +@kbd{K b} manually to display the information. Use the +@code{gnus-buttonized-mime-types} and +@code{gnus-unbuttonized-mime-types} variables to control this +permanently. @ref{MIME Commands} for further details, and hints on +how to customize these variables to always display security +information. + +@cindex snarfing keys +@cindex importing PGP keys +@cindex PGP key ring import +Snarfing OpenPGP keys (i.e., importing keys from articles into your +key ring) is not supported explicitly through a menu item or command, +rather Gnus do detect and label keys as @samp{application/pgp-keys}, +allowing you to specify whatever action you think is appropriate +through the usual @acronym{MIME} infrastructure. You can use a +@file{~/.mailcap} entry (@pxref{mailcap, , mailcap, emacs-mime, The +Emacs MIME Manual}) such as the following to import keys using GNU +Privacy Guard when you click on the @acronym{MIME} button +(@pxref{Using MIME}). @example -@group -@{***@} - |--------------------------\-----\-----\ -(***) [Bjo] [Gun] [Gun] - |--\-----\-----\ | -[odd] [Jan] [odd] (***) [Jor] - | | |--\ -[Gun] [Eri] [Eri] [odd] - | - [Paa] -@end group +application/pgp-keys; gpg --import --interactive --verbose; needsterminal @end example +@noindent +This happens to also be the default action defined in +@code{mailcap-mime-data}. -If you're using horizontal trees, it might be nice to display the trees -side-by-side with the summary buffer. You could add something like the -following to your @file{~/.gnus.el} file: +More information on how to set things for sending outgoing signed and +encrypted messages up can be found in the message manual +(@pxref{Security, ,Security, message, Message Manual}). -@lisp -(setq gnus-use-trees t - gnus-generate-tree-function 'gnus-generate-horizontal-tree - gnus-tree-minimize-window nil) -(gnus-add-configuration - '(article - (vertical 1.0 - (horizontal 0.25 - (summary 0.75 point) - (tree 1.0)) - (article 1.0)))) -@end lisp +@node Mailing List +@section Mailing List +@cindex mailing list +@cindex RFC 2396 -@xref{Window Layout}. +@kindex A M (summary) +@findex gnus-mailing-list-insinuate +Gnus understands some mailing list fields of RFC 2369. To enable it, +add a @code{to-list} group parameter (@pxref{Group Parameters}), +possibly using @kbd{A M} (@code{gnus-mailing-list-insinuate}) in the +summary buffer. +That enables the following commands to the summary buffer: -@node Mail Group Commands -@section Mail Group Commands -@cindex mail group commands +@table @kbd -Some commands only make sense in mail groups. If these commands are -invalid in the current group, they will raise a hell and let you know. +@item C-c C-n h +@kindex C-c C-n h (Summary) +@findex gnus-mailing-list-help +Send a message to fetch mailing list help, if List-Help field exists. -All these commands (except the expiry and edit commands) use the -process/prefix convention (@pxref{Process/Prefix}). +@item C-c C-n s +@kindex C-c C-n s (Summary) +@findex gnus-mailing-list-subscribe +Send a message to subscribe the mailing list, if List-Subscribe field exists. -@table @kbd +@item C-c C-n u +@kindex C-c C-n u (Summary) +@findex gnus-mailing-list-unsubscribe +Send a message to unsubscribe the mailing list, if List-Unsubscribe +field exists. -@item B e -@kindex B e (Summary) -@findex gnus-summary-expire-articles -@cindex expiring mail -Run all expirable articles in the current group through the expiry -process (@code{gnus-summary-expire-articles}). That is, delete all -expirable articles in the group that have been around for a while. -(@pxref{Expiring Mail}). +@item C-c C-n p +@kindex C-c C-n p (Summary) +@findex gnus-mailing-list-post +Post to the mailing list, if List-Post field exists. -@item B C-M-e -@kindex B C-M-e (Summary) -@findex gnus-summary-expire-articles-now -@cindex expiring mail -Delete all the expirable articles in the group -(@code{gnus-summary-expire-articles-now}). This means that @strong{all} -articles eligible for expiry in the current group will -disappear forever into that big @file{/dev/null} in the sky. +@item C-c C-n o +@kindex C-c C-n o (Summary) +@findex gnus-mailing-list-owner +Send a message to the mailing list owner, if List-Owner field exists. -@item B DEL -@kindex B DEL (Summary) -@cindex deleting mail -@findex gnus-summary-delete-article -@c @icon{gnus-summary-mail-delete} -Delete the mail article. This is ``delete'' as in ``delete it from your -disk forever and ever, never to return again.'' Use with caution. -(@code{gnus-summary-delete-article}). +@item C-c C-n a +@kindex C-c C-n a (Summary) +@findex gnus-mailing-list-archive +Browse the mailing list archive, if List-Archive field exists. -@item B m -@kindex B m (Summary) -@cindex move mail -@findex gnus-summary-move-article -@vindex gnus-preserve-marks -Move the article from one mail group to another -(@code{gnus-summary-move-article}). Marks will be preserved if -@code{gnus-preserve-marks} is non-@code{nil} (which is the default). +@end table -@item B c -@kindex B c (Summary) -@cindex copy mail -@findex gnus-summary-copy-article -@c @icon{gnus-summary-mail-copy} -Copy the article from one group (mail group or not) to a mail group -(@code{gnus-summary-copy-article}). Marks will be preserved if -@code{gnus-preserve-marks} is non-@code{nil} (which is the default). -@item B B -@kindex B B (Summary) -@cindex crosspost mail -@findex gnus-summary-crosspost-article -Crosspost the current article to some other group -(@code{gnus-summary-crosspost-article}). This will create a new copy of -the article in the other group, and the Xref headers of the article will -be properly updated. +@node Article Buffer +@chapter Article Buffer +@cindex article buffer -@item B i -@kindex B i (Summary) -@findex gnus-summary-import-article -Import an arbitrary file into the current mail newsgroup -(@code{gnus-summary-import-article}). You will be prompted for a file -name, a @code{From} header and a @code{Subject} header. +The articles are displayed in the article buffer, of which there is only +one. All the summary buffers share the same article buffer unless you +tell Gnus otherwise. -@item B I -@kindex B I (Summary) -@findex gnus-summary-create-article -Create an empty article in the current mail newsgroups -(@code{gnus-summary-create-article}). You will be prompted for a -@code{From} header and a @code{Subject} header. +@menu +* Hiding Headers:: Deciding what headers should be displayed. +* Using MIME:: Pushing articles through @acronym{MIME} before reading them. +* HTML:: Reading @acronym{HTML} messages. +* Customizing Articles:: Tailoring the look of the articles. +* Article Keymap:: Keystrokes available in the article buffer. +* Misc Article:: Other stuff. +@end menu -@item B r -@kindex B r (Summary) -@findex gnus-summary-respool-article -@vindex gnus-summary-respool-default-method -Respool the mail article (@code{gnus-summary-respool-article}). -@code{gnus-summary-respool-default-method} will be used as the default -select method when respooling. This variable is @code{nil} by default, -which means that the current group select method will be used instead. -Marks will be preserved if @code{gnus-preserve-marks} is non-@code{nil} -(which is the default). -@item B w -@itemx e -@kindex B w (Summary) -@kindex e (Summary) -@findex gnus-summary-edit-article -@kindex C-c C-c (Article) -@findex gnus-summary-edit-article-done -Edit the current article (@code{gnus-summary-edit-article}). To finish -editing and make the changes permanent, type @kbd{C-c C-c} -(@code{gnus-summary-edit-article-done}). If you give a prefix to the -@kbd{C-c C-c} command, Gnus won't re-highlight the article. +@node Hiding Headers +@section Hiding Headers +@cindex hiding headers +@cindex deleting headers -@item B q -@kindex B q (Summary) -@findex gnus-summary-respool-query -If you want to re-spool an article, you might be curious as to what group -the article will end up in before you do the re-spooling. This command -will tell you (@code{gnus-summary-respool-query}). +The top section of each article is the @dfn{head}. (The rest is the +@dfn{body}, but you may have guessed that already.) -@item B t -@kindex B t (Summary) -@findex gnus-summary-respool-trace -Similarly, this command will display all fancy splitting patterns used -when respooling, if any (@code{gnus-summary-respool-trace}). +@vindex gnus-show-all-headers +There is a lot of useful information in the head: the name of the person +who wrote the article, the date it was written and the subject of the +article. That's well and nice, but there's also lots of information +most people do not want to see---what systems the article has passed +through before reaching you, the @code{Message-ID}, the +@code{References}, etc. ad nauseam---and you'll probably want to get rid +of some of those lines. If you want to keep all those lines in the +article buffer, you can set @code{gnus-show-all-headers} to @code{t}. -@item B p -@kindex B p (Summary) -@findex gnus-summary-article-posted-p -Some people have a tendency to send you ``courtesy'' copies when they -follow up to articles you have posted. These usually have a -@code{Newsgroups} header in them, but not always. This command -(@code{gnus-summary-article-posted-p}) will try to fetch the current -article from your news server (or rather, from -@code{gnus-refer-article-method} or @code{gnus-select-method}) and will -report back whether it found the article or not. Even if it says that -it didn't find the article, it may have been posted anyway---mail -propagation is much faster than news propagation, and the news copy may -just not have arrived yet. +Gnus provides you with two variables for sifting headers: -@item K E -@kindex K E (Summary) -@findex gnus-article-encrypt-body -@vindex gnus-article-encrypt-protocol -Encrypt the body of an article (@code{gnus-article-encrypt-body}). -The body is encrypted with the encryption protocol specified by the -variable @code{gnus-article-encrypt-protocol}. +@table @code -@end table +@item gnus-visible-headers +@vindex gnus-visible-headers +If this variable is non-@code{nil}, it should be a regular expression +that says what headers you wish to keep in the article buffer. All +headers that do not match this variable will be hidden. -@vindex gnus-move-split-methods -@cindex moving articles -If you move (or copy) articles regularly, you might wish to have Gnus -suggest where to put the articles. @code{gnus-move-split-methods} is a -variable that uses the same syntax as @code{gnus-split-methods} -(@pxref{Saving Articles}). You may customize that variable to create -suggestions you find reasonable. (Note that -@code{gnus-move-split-methods} uses group names where -@code{gnus-split-methods} uses file names.) +For instance, if you only want to see the name of the person who wrote +the article and the subject, you'd say: + +@lisp +(setq gnus-visible-headers "^From:\\|^Subject:") +@end lisp + +This variable can also be a list of regexps to match headers to +remain visible. + +@item gnus-ignored-headers +@vindex gnus-ignored-headers +This variable is the reverse of @code{gnus-visible-headers}. If this +variable is set (and @code{gnus-visible-headers} is @code{nil}), it +should be a regular expression that matches all lines that you want to +hide. All lines that do not match this variable will remain visible. + +For instance, if you just want to get rid of the @code{References} line +and the @code{Xref} line, you might say: @lisp -(setq gnus-move-split-methods - '(("^From:.*Lars Magne" "nnml:junk") - ("^Subject:.*gnus" "nnfolder:important") - (".*" "nnml:misc"))) +(setq gnus-ignored-headers "^References:\\|^Xref:") @end lisp +This variable can also be a list of regexps to match headers to +be removed. -@node Various Summary Stuff -@section Various Summary Stuff - -@menu -* Summary Group Information:: Information oriented commands. -* Searching for Articles:: Multiple article commands. -* Summary Generation Commands:: -* Really Various Summary Commands:: Those pesky non-conformant commands. -@end menu - -@table @code -@vindex gnus-summary-display-while-building -@item gnus-summary-display-while-building -If non-@code{nil}, show and update the summary buffer as it's being -built. If @code{t}, update the buffer after every line is inserted. -If the value is an integer, @var{n}, update the display every @var{n} -lines. The default is @code{nil}. +Note that if @code{gnus-visible-headers} is non-@code{nil}, this +variable will have no effect. -@vindex gnus-summary-display-arrow -@item gnus-summary-display-arrow -If non-@code{nil}, display an arrow in the fringe to indicate the -current article. +@end table -@vindex gnus-summary-mode-hook -@item gnus-summary-mode-hook -This hook is called when creating a summary mode buffer. +@vindex gnus-sorted-header-list +Gnus can also sort the headers for you. (It does this by default.) You +can control the sorting by setting the @code{gnus-sorted-header-list} +variable. It is a list of regular expressions that says in what order +the headers are to be displayed. -@vindex gnus-summary-generate-hook -@item gnus-summary-generate-hook -This is called as the last thing before doing the threading and the -generation of the summary buffer. It's quite convenient for customizing -the threading variables based on what data the newsgroup has. This hook -is called from the summary buffer after most summary buffer variables -have been set. +For instance, if you want the name of the author of the article first, +and then the subject, you might say something like: -@vindex gnus-summary-prepare-hook -@item gnus-summary-prepare-hook -It is called after the summary buffer has been generated. You might use -it to, for instance, highlight lines or modify the look of the buffer in -some other ungodly manner. I don't care. +@lisp +(setq gnus-sorted-header-list '("^From:" "^Subject:")) +@end lisp -@vindex gnus-summary-prepared-hook -@item gnus-summary-prepared-hook -A hook called as the very last thing after the summary buffer has been -generated. +Any headers that are to remain visible, but are not listed in this +variable, will be displayed in random order after all the headers listed in this variable. -@vindex gnus-summary-ignore-duplicates -@item gnus-summary-ignore-duplicates -When Gnus discovers two articles that have the same @code{Message-ID}, -it has to do something drastic. No articles are allowed to have the -same @code{Message-ID}, but this may happen when reading mail from some -sources. Gnus allows you to customize what happens with this variable. -If it is @code{nil} (which is the default), Gnus will rename the -@code{Message-ID} (for display purposes only) and display the article as -any other article. If this variable is @code{t}, it won't display the -article---it'll be as if it never existed. +@findex gnus-article-hide-boring-headers +@vindex gnus-boring-article-headers +You can hide further boring headers by setting +@code{gnus-treat-hide-boring-headers} to @code{head}. What this function +does depends on the @code{gnus-boring-article-headers} variable. It's a +list, but this list doesn't actually contain header names. Instead it +lists various @dfn{boring conditions} that Gnus can check and remove +from sight. -@vindex gnus-alter-articles-to-read-function -@item gnus-alter-articles-to-read-function -This function, which takes two parameters (the group name and the list -of articles to be selected), is called to allow the user to alter the -list of articles to be selected. +These conditions are: +@table @code +@item empty +Remove all empty headers. +@item followup-to +Remove the @code{Followup-To} header if it is identical to the +@code{Newsgroups} header. +@item reply-to +Remove the @code{Reply-To} header if it lists the same addresses as +the @code{From} header, or if the @code{broken-reply-to} group +parameter is set. +@item newsgroups +Remove the @code{Newsgroups} header if it only contains the current group +name. +@item to-address +Remove the @code{To} header if it only contains the address identical to +the current group's @code{to-address} parameter. +@item to-list +Remove the @code{To} header if it only contains the address identical to +the current group's @code{to-list} parameter. +@item cc-list +Remove the @code{Cc} header if it only contains the address identical to +the current group's @code{to-list} parameter. +@item date +Remove the @code{Date} header if the article is less than three days +old. +@item long-to +Remove the @code{To} and/or @code{Cc} header if it is very long. +@item many-to +Remove all @code{To} and/or @code{Cc} headers if there are more than one. +@end table -For instance, the following function adds the list of cached articles to -the list in one particular group: +To include these three elements, you could say something like: @lisp -(defun my-add-cached-articles (group articles) - (if (string= group "some.group") - (append gnus-newsgroup-cached articles) - articles)) +(setq gnus-boring-article-headers + '(empty followup-to reply-to)) @end lisp -@vindex gnus-newsgroup-variables -@item gnus-newsgroup-variables -A list of newsgroup (summary buffer) local variables, or cons of -variables and their default expressions to be evalled (when the default -values are not @code{nil}), that should be made global while the summary -buffer is active. - -Note: The default expressions will be evaluated (using function -@code{eval}) before assignment to the local variable rather than just -assigned to it. If the default expression is the symbol @code{global}, -that symbol will not be evaluated but the global value of the local -variable will be used instead. +This is also the default value for this variable. -These variables can be used to set variables in the group parameters -while still allowing them to affect operations done in other -buffers. For example: -@lisp -(setq gnus-newsgroup-variables - '(message-use-followup-to - (gnus-visible-headers . - "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^To:"))) -@end lisp +@node Using MIME +@section Using MIME +@cindex @acronym{MIME} -Also @pxref{Group Parameters}. +Mime is a standard for waving your hands through the air, aimlessly, +while people stand around yawning. -@vindex gnus-propagate-marks -@item gnus-propagate-marks -If non-@code{nil}, propagate marks to the backends for possible -storing. @xref{NNTP marks}, and friends, for a more fine-grained -sieve. +@acronym{MIME}, however, is a standard for encoding your articles, aimlessly, +while all newsreaders die of fear. -@end table +@acronym{MIME} may specify what character set the article uses, the encoding +of the characters, and it also makes it possible to embed pictures and +other naughty stuff in innocent-looking articles. +@vindex gnus-display-mime-function +@findex gnus-display-mime +Gnus pushes @acronym{MIME} articles through @code{gnus-display-mime-function} +to display the @acronym{MIME} parts. This is @code{gnus-display-mime} by +default, which creates a bundle of clickable buttons that can be used to +display, save and manipulate the @acronym{MIME} objects. -@node Summary Group Information -@subsection Summary Group Information +The following commands are available when you have placed point over a +@acronym{MIME} button: @table @kbd +@findex gnus-article-press-button +@item RET (Article) +@kindex RET (Article) +@itemx BUTTON-2 (Article) +Toggle displaying of the @acronym{MIME} object +(@code{gnus-article-press-button}). If built-in viewers can not display +the object, Gnus resorts to external viewers in the @file{mailcap} +files. If a viewer has the @samp{copiousoutput} specification, the +object is displayed inline. -@item H d -@kindex H d (Summary) -@findex gnus-summary-describe-group -Give a brief description of the current group -(@code{gnus-summary-describe-group}). If given a prefix, force -rereading the description from the server. +@findex gnus-mime-view-part +@item M-RET (Article) +@kindex M-RET (Article) +@itemx v (Article) +Prompt for a method, and then view the @acronym{MIME} object using this +method (@code{gnus-mime-view-part}). -@item H h -@kindex H h (Summary) -@findex gnus-summary-describe-briefly -Give an extremely brief description of the most important summary -keystrokes (@code{gnus-summary-describe-briefly}). +@findex gnus-mime-view-part-as-type +@item t (Article) +@kindex t (Article) +View the @acronym{MIME} object as if it were a different @acronym{MIME} media type +(@code{gnus-mime-view-part-as-type}). -@item H i -@kindex H i (Summary) -@findex gnus-info-find-node -Go to the Gnus info node (@code{gnus-info-find-node}). -@end table +@findex gnus-mime-view-part-as-charset +@item C (Article) +@kindex C (Article) +Prompt for a charset, and then view the @acronym{MIME} object using this +charset (@code{gnus-mime-view-part-as-charset}). + +@findex gnus-mime-save-part +@item o (Article) +@kindex o (Article) +Prompt for a file name, and then save the @acronym{MIME} object +(@code{gnus-mime-save-part}). +@findex gnus-mime-save-part-and-strip +@item C-o (Article) +@kindex C-o (Article) +Prompt for a file name, then save the @acronym{MIME} object and strip it from +the article. Then proceed to article editing, where a reasonable +suggestion is being made on how the altered article should look +like. The stripped @acronym{MIME} object will be referred via the +message/external-body @acronym{MIME} type. +(@code{gnus-mime-save-part-and-strip}). -@node Searching for Articles -@subsection Searching for Articles +@findex gnus-mime-replace-part +@item r (Article) +@kindex r (Article) +Prompt for a file name, replace the @acronym{MIME} object with an +external body refering to the file via the message/external-body +@acronym{MIME} type. (@code{gnus-mime-replace-part}). -@table @kbd +@findex gnus-mime-delete-part +@item d (Article) +@kindex d (Article) +Delete the @acronym{MIME} object from the article and replace it with some +information about the removed @acronym{MIME} object +(@code{gnus-mime-delete-part}). + +@c FIXME: gnus-auto-select-part should be documented here + +@findex gnus-mime-copy-part +@item c (Article) +@kindex c (Article) +Copy the @acronym{MIME} object to a fresh buffer and display this buffer +(@code{gnus-mime-copy-part}). If given a prefix, copy the raw contents +without decoding. If given a numerical prefix, you can do semi-manual +charset stuff (see @code{gnus-summary-show-article-charset-alist} in +@ref{Paging the Article}). Compressed files like @file{.gz} and +@file{.bz2} are automatically decompressed if +@code{auto-compression-mode} is enabled (@pxref{Compressed Files,, +Accessing Compressed Files, emacs, The Emacs Editor}). -@item M-s -@kindex M-s (Summary) -@findex gnus-summary-search-article-forward -Search through all subsequent (raw) articles for a regexp -(@code{gnus-summary-search-article-forward}). +@findex gnus-mime-print-part +@item p (Article) +@kindex p (Article) +Print the @acronym{MIME} object (@code{gnus-mime-print-part}). This +command respects the @samp{print=} specifications in the +@file{.mailcap} file. -@item M-r -@kindex M-r (Summary) -@findex gnus-summary-search-article-backward -Search through all previous (raw) articles for a regexp -(@code{gnus-summary-search-article-backward}). +@findex gnus-mime-inline-part +@item i (Article) +@kindex i (Article) +Insert the contents of the @acronym{MIME} object into the buffer +(@code{gnus-mime-inline-part}) as @samp{text/plain}. If given a prefix, insert +the raw contents without decoding. If given a numerical prefix, you can +do semi-manual charset stuff (see +@code{gnus-summary-show-article-charset-alist} in @ref{Paging the +Article}). Compressed files like @file{.gz} and @file{.bz2} are +automatically decompressed depending on @code{jka-compr} regardless of +@code{auto-compression-mode} (@pxref{Compressed Files,, Accessing +Compressed Files, emacs, The Emacs Editor}). -@item M-S -@kindex M-S (Summary) -@findex gnus-summary-repeat-search-article-forward -Repeat the previous search forwards -(@code{gnus-summary-repeat-search-article-forward}). +@findex gnus-mime-view-part-internally +@item E (Article) +@kindex E (Article) +View the @acronym{MIME} object with an internal viewer. If no internal +viewer is available, use an external viewer +(@code{gnus-mime-view-part-internally}). -@item M-R -@kindex M-R (Summary) -@findex gnus-summary-repeat-search-article-backward -Repeat the previous search backwards -(@code{gnus-summary-repeat-search-article-backward}). +@findex gnus-mime-view-part-externally +@item e (Article) +@kindex e (Article) +View the @acronym{MIME} object with an external viewer. +(@code{gnus-mime-view-part-externally}). -@item & -@kindex & (Summary) -@findex gnus-summary-execute-command -This command will prompt you for a header, a regular expression to match -on this field, and a command to be executed if the match is made -(@code{gnus-summary-execute-command}). If the header is an empty -string, the match is done on the entire article. If given a prefix, -search backward instead. +@findex gnus-mime-pipe-part +@item | (Article) +@kindex | (Article) +Output the @acronym{MIME} object to a process (@code{gnus-mime-pipe-part}). -For instance, @kbd{& RET some.*string RET #} will put the process mark on -all articles that have heads or bodies that match @samp{some.*string}. +@findex gnus-mime-action-on-part +@item . (Article) +@kindex . (Article) +Interactively run an action on the @acronym{MIME} object +(@code{gnus-mime-action-on-part}). -@item M-& -@kindex M-& (Summary) -@findex gnus-summary-universal-argument -Perform any operation on all articles that have been marked with -the process mark (@code{gnus-summary-universal-argument}). @end table -@node Summary Generation Commands -@subsection Summary Generation Commands - -@table @kbd +Gnus will display some @acronym{MIME} objects automatically. The way Gnus +determines which parts to do this with is described in the Emacs +@acronym{MIME} manual. -@item Y g -@kindex Y g (Summary) -@findex gnus-summary-prepare -Regenerate the current summary buffer (@code{gnus-summary-prepare}). +It might be best to just use the toggling functions from the article +buffer to avoid getting nasty surprises. (For instance, you enter the +group @samp{alt.sing-a-long} and, before you know it, @acronym{MIME} has +decoded the sound file in the article and some horrible sing-a-long song +comes screaming out your speakers, and you can't find the volume button, +because there isn't one, and people are starting to look at you, and you +try to stop the program, but you can't, and you can't find the program +to control the volume, and everybody else in the room suddenly decides +to look at you disdainfully, and you'll feel rather stupid.) -@item Y c -@kindex Y c (Summary) -@findex gnus-summary-insert-cached-articles -Pull all cached articles (for the current group) into the summary buffer -(@code{gnus-summary-insert-cached-articles}). +Any similarity to real events and people is purely coincidental. Ahem. -@item Y d -@kindex Y d (Summary) -@findex gnus-summary-insert-dormant-articles -Pull all dormant articles (for the current group) into the summary buffer -(@code{gnus-summary-insert-dormant-articles}). +Also @pxref{MIME Commands}. -@item Y t -@kindex Y t (Summary) -@findex gnus-summary-insert-ticked-articles -Pull all ticked articles (for the current group) into the summary buffer -(@code{gnus-summary-insert-ticked-articles}). -@end table +@node HTML +@section @acronym{HTML} +@cindex @acronym{HTML} +If you have @code{w3m} installed on your system, Gnus can display +@acronym{HTML} articles in the article buffer. There are many Gnus +add-ons for doing this, using various approaches, but there's one +(sort of) built-in method that's used by default. -@node Really Various Summary Commands -@subsection Really Various Summary Commands +For a complete overview, consult @xref{Display Customization, +,Display Customization, emacs-mime, The Emacs MIME Manual}. This +section only describes the default method. -@table @kbd +@table @code +@item mm-text-html-renderer +@vindex mm-text-html-renderer +If set to @code{gnus-article-html}, Gnus will use the built-in method, +that's based on @code{w3m}. -@item A D -@itemx C-d -@kindex C-d (Summary) -@kindex A D (Summary) -@findex gnus-summary-enter-digest-group -If the current article is a collection of other articles (for instance, -a digest), you might use this command to enter a group based on the that -article (@code{gnus-summary-enter-digest-group}). Gnus will try to -guess what article type is currently displayed unless you give a prefix -to this command, which forces a ``digest'' interpretation. Basically, -whenever you see a message that is a collection of other messages of -some format, you @kbd{C-d} and read these messages in a more convenient -fashion. +@item gnus-blocked-images +@vindex gnus-blocked-images +External images that have @acronym{URL}s that match this regexp won't +be fetched and displayed. For instance, do block all @acronym{URL}s +that have the string ``ads'' in them, do the following: -@vindex gnus-auto-select-on-ephemeral-exit -The variable @code{gnus-auto-select-on-ephemeral-exit} controls what -article should be selected after exiting a digest group. Valid values -include: +@lisp +(setq gnus-blocked-images "ads") +@end lisp -@table @code -@item next -Select the next article. +This can also be a function to be evaluated. If so, it will be +called with the group name as the parameter. The default value is +@code{gnus-block-private-groups}, which will return @samp{"."} for +anything that isn't a newsgroup. This means that no external images +will be fetched as a result of reading mail, so that nobody can use +web bugs (and the like) to track whether you've read email. -@item next-unread -Select the next unread article. +Also @pxref{Misc Article} for @code{gnus-inhibit-images}. -@item next-noselect -Move the cursor to the next article. This is the default. +@item gnus-html-cache-directory +@vindex gnus-html-cache-directory +Gnus will download and cache images according to how +@code{gnus-blocked-images} is set. These images will be stored in +this directory. -@item next-unread-noselect -Move the cursor to the next unread article. -@end table +@item gnus-html-cache-size +@vindex gnus-html-cache-size +When @code{gnus-html-cache-size} bytes have been used in that +directory, the oldest files will be deleted. The default is 500MB. -If it has any other value or there is no next (unread) article, the -article selected before entering to the digest group will appear. +@item gnus-html-frame-width +@vindex gnus-html-frame-width +The width to use when rendering HTML. The default is 70. -@item C-M-d -@kindex C-M-d (Summary) -@findex gnus-summary-read-document -This command is very similar to the one above, but lets you gather -several documents into one biiig group -(@code{gnus-summary-read-document}). It does this by opening several -@code{nndoc} groups for each document, and then opening an -@code{nnvirtual} group on top of these @code{nndoc} groups. This -command understands the process/prefix convention -(@pxref{Process/Prefix}). +@item gnus-max-image-proportion +@vindex gnus-max-image-proportion +How big pictures displayed are in relation to the window they're in. +A value of 0.7 (the default) means that they are allowed to take up +70% of the width and height of the window. If they are larger than +this, and Emacs supports it, then the images will be rescaled down to +fit these criteria. -@item C-t -@kindex C-t (Summary) -@findex gnus-summary-toggle-truncation -Toggle truncation of summary lines -(@code{gnus-summary-toggle-truncation}). This will probably confuse the -line centering function in the summary buffer, so it's not a good idea -to have truncation switched off while reading articles. +@end table -@item = -@kindex = (Summary) -@findex gnus-summary-expand-window -Expand the summary buffer window (@code{gnus-summary-expand-window}). -If given a prefix, force an @code{article} window configuration. +To use this, make sure that you have @code{w3m} and @code{curl} +installed. If you have, then Gnus should display @acronym{HTML} +automatically. -@item C-M-e -@kindex C-M-e (Summary) -@findex gnus-summary-edit-parameters -Edit the group parameters (@pxref{Group Parameters}) of the current -group (@code{gnus-summary-edit-parameters}). -@item C-M-a -@kindex C-M-a (Summary) -@findex gnus-summary-customize-parameters -Customize the group parameters (@pxref{Group Parameters}) of the current -group (@code{gnus-summary-customize-parameters}). -@end table +@node Customizing Articles +@section Customizing Articles +@cindex article customization +A slew of functions for customizing how the articles are to look like +exist. You can call these functions interactively +(@pxref{Article Washing}), or you can have them +called automatically when you select the articles. -@node Exiting the Summary Buffer -@section Exiting the Summary Buffer -@cindex summary exit -@cindex exiting groups +To have them called automatically, you should set the corresponding +``treatment'' variable. For instance, to have headers hidden, you'd set +@code{gnus-treat-hide-headers}. Below is a list of variables that can +be set, but first we discuss the values these variables can have. -Exiting from the summary buffer will normally update all info on the -group and return you to the group buffer. +Note: Some values, while valid, make little sense. Check the list below +for sensible values. -@table @kbd +@enumerate +@item +@code{nil}: Don't do this treatment. -@item Z Z -@itemx Z Q -@itemx q -@kindex Z Z (Summary) -@kindex Z Q (Summary) -@kindex q (Summary) -@findex gnus-summary-exit -@vindex gnus-summary-exit-hook -@vindex gnus-summary-prepare-exit-hook -@vindex gnus-group-no-more-groups-hook -@c @icon{gnus-summary-exit} -Exit the current group and update all information on the group -(@code{gnus-summary-exit}). @code{gnus-summary-prepare-exit-hook} is -called before doing much of the exiting, which calls -@code{gnus-summary-expire-articles} by default. -@code{gnus-summary-exit-hook} is called after finishing the exit -process. @code{gnus-group-no-more-groups-hook} is run when returning to -group mode having no more (unread) groups. +@item +@code{t}: Do this treatment on all body parts. -@item Z E -@itemx Q -@kindex Z E (Summary) -@kindex Q (Summary) -@findex gnus-summary-exit-no-update -Exit the current group without updating any information on the group -(@code{gnus-summary-exit-no-update}). +@item +@code{head}: Do the treatment on the headers. -@item Z c -@itemx c -@kindex Z c (Summary) -@kindex c (Summary) -@findex gnus-summary-catchup-and-exit -@c @icon{gnus-summary-catchup-and-exit} -Mark all unticked articles in the group as read and then exit -(@code{gnus-summary-catchup-and-exit}). +@item +@code{first}: Do this treatment on the first body part. -@item Z C -@kindex Z C (Summary) -@findex gnus-summary-catchup-all-and-exit -Mark all articles, even the ticked ones, as read and then exit -(@code{gnus-summary-catchup-all-and-exit}). +@item +@code{last}: Do this treatment on the last body part. -@item Z n -@kindex Z n (Summary) -@findex gnus-summary-catchup-and-goto-next-group -Mark all articles as read and go to the next group -(@code{gnus-summary-catchup-and-goto-next-group}). +@item +An integer: Do this treatment on all body parts that have a length less +than this number. -@item Z p -@kindex Z p (Summary) -@findex gnus-summary-catchup-and-goto-prev-group -Mark all articles as read and go to the previous group -(@code{gnus-summary-catchup-and-goto-prev-group}). +@item +A list of strings: Do this treatment on all body parts that are in +articles that are read in groups that have names that match one of the +regexps in the list. -@item Z R -@itemx C-x C-s -@kindex Z R (Summary) -@kindex C-x C-s (Summary) -@findex gnus-summary-reselect-current-group -Exit this group, and then enter it again -(@code{gnus-summary-reselect-current-group}). If given a prefix, select -all articles, both read and unread. +@item +A list where the first element is not a string: -@item Z G -@itemx M-g -@kindex Z G (Summary) -@kindex M-g (Summary) -@findex gnus-summary-rescan-group -@c @icon{gnus-summary-mail-get} -Exit the group, check for new articles in the group, and select the -group (@code{gnus-summary-rescan-group}). If given a prefix, select all -articles, both read and unread. +The list is evaluated recursively. The first element of the list is a +predicate. The following predicates are recognized: @code{or}, +@code{and}, @code{not} and @code{typep}. Here's an example: -@item Z N -@kindex Z N (Summary) -@findex gnus-summary-next-group -Exit the group and go to the next group -(@code{gnus-summary-next-group}). +@lisp +(or last + (typep "text/x-vcard")) +@end lisp -@item Z P -@kindex Z P (Summary) -@findex gnus-summary-prev-group -Exit the group and go to the previous group -(@code{gnus-summary-prev-group}). +@end enumerate -@item Z s -@kindex Z s (Summary) -@findex gnus-summary-save-newsrc -Save the current number of read/marked articles in the dribble buffer -and then save the dribble buffer (@code{gnus-summary-save-newsrc}). If -given a prefix, also save the @file{.newsrc} file(s). Using this -command will make exit without updating (the @kbd{Q} command) worthless. -@end table +You may have noticed that the word @dfn{part} is used here. This refers +to the fact that some messages are @acronym{MIME} multipart articles that may +be divided into several parts. Articles that are not multiparts are +considered to contain just a single part. -@vindex gnus-exit-group-hook -@code{gnus-exit-group-hook} is called when you exit the current group -with an ``updating'' exit. For instance @kbd{Q} -(@code{gnus-summary-exit-no-update}) does not call this hook. +@vindex gnus-article-treat-types +Are the treatments applied to all sorts of multipart parts? Yes, if you +want to, but by default, only @samp{text/plain} parts are given the +treatment. This is controlled by the @code{gnus-article-treat-types} +variable, which is a list of regular expressions that are matched to the +type of the part. This variable is ignored if the value of the +controlling variable is a predicate list, as described above. -@findex gnus-summary-wake-up-the-dead -@findex gnus-dead-summary-mode -@vindex gnus-kill-summary-on-exit -If you're in the habit of exiting groups, and then changing your mind -about it, you might set @code{gnus-kill-summary-on-exit} to @code{nil}. -If you do that, Gnus won't kill the summary buffer when you exit it. -(Quelle surprise!) Instead it will change the name of the buffer to -something like @samp{*Dead Summary ... *} and install a minor mode -called @code{gnus-dead-summary-mode}. Now, if you switch back to this -buffer, you'll find that all keys are mapped to a function called -@code{gnus-summary-wake-up-the-dead}. So tapping any keys in a dead -summary buffer will result in a live, normal summary buffer. +@ifinfo +@c Avoid sort of redundant entries in the same section for the printed +@c manual, but add them in info to allow `i gnus-treat-foo-bar RET' or +@c `i foo-bar'. +@vindex gnus-treat-buttonize +@vindex gnus-treat-buttonize-head +@vindex gnus-treat-capitalize-sentences +@vindex gnus-treat-overstrike +@vindex gnus-treat-strip-cr +@vindex gnus-treat-strip-headers-in-body +@vindex gnus-treat-strip-leading-blank-lines +@vindex gnus-treat-strip-multiple-blank-lines +@vindex gnus-treat-strip-pem +@vindex gnus-treat-strip-trailing-blank-lines +@vindex gnus-treat-unsplit-urls +@vindex gnus-treat-wash-html +@vindex gnus-treat-date-english +@vindex gnus-treat-date-iso8601 +@vindex gnus-treat-date-lapsed +@vindex gnus-treat-date-local +@vindex gnus-treat-date-original +@vindex gnus-treat-date-user-defined +@vindex gnus-treat-date-ut +@vindex gnus-treat-from-picon +@vindex gnus-treat-mail-picon +@vindex gnus-treat-newsgroups-picon +@vindex gnus-treat-from-gravatar +@vindex gnus-treat-mail-gravatar +@vindex gnus-treat-display-smileys +@vindex gnus-treat-body-boundary +@vindex gnus-treat-display-x-face +@vindex gnus-treat-display-face +@vindex gnus-treat-emphasize +@vindex gnus-treat-fill-article +@vindex gnus-treat-fill-long-lines +@vindex gnus-treat-hide-boring-headers +@vindex gnus-treat-hide-citation +@vindex gnus-treat-hide-citation-maybe +@vindex gnus-treat-hide-headers +@vindex gnus-treat-hide-signature +@vindex gnus-treat-strip-banner +@vindex gnus-treat-strip-list-identifiers +@vindex gnus-treat-highlight-citation +@vindex gnus-treat-highlight-headers +@vindex gnus-treat-highlight-signature +@vindex gnus-treat-play-sounds +@vindex gnus-treat-x-pgp-sig +@vindex gnus-treat-unfold-headers +@vindex gnus-treat-fold-headers +@vindex gnus-treat-fold-newsgroups +@vindex gnus-treat-leading-whitespace +@end ifinfo -There will never be more than one dead summary buffer at any one time. +The following treatment options are available. The easiest way to +customize this is to examine the @code{gnus-article-treat} customization +group. Values in parenthesis are suggested sensible values. Others are +possible but those listed are probably sufficient for most people. -@vindex gnus-use-cross-reference -The data on the current group will be updated (which articles you have -read, which articles you have replied to, etc.) when you exit the -summary buffer. If the @code{gnus-use-cross-reference} variable is -@code{t} (which is the default), articles that are cross-referenced to -this group and are marked as read, will also be marked as read in the -other subscribed groups they were cross-posted to. If this variable is -neither @code{nil} nor @code{t}, the article will be marked as read in -both subscribed and unsubscribed groups (@pxref{Crosspost Handling}). +@table @code +@item gnus-treat-buttonize (t, integer) +@item gnus-treat-buttonize-head (head) +@xref{Article Buttons}. -@node Crosspost Handling -@section Crosspost Handling +@item gnus-treat-capitalize-sentences (t, integer) +@item gnus-treat-overstrike (t, integer) +@item gnus-treat-strip-cr (t, integer) +@item gnus-treat-strip-headers-in-body (t, integer) +@item gnus-treat-strip-leading-blank-lines (t, first, integer) +@item gnus-treat-strip-multiple-blank-lines (t, integer) +@item gnus-treat-strip-pem (t, last, integer) +@item gnus-treat-strip-trailing-blank-lines (t, last, integer) +@item gnus-treat-unsplit-urls (t, integer) +@item gnus-treat-wash-html (t, integer) -@cindex velveeta -@cindex spamming -Marking cross-posted articles as read ensures that you'll never have to -read the same article more than once. Unless, of course, somebody has -posted it to several groups separately. Posting the same article to -several groups (not cross-posting) is called @dfn{spamming}, and you are -by law required to send nasty-grams to anyone who perpetrates such a -heinous crime. +@xref{Article Washing}. -Remember: Cross-posting is kinda ok, but posting the same article -separately to several groups is not. Massive cross-posting (aka. -@dfn{velveeta}) is to be avoided at all costs, and you can even use the -@code{gnus-summary-mail-crosspost-complaint} command to complain about -excessive crossposting (@pxref{Summary Mail Commands}). +@item gnus-treat-date-english (head) +@item gnus-treat-date-iso8601 (head) +@item gnus-treat-date-lapsed (head) +@item gnus-treat-date-local (head) +@item gnus-treat-date-original (head) +@item gnus-treat-date-user-defined (head) +@item gnus-treat-date-ut (head) -@cindex cross-posting -@cindex Xref -@cindex @acronym{NOV} -One thing that may cause Gnus to not do the cross-posting thing -correctly is if you use an @acronym{NNTP} server that supports @sc{xover} -(which is very nice, because it speeds things up considerably) which -does not include the @code{Xref} header in its @acronym{NOV} lines. This is -Evil, but all too common, alas, alack. Gnus tries to Do The Right Thing -even with @sc{xover} by registering the @code{Xref} lines of all -articles you actually read, but if you kill the articles, or just mark -them as read without reading them, Gnus will not get a chance to snoop -the @code{Xref} lines out of these articles, and will be unable to use -the cross reference mechanism. +@xref{Article Date}. -@cindex LIST overview.fmt -@cindex overview.fmt -To check whether your @acronym{NNTP} server includes the @code{Xref} header -in its overview files, try @samp{telnet your.nntp.server nntp}, -@samp{MODE READER} on @code{inn} servers, and then say @samp{LIST -overview.fmt}. This may not work, but if it does, and the last line you -get does not read @samp{Xref:full}, then you should shout and whine at -your news admin until she includes the @code{Xref} header in the -overview files. +@item gnus-treat-from-picon (head) +@item gnus-treat-mail-picon (head) +@item gnus-treat-newsgroups-picon (head) -If you want Gnus to get the @code{Xref}s right all the time, you have to -set @code{nntp-nov-is-evil} to @code{t}, which slows things down -considerably. Also @pxref{Slow/Expensive Connection}. +@xref{Picons}. -C'est la vie. +@item gnus-treat-from-gravatar (head) +@item gnus-treat-mail-gravatar (head) -For an alternative approach, @pxref{Duplicate Suppression}. +@xref{Gravatars}. +@item gnus-treat-display-smileys (t, integer) -@node Duplicate Suppression -@section Duplicate Suppression +@item gnus-treat-body-boundary (head) -By default, Gnus tries to make sure that you don't have to read the same -article more than once by utilizing the crossposting mechanism -(@pxref{Crosspost Handling}). However, that simple and efficient -approach may not work satisfactory for some users for various -reasons. +@vindex gnus-body-boundary-delimiter +Adds a delimiter between header and body, the string used as delimiter +is controlled by @code{gnus-body-boundary-delimiter}. -@enumerate -@item -The @acronym{NNTP} server may fail to generate the @code{Xref} header. This -is evil and not very common. +@xref{Smileys}. -@item -The @acronym{NNTP} server may fail to include the @code{Xref} header in the -@file{.overview} data bases. This is evil and all too common, alas. +@vindex gnus-treat-display-x-face +@item gnus-treat-display-x-face (head) -@item -You may be reading the same group (or several related groups) from -different @acronym{NNTP} servers. +@xref{X-Face}. -@item -You may be getting mail that duplicates articles posted to groups. -@end enumerate +@vindex gnus-treat-display-face +@item gnus-treat-display-face (head) -I'm sure there are other situations where @code{Xref} handling fails as -well, but these four are the most common situations. +@xref{Face}. -If, and only if, @code{Xref} handling fails for you, then you may -consider switching on @dfn{duplicate suppression}. If you do so, Gnus -will remember the @code{Message-ID}s of all articles you have read or -otherwise marked as read, and then, as if by magic, mark them as read -all subsequent times you see them---in @emph{all} groups. Using this -mechanism is quite likely to be somewhat inefficient, but not overly -so. It's certainly preferable to reading the same articles more than -once. +@vindex gnus-treat-emphasize +@item gnus-treat-emphasize (t, head, integer) +@vindex gnus-treat-fill-article +@item gnus-treat-fill-article (t, integer) +@vindex gnus-treat-fill-long-lines +@item gnus-treat-fill-long-lines (t, integer) +@vindex gnus-treat-hide-boring-headers +@item gnus-treat-hide-boring-headers (head) +@vindex gnus-treat-hide-citation +@item gnus-treat-hide-citation (t, integer) +@vindex gnus-treat-hide-citation-maybe +@item gnus-treat-hide-citation-maybe (t, integer) +@vindex gnus-treat-hide-headers +@item gnus-treat-hide-headers (head) +@vindex gnus-treat-hide-signature +@item gnus-treat-hide-signature (t, last) +@vindex gnus-treat-strip-banner +@item gnus-treat-strip-banner (t, last) +@vindex gnus-treat-strip-list-identifiers +@item gnus-treat-strip-list-identifiers (head) -Duplicate suppression is not a very subtle instrument. It's more like a -sledge hammer than anything else. It works in a very simple -fashion---if you have marked an article as read, it adds this Message-ID -to a cache. The next time it sees this Message-ID, it will mark the -article as read with the @samp{M} mark. It doesn't care what group it -saw the article in. +@xref{Article Hiding}. -@table @code -@item gnus-suppress-duplicates -@vindex gnus-suppress-duplicates -If non-@code{nil}, suppress duplicates. +@vindex gnus-treat-highlight-citation +@item gnus-treat-highlight-citation (t, integer) +@vindex gnus-treat-highlight-headers +@item gnus-treat-highlight-headers (head) +@vindex gnus-treat-highlight-signature +@item gnus-treat-highlight-signature (t, last, integer) -@item gnus-save-duplicate-list -@vindex gnus-save-duplicate-list -If non-@code{nil}, save the list of duplicates to a file. This will -make startup and shutdown take longer, so the default is @code{nil}. -However, this means that only duplicate articles read in a single Gnus -session are suppressed. +@xref{Article Highlighting}. -@item gnus-duplicate-list-length -@vindex gnus-duplicate-list-length -This variable says how many @code{Message-ID}s to keep in the duplicate -suppression list. The default is 10000. +@vindex gnus-treat-play-sounds +@item gnus-treat-play-sounds +@item gnus-treat-ansi-sequences (t) +@vindex gnus-treat-x-pgp-sig +@item gnus-treat-x-pgp-sig (head) -@item gnus-duplicate-file -@vindex gnus-duplicate-file -The name of the file to store the duplicate suppression list in. The -default is @file{~/News/suppression}. -@end table +@vindex gnus-treat-unfold-headers +@item gnus-treat-unfold-headers (head) +@vindex gnus-treat-fold-headers +@item gnus-treat-fold-headers (head) +@vindex gnus-treat-fold-newsgroups +@item gnus-treat-fold-newsgroups (head) +@vindex gnus-treat-leading-whitespace +@item gnus-treat-leading-whitespace (head) -If you have a tendency to stop and start Gnus often, setting -@code{gnus-save-duplicate-list} to @code{t} is probably a good idea. If -you leave Gnus running for weeks on end, you may have it @code{nil}. On -the other hand, saving the list makes startup and shutdown much slower, -so that means that if you stop and start Gnus often, you should set -@code{gnus-save-duplicate-list} to @code{nil}. Uhm. I'll leave this up -to you to figure out, I think. +@xref{Article Header}. -@node Security -@section Security -Gnus is able to verify signed messages or decrypt encrypted messages. -The formats that are supported are @acronym{PGP}, @acronym{PGP/MIME} -and @acronym{S/MIME}, however you need some external programs to get -things to work: +@end table -@enumerate -@item -To handle @acronym{PGP} and @acronym{PGP/MIME} messages, you have to -install an OpenPGP implementation such as GnuPG. The Lisp interface -to GnuPG included with Emacs is called EasyPG (@pxref{Top, ,EasyPG, -epa, EasyPG Assistant user's manual}), but PGG (@pxref{Top, ,PGG, pgg, -PGG Manual}), and Mailcrypt are also supported. +@vindex gnus-part-display-hook +You can, of course, write your own functions to be called from +@code{gnus-part-display-hook}. The functions are called narrowed to the +part, and you can do anything you like, pretty much. There is no +information that you have to keep in the buffer---you can change +everything. -@item -To handle @acronym{S/MIME} message, you need to install OpenSSL. OpenSSL 0.9.6 -or newer is recommended. -@end enumerate +@node Article Keymap +@section Article Keymap -The variables that control security functionality on reading/composing -messages include: +Most of the keystrokes in the summary buffer can also be used in the +article buffer. They should behave as if you typed them in the summary +buffer, which means that you don't actually have to have a summary +buffer displayed while reading. You can do it all from the article +buffer. -@table @code -@item mm-verify-option -@vindex mm-verify-option -Option of verifying signed parts. @code{never}, not verify; -@code{always}, always verify; @code{known}, only verify known -protocols. Otherwise, ask user. +@kindex v (Article) +@cindex keys, reserved for users (Article) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. -@item mm-decrypt-option -@vindex mm-decrypt-option -Option of decrypting encrypted parts. @code{never}, no decryption; -@code{always}, always decrypt; @code{known}, only decrypt known -protocols. Otherwise, ask user. +A few additional keystrokes are available: -@item mm-sign-option -@vindex mm-sign-option -Option of creating signed parts. @code{nil}, use default signing -keys; @code{guided}, ask user to select signing keys from the menu. +@table @kbd -@item mm-encrypt-option -@vindex mm-encrypt-option -Option of creating encrypted parts. @code{nil}, use the first -public-key matching the @samp{From:} header as the recipient; -@code{guided}, ask user to select recipient keys from the menu. +@item SPACE +@kindex SPACE (Article) +@findex gnus-article-next-page +Scroll forwards one page (@code{gnus-article-next-page}). +This is exactly the same as @kbd{h SPACE h}. -@item mml1991-use -@vindex mml1991-use -Symbol indicating elisp interface to OpenPGP implementation for -@acronym{PGP} messages. The default is @code{epg}, but @code{pgg}, -and @code{mailcrypt} are also supported although -deprecated. By default, Gnus uses the first available interface in -this order. +@item DEL +@kindex DEL (Article) +@findex gnus-article-prev-page +Scroll backwards one page (@code{gnus-article-prev-page}). +This is exactly the same as @kbd{h DEL h}. -@item mml2015-use -@vindex mml2015-use -Symbol indicating elisp interface to OpenPGP implementation for -@acronym{PGP/MIME} messages. The default is @code{epg}, but -@code{pgg}, and @code{mailcrypt} are also supported -although deprecated. By default, Gnus uses the first available -interface in this order. +@item C-c ^ +@kindex C-c ^ (Article) +@findex gnus-article-refer-article +If point is in the neighborhood of a @code{Message-ID} and you press +@kbd{C-c ^}, Gnus will try to get that article from the server +(@code{gnus-article-refer-article}). -@end table +@item C-c C-m +@kindex C-c C-m (Article) +@findex gnus-article-mail +Send a reply to the address near point (@code{gnus-article-mail}). If +given a prefix, include the mail. -By default the buttons that display security information are not -shown, because they clutter reading the actual e-mail. You can type -@kbd{K b} manually to display the information. Use the -@code{gnus-buttonized-mime-types} and -@code{gnus-unbuttonized-mime-types} variables to control this -permanently. @ref{MIME Commands} for further details, and hints on -how to customize these variables to always display security -information. +@item s +@kindex s (Article) +@findex gnus-article-show-summary +Reconfigure the buffers so that the summary buffer becomes visible +(@code{gnus-article-show-summary}). + +@item ? +@kindex ? (Article) +@findex gnus-article-describe-briefly +Give a very brief description of the available keystrokes +(@code{gnus-article-describe-briefly}). + +@item TAB +@kindex TAB (Article) +@findex gnus-article-next-button +Go to the next button, if any (@code{gnus-article-next-button}). This +only makes sense if you have buttonizing turned on. -@cindex snarfing keys -@cindex importing PGP keys -@cindex PGP key ring import -Snarfing OpenPGP keys (i.e., importing keys from articles into your -key ring) is not supported explicitly through a menu item or command, -rather Gnus do detect and label keys as @samp{application/pgp-keys}, -allowing you to specify whatever action you think is appropriate -through the usual @acronym{MIME} infrastructure. You can use a -@file{~/.mailcap} entry (@pxref{mailcap, , mailcap, emacs-mime, The -Emacs MIME Manual}) such as the following to import keys using GNU -Privacy Guard when you click on the @acronym{MIME} button -(@pxref{Using MIME}). +@item M-TAB +@kindex M-TAB (Article) +@findex gnus-article-prev-button +Go to the previous button, if any (@code{gnus-article-prev-button}). -@example -application/pgp-keys; gpg --import --interactive --verbose; needsterminal -@end example -@noindent -This happens to also be the default action defined in -@code{mailcap-mime-data}. +@item R +@kindex R (Article) +@findex gnus-article-reply-with-original +Send a reply to the current article and yank the current article +(@code{gnus-article-reply-with-original}). If the region is active, +only yank the text in the region. -More information on how to set things for sending outgoing signed and -encrypted messages up can be found in the message manual -(@pxref{Security, ,Security, message, Message Manual}). +@item S W +@kindex S W (Article) +@findex gnus-article-wide-reply-with-original +Send a wide reply to the current article and yank the current article +(@code{gnus-article-wide-reply-with-original}). If the region is +active, only yank the text in the region. -@node Mailing List -@section Mailing List -@cindex mailing list -@cindex RFC 2396 +@item F +@kindex F (Article) +@findex gnus-article-followup-with-original +Send a followup to the current article and yank the current article +(@code{gnus-article-followup-with-original}). If the region is active, +only yank the text in the region. -@kindex A M (summary) -@findex gnus-mailing-list-insinuate -Gnus understands some mailing list fields of RFC 2369. To enable it, -add a @code{to-list} group parameter (@pxref{Group Parameters}), -possibly using @kbd{A M} (@code{gnus-mailing-list-insinuate}) in the -summary buffer. -That enables the following commands to the summary buffer: +@end table -@table @kbd -@item C-c C-n h -@kindex C-c C-n h (Summary) -@findex gnus-mailing-list-help -Send a message to fetch mailing list help, if List-Help field exists. +@node Misc Article +@section Misc Article -@item C-c C-n s -@kindex C-c C-n s (Summary) -@findex gnus-mailing-list-subscribe -Send a message to subscribe the mailing list, if List-Subscribe field exists. +@table @code -@item C-c C-n u -@kindex C-c C-n u (Summary) -@findex gnus-mailing-list-unsubscribe -Send a message to unsubscribe the mailing list, if List-Unsubscribe -field exists. +@item gnus-single-article-buffer +@vindex gnus-single-article-buffer +@cindex article buffers, several +If non-@code{nil}, use the same article buffer for all the groups. +(This is the default.) If @code{nil}, each group will have its own +article buffer. -@item C-c C-n p -@kindex C-c C-n p (Summary) -@findex gnus-mailing-list-post -Post to the mailing list, if List-Post field exists. +@item gnus-widen-article-window +@cindex gnus-widen-article-window +If non-@code{nil}, selecting the article buffer with the @kbd{h} +command will ``widen'' the article window to take the entire frame. -@item C-c C-n o -@kindex C-c C-n o (Summary) -@findex gnus-mailing-list-owner -Send a message to the mailing list owner, if List-Owner field exists. +@vindex gnus-article-decode-hook +@item gnus-article-decode-hook +@cindex @acronym{MIME} +Hook used to decode @acronym{MIME} articles. The default value is +@code{(article-decode-charset article-decode-encoded-words)} -@item C-c C-n a -@kindex C-c C-n a (Summary) -@findex gnus-mailing-list-archive -Browse the mailing list archive, if List-Archive field exists. +@vindex gnus-article-prepare-hook +@item gnus-article-prepare-hook +This hook is called right after the article has been inserted into the +article buffer. It is mainly intended for functions that do something +depending on the contents; it should probably not be used for changing +the contents of the article buffer. -@end table +@item gnus-article-mode-hook +@vindex gnus-article-mode-hook +Hook called in article mode buffers. +@item gnus-article-mode-syntax-table +@vindex gnus-article-mode-syntax-table +Syntax table used in article buffers. It is initialized from +@code{text-mode-syntax-table}. -@node Article Buffer -@chapter Article Buffer -@cindex article buffer +@vindex gnus-article-over-scroll +@item gnus-article-over-scroll +If non-@code{nil}, allow scrolling the article buffer even when there +no more new text to scroll in. The default is @code{nil}. -The articles are displayed in the article buffer, of which there is only -one. All the summary buffers share the same article buffer unless you -tell Gnus otherwise. +@vindex gnus-article-mode-line-format +@item gnus-article-mode-line-format +This variable is a format string along the same lines as +@code{gnus-summary-mode-line-format} (@pxref{Summary Buffer Mode +Line}). It accepts the same format specifications as that variable, +with two extensions: -@menu -* Hiding Headers:: Deciding what headers should be displayed. -* Using MIME:: Pushing articles through @acronym{MIME} before reading them. -* HTML:: Reading @acronym{HTML} messages. -* Customizing Articles:: Tailoring the look of the articles. -* Article Keymap:: Keystrokes available in the article buffer. -* Misc Article:: Other stuff. -@end menu +@table @samp +@item w +The @dfn{wash status} of the article. This is a short string with one +character for each possible article wash operation that may have been +performed. The characters and their meaning: -@node Hiding Headers -@section Hiding Headers -@cindex hiding headers -@cindex deleting headers +@table @samp -The top section of each article is the @dfn{head}. (The rest is the -@dfn{body}, but you may have guessed that already.) +@item c +Displayed when cited text may be hidden in the article buffer. -@vindex gnus-show-all-headers -There is a lot of useful information in the head: the name of the person -who wrote the article, the date it was written and the subject of the -article. That's well and nice, but there's also lots of information -most people do not want to see---what systems the article has passed -through before reaching you, the @code{Message-ID}, the -@code{References}, etc. ad nauseam---and you'll probably want to get rid -of some of those lines. If you want to keep all those lines in the -article buffer, you can set @code{gnus-show-all-headers} to @code{t}. +@item h +Displayed when headers are hidden in the article buffer. -Gnus provides you with two variables for sifting headers: +@item p +Displayed when article is digitally signed or encrypted, and Gnus has +hidden the security headers. (N.B. does not tell anything about +security status, i.e. good or bad signature.) -@table @code +@item s +Displayed when the signature has been hidden in the Article buffer. -@item gnus-visible-headers -@vindex gnus-visible-headers -If this variable is non-@code{nil}, it should be a regular expression -that says what headers you wish to keep in the article buffer. All -headers that do not match this variable will be hidden. +@item o +Displayed when Gnus has treated overstrike characters in the article buffer. -For instance, if you only want to see the name of the person who wrote -the article and the subject, you'd say: +@item e +Displayed when Gnus has treated emphasized strings in the article buffer. -@lisp -(setq gnus-visible-headers "^From:\\|^Subject:") -@end lisp +@end table -This variable can also be a list of regexps to match headers to -remain visible. +@item m +The number of @acronym{MIME} parts in the article. -@item gnus-ignored-headers -@vindex gnus-ignored-headers -This variable is the reverse of @code{gnus-visible-headers}. If this -variable is set (and @code{gnus-visible-headers} is @code{nil}), it -should be a regular expression that matches all lines that you want to -hide. All lines that do not match this variable will remain visible. +@end table -For instance, if you just want to get rid of the @code{References} line -and the @code{Xref} line, you might say: +@vindex gnus-break-pages -@lisp -(setq gnus-ignored-headers "^References:\\|^Xref:") -@end lisp +@item gnus-break-pages +Controls whether @dfn{page breaking} is to take place. If this variable +is non-@code{nil}, the articles will be divided into pages whenever a +page delimiter appears in the article. If this variable is @code{nil}, +paging will not be done. -This variable can also be a list of regexps to match headers to -be removed. +@item gnus-page-delimiter +@vindex gnus-page-delimiter +This is the delimiter mentioned above. By default, it is @samp{^L} +(formfeed). -Note that if @code{gnus-visible-headers} is non-@code{nil}, this -variable will have no effect. +@cindex IDNA +@cindex internationalized domain names +@vindex gnus-use-idna +@item gnus-use-idna +This variable controls whether Gnus performs IDNA decoding of +internationalized domain names inside @samp{From}, @samp{To} and +@samp{Cc} headers. @xref{IDNA, ,IDNA,message, The Message Manual}, +for how to compose such messages. This requires +@uref{http://www.gnu.org/software/libidn/, GNU Libidn}, and this +variable is only enabled if you have installed it. -@end table +@vindex gnus-inhibit-images +@item gnus-inhibit-images +If this is non-@code{nil}, inhibit displaying of images inline in the +article body. It is effective to images that are in articles as +@acronym{MIME} parts, and images in @acronym{HTML} articles rendered +when @code{mm-text-html-renderer} (@pxref{Display Customization, +,Display Customization, emacs-mime, The Emacs MIME Manual}) is +@code{shr} or @code{gnus-w3m}. -@vindex gnus-sorted-header-list -Gnus can also sort the headers for you. (It does this by default.) You -can control the sorting by setting the @code{gnus-sorted-header-list} -variable. It is a list of regular expressions that says in what order -the headers are to be displayed. +@end table -For instance, if you want the name of the author of the article first, -and then the subject, you might say something like: -@lisp -(setq gnus-sorted-header-list '("^From:" "^Subject:")) -@end lisp +@node Composing Messages +@chapter Composing Messages +@cindex composing messages +@cindex messages +@cindex mail +@cindex sending mail +@cindex reply +@cindex followup +@cindex post +@cindex using gpg +@cindex using s/mime +@cindex using smime -Any headers that are to remain visible, but are not listed in this -variable, will be displayed in random order after all the headers listed in this variable. +@kindex C-c C-c (Post) +All commands for posting and mailing will put you in a message buffer +where you can edit the article all you like, before you send the +article by pressing @kbd{C-c C-c}. @xref{Top, , Overview, message, +Message Manual}. Where the message will be posted/mailed to depends +on your setup (@pxref{Posting Server}). -@findex gnus-article-hide-boring-headers -@vindex gnus-boring-article-headers -You can hide further boring headers by setting -@code{gnus-treat-hide-boring-headers} to @code{head}. What this function -does depends on the @code{gnus-boring-article-headers} variable. It's a -list, but this list doesn't actually contain header names. Instead it -lists various @dfn{boring conditions} that Gnus can check and remove -from sight. +@menu +* Mail:: Mailing and replying. +* Posting Server:: What server should you post and mail via? +* POP before SMTP:: You cannot send a mail unless you read a mail. +* Mail and Post:: Mailing and posting at the same time. +* Archived Messages:: Where Gnus stores the messages you've sent. +* Posting Styles:: An easier way to specify who you are. +* Drafts:: Postponing messages and rejected messages. +* Rejected Articles:: What happens if the server doesn't like your article? +* Signing and encrypting:: How to compose secure messages. +@end menu -These conditions are: -@table @code -@item empty -Remove all empty headers. -@item followup-to -Remove the @code{Followup-To} header if it is identical to the -@code{Newsgroups} header. -@item reply-to -Remove the @code{Reply-To} header if it lists the same addresses as -the @code{From} header, or if the @code{broken-reply-to} group -parameter is set. -@item newsgroups -Remove the @code{Newsgroups} header if it only contains the current group -name. -@item to-address -Remove the @code{To} header if it only contains the address identical to -the current group's @code{to-address} parameter. -@item to-list -Remove the @code{To} header if it only contains the address identical to -the current group's @code{to-list} parameter. -@item cc-list -Remove the @code{Cc} header if it only contains the address identical to -the current group's @code{to-list} parameter. -@item date -Remove the @code{Date} header if the article is less than three days -old. -@item long-to -Remove the @code{To} and/or @code{Cc} header if it is very long. -@item many-to -Remove all @code{To} and/or @code{Cc} headers if there are more than one. -@end table +Also @pxref{Canceling and Superseding} for information on how to +remove articles you shouldn't have posted. -To include these three elements, you could say something like: -@lisp -(setq gnus-boring-article-headers - '(empty followup-to reply-to)) -@end lisp +@node Mail +@section Mail -This is also the default value for this variable. +Variables for customizing outgoing mail: +@table @code +@item gnus-uu-digest-headers +@vindex gnus-uu-digest-headers +List of regexps to match headers included in digested messages. The +headers will be included in the sequence they are matched. If +@code{nil} include all headers. -@node Using MIME -@section Using MIME -@cindex @acronym{MIME} +@item gnus-add-to-list +@vindex gnus-add-to-list +If non-@code{nil}, add a @code{to-list} group parameter to mail groups +that have none when you do a @kbd{a}. -Mime is a standard for waving your hands through the air, aimlessly, -while people stand around yawning. +@item gnus-confirm-mail-reply-to-news +@vindex gnus-confirm-mail-reply-to-news +If non-@code{nil}, Gnus will ask you for a confirmation when you are +about to reply to news articles by mail. If it is @code{nil}, nothing +interferes in what you want to do. This can also be a function +receiving the group name as the only parameter which should return +non-@code{nil} if a confirmation is needed, or a regular expression +matching group names, where confirmation should be asked for. -@acronym{MIME}, however, is a standard for encoding your articles, aimlessly, -while all newsreaders die of fear. +If you find yourself never wanting to reply to mail, but occasionally +press @kbd{R} anyway, this variable might be for you. -@acronym{MIME} may specify what character set the article uses, the encoding -of the characters, and it also makes it possible to embed pictures and -other naughty stuff in innocent-looking articles. +@item gnus-confirm-treat-mail-like-news +@vindex gnus-confirm-treat-mail-like-news +If non-@code{nil}, Gnus also requests confirmation according to +@code{gnus-confirm-mail-reply-to-news} when replying to mail. This is +useful for treating mailing lists like newsgroups. -@vindex gnus-display-mime-function -@findex gnus-display-mime -Gnus pushes @acronym{MIME} articles through @code{gnus-display-mime-function} -to display the @acronym{MIME} parts. This is @code{gnus-display-mime} by -default, which creates a bundle of clickable buttons that can be used to -display, save and manipulate the @acronym{MIME} objects. +@end table -The following commands are available when you have placed point over a -@acronym{MIME} button: -@table @kbd -@findex gnus-article-press-button -@item RET (Article) -@kindex RET (Article) -@itemx BUTTON-2 (Article) -Toggle displaying of the @acronym{MIME} object -(@code{gnus-article-press-button}). If built-in viewers can not display -the object, Gnus resorts to external viewers in the @file{mailcap} -files. If a viewer has the @samp{copiousoutput} specification, the -object is displayed inline. +@node Posting Server +@section Posting Server -@findex gnus-mime-view-part -@item M-RET (Article) -@kindex M-RET (Article) -@itemx v (Article) -Prompt for a method, and then view the @acronym{MIME} object using this -method (@code{gnus-mime-view-part}). +When you press those magical @kbd{C-c C-c} keys to ship off your latest +(extremely intelligent, of course) article, where does it go? -@findex gnus-mime-view-part-as-type -@item t (Article) -@kindex t (Article) -View the @acronym{MIME} object as if it were a different @acronym{MIME} media type -(@code{gnus-mime-view-part-as-type}). +Thank you for asking. I hate you. -@findex gnus-mime-view-part-as-charset -@item C (Article) -@kindex C (Article) -Prompt for a charset, and then view the @acronym{MIME} object using this -charset (@code{gnus-mime-view-part-as-charset}). +It can be quite complicated. -@findex gnus-mime-save-part -@item o (Article) -@kindex o (Article) -Prompt for a file name, and then save the @acronym{MIME} object -(@code{gnus-mime-save-part}). +@vindex gnus-post-method +When posting news, Message usually invokes @code{message-send-news} +(@pxref{News Variables, , News Variables, message, Message Manual}). +Normally, Gnus will post using the same select method as you're +reading from (which might be convenient if you're reading lots of +groups from different private servers). However. If the server +you're reading from doesn't allow posting, just reading, you probably +want to use some other server to post your (extremely intelligent and +fabulously interesting) articles. You can then set the +@code{gnus-post-method} to some other method: -@findex gnus-mime-save-part-and-strip -@item C-o (Article) -@kindex C-o (Article) -Prompt for a file name, then save the @acronym{MIME} object and strip it from -the article. Then proceed to article editing, where a reasonable -suggestion is being made on how the altered article should look -like. The stripped @acronym{MIME} object will be referred via the -message/external-body @acronym{MIME} type. -(@code{gnus-mime-save-part-and-strip}). +@lisp +(setq gnus-post-method '(nnspool "")) +@end lisp -@findex gnus-mime-replace-part -@item r (Article) -@kindex r (Article) -Prompt for a file name, replace the @acronym{MIME} object with an -external body refering to the file via the message/external-body -@acronym{MIME} type. (@code{gnus-mime-replace-part}). +Now, if you've done this, and then this server rejects your article, or +this server is down, what do you do then? To override this variable you +can use a non-zero prefix to the @kbd{C-c C-c} command to force using +the ``current'' server, to get back the default behavior, for posting. -@findex gnus-mime-delete-part -@item d (Article) -@kindex d (Article) -Delete the @acronym{MIME} object from the article and replace it with some -information about the removed @acronym{MIME} object -(@code{gnus-mime-delete-part}). +If you give a zero prefix (i.e., @kbd{C-u 0 C-c C-c}) to that command, +Gnus will prompt you for what method to use for posting. -@c FIXME: gnus-auto-select-part should be documented here +You can also set @code{gnus-post-method} to a list of select methods. +If that's the case, Gnus will always prompt you for what method to use +for posting. -@findex gnus-mime-copy-part -@item c (Article) -@kindex c (Article) -Copy the @acronym{MIME} object to a fresh buffer and display this buffer -(@code{gnus-mime-copy-part}). If given a prefix, copy the raw contents -without decoding. If given a numerical prefix, you can do semi-manual -charset stuff (see @code{gnus-summary-show-article-charset-alist} in -@ref{Paging the Article}). Compressed files like @file{.gz} and -@file{.bz2} are automatically decompressed if -@code{auto-compression-mode} is enabled (@pxref{Compressed Files,, -Accessing Compressed Files, emacs, The Emacs Editor}). +Finally, if you want to always post using the native select method, +you can set this variable to @code{native}. -@findex gnus-mime-print-part -@item p (Article) -@kindex p (Article) -Print the @acronym{MIME} object (@code{gnus-mime-print-part}). This -command respects the @samp{print=} specifications in the -@file{.mailcap} file. +@vindex message-send-mail-function +When sending mail, Message invokes the function specified by the +variable @code{message-send-mail-function}. Gnus tries to set it to a +value suitable for your system. +@xref{Mail Variables, ,Mail Variables,message,Message manual}, for more +information. -@findex gnus-mime-inline-part -@item i (Article) -@kindex i (Article) -Insert the contents of the @acronym{MIME} object into the buffer -(@code{gnus-mime-inline-part}) as @samp{text/plain}. If given a prefix, insert -the raw contents without decoding. If given a numerical prefix, you can -do semi-manual charset stuff (see -@code{gnus-summary-show-article-charset-alist} in @ref{Paging the -Article}). Compressed files like @file{.gz} and @file{.bz2} are -automatically decompressed depending on @code{jka-compr} regardless of -@code{auto-compression-mode} (@pxref{Compressed Files,, Accessing -Compressed Files, emacs, The Emacs Editor}). +@node POP before SMTP +@section POP before SMTP +@cindex pop before smtp +@findex message-smtpmail-send-it +@findex mail-source-touch-pop -@findex gnus-mime-view-part-internally -@item E (Article) -@kindex E (Article) -View the @acronym{MIME} object with an internal viewer. If no internal -viewer is available, use an external viewer -(@code{gnus-mime-view-part-internally}). +Does your @acronym{ISP} require the @acronym{POP}-before-@acronym{SMTP} +authentication? It is whether you need to connect to the @acronym{POP} +mail server within a certain time before sending mails. If so, there is +a convenient way. To do that, put the following lines in your +@file{~/.gnus.el} file: -@findex gnus-mime-view-part-externally -@item e (Article) -@kindex e (Article) -View the @acronym{MIME} object with an external viewer. -(@code{gnus-mime-view-part-externally}). +@lisp +(setq message-send-mail-function 'message-smtpmail-send-it) +(add-hook 'message-send-mail-hook 'mail-source-touch-pop) +@end lisp -@findex gnus-mime-pipe-part -@item | (Article) -@kindex | (Article) -Output the @acronym{MIME} object to a process (@code{gnus-mime-pipe-part}). +@noindent +It means to let Gnus connect to the @acronym{POP} mail server in advance +whenever you send a mail. The @code{mail-source-touch-pop} function +does only a @acronym{POP} authentication according to the value of +@code{mail-sources} without fetching mails, just before sending a mail. +Note that you have to use @code{message-smtpmail-send-it} which runs +@code{message-send-mail-hook} rather than @code{smtpmail-send-it} and +set the value of @code{mail-sources} for a @acronym{POP} connection +correctly. @xref{Mail Sources}. -@findex gnus-mime-action-on-part -@item . (Article) -@kindex . (Article) -Interactively run an action on the @acronym{MIME} object -(@code{gnus-mime-action-on-part}). +If you have two or more @acronym{POP} mail servers set in +@code{mail-sources}, you may want to specify one of them to +@code{mail-source-primary-source} as the @acronym{POP} mail server to be +used for the @acronym{POP}-before-@acronym{SMTP} authentication. If it +is your primary @acronym{POP} mail server (i.e., you are fetching mails +mainly from that server), you can set it permanently as follows: -@end table +@lisp +(setq mail-source-primary-source + '(pop :server "pop3.mail.server" + :password "secret")) +@end lisp -Gnus will display some @acronym{MIME} objects automatically. The way Gnus -determines which parts to do this with is described in the Emacs -@acronym{MIME} manual. +@noindent +Otherwise, bind it dynamically only when performing the +@acronym{POP}-before-@acronym{SMTP} authentication as follows: -It might be best to just use the toggling functions from the article -buffer to avoid getting nasty surprises. (For instance, you enter the -group @samp{alt.sing-a-long} and, before you know it, @acronym{MIME} has -decoded the sound file in the article and some horrible sing-a-long song -comes screaming out your speakers, and you can't find the volume button, -because there isn't one, and people are starting to look at you, and you -try to stop the program, but you can't, and you can't find the program -to control the volume, and everybody else in the room suddenly decides -to look at you disdainfully, and you'll feel rather stupid.) +@lisp +(add-hook 'message-send-mail-hook + (lambda () + (let ((mail-source-primary-source + '(pop :server "pop3.mail.server" + :password "secret"))) + (mail-source-touch-pop)))) +@end lisp -Any similarity to real events and people is purely coincidental. Ahem. +@node Mail and Post +@section Mail and Post -Also @pxref{MIME Commands}. +Here's a list of variables relevant to both mailing and +posting: +@table @code +@item gnus-mailing-list-groups +@findex gnus-mailing-list-groups +@cindex mailing lists -@node HTML -@section @acronym{HTML} -@cindex @acronym{HTML} +If your news server offers groups that are really mailing lists +gatewayed to the @acronym{NNTP} server, you can read those groups without +problems, but you can't post/followup to them without some difficulty. +One solution is to add a @code{to-address} to the group parameters +(@pxref{Group Parameters}). An easier thing to do is set the +@code{gnus-mailing-list-groups} to a regexp that matches the groups that +really are mailing lists. Then, at least, followups to the mailing +lists will work most of the time. Posting to these groups (@kbd{a}) is +still a pain, though. -If you have @code{w3m} installed on your system, Gnus can display -@acronym{HTML} articles in the article buffer. There are many Gnus -add-ons for doing this, using various approaches, but there's one -(sort of) built-in method that's used by default. +@item gnus-user-agent +@vindex gnus-user-agent +@cindex User-Agent -For a complete overview, consult @xref{Display Customization, -,Display Customization, emacs-mime, The Emacs MIME Manual}. This -section only describes the default method. +This variable controls which information should be exposed in the +User-Agent header. It can be a list of symbols or a string. Valid +symbols are @code{gnus} (show Gnus version) and @code{emacs} (show Emacs +version). In addition to the Emacs version, you can add @code{codename} +(show (S)XEmacs codename) or either @code{config} (show system +configuration) or @code{type} (show system type). If you set it to a +string, be sure to use a valid format, see RFC 2616. -@table @code -@item mm-text-html-renderer -@vindex mm-text-html-renderer -If set to @code{gnus-article-html}, Gnus will use the built-in method, -that's based on @code{w3m}. +@end table -@item gnus-blocked-images -@vindex gnus-blocked-images -External images that have @acronym{URL}s that match this regexp won't -be fetched and displayed. For instance, do block all @acronym{URL}s -that have the string ``ads'' in them, do the following: +You may want to do spell-checking on messages that you send out. Or, if +you don't want to spell-check by hand, you could add automatic +spell-checking via the @code{ispell} package: +@cindex ispell +@findex ispell-message @lisp -(setq gnus-blocked-images "ads") +(add-hook 'message-send-hook 'ispell-message) @end lisp -This can also be a function to be evaluated. If so, it will be -called with the group name as the parameter. The default value is -@code{gnus-block-private-groups}, which will return @samp{"."} for -anything that isn't a newsgroup. This means that no external images -will be fetched as a result of reading mail, so that nobody can use -web bugs (and the like) to track whether you've read email. +If you want to change the @code{ispell} dictionary based on what group +you're in, you could say something like the following: -Also @pxref{Misc Article} for @code{gnus-inhibit-images}. +@lisp +(add-hook 'gnus-select-group-hook + (lambda () + (cond + ((string-match + "^de\\." (gnus-group-real-name gnus-newsgroup-name)) + (ispell-change-dictionary "deutsch")) + (t + (ispell-change-dictionary "english"))))) +@end lisp -@item gnus-html-cache-directory -@vindex gnus-html-cache-directory -Gnus will download and cache images according to how -@code{gnus-blocked-images} is set. These images will be stored in -this directory. +Modify to suit your needs. -@item gnus-html-cache-size -@vindex gnus-html-cache-size -When @code{gnus-html-cache-size} bytes have been used in that -directory, the oldest files will be deleted. The default is 500MB. +@vindex gnus-message-highlight-citation +If @code{gnus-message-highlight-citation} is t, different levels of +citations are highlighted like in Gnus article buffers also in message +mode buffers. -@item gnus-html-frame-width -@vindex gnus-html-frame-width -The width to use when rendering HTML. The default is 70. +@node Archived Messages +@section Archived Messages +@cindex archived messages +@cindex sent messages -@item gnus-max-image-proportion -@vindex gnus-max-image-proportion -How big pictures displayed are in relation to the window they're in. -A value of 0.7 (the default) means that they are allowed to take up -70% of the width and height of the window. If they are larger than -this, and Emacs supports it, then the images will be rescaled down to -fit these criteria. +Gnus provides a few different methods for storing the mail and news you +send. The default method is to use the @dfn{archive virtual server} to +store the messages. If you want to disable this completely, the +@code{gnus-message-archive-group} variable should be @code{nil}, which +is the default. -@end table +For archiving interesting messages in a group you read, see the +@kbd{B c} (@code{gnus-summary-copy-article}) command (@pxref{Mail +Group Commands}). -To use this, make sure that you have @code{w3m} and @code{curl} -installed. If you have, then Gnus should display @acronym{HTML} -automatically. +@vindex gnus-message-archive-method +@code{gnus-message-archive-method} says what virtual server Gnus is to +use to store sent messages. The default is @code{"archive"}, and when +actually being used it is expanded into: +@lisp +(nnfolder "archive" + (nnfolder-directory "~/Mail/archive") + (nnfolder-active-file "~/Mail/archive/active") + (nnfolder-get-new-mail nil) + (nnfolder-inhibit-expiry t)) +@end lisp +@quotation +@vindex gnus-update-message-archive-method +Note: a server like this is saved in the @file{~/.newsrc.eld} file first +so that it may be used as a real method of the server which is named +@code{"archive"} (that is, for the case where +@code{gnus-message-archive-method} is set to @code{"archive"}) ever +since. If it once has been saved, it will never be updated by default +even if you change the value of @code{gnus-message-archive-method} +afterward. Therefore, the server @code{"archive"} doesn't necessarily +mean the @code{nnfolder} server like this at all times. If you want the +saved method to reflect always the value of +@code{gnus-message-archive-method}, set the +@code{gnus-update-message-archive-method} variable to a non-@code{nil} +value. The default value of this variable is @code{nil}. +@end quotation -@node Customizing Articles -@section Customizing Articles -@cindex article customization +You can, however, use any mail select method (@code{nnml}, +@code{nnmbox}, etc.). @code{nnfolder} is a quite likable select method +for doing this sort of thing, though. If you don't like the default +directory chosen, you could say something like: -A slew of functions for customizing how the articles are to look like -exist. You can call these functions interactively -(@pxref{Article Washing}), or you can have them -called automatically when you select the articles. +@lisp +(setq gnus-message-archive-method + '(nnfolder "archive" + (nnfolder-inhibit-expiry t) + (nnfolder-active-file "~/News/sent-mail/active") + (nnfolder-directory "~/News/sent-mail/"))) +@end lisp -To have them called automatically, you should set the corresponding -``treatment'' variable. For instance, to have headers hidden, you'd set -@code{gnus-treat-hide-headers}. Below is a list of variables that can -be set, but first we discuss the values these variables can have. +@vindex gnus-message-archive-group +@cindex Gcc +Gnus will insert @code{Gcc} headers in all outgoing messages that point +to one or more group(s) on that server. Which group to use is +determined by the @code{gnus-message-archive-group} variable. -Note: Some values, while valid, make little sense. Check the list below -for sensible values. +This variable can be used to do the following: -@enumerate -@item -@code{nil}: Don't do this treatment. +@table @asis +@item a string +Messages will be saved in that group. -@item -@code{t}: Do this treatment on all body parts. +Note that you can include a select method in the group name, then the +message will not be stored in the select method given by +@code{gnus-message-archive-method}, but in the select method specified +by the group name, instead. Suppose @code{gnus-message-archive-method} +has the default value shown above. Then setting +@code{gnus-message-archive-group} to @code{"foo"} means that outgoing +messages are stored in @samp{nnfolder+archive:foo}, but if you use the +value @code{"nnml:foo"}, then outgoing messages will be stored in +@samp{nnml:foo}. -@item -@code{head}: Do the treatment on the headers. +@item a list of strings +Messages will be saved in all those groups. -@item -@code{first}: Do this treatment on the first body part. +@item an alist of regexps, functions and forms +When a key ``matches'', the result is used. -@item -@code{last}: Do this treatment on the last body part. +@item @code{nil} +No message archiving will take place. This is the default. +@end table -@item -An integer: Do this treatment on all body parts that have a length less -than this number. +Let's illustrate: -@item -A list of strings: Do this treatment on all body parts that are in -articles that are read in groups that have names that match one of the -regexps in the list. +Just saving to a single group called @samp{MisK}: +@lisp +(setq gnus-message-archive-group "MisK") +@end lisp -@item -A list where the first element is not a string: +Saving to two groups, @samp{MisK} and @samp{safe}: +@lisp +(setq gnus-message-archive-group '("MisK" "safe")) +@end lisp -The list is evaluated recursively. The first element of the list is a -predicate. The following predicates are recognized: @code{or}, -@code{and}, @code{not} and @code{typep}. Here's an example: +Save to different groups based on what group you are in: +@lisp +(setq gnus-message-archive-group + '(("^alt" "sent-to-alt") + ("mail" "sent-to-mail") + (".*" "sent-to-misc"))) +@end lisp +More complex stuff: @lisp -(or last - (typep "text/x-vcard")) +(setq gnus-message-archive-group + '((if (message-news-p) + "misc-news" + "misc-mail"))) @end lisp -@end enumerate +How about storing all news messages in one file, but storing all mail +messages in one file per month: -You may have noticed that the word @dfn{part} is used here. This refers -to the fact that some messages are @acronym{MIME} multipart articles that may -be divided into several parts. Articles that are not multiparts are -considered to contain just a single part. +@lisp +(setq gnus-message-archive-group + '((if (message-news-p) + "misc-news" + (concat "mail." (format-time-string "%Y-%m"))))) +@end lisp -@vindex gnus-article-treat-types -Are the treatments applied to all sorts of multipart parts? Yes, if you -want to, but by default, only @samp{text/plain} parts are given the -treatment. This is controlled by the @code{gnus-article-treat-types} -variable, which is a list of regular expressions that are matched to the -type of the part. This variable is ignored if the value of the -controlling variable is a predicate list, as described above. +@c (XEmacs 19.13 doesn't have @code{format-time-string}, so you'll have to +@c use a different value for @code{gnus-message-archive-group} there.) -@ifinfo -@c Avoid sort of redundant entries in the same section for the printed -@c manual, but add them in info to allow `i gnus-treat-foo-bar RET' or -@c `i foo-bar'. -@vindex gnus-treat-buttonize -@vindex gnus-treat-buttonize-head -@vindex gnus-treat-capitalize-sentences -@vindex gnus-treat-overstrike -@vindex gnus-treat-strip-cr -@vindex gnus-treat-strip-headers-in-body -@vindex gnus-treat-strip-leading-blank-lines -@vindex gnus-treat-strip-multiple-blank-lines -@vindex gnus-treat-strip-pem -@vindex gnus-treat-strip-trailing-blank-lines -@vindex gnus-treat-unsplit-urls -@vindex gnus-treat-wash-html -@vindex gnus-treat-date-english -@vindex gnus-treat-date-iso8601 -@vindex gnus-treat-date-lapsed -@vindex gnus-treat-date-local -@vindex gnus-treat-date-original -@vindex gnus-treat-date-user-defined -@vindex gnus-treat-date-ut -@vindex gnus-treat-from-picon -@vindex gnus-treat-mail-picon -@vindex gnus-treat-newsgroups-picon -@vindex gnus-treat-from-gravatar -@vindex gnus-treat-mail-gravatar -@vindex gnus-treat-display-smileys -@vindex gnus-treat-body-boundary -@vindex gnus-treat-display-x-face -@vindex gnus-treat-display-face -@vindex gnus-treat-emphasize -@vindex gnus-treat-fill-article -@vindex gnus-treat-fill-long-lines -@vindex gnus-treat-hide-boring-headers -@vindex gnus-treat-hide-citation -@vindex gnus-treat-hide-citation-maybe -@vindex gnus-treat-hide-headers -@vindex gnus-treat-hide-signature -@vindex gnus-treat-strip-banner -@vindex gnus-treat-strip-list-identifiers -@vindex gnus-treat-highlight-citation -@vindex gnus-treat-highlight-headers -@vindex gnus-treat-highlight-signature -@vindex gnus-treat-play-sounds -@vindex gnus-treat-x-pgp-sig -@vindex gnus-treat-unfold-headers -@vindex gnus-treat-fold-headers -@vindex gnus-treat-fold-newsgroups -@vindex gnus-treat-leading-whitespace -@end ifinfo +Now, when you send a message off, it will be stored in the appropriate +group. (If you want to disable storing for just one particular message, +you can just remove the @code{Gcc} header that has been inserted.) The +archive group will appear in the group buffer the next time you start +Gnus, or the next time you press @kbd{F} in the group buffer. You can +enter it and read the articles in it just like you'd read any other +group. If the group gets really big and annoying, you can simply rename +if (using @kbd{G r} in the group buffer) to something +nice---@samp{misc-mail-september-1995}, or whatever. New messages will +continue to be stored in the old (now empty) group. -The following treatment options are available. The easiest way to -customize this is to examine the @code{gnus-article-treat} customization -group. Values in parenthesis are suggested sensible values. Others are -possible but those listed are probably sufficient for most people. +That's the default method of archiving sent messages. Gnus offers a +different way for the people who don't like the default method. In that +case you should set @code{gnus-message-archive-group} to @code{nil}; +this will disable archiving. @table @code -@item gnus-treat-buttonize (t, integer) -@item gnus-treat-buttonize-head (head) - -@xref{Article Buttons}. +@item gnus-gcc-mark-as-read +@vindex gnus-gcc-mark-as-read +If non-@code{nil}, automatically mark @code{Gcc} articles as read. -@item gnus-treat-capitalize-sentences (t, integer) -@item gnus-treat-overstrike (t, integer) -@item gnus-treat-strip-cr (t, integer) -@item gnus-treat-strip-headers-in-body (t, integer) -@item gnus-treat-strip-leading-blank-lines (t, first, integer) -@item gnus-treat-strip-multiple-blank-lines (t, integer) -@item gnus-treat-strip-pem (t, last, integer) -@item gnus-treat-strip-trailing-blank-lines (t, last, integer) -@item gnus-treat-unsplit-urls (t, integer) -@item gnus-treat-wash-html (t, integer) +@item gnus-gcc-externalize-attachments +@vindex gnus-gcc-externalize-attachments +If @code{nil}, attach files as normal parts in Gcc copies; if a regexp +and matches the Gcc group name, attach files as external parts; if it is +@code{all}, attach local files as external parts; if it is other +non-@code{nil}, the behavior is the same as @code{all}, but it may be +changed in the future. -@xref{Article Washing}. +@end table -@item gnus-treat-date-english (head) -@item gnus-treat-date-iso8601 (head) -@item gnus-treat-date-lapsed (head) -@item gnus-treat-date-local (head) -@item gnus-treat-date-original (head) -@item gnus-treat-date-user-defined (head) -@item gnus-treat-date-ut (head) -@xref{Article Date}. +@node Posting Styles +@section Posting Styles +@cindex posting styles +@cindex styles -@item gnus-treat-from-picon (head) -@item gnus-treat-mail-picon (head) -@item gnus-treat-newsgroups-picon (head) +All them variables, they make my head swim. -@xref{Picons}. +So what if you want a different @code{Organization} and signature based +on what groups you post to? And you post both from your home machine +and your work machine, and you want different @code{From} lines, and so +on? -@item gnus-treat-from-gravatar (head) -@item gnus-treat-mail-gravatar (head) +@vindex gnus-posting-styles +One way to do stuff like that is to write clever hooks that change the +variables you need to have changed. That's a bit boring, so somebody +came up with the bright idea of letting the user specify these things in +a handy alist. Here's an example of a @code{gnus-posting-styles} +variable: -@xref{Gravatars}. +@lisp +((".*" + (signature "Peace and happiness") + (organization "What me?")) + ("^comp" + (signature "Death to everybody")) + ("comp.emacs.i-love-it" + (organization "Emacs is it"))) +@end lisp -@item gnus-treat-display-smileys (t, integer) +As you might surmise from this example, this alist consists of several +@dfn{styles}. Each style will be applicable if the first element +``matches'', in some form or other. The entire alist will be iterated +over, from the beginning towards the end, and each match will be +applied, which means that attributes in later styles that match override +the same attributes in earlier matching styles. So +@samp{comp.programming.literate} will have the @samp{Death to everybody} +signature and the @samp{What me?} @code{Organization} header. -@item gnus-treat-body-boundary (head) +The first element in each style is called the @code{match}. If it's a +string, then Gnus will try to regexp match it against the group name. +If it is the form @code{(header @var{match} @var{regexp})}, then Gnus +will look in the original article for a header whose name is +@var{match} and compare that @var{regexp}. @var{match} and +@var{regexp} are strings. (The original article is the one you are +replying or following up to. If you are not composing a reply or a +followup, then there is nothing to match against.) If the +@code{match} is a function symbol, that function will be called with +no arguments. If it's a variable symbol, then the variable will be +referenced. If it's a list, then that list will be @code{eval}ed. In +any case, if this returns a non-@code{nil} value, then the style is +said to @dfn{match}. -@vindex gnus-body-boundary-delimiter -Adds a delimiter between header and body, the string used as delimiter -is controlled by @code{gnus-body-boundary-delimiter}. +Each style may contain an arbitrary amount of @dfn{attributes}. Each +attribute consists of a @code{(@var{name} @var{value})} pair. In +addition, you can also use the @code{(@var{name} :file @var{value})} +form or the @code{(@var{name} :value @var{value})} form. Where +@code{:file} signifies @var{value} represents a file name and its +contents should be used as the attribute value, @code{:value} signifies +@var{value} does not represent a file name explicitly. The attribute +name can be one of: -@xref{Smileys}. +@itemize @bullet +@item @code{signature} +@item @code{signature-file} +@item @code{x-face-file} +@item @code{address}, overriding @code{user-mail-address} +@item @code{name}, overriding @code{(user-full-name)} +@item @code{body} +@end itemize -@vindex gnus-treat-display-x-face -@item gnus-treat-display-x-face (head) +Note that the @code{signature-file} attribute honors the variable +@code{message-signature-directory}. -@xref{X-Face}. +The attribute name can also be a string or a symbol. In that case, +this will be used as a header name, and the value will be inserted in +the headers of the article; if the value is @code{nil}, the header +name will be removed. If the attribute name is @code{eval}, the form +is evaluated, and the result is thrown away. -@vindex gnus-treat-display-face -@item gnus-treat-display-face (head) +The attribute value can be a string, a function with zero arguments +(the return value will be used), a variable (its value will be used) +or a list (it will be @code{eval}ed and the return value will be +used). The functions and sexps are called/@code{eval}ed in the +message buffer that is being set up. The headers of the current +article are available through the @code{message-reply-headers} +variable, which is a vector of the following headers: number subject +from date id references chars lines xref extra. -@xref{Face}. +In the case of a string value, if the @code{match} is a regular +expression, a @samp{gnus-match-substitute-replacement} is proceed on +the value to replace the positional parameters @samp{\@var{n}} by the +corresponding parenthetical matches (see @xref{Replacing the Text that +Matched, , Text Replacement, elisp, The Emacs Lisp Reference Manual}.) -@vindex gnus-treat-emphasize -@item gnus-treat-emphasize (t, head, integer) -@vindex gnus-treat-fill-article -@item gnus-treat-fill-article (t, integer) -@vindex gnus-treat-fill-long-lines -@item gnus-treat-fill-long-lines (t, integer) -@vindex gnus-treat-hide-boring-headers -@item gnus-treat-hide-boring-headers (head) -@vindex gnus-treat-hide-citation -@item gnus-treat-hide-citation (t, integer) -@vindex gnus-treat-hide-citation-maybe -@item gnus-treat-hide-citation-maybe (t, integer) -@vindex gnus-treat-hide-headers -@item gnus-treat-hide-headers (head) -@vindex gnus-treat-hide-signature -@item gnus-treat-hide-signature (t, last) -@vindex gnus-treat-strip-banner -@item gnus-treat-strip-banner (t, last) -@vindex gnus-treat-strip-list-identifiers -@item gnus-treat-strip-list-identifiers (head) +@vindex message-reply-headers -@xref{Article Hiding}. +If you wish to check whether the message you are about to compose is +meant to be a news article or a mail message, you can check the values +of the @code{message-news-p} and @code{message-mail-p} functions. -@vindex gnus-treat-highlight-citation -@item gnus-treat-highlight-citation (t, integer) -@vindex gnus-treat-highlight-headers -@item gnus-treat-highlight-headers (head) -@vindex gnus-treat-highlight-signature -@item gnus-treat-highlight-signature (t, last, integer) +@findex message-mail-p +@findex message-news-p -@xref{Article Highlighting}. +So here's a new example: -@vindex gnus-treat-play-sounds -@item gnus-treat-play-sounds -@item gnus-treat-ansi-sequences (t) -@vindex gnus-treat-x-pgp-sig -@item gnus-treat-x-pgp-sig (head) +@lisp +(setq gnus-posting-styles + '((".*" + (signature-file "~/.signature") + (name "User Name") + (x-face-file "~/.xface") + (x-url (getenv "WWW_HOME")) + (organization "People's Front Against MWM")) + ("^rec.humor" + (signature my-funny-signature-randomizer)) + ((equal (system-name) "gnarly") ;; @r{A form} + (signature my-quote-randomizer)) + (message-news-p ;; @r{A function symbol} + (signature my-news-signature)) + (window-system ;; @r{A value symbol} + ("X-Window-System" (format "%s" window-system))) + ;; @r{If I'm replying to Larsi, set the Organization header.} + ((header "from" "larsi.*org") + (Organization "Somewhere, Inc.")) + ((posting-from-work-p) ;; @r{A user defined function} + (signature-file "~/.work-signature") + (address "user@@bar.foo") + (body "You are fired.\n\nSincerely, your boss.") + (organization "Important Work, Inc")) + ("nnml:.*" + (From (with-current-buffer gnus-article-buffer + (message-fetch-field "to")))) + ("^nn.+:" + (signature-file "~/.mail-signature")))) +@end lisp -@vindex gnus-treat-unfold-headers -@item gnus-treat-unfold-headers (head) -@vindex gnus-treat-fold-headers -@item gnus-treat-fold-headers (head) -@vindex gnus-treat-fold-newsgroups -@item gnus-treat-fold-newsgroups (head) -@vindex gnus-treat-leading-whitespace -@item gnus-treat-leading-whitespace (head) +The @samp{nnml:.*} rule means that you use the @code{To} address as the +@code{From} address in all your outgoing replies, which might be handy +if you fill many roles. +You may also use @code{message-alternative-emails} instead. +@xref{Message Headers, ,Message Headers, message, Message Manual}. -@xref{Article Header}. +@node Drafts +@section Drafts +@cindex drafts + +If you are writing a message (mail or news) and suddenly remember that +you have a steak in the oven (or some pesto in the food processor, you +craaazy vegetarians), you'll probably wish there was a method to save +the message you are writing so that you can continue editing it some +other day, and send it when you feel its finished. +Well, don't worry about it. Whenever you start composing a message of +some sort using the Gnus mail and post commands, the buffer you get will +automatically associate to an article in a special @dfn{draft} group. +If you save the buffer the normal way (@kbd{C-x C-s}, for instance), the +article will be saved there. (Auto-save files also go to the draft +group.) -@end table +@cindex nndraft +@vindex nndraft-directory +The draft group is a special group (which is implemented as an +@code{nndraft} group, if you absolutely have to know) called +@samp{nndraft:drafts}. The variable @code{nndraft-directory} says where +@code{nndraft} is to store its files. What makes this group special is +that you can't tick any articles in it or mark any articles as +read---all articles in the group are permanently unread. -@vindex gnus-part-display-hook -You can, of course, write your own functions to be called from -@code{gnus-part-display-hook}. The functions are called narrowed to the -part, and you can do anything you like, pretty much. There is no -information that you have to keep in the buffer---you can change -everything. +If the group doesn't exist, it will be created and you'll be subscribed +to it. The only way to make it disappear from the Group buffer is to +unsubscribe it. The special properties of the draft group comes from +a group property (@pxref{Group Parameters}), and if lost the group +behaves like any other group. This means the commands below will not +be available. To restore the special properties of the group, the +simplest way is to kill the group, using @kbd{C-k}, and restart +Gnus. The group is automatically created again with the +correct parameters. The content of the group is not lost. +@c @findex gnus-dissociate-buffer-from-draft +@c @kindex C-c M-d (Mail) +@c @kindex C-c M-d (Post) +@c @findex gnus-associate-buffer-with-draft +@c @kindex C-c C-d (Mail) +@c @kindex C-c C-d (Post) +@c If you're writing some super-secret message that you later want to +@c encode with PGP before sending, you may wish to turn the auto-saving +@c (and association with the draft group) off. You never know who might be +@c interested in reading all your extremely valuable and terribly horrible +@c and interesting secrets. The @kbd{C-c M-d} +@c (@code{gnus-dissociate-buffer-from-draft}) command does that for you. +@c If you change your mind and want to turn the auto-saving back on again, +@c @kbd{C-c C-d} (@code{gnus-associate-buffer-with-draft} does that. +@c +@c @vindex gnus-use-draft +@c To leave association with the draft group off by default, set +@c @code{gnus-use-draft} to @code{nil}. It is @code{t} by default. -@node Article Keymap -@section Article Keymap +@findex gnus-draft-edit-message +@kindex D e (Draft) +When you want to continue editing the article, you simply enter the +draft group and push @kbd{D e} (@code{gnus-draft-edit-message}) to do +that. You will be placed in a buffer where you left off. -Most of the keystrokes in the summary buffer can also be used in the -article buffer. They should behave as if you typed them in the summary -buffer, which means that you don't actually have to have a summary -buffer displayed while reading. You can do it all from the article -buffer. +Rejected articles will also be put in this draft group (@pxref{Rejected +Articles}). -@kindex v (Article) -@cindex keys, reserved for users (Article) -The key @kbd{v} is reserved for users. You can bind it to some -command or better use it as a prefix key. +@findex gnus-draft-send-all-messages +@kindex D s (Draft) +@findex gnus-draft-send-message +@kindex D S (Draft) +If you have lots of rejected messages you want to post (or mail) without +doing further editing, you can use the @kbd{D s} command +(@code{gnus-draft-send-message}). This command understands the +process/prefix convention (@pxref{Process/Prefix}). The @kbd{D S} +command (@code{gnus-draft-send-all-messages}) will ship off all messages +in the buffer. -A few additional keystrokes are available: +@findex gnus-draft-toggle-sending +@kindex D t (Draft) +If you have some messages that you wish not to send, you can use the +@kbd{D t} (@code{gnus-draft-toggle-sending}) command to mark the message +as unsendable. This is a toggling command. -@table @kbd +Finally, if you want to delete a draft, use the normal @kbd{B DEL} +command (@pxref{Mail Group Commands}). -@item SPACE -@kindex SPACE (Article) -@findex gnus-article-next-page -Scroll forwards one page (@code{gnus-article-next-page}). -This is exactly the same as @kbd{h SPACE h}. -@item DEL -@kindex DEL (Article) -@findex gnus-article-prev-page -Scroll backwards one page (@code{gnus-article-prev-page}). -This is exactly the same as @kbd{h DEL h}. +@node Rejected Articles +@section Rejected Articles +@cindex rejected articles -@item C-c ^ -@kindex C-c ^ (Article) -@findex gnus-article-refer-article -If point is in the neighborhood of a @code{Message-ID} and you press -@kbd{C-c ^}, Gnus will try to get that article from the server -(@code{gnus-article-refer-article}). +Sometimes a news server will reject an article. Perhaps the server +doesn't like your face. Perhaps it just feels miserable. Perhaps +@emph{there be demons}. Perhaps you have included too much cited text. +Perhaps the disk is full. Perhaps the server is down. -@item C-c C-m -@kindex C-c C-m (Article) -@findex gnus-article-mail -Send a reply to the address near point (@code{gnus-article-mail}). If -given a prefix, include the mail. +These situations are, of course, totally beyond the control of Gnus. +(Gnus, of course, loves the way you look, always feels great, has angels +fluttering around inside of it, doesn't care about how much cited text +you include, never runs full and never goes down.) So Gnus saves these +articles until some later time when the server feels better. -@item s -@kindex s (Article) -@findex gnus-article-show-summary -Reconfigure the buffers so that the summary buffer becomes visible -(@code{gnus-article-show-summary}). +The rejected articles will automatically be put in a special draft group +(@pxref{Drafts}). When the server comes back up again, you'd then +typically enter that group and send all the articles off. -@item ? -@kindex ? (Article) -@findex gnus-article-describe-briefly -Give a very brief description of the available keystrokes -(@code{gnus-article-describe-briefly}). +@node Signing and encrypting +@section Signing and encrypting +@cindex using gpg +@cindex using s/mime +@cindex using smime -@item TAB -@kindex TAB (Article) -@findex gnus-article-next-button -Go to the next button, if any (@code{gnus-article-next-button}). This -only makes sense if you have buttonizing turned on. +Gnus can digitally sign and encrypt your messages, using vanilla +@acronym{PGP} format or @acronym{PGP/MIME} or @acronym{S/MIME}. For +decoding such messages, see the @code{mm-verify-option} and +@code{mm-decrypt-option} options (@pxref{Security}). -@item M-TAB -@kindex M-TAB (Article) -@findex gnus-article-prev-button -Go to the previous button, if any (@code{gnus-article-prev-button}). +@vindex gnus-message-replysign +@vindex gnus-message-replyencrypt +@vindex gnus-message-replysignencrypted +Often, you would like to sign replies to people who send you signed +messages. Even more often, you might want to encrypt messages which +are in reply to encrypted messages. Gnus offers +@code{gnus-message-replysign} to enable the former, and +@code{gnus-message-replyencrypt} for the latter. In addition, setting +@code{gnus-message-replysignencrypted} (on by default) will sign +automatically encrypted messages. -@item R -@kindex R (Article) -@findex gnus-article-reply-with-original -Send a reply to the current article and yank the current article -(@code{gnus-article-reply-with-original}). If the region is active, -only yank the text in the region. +Instructing @acronym{MML} to perform security operations on a +@acronym{MIME} part is done using the @kbd{C-c C-m s} key map for +signing and the @kbd{C-c C-m c} key map for encryption, as follows. -@item S W -@kindex S W (Article) -@findex gnus-article-wide-reply-with-original -Send a wide reply to the current article and yank the current article -(@code{gnus-article-wide-reply-with-original}). If the region is -active, only yank the text in the region. +@table @kbd -@item F -@kindex F (Article) -@findex gnus-article-followup-with-original -Send a followup to the current article and yank the current article -(@code{gnus-article-followup-with-original}). If the region is active, -only yank the text in the region. +@item C-c C-m s s +@kindex C-c C-m s s (Message) +@findex mml-secure-message-sign-smime +Digitally sign current message using @acronym{S/MIME}. -@end table +@item C-c C-m s o +@kindex C-c C-m s o (Message) +@findex mml-secure-message-sign-pgp +Digitally sign current message using @acronym{PGP}. -@node Misc Article -@section Misc Article +@item C-c C-m s p +@kindex C-c C-m s p (Message) +@findex mml-secure-message-sign-pgp -@table @code +Digitally sign current message using @acronym{PGP/MIME}. -@item gnus-single-article-buffer -@vindex gnus-single-article-buffer -@cindex article buffers, several -If non-@code{nil}, use the same article buffer for all the groups. -(This is the default.) If @code{nil}, each group will have its own -article buffer. +@item C-c C-m c s +@kindex C-c C-m c s (Message) +@findex mml-secure-message-encrypt-smime -@item gnus-widen-article-window -@cindex gnus-widen-article-window -If non-@code{nil}, selecting the article buffer with the @kbd{h} -command will ``widen'' the article window to take the entire frame. +Digitally encrypt current message using @acronym{S/MIME}. -@vindex gnus-article-decode-hook -@item gnus-article-decode-hook -@cindex @acronym{MIME} -Hook used to decode @acronym{MIME} articles. The default value is -@code{(article-decode-charset article-decode-encoded-words)} +@item C-c C-m c o +@kindex C-c C-m c o (Message) +@findex mml-secure-message-encrypt-pgp -@vindex gnus-article-prepare-hook -@item gnus-article-prepare-hook -This hook is called right after the article has been inserted into the -article buffer. It is mainly intended for functions that do something -depending on the contents; it should probably not be used for changing -the contents of the article buffer. +Digitally encrypt current message using @acronym{PGP}. -@item gnus-article-mode-hook -@vindex gnus-article-mode-hook -Hook called in article mode buffers. +@item C-c C-m c p +@kindex C-c C-m c p (Message) +@findex mml-secure-message-encrypt-pgpmime -@item gnus-article-mode-syntax-table -@vindex gnus-article-mode-syntax-table -Syntax table used in article buffers. It is initialized from -@code{text-mode-syntax-table}. +Digitally encrypt current message using @acronym{PGP/MIME}. -@vindex gnus-article-over-scroll -@item gnus-article-over-scroll -If non-@code{nil}, allow scrolling the article buffer even when there -no more new text to scroll in. The default is @code{nil}. +@item C-c C-m C-n +@kindex C-c C-m C-n (Message) +@findex mml-unsecure-message +Remove security related @acronym{MML} tags from message. -@vindex gnus-article-mode-line-format -@item gnus-article-mode-line-format -This variable is a format string along the same lines as -@code{gnus-summary-mode-line-format} (@pxref{Summary Buffer Mode -Line}). It accepts the same format specifications as that variable, -with two extensions: +@end table -@table @samp +@xref{Security, ,Security, message, Message Manual}, for more information. -@item w -The @dfn{wash status} of the article. This is a short string with one -character for each possible article wash operation that may have been -performed. The characters and their meaning: +@node Select Methods +@chapter Select Methods +@cindex foreign groups +@cindex select methods -@table @samp +A @dfn{foreign group} is a group not read by the usual (or +default) means. It could be, for instance, a group from a different +@acronym{NNTP} server, it could be a virtual group, or it could be your own +personal mail group. -@item c -Displayed when cited text may be hidden in the article buffer. +A foreign group (or any group, really) is specified by a @dfn{name} and +a @dfn{select method}. To take the latter first, a select method is a +list where the first element says what back end to use (e.g. @code{nntp}, +@code{nnspool}, @code{nnml}) and the second element is the @dfn{server +name}. There may be additional elements in the select method, where the +value may have special meaning for the back end in question. -@item h -Displayed when headers are hidden in the article buffer. +One could say that a select method defines a @dfn{virtual server}---so +we do just that (@pxref{Server Buffer}). -@item p -Displayed when article is digitally signed or encrypted, and Gnus has -hidden the security headers. (N.B. does not tell anything about -security status, i.e. good or bad signature.) +The @dfn{name} of the group is the name the back end will recognize the +group as. -@item s -Displayed when the signature has been hidden in the Article buffer. +For instance, the group @samp{soc.motss} on the @acronym{NNTP} server +@samp{some.where.edu} will have the name @samp{soc.motss} and select +method @code{(nntp "some.where.edu")}. Gnus will call this group +@samp{nntp+some.where.edu:soc.motss}, even though the @code{nntp} +back end just knows this group as @samp{soc.motss}. -@item o -Displayed when Gnus has treated overstrike characters in the article buffer. +The different methods all have their peculiarities, of course. -@item e -Displayed when Gnus has treated emphasized strings in the article buffer. +@menu +* Server Buffer:: Making and editing virtual servers. +* Getting News:: Reading USENET news with Gnus. +* Using IMAP:: Reading mail from @acronym{IMAP}. +* Getting Mail:: Reading your personal mail with Gnus. +* Browsing the Web:: Getting messages from a plethora of Web sources. +* Other Sources:: Reading directories, files. +* Combined Groups:: Combining groups into one group. +* Email Based Diary:: Using mails to manage diary events in Gnus. +* Gnus Unplugged:: Reading news and mail offline. +@end menu -@end table -@item m -The number of @acronym{MIME} parts in the article. +@node Server Buffer +@section Server Buffer -@end table +Traditionally, a @dfn{server} is a machine or a piece of software that +one connects to, and then requests information from. Gnus does not +connect directly to any real servers, but does all transactions through +one back end or other. But that's just putting one layer more between +the actual media and Gnus, so we might just as well say that each +back end represents a virtual server. -@vindex gnus-break-pages +For instance, the @code{nntp} back end may be used to connect to several +different actual @acronym{NNTP} servers, or, perhaps, to many different ports +on the same actual @acronym{NNTP} server. You tell Gnus which back end to +use, and what parameters to set by specifying a @dfn{select method}. -@item gnus-break-pages -Controls whether @dfn{page breaking} is to take place. If this variable -is non-@code{nil}, the articles will be divided into pages whenever a -page delimiter appears in the article. If this variable is @code{nil}, -paging will not be done. +These select method specifications can sometimes become quite +complicated---say, for instance, that you want to read from the +@acronym{NNTP} server @samp{news.funet.fi} on port number 13, which +hangs if queried for @acronym{NOV} headers and has a buggy select. Ahem. +Anyway, if you had to specify that for each group that used this +server, that would be too much work, so Gnus offers a way of naming +select methods, which is what you do in the server buffer. -@item gnus-page-delimiter -@vindex gnus-page-delimiter -This is the delimiter mentioned above. By default, it is @samp{^L} -(formfeed). +To enter the server buffer, use the @kbd{^} +(@code{gnus-group-enter-server-mode}) command in the group buffer. -@cindex IDNA -@cindex internationalized domain names -@vindex gnus-use-idna -@item gnus-use-idna -This variable controls whether Gnus performs IDNA decoding of -internationalized domain names inside @samp{From}, @samp{To} and -@samp{Cc} headers. @xref{IDNA, ,IDNA,message, The Message Manual}, -for how to compose such messages. This requires -@uref{http://www.gnu.org/software/libidn/, GNU Libidn}, and this -variable is only enabled if you have installed it. +@menu +* Server Buffer Format:: You can customize the look of this buffer. +* Server Commands:: Commands to manipulate servers. +* Example Methods:: Examples server specifications. +* Creating a Virtual Server:: An example session. +* Server Variables:: Which variables to set. +* Servers and Methods:: You can use server names as select methods. +* Unavailable Servers:: Some servers you try to contact may be down. +@end menu -@vindex gnus-inhibit-images -@item gnus-inhibit-images -If this is non-@code{nil}, inhibit displaying of images inline in the -article body. It is effective to images that are in articles as -@acronym{MIME} parts, and images in @acronym{HTML} articles rendered -when @code{mm-text-html-renderer} (@pxref{Display Customization, -,Display Customization, emacs-mime, The Emacs MIME Manual}) is -@code{shr} or @code{gnus-w3m}. +@vindex gnus-server-mode-hook +@code{gnus-server-mode-hook} is run when creating the server buffer. -@end table +@node Server Buffer Format +@subsection Server Buffer Format +@cindex server buffer format -@node Composing Messages -@chapter Composing Messages -@cindex composing messages -@cindex messages -@cindex mail -@cindex sending mail -@cindex reply -@cindex followup -@cindex post -@cindex using gpg -@cindex using s/mime -@cindex using smime +@vindex gnus-server-line-format +You can change the look of the server buffer lines by changing the +@code{gnus-server-line-format} variable. This is a @code{format}-like +variable, with some simple extensions: -@kindex C-c C-c (Post) -All commands for posting and mailing will put you in a message buffer -where you can edit the article all you like, before you send the -article by pressing @kbd{C-c C-c}. @xref{Top, , Overview, message, -Message Manual}. Where the message will be posted/mailed to depends -on your setup (@pxref{Posting Server}). +@table @samp -@menu -* Mail:: Mailing and replying. -* Posting Server:: What server should you post and mail via? -* POP before SMTP:: You cannot send a mail unless you read a mail. -* Mail and Post:: Mailing and posting at the same time. -* Archived Messages:: Where Gnus stores the messages you've sent. -* Posting Styles:: An easier way to specify who you are. -* Drafts:: Postponing messages and rejected messages. -* Rejected Articles:: What happens if the server doesn't like your article? -* Signing and encrypting:: How to compose secure messages. -@end menu +@item h +How the news is fetched---the back end name. + +@item n +The name of this server. -Also @pxref{Canceling and Superseding} for information on how to -remove articles you shouldn't have posted. +@item w +Where the news is to be fetched from---the address. +@item s +The opened/closed/denied status of the server. -@node Mail -@section Mail +@item a +Whether this server is agentized. +@end table -Variables for customizing outgoing mail: +@vindex gnus-server-mode-line-format +The mode line can also be customized by using the +@code{gnus-server-mode-line-format} variable (@pxref{Mode Line +Formatting}). The following specs are understood: -@table @code -@item gnus-uu-digest-headers -@vindex gnus-uu-digest-headers -List of regexps to match headers included in digested messages. The -headers will be included in the sequence they are matched. If -@code{nil} include all headers. +@table @samp +@item S +Server name. -@item gnus-add-to-list -@vindex gnus-add-to-list -If non-@code{nil}, add a @code{to-list} group parameter to mail groups -that have none when you do a @kbd{a}. +@item M +Server method. +@end table -@item gnus-confirm-mail-reply-to-news -@vindex gnus-confirm-mail-reply-to-news -If non-@code{nil}, Gnus will ask you for a confirmation when you are -about to reply to news articles by mail. If it is @code{nil}, nothing -interferes in what you want to do. This can also be a function -receiving the group name as the only parameter which should return -non-@code{nil} if a confirmation is needed, or a regular expression -matching group names, where confirmation should be asked for. +Also @pxref{Formatting Variables}. -If you find yourself never wanting to reply to mail, but occasionally -press @kbd{R} anyway, this variable might be for you. -@item gnus-confirm-treat-mail-like-news -@vindex gnus-confirm-treat-mail-like-news -If non-@code{nil}, Gnus also requests confirmation according to -@code{gnus-confirm-mail-reply-to-news} when replying to mail. This is -useful for treating mailing lists like newsgroups. +@node Server Commands +@subsection Server Commands +@cindex server commands -@end table +@table @kbd +@item v +@kindex v (Server) +@cindex keys, reserved for users (Server) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. -@node Posting Server -@section Posting Server +@item a +@kindex a (Server) +@findex gnus-server-add-server +Add a new server (@code{gnus-server-add-server}). -When you press those magical @kbd{C-c C-c} keys to ship off your latest -(extremely intelligent, of course) article, where does it go? +@item e +@kindex e (Server) +@findex gnus-server-edit-server +Edit a server (@code{gnus-server-edit-server}). -Thank you for asking. I hate you. +@item S +@kindex S (Server) +@findex gnus-server-show-server +Show the definition of a server (@code{gnus-server-show-server}). -It can be quite complicated. +@item SPACE +@kindex SPACE (Server) +@findex gnus-server-read-server +Browse the current server (@code{gnus-server-read-server}). -@vindex gnus-post-method -When posting news, Message usually invokes @code{message-send-news} -(@pxref{News Variables, , News Variables, message, Message Manual}). -Normally, Gnus will post using the same select method as you're -reading from (which might be convenient if you're reading lots of -groups from different private servers). However. If the server -you're reading from doesn't allow posting, just reading, you probably -want to use some other server to post your (extremely intelligent and -fabulously interesting) articles. You can then set the -@code{gnus-post-method} to some other method: +@item q +@kindex q (Server) +@findex gnus-server-exit +Return to the group buffer (@code{gnus-server-exit}). -@lisp -(setq gnus-post-method '(nnspool "")) -@end lisp +@item k +@kindex k (Server) +@findex gnus-server-kill-server +Kill the current server (@code{gnus-server-kill-server}). -Now, if you've done this, and then this server rejects your article, or -this server is down, what do you do then? To override this variable you -can use a non-zero prefix to the @kbd{C-c C-c} command to force using -the ``current'' server, to get back the default behavior, for posting. +@item y +@kindex y (Server) +@findex gnus-server-yank-server +Yank the previously killed server (@code{gnus-server-yank-server}). -If you give a zero prefix (i.e., @kbd{C-u 0 C-c C-c}) to that command, -Gnus will prompt you for what method to use for posting. +@item c +@kindex c (Server) +@findex gnus-server-copy-server +Copy the current server (@code{gnus-server-copy-server}). -You can also set @code{gnus-post-method} to a list of select methods. -If that's the case, Gnus will always prompt you for what method to use -for posting. +@item l +@kindex l (Server) +@findex gnus-server-list-servers +List all servers (@code{gnus-server-list-servers}). -Finally, if you want to always post using the native select method, -you can set this variable to @code{native}. +@item s +@kindex s (Server) +@findex gnus-server-scan-server +Request that the server scan its sources for new articles +(@code{gnus-server-scan-server}). This is mainly sensible with mail +servers. -@vindex message-send-mail-function -When sending mail, Message invokes the function specified by the -variable @code{message-send-mail-function}. Gnus tries to set it to a -value suitable for your system. -@xref{Mail Variables, ,Mail Variables,message,Message manual}, for more -information. +@item g +@kindex g (Server) +@findex gnus-server-regenerate-server +Request that the server regenerate all its data structures +(@code{gnus-server-regenerate-server}). This can be useful if you have +a mail back end that has gotten out of sync. -@node POP before SMTP -@section POP before SMTP -@cindex pop before smtp -@findex message-smtpmail-send-it -@findex mail-source-touch-pop +@item z +@kindex z (Server) +@findex gnus-server-compact-server -Does your @acronym{ISP} require the @acronym{POP}-before-@acronym{SMTP} -authentication? It is whether you need to connect to the @acronym{POP} -mail server within a certain time before sending mails. If so, there is -a convenient way. To do that, put the following lines in your -@file{~/.gnus.el} file: +Compact all groups in the server under point +(@code{gnus-server-compact-server}). Currently implemented only in +nnml (@pxref{Mail Spool}). This removes gaps between article numbers, +hence getting a correct total article count. -@lisp -(setq message-send-mail-function 'message-smtpmail-send-it) -(add-hook 'message-send-mail-hook 'mail-source-touch-pop) -@end lisp +@end table -@noindent -It means to let Gnus connect to the @acronym{POP} mail server in advance -whenever you send a mail. The @code{mail-source-touch-pop} function -does only a @acronym{POP} authentication according to the value of -@code{mail-sources} without fetching mails, just before sending a mail. -Note that you have to use @code{message-smtpmail-send-it} which runs -@code{message-send-mail-hook} rather than @code{smtpmail-send-it} and -set the value of @code{mail-sources} for a @acronym{POP} connection -correctly. @xref{Mail Sources}. +Some more commands for closing, disabling, and re-opening servers are +listed in @ref{Unavailable Servers}. -If you have two or more @acronym{POP} mail servers set in -@code{mail-sources}, you may want to specify one of them to -@code{mail-source-primary-source} as the @acronym{POP} mail server to be -used for the @acronym{POP}-before-@acronym{SMTP} authentication. If it -is your primary @acronym{POP} mail server (i.e., you are fetching mails -mainly from that server), you can set it permanently as follows: -@lisp -(setq mail-source-primary-source - '(pop :server "pop3.mail.server" - :password "secret")) -@end lisp +@node Example Methods +@subsection Example Methods -@noindent -Otherwise, bind it dynamically only when performing the -@acronym{POP}-before-@acronym{SMTP} authentication as follows: +Most select methods are pretty simple and self-explanatory: @lisp -(add-hook 'message-send-mail-hook - (lambda () - (let ((mail-source-primary-source - '(pop :server "pop3.mail.server" - :password "secret"))) - (mail-source-touch-pop)))) +(nntp "news.funet.fi") @end lisp -@node Mail and Post -@section Mail and Post - -Here's a list of variables relevant to both mailing and -posting: +Reading directly from the spool is even simpler: -@table @code -@item gnus-mailing-list-groups -@findex gnus-mailing-list-groups -@cindex mailing lists +@lisp +(nnspool "") +@end lisp -If your news server offers groups that are really mailing lists -gatewayed to the @acronym{NNTP} server, you can read those groups without -problems, but you can't post/followup to them without some difficulty. -One solution is to add a @code{to-address} to the group parameters -(@pxref{Group Parameters}). An easier thing to do is set the -@code{gnus-mailing-list-groups} to a regexp that matches the groups that -really are mailing lists. Then, at least, followups to the mailing -lists will work most of the time. Posting to these groups (@kbd{a}) is -still a pain, though. +As you can see, the first element in a select method is the name of the +back end, and the second is the @dfn{address}, or @dfn{name}, if you +will. -@item gnus-user-agent -@vindex gnus-user-agent -@cindex User-Agent +After these two elements, there may be an arbitrary number of +@code{(@var{variable} @var{form})} pairs. -This variable controls which information should be exposed in the -User-Agent header. It can be a list of symbols or a string. Valid -symbols are @code{gnus} (show Gnus version) and @code{emacs} (show Emacs -version). In addition to the Emacs version, you can add @code{codename} -(show (S)XEmacs codename) or either @code{config} (show system -configuration) or @code{type} (show system type). If you set it to a -string, be sure to use a valid format, see RFC 2616. +To go back to the first example---imagine that you want to read from +port 15 on that machine. This is what the select method should +look like then: -@end table +@lisp +(nntp "news.funet.fi" (nntp-port-number 15)) +@end lisp -You may want to do spell-checking on messages that you send out. Or, if -you don't want to spell-check by hand, you could add automatic -spell-checking via the @code{ispell} package: +You should read the documentation to each back end to find out what +variables are relevant, but here's an @code{nnmh} example: + +@code{nnmh} is a mail back end that reads a spool-like structure. Say +you have two structures that you wish to access: One is your private +mail spool, and the other is a public one. Here's the possible spec for +your private mail: -@cindex ispell -@findex ispell-message @lisp -(add-hook 'message-send-hook 'ispell-message) +(nnmh "private" (nnmh-directory "~/private/mail/")) @end lisp -If you want to change the @code{ispell} dictionary based on what group -you're in, you could say something like the following: +(This server is then called @samp{private}, but you may have guessed +that.) + +Here's the method for a public spool: @lisp -(add-hook 'gnus-select-group-hook - (lambda () - (cond - ((string-match - "^de\\." (gnus-group-real-name gnus-newsgroup-name)) - (ispell-change-dictionary "deutsch")) - (t - (ispell-change-dictionary "english"))))) +(nnmh "public" + (nnmh-directory "/usr/information/spool/") + (nnmh-get-new-mail nil)) @end lisp -Modify to suit your needs. +@cindex proxy +@cindex firewall -@vindex gnus-message-highlight-citation -If @code{gnus-message-highlight-citation} is t, different levels of -citations are highlighted like in Gnus article buffers also in message -mode buffers. +If you are behind a firewall and only have access to the @acronym{NNTP} +server from the firewall machine, you can instruct Gnus to @code{rlogin} +on the firewall machine and connect with +@uref{http://netcat.sourceforge.net/, netcat} from there to the +@acronym{NNTP} server. +Doing this can be rather fiddly, but your virtual server definition +should probably look something like this: -@node Archived Messages -@section Archived Messages -@cindex archived messages -@cindex sent messages +@lisp +(nntp "firewall" + (nntp-open-connection-function nntp-open-via-rlogin-and-netcat) + (nntp-via-address "the.firewall.machine") + (nntp-address "the.real.nntp.host")) +@end lisp -Gnus provides a few different methods for storing the mail and news you -send. The default method is to use the @dfn{archive virtual server} to -store the messages. If you want to disable this completely, the -@code{gnus-message-archive-group} variable should be @code{nil}, which -is the default. +If you want to use the wonderful @code{ssh} program to provide a +compressed connection over the modem line, you could add the following +configuration to the example above: -For archiving interesting messages in a group you read, see the -@kbd{B c} (@code{gnus-summary-copy-article}) command (@pxref{Mail -Group Commands}). +@lisp + (nntp-via-rlogin-command "ssh") +@end lisp -@vindex gnus-message-archive-method -@code{gnus-message-archive-method} says what virtual server Gnus is to -use to store sent messages. The default is @code{"archive"}, and when -actually being used it is expanded into: +See also @code{nntp-via-rlogin-command-switches}. Here's an example for +an indirect connection: @lisp -(nnfolder "archive" - (nnfolder-directory "~/Mail/archive") - (nnfolder-active-file "~/Mail/archive/active") - (nnfolder-get-new-mail nil) - (nnfolder-inhibit-expiry t)) +(setq gnus-select-method + '(nntp "indirect" + (nntp-address "news.server.example") + (nntp-via-user-name "intermediate_user_name") + (nntp-via-address "intermediate.host.example") + (nntp-via-rlogin-command "ssh") + (nntp-via-rlogin-command-switches ("-C")) + (nntp-open-connection-function nntp-open-via-rlogin-and-netcat))) @end lisp -@quotation -@vindex gnus-update-message-archive-method -Note: a server like this is saved in the @file{~/.newsrc.eld} file first -so that it may be used as a real method of the server which is named -@code{"archive"} (that is, for the case where -@code{gnus-message-archive-method} is set to @code{"archive"}) ever -since. If it once has been saved, it will never be updated by default -even if you change the value of @code{gnus-message-archive-method} -afterward. Therefore, the server @code{"archive"} doesn't necessarily -mean the @code{nnfolder} server like this at all times. If you want the -saved method to reflect always the value of -@code{gnus-message-archive-method}, set the -@code{gnus-update-message-archive-method} variable to a non-@code{nil} -value. The default value of this variable is @code{nil}. -@end quotation +This means that you have to have set up @code{ssh-agent} correctly to +provide automatic authorization, of course. -You can, however, use any mail select method (@code{nnml}, -@code{nnmbox}, etc.). @code{nnfolder} is a quite likable select method -for doing this sort of thing, though. If you don't like the default -directory chosen, you could say something like: +If you're behind a firewall, but have direct access to the outside world +through a wrapper command like "runsocks", you could open a socksified +netcat connection to the news server as follows: @lisp -(setq gnus-message-archive-method - '(nnfolder "archive" - (nnfolder-inhibit-expiry t) - (nnfolder-active-file "~/News/sent-mail/active") - (nnfolder-directory "~/News/sent-mail/"))) +(nntp "outside" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-netcat-stream) + (nntp-address "the.news.server")) @end lisp -@vindex gnus-message-archive-group -@cindex Gcc -Gnus will insert @code{Gcc} headers in all outgoing messages that point -to one or more group(s) on that server. Which group to use is -determined by the @code{gnus-message-archive-group} variable. - -This variable can be used to do the following: - -@table @asis -@item a string -Messages will be saved in that group. -Note that you can include a select method in the group name, then the -message will not be stored in the select method given by -@code{gnus-message-archive-method}, but in the select method specified -by the group name, instead. Suppose @code{gnus-message-archive-method} -has the default value shown above. Then setting -@code{gnus-message-archive-group} to @code{"foo"} means that outgoing -messages are stored in @samp{nnfolder+archive:foo}, but if you use the -value @code{"nnml:foo"}, then outgoing messages will be stored in -@samp{nnml:foo}. +@node Creating a Virtual Server +@subsection Creating a Virtual Server -@item a list of strings -Messages will be saved in all those groups. +If you're saving lots of articles in the cache by using persistent +articles, you may want to create a virtual server to read the cache. -@item an alist of regexps, functions and forms -When a key ``matches'', the result is used. +First you need to add a new server. The @kbd{a} command does that. It +would probably be best to use @code{nnml} to read the cache. You +could also use @code{nnspool} or @code{nnmh}, though. -@item @code{nil} -No message archiving will take place. This is the default. -@end table +Type @kbd{a nnml RET cache RET}. -Let's illustrate: +You should now have a brand new @code{nnml} virtual server called +@samp{cache}. You now need to edit it to have the right definitions. +Type @kbd{e} to edit the server. You'll be entered into a buffer that +will contain the following: -Just saving to a single group called @samp{MisK}: @lisp -(setq gnus-message-archive-group "MisK") +(nnml "cache") @end lisp -Saving to two groups, @samp{MisK} and @samp{safe}: -@lisp -(setq gnus-message-archive-group '("MisK" "safe")) -@end lisp +Change that to: -Save to different groups based on what group you are in: @lisp -(setq gnus-message-archive-group - '(("^alt" "sent-to-alt") - ("mail" "sent-to-mail") - (".*" "sent-to-misc"))) +(nnml "cache" + (nnml-directory "~/News/cache/") + (nnml-active-file "~/News/cache/active")) @end lisp -More complex stuff: -@lisp -(setq gnus-message-archive-group - '((if (message-news-p) - "misc-news" - "misc-mail"))) -@end lisp +Type @kbd{C-c C-c} to return to the server buffer. If you now press +@kbd{RET} over this virtual server, you should be entered into a browse +buffer, and you should be able to enter any of the groups displayed. -How about storing all news messages in one file, but storing all mail -messages in one file per month: + +@node Server Variables +@subsection Server Variables +@cindex server variables +@cindex server parameters + +One sticky point when defining variables (both on back ends and in Emacs +in general) is that some variables are typically initialized from other +variables when the definition of the variables is being loaded. If you +change the ``base'' variable after the variables have been loaded, you +won't change the ``derived'' variables. + +This typically affects directory and file variables. For instance, +@code{nnml-directory} is @file{~/Mail/} by default, and all @code{nnml} +directory variables are initialized from that variable, so +@code{nnml-active-file} will be @file{~/Mail/active}. If you define a +new virtual @code{nnml} server, it will @emph{not} suffice to set just +@code{nnml-directory}---you have to explicitly set all the file +variables to be what you want them to be. For a complete list of +variables for each back end, see each back end's section later in this +manual, but here's an example @code{nnml} definition: @lisp -(setq gnus-message-archive-group - '((if (message-news-p) - "misc-news" - (concat "mail." (format-time-string "%Y-%m"))))) +(nnml "public" + (nnml-directory "~/my-mail/") + (nnml-active-file "~/my-mail/active") + (nnml-newsgroups-file "~/my-mail/newsgroups")) @end lisp -@c (XEmacs 19.13 doesn't have @code{format-time-string}, so you'll have to -@c use a different value for @code{gnus-message-archive-group} there.) +Server variables are often called @dfn{server parameters}. + +@node Servers and Methods +@subsection Servers and Methods + +Wherever you would normally use a select method +(e.g. @code{gnus-secondary-select-method}, in the group select method, +when browsing a foreign server) you can use a virtual server name +instead. This could potentially save lots of typing. And it's nice all +over. + + +@node Unavailable Servers +@subsection Unavailable Servers + +If a server seems to be unreachable, Gnus will mark that server as +@code{denied}. That means that any subsequent attempt to make contact +with that server will just be ignored. ``It can't be opened,'' Gnus +will tell you, without making the least effort to see whether that is +actually the case or not. + +That might seem quite naughty, but it does make sense most of the time. +Let's say you have 10 groups subscribed to on server +@samp{nephelococcygia.com}. This server is located somewhere quite far +away from you and the machine is quite slow, so it takes 1 minute just +to find out that it refuses connection to you today. If Gnus were to +attempt to do that 10 times, you'd be quite annoyed, so Gnus won't +attempt to do that. Once it has gotten a single ``connection refused'', +it will regard that server as ``down''. + +So, what happens if the machine was only feeling unwell temporarily? +How do you test to see whether the machine has come up again? + +You jump to the server buffer (@pxref{Server Buffer}) and poke it +with the following commands: + +@table @kbd + +@item O +@kindex O (Server) +@findex gnus-server-open-server +Try to establish connection to the server on the current line +(@code{gnus-server-open-server}). + +@item C +@kindex C (Server) +@findex gnus-server-close-server +Close the connection (if any) to the server +(@code{gnus-server-close-server}). + +@item D +@kindex D (Server) +@findex gnus-server-deny-server +Mark the current server as unreachable +(@code{gnus-server-deny-server}). -Now, when you send a message off, it will be stored in the appropriate -group. (If you want to disable storing for just one particular message, -you can just remove the @code{Gcc} header that has been inserted.) The -archive group will appear in the group buffer the next time you start -Gnus, or the next time you press @kbd{F} in the group buffer. You can -enter it and read the articles in it just like you'd read any other -group. If the group gets really big and annoying, you can simply rename -if (using @kbd{G r} in the group buffer) to something -nice---@samp{misc-mail-september-1995}, or whatever. New messages will -continue to be stored in the old (now empty) group. +@item M-o +@kindex M-o (Server) +@findex gnus-server-open-all-servers +Open the connections to all servers in the buffer +(@code{gnus-server-open-all-servers}). -That's the default method of archiving sent messages. Gnus offers a -different way for the people who don't like the default method. In that -case you should set @code{gnus-message-archive-group} to @code{nil}; -this will disable archiving. +@item M-c +@kindex M-c (Server) +@findex gnus-server-close-all-servers +Close the connections to all servers in the buffer +(@code{gnus-server-close-all-servers}). -@table @code -@item gnus-gcc-mark-as-read -@vindex gnus-gcc-mark-as-read -If non-@code{nil}, automatically mark @code{Gcc} articles as read. +@item R +@kindex R (Server) +@findex gnus-server-remove-denials +Remove all marks to whether Gnus was denied connection from any servers +(@code{gnus-server-remove-denials}). -@item gnus-gcc-externalize-attachments -@vindex gnus-gcc-externalize-attachments -If @code{nil}, attach files as normal parts in Gcc copies; if a regexp -and matches the Gcc group name, attach files as external parts; if it is -@code{all}, attach local files as external parts; if it is other -non-@code{nil}, the behavior is the same as @code{all}, but it may be -changed in the future. +@item c +@kindex c (Server) +@findex gnus-server-copy-server +Copy a server and give it a new name +(@code{gnus-server-copy-server}). This can be useful if you have a +complex method definition, and want to use the same definition towards +a different (physical) server. + +@item L +@kindex L (Server) +@findex gnus-server-offline-server +Set server status to offline (@code{gnus-server-offline-server}). @end table -@node Posting Styles -@section Posting Styles -@cindex posting styles -@cindex styles +@node Getting News +@section Getting News +@cindex reading news +@cindex news back ends -All them variables, they make my head swim. +A newsreader is normally used for reading news. Gnus currently provides +only two methods of getting news---it can read from an @acronym{NNTP} server, +or it can read from a local spool. -So what if you want a different @code{Organization} and signature based -on what groups you post to? And you post both from your home machine -and your work machine, and you want different @code{From} lines, and so -on? +@menu +* NNTP:: Reading news from an @acronym{NNTP} server. +* News Spool:: Reading news from the local spool. +@end menu -@vindex gnus-posting-styles -One way to do stuff like that is to write clever hooks that change the -variables you need to have changed. That's a bit boring, so somebody -came up with the bright idea of letting the user specify these things in -a handy alist. Here's an example of a @code{gnus-posting-styles} -variable: -@lisp -((".*" - (signature "Peace and happiness") - (organization "What me?")) - ("^comp" - (signature "Death to everybody")) - ("comp.emacs.i-love-it" - (organization "Emacs is it"))) -@end lisp +@node NNTP +@subsection NNTP +@cindex nntp -As you might surmise from this example, this alist consists of several -@dfn{styles}. Each style will be applicable if the first element -``matches'', in some form or other. The entire alist will be iterated -over, from the beginning towards the end, and each match will be -applied, which means that attributes in later styles that match override -the same attributes in earlier matching styles. So -@samp{comp.programming.literate} will have the @samp{Death to everybody} -signature and the @samp{What me?} @code{Organization} header. +Subscribing to a foreign group from an @acronym{NNTP} server is rather easy. +You just specify @code{nntp} as method and the address of the @acronym{NNTP} +server as the, uhm, address. -The first element in each style is called the @code{match}. If it's a -string, then Gnus will try to regexp match it against the group name. -If it is the form @code{(header @var{match} @var{regexp})}, then Gnus -will look in the original article for a header whose name is -@var{match} and compare that @var{regexp}. @var{match} and -@var{regexp} are strings. (The original article is the one you are -replying or following up to. If you are not composing a reply or a -followup, then there is nothing to match against.) If the -@code{match} is a function symbol, that function will be called with -no arguments. If it's a variable symbol, then the variable will be -referenced. If it's a list, then that list will be @code{eval}ed. In -any case, if this returns a non-@code{nil} value, then the style is -said to @dfn{match}. +If the @acronym{NNTP} server is located at a non-standard port, setting the +third element of the select method to this port number should allow you +to connect to the right port. You'll have to edit the group info for +that (@pxref{Foreign Groups}). -Each style may contain an arbitrary amount of @dfn{attributes}. Each -attribute consists of a @code{(@var{name} @var{value})} pair. In -addition, you can also use the @code{(@var{name} :file @var{value})} -form or the @code{(@var{name} :value @var{value})} form. Where -@code{:file} signifies @var{value} represents a file name and its -contents should be used as the attribute value, @code{:value} signifies -@var{value} does not represent a file name explicitly. The attribute -name can be one of: +The name of the foreign group can be the same as a native group. In +fact, you can subscribe to the same group from as many different servers +you feel like. There will be no name collisions. -@itemize @bullet -@item @code{signature} -@item @code{signature-file} -@item @code{x-face-file} -@item @code{address}, overriding @code{user-mail-address} -@item @code{name}, overriding @code{(user-full-name)} -@item @code{body} -@end itemize +The following variables can be used to create a virtual @code{nntp} +server: -Note that the @code{signature-file} attribute honors the variable -@code{message-signature-directory}. +@table @code -The attribute name can also be a string or a symbol. In that case, -this will be used as a header name, and the value will be inserted in -the headers of the article; if the value is @code{nil}, the header -name will be removed. If the attribute name is @code{eval}, the form -is evaluated, and the result is thrown away. +@item nntp-server-opened-hook +@vindex nntp-server-opened-hook +@cindex @sc{mode reader} +@cindex authinfo +@cindex authentication +@cindex nntp authentication +@findex nntp-send-authinfo +@findex nntp-send-mode-reader +is run after a connection has been made. It can be used to send +commands to the @acronym{NNTP} server after it has been contacted. By +default it sends the command @code{MODE READER} to the server with the +@code{nntp-send-mode-reader} function. This function should always be +present in this hook. -The attribute value can be a string, a function with zero arguments -(the return value will be used), a variable (its value will be used) -or a list (it will be @code{eval}ed and the return value will be -used). The functions and sexps are called/@code{eval}ed in the -message buffer that is being set up. The headers of the current -article are available through the @code{message-reply-headers} -variable, which is a vector of the following headers: number subject -from date id references chars lines xref extra. +@item nntp-authinfo-function +@vindex nntp-authinfo-function +@findex nntp-send-authinfo +@vindex nntp-authinfo-file +This function will be used to send @samp{AUTHINFO} to the @acronym{NNTP} +server. The default function is @code{nntp-send-authinfo}, which looks +through your @file{~/.authinfo} (or whatever you've set the +@code{nntp-authinfo-file} variable to) for applicable entries. If none +are found, it will prompt you for a login name and a password. The +format of the @file{~/.authinfo} file is (almost) the same as the +@code{ftp} @file{~/.netrc} file, which is defined in the @code{ftp} +manual page, but here are the salient facts: -In the case of a string value, if the @code{match} is a regular -expression, a @samp{gnus-match-substitute-replacement} is proceed on -the value to replace the positional parameters @samp{\@var{n}} by the -corresponding parenthetical matches (see @xref{Replacing the Text that -Matched, , Text Replacement, elisp, The Emacs Lisp Reference Manual}.) +@enumerate +@item +The file contains one or more line, each of which define one server. -@vindex message-reply-headers +@item +Each line may contain an arbitrary number of token/value pairs. -If you wish to check whether the message you are about to compose is -meant to be a news article or a mail message, you can check the values -of the @code{message-news-p} and @code{message-mail-p} functions. +The valid tokens include @samp{machine}, @samp{login}, @samp{password}, +@samp{default}. In addition Gnus introduces two new tokens, not present +in the original @file{.netrc}/@code{ftp} syntax, namely @samp{port} and +@samp{force}. (This is the only way the @file{.authinfo} file format +deviates from the @file{.netrc} file format.) @samp{port} is used to +indicate what port on the server the credentials apply to and +@samp{force} is explained below. -@findex message-mail-p -@findex message-news-p +@end enumerate -So here's a new example: +Here's an example file: -@lisp -(setq gnus-posting-styles - '((".*" - (signature-file "~/.signature") - (name "User Name") - (x-face-file "~/.xface") - (x-url (getenv "WWW_HOME")) - (organization "People's Front Against MWM")) - ("^rec.humor" - (signature my-funny-signature-randomizer)) - ((equal (system-name) "gnarly") ;; @r{A form} - (signature my-quote-randomizer)) - (message-news-p ;; @r{A function symbol} - (signature my-news-signature)) - (window-system ;; @r{A value symbol} - ("X-Window-System" (format "%s" window-system))) - ;; @r{If I'm replying to Larsi, set the Organization header.} - ((header "from" "larsi.*org") - (Organization "Somewhere, Inc.")) - ((posting-from-work-p) ;; @r{A user defined function} - (signature-file "~/.work-signature") - (address "user@@bar.foo") - (body "You are fired.\n\nSincerely, your boss.") - (organization "Important Work, Inc")) - ("nnml:.*" - (From (with-current-buffer gnus-article-buffer - (message-fetch-field "to")))) - ("^nn.+:" - (signature-file "~/.mail-signature")))) -@end lisp +@example +machine news.uio.no login larsi password geheimnis +machine nntp.ifi.uio.no login larsi force yes +@end example + +The token/value pairs may appear in any order; @samp{machine} doesn't +have to be first, for instance. + +In this example, both login name and password have been supplied for the +former server, while the latter has only the login name listed, and the +user will be prompted for the password. The latter also has the +@samp{force} tag, which means that the authinfo will be sent to the +@var{nntp} server upon connection; the default (i.e., when there is not +@samp{force} tag) is to not send authinfo to the @var{nntp} server +until the @var{nntp} server asks for it. -The @samp{nnml:.*} rule means that you use the @code{To} address as the -@code{From} address in all your outgoing replies, which might be handy -if you fill many roles. -You may also use @code{message-alternative-emails} instead. -@xref{Message Headers, ,Message Headers, message, Message Manual}. +You can also add @samp{default} lines that will apply to all servers +that don't have matching @samp{machine} lines. -@node Drafts -@section Drafts -@cindex drafts +@example +default force yes +@end example -If you are writing a message (mail or news) and suddenly remember that -you have a steak in the oven (or some pesto in the food processor, you -craaazy vegetarians), you'll probably wish there was a method to save -the message you are writing so that you can continue editing it some -other day, and send it when you feel its finished. +This will force sending @samp{AUTHINFO} commands to all servers not +previously mentioned. -Well, don't worry about it. Whenever you start composing a message of -some sort using the Gnus mail and post commands, the buffer you get will -automatically associate to an article in a special @dfn{draft} group. -If you save the buffer the normal way (@kbd{C-x C-s}, for instance), the -article will be saved there. (Auto-save files also go to the draft -group.) +Remember to not leave the @file{~/.authinfo} file world-readable. -@cindex nndraft -@vindex nndraft-directory -The draft group is a special group (which is implemented as an -@code{nndraft} group, if you absolutely have to know) called -@samp{nndraft:drafts}. The variable @code{nndraft-directory} says where -@code{nndraft} is to store its files. What makes this group special is -that you can't tick any articles in it or mark any articles as -read---all articles in the group are permanently unread. +@item nntp-server-action-alist +@vindex nntp-server-action-alist +This is a list of regexps to match on server types and actions to be +taken when matches are made. For instance, if you want Gnus to beep +every time you connect to innd, you could say something like: -If the group doesn't exist, it will be created and you'll be subscribed -to it. The only way to make it disappear from the Group buffer is to -unsubscribe it. The special properties of the draft group comes from -a group property (@pxref{Group Parameters}), and if lost the group -behaves like any other group. This means the commands below will not -be available. To restore the special properties of the group, the -simplest way is to kill the group, using @kbd{C-k}, and restart -Gnus. The group is automatically created again with the -correct parameters. The content of the group is not lost. +@lisp +(setq nntp-server-action-alist + '(("innd" (ding)))) +@end lisp -@c @findex gnus-dissociate-buffer-from-draft -@c @kindex C-c M-d (Mail) -@c @kindex C-c M-d (Post) -@c @findex gnus-associate-buffer-with-draft -@c @kindex C-c C-d (Mail) -@c @kindex C-c C-d (Post) -@c If you're writing some super-secret message that you later want to -@c encode with PGP before sending, you may wish to turn the auto-saving -@c (and association with the draft group) off. You never know who might be -@c interested in reading all your extremely valuable and terribly horrible -@c and interesting secrets. The @kbd{C-c M-d} -@c (@code{gnus-dissociate-buffer-from-draft}) command does that for you. -@c If you change your mind and want to turn the auto-saving back on again, -@c @kbd{C-c C-d} (@code{gnus-associate-buffer-with-draft} does that. -@c -@c @vindex gnus-use-draft -@c To leave association with the draft group off by default, set -@c @code{gnus-use-draft} to @code{nil}. It is @code{t} by default. +You probably don't want to do that, though. -@findex gnus-draft-edit-message -@kindex D e (Draft) -When you want to continue editing the article, you simply enter the -draft group and push @kbd{D e} (@code{gnus-draft-edit-message}) to do -that. You will be placed in a buffer where you left off. +The default value is -Rejected articles will also be put in this draft group (@pxref{Rejected -Articles}). +@lisp +'(("nntpd 1\\.5\\.11t" + (remove-hook 'nntp-server-opened-hook + 'nntp-send-mode-reader))) +@end lisp -@findex gnus-draft-send-all-messages -@kindex D s (Draft) -@findex gnus-draft-send-message -@kindex D S (Draft) -If you have lots of rejected messages you want to post (or mail) without -doing further editing, you can use the @kbd{D s} command -(@code{gnus-draft-send-message}). This command understands the -process/prefix convention (@pxref{Process/Prefix}). The @kbd{D S} -command (@code{gnus-draft-send-all-messages}) will ship off all messages -in the buffer. +This ensures that Gnus doesn't send the @code{MODE READER} command to +nntpd 1.5.11t, since that command chokes that server, I've been told. -@findex gnus-draft-toggle-sending -@kindex D t (Draft) -If you have some messages that you wish not to send, you can use the -@kbd{D t} (@code{gnus-draft-toggle-sending}) command to mark the message -as unsendable. This is a toggling command. +@item nntp-maximum-request +@vindex nntp-maximum-request +If the @acronym{NNTP} server doesn't support @acronym{NOV} headers, this back end +will collect headers by sending a series of @code{head} commands. To +speed things up, the back end sends lots of these commands without +waiting for reply, and then reads all the replies. This is controlled +by the @code{nntp-maximum-request} variable, and is 400 by default. If +your network is buggy, you should set this to 1. -Finally, if you want to delete a draft, use the normal @kbd{B DEL} -command (@pxref{Mail Group Commands}). +@item nntp-connection-timeout +@vindex nntp-connection-timeout +If you have lots of foreign @code{nntp} groups that you connect to +regularly, you're sure to have problems with @acronym{NNTP} servers not +responding properly, or being too loaded to reply within reasonable +time. This is can lead to awkward problems, which can be helped +somewhat by setting @code{nntp-connection-timeout}. This is an integer +that says how many seconds the @code{nntp} back end should wait for a +connection before giving up. If it is @code{nil}, which is the default, +no timeouts are done. + +@item nntp-nov-is-evil +@vindex nntp-nov-is-evil +If the @acronym{NNTP} server does not support @acronym{NOV}, you could set this +variable to @code{t}, but @code{nntp} usually checks automatically whether @acronym{NOV} +can be used. +@item nntp-xover-commands +@vindex nntp-xover-commands +@cindex @acronym{NOV} +@cindex XOVER +List of strings used as commands to fetch @acronym{NOV} lines from a +server. The default value of this variable is @code{("XOVER" +"XOVERVIEW")}. -@node Rejected Articles -@section Rejected Articles -@cindex rejected articles +@item nntp-nov-gap +@vindex nntp-nov-gap +@code{nntp} normally sends just one big request for @acronym{NOV} lines to +the server. The server responds with one huge list of lines. However, +if you have read articles 2-5000 in the group, and only want to read +article 1 and 5001, that means that @code{nntp} will fetch 4999 @acronym{NOV} +lines that you will not need. This variable says how +big a gap between two consecutive articles is allowed to be before the +@code{XOVER} request is split into several request. Note that if your +network is fast, setting this variable to a really small number means +that fetching will probably be slower. If this variable is @code{nil}, +@code{nntp} will never split requests. The default is 5. -Sometimes a news server will reject an article. Perhaps the server -doesn't like your face. Perhaps it just feels miserable. Perhaps -@emph{there be demons}. Perhaps you have included too much cited text. -Perhaps the disk is full. Perhaps the server is down. +@item nntp-xref-number-is-evil +@vindex nntp-xref-number-is-evil +When Gnus refers to an article having the @code{Message-ID} that a user +specifies or having the @code{Message-ID} of the parent article of the +current one (@pxref{Finding the Parent}), Gnus sends a @code{HEAD} +command to the @acronym{NNTP} server to know where it is, and the server +returns the data containing the pairs of a group and an article number +in the @code{Xref} header. Gnus normally uses the article number to +refer to the article if the data shows that that article is in the +current group, while it uses the @code{Message-ID} otherwise. However, +some news servers, e.g., ones running Diablo, run multiple engines +having the same articles but article numbers are not kept synchronized +between them. In that case, the article number that appears in the +@code{Xref} header varies by which engine is chosen, so you cannot refer +to the parent article that is in the current group, for instance. If +you connect to such a server, set this variable to a non-@code{nil} +value, and Gnus never uses article numbers. For example: -These situations are, of course, totally beyond the control of Gnus. -(Gnus, of course, loves the way you look, always feels great, has angels -fluttering around inside of it, doesn't care about how much cited text -you include, never runs full and never goes down.) So Gnus saves these -articles until some later time when the server feels better. +@lisp +(setq gnus-select-method + '(nntp "newszilla" + (nntp-address "newszilla.example.com") + (nntp-xref-number-is-evil t) + @dots{})) +@end lisp -The rejected articles will automatically be put in a special draft group -(@pxref{Drafts}). When the server comes back up again, you'd then -typically enter that group and send all the articles off. +The default value of this server variable is @code{nil}. -@node Signing and encrypting -@section Signing and encrypting -@cindex using gpg -@cindex using s/mime -@cindex using smime +@item nntp-prepare-server-hook +@vindex nntp-prepare-server-hook +A hook run before attempting to connect to an @acronym{NNTP} server. -Gnus can digitally sign and encrypt your messages, using vanilla -@acronym{PGP} format or @acronym{PGP/MIME} or @acronym{S/MIME}. For -decoding such messages, see the @code{mm-verify-option} and -@code{mm-decrypt-option} options (@pxref{Security}). +@item nntp-record-commands +@vindex nntp-record-commands +If non-@code{nil}, @code{nntp} will log all commands it sends to the +@acronym{NNTP} server (along with a timestamp) in the @samp{*nntp-log*} +buffer. This is useful if you are debugging a Gnus/@acronym{NNTP} connection +that doesn't seem to work. -@vindex gnus-message-replysign -@vindex gnus-message-replyencrypt -@vindex gnus-message-replysignencrypted -Often, you would like to sign replies to people who send you signed -messages. Even more often, you might want to encrypt messages which -are in reply to encrypted messages. Gnus offers -@code{gnus-message-replysign} to enable the former, and -@code{gnus-message-replyencrypt} for the latter. In addition, setting -@code{gnus-message-replysignencrypted} (on by default) will sign -automatically encrypted messages. +@item nntp-open-connection-function +@vindex nntp-open-connection-function +It is possible to customize how the connection to the nntp server will +be opened. If you specify an @code{nntp-open-connection-function} +parameter, Gnus will use that function to establish the connection. +Seven pre-made functions are supplied. These functions can be grouped +in two categories: direct connection functions (four pre-made), and +indirect ones (three pre-made). + +@item nntp-never-echoes-commands +@vindex nntp-never-echoes-commands +Non-@code{nil} means the nntp server never echoes commands. It is +reported that some nntps server doesn't echo commands. So, you may want +to set this to non-@code{nil} in the method for such a server setting +@code{nntp-open-connection-function} to @code{nntp-open-ssl-stream} for +example. The default value is @code{nil}. Note that the +@code{nntp-open-connection-functions-never-echo-commands} variable +overrides the @code{nil} value of this variable. + +@item nntp-open-connection-functions-never-echo-commands +@vindex nntp-open-connection-functions-never-echo-commands +List of functions that never echo commands. Add or set a function which +you set to @code{nntp-open-connection-function} to this list if it does +not echo commands. Note that a non-@code{nil} value of the +@code{nntp-never-echoes-commands} variable overrides this variable. The +default value is @code{(nntp-open-network-stream)}. + +@item nntp-prepare-post-hook +@vindex nntp-prepare-post-hook +A hook run just before posting an article. If there is no +@code{Message-ID} header in the article and the news server provides the +recommended ID, it will be added to the article before running this +hook. It is useful to make @code{Cancel-Lock} headers even if you +inhibit Gnus to add a @code{Message-ID} header, you could say: + +@lisp +(add-hook 'nntp-prepare-post-hook 'canlock-insert-header) +@end lisp -Instructing @acronym{MML} to perform security operations on a -@acronym{MIME} part is done using the @kbd{C-c C-m s} key map for -signing and the @kbd{C-c C-m c} key map for encryption, as follows. +Note that not all servers support the recommended ID. This works for +INN versions 2.3.0 and later, for instance. -@table @kbd +@item nntp-server-list-active-group +If @code{nil}, then always use @samp{GROUP} instead of @samp{LIST +ACTIVE}. This is usually slower, but on misconfigured servers that +don't update their active files often, this can help. -@item C-c C-m s s -@kindex C-c C-m s s (Message) -@findex mml-secure-message-sign-smime -Digitally sign current message using @acronym{S/MIME}. +@end table -@item C-c C-m s o -@kindex C-c C-m s o (Message) -@findex mml-secure-message-sign-pgp +@menu +* Direct Functions:: Connecting directly to the server. +* Indirect Functions:: Connecting indirectly to the server. +* Common Variables:: Understood by several connection functions. +* NNTP marks:: Storing marks for @acronym{NNTP} servers. +@end menu -Digitally sign current message using @acronym{PGP}. -@item C-c C-m s p -@kindex C-c C-m s p (Message) -@findex mml-secure-message-sign-pgp +@node Direct Functions +@subsubsection Direct Functions +@cindex direct connection functions -Digitally sign current message using @acronym{PGP/MIME}. +These functions are called direct because they open a direct connection +between your machine and the @acronym{NNTP} server. The behavior of these +functions is also affected by commonly understood variables +(@pxref{Common Variables}). -@item C-c C-m c s -@kindex C-c C-m c s (Message) -@findex mml-secure-message-encrypt-smime +@table @code +@findex nntp-open-network-stream +@item nntp-open-network-stream +This is the default, and simply connects to some port or other on the +remote system. If both Emacs and the server supports it, the +connection will be upgraded to an encrypted @acronym{STARTTLS} +connection automatically. -Digitally encrypt current message using @acronym{S/MIME}. +@item network-only +The same as the above, but don't do automatic @acronym{STARTTLS} upgrades. -@item C-c C-m c o -@kindex C-c C-m c o (Message) -@findex mml-secure-message-encrypt-pgp +@findex nntp-open-tls-stream +@item nntp-open-tls-stream +Opens a connection to a server over a @dfn{secure} channel. To use +this you must have @uref{http://www.gnu.org/software/gnutls/, GNUTLS} +installed. You then define a server as follows: -Digitally encrypt current message using @acronym{PGP}. +@lisp +;; @r{"nntps" is port 563 and is predefined in our @file{/etc/services}} +;; @r{however, @samp{gnutls-cli -p} doesn't like named ports.} +;; +(nntp "snews.bar.com" + (nntp-open-connection-function nntp-open-tls-stream) + (nntp-port-number 563) + (nntp-address "snews.bar.com")) +@end lisp -@item C-c C-m c p -@kindex C-c C-m c p (Message) -@findex mml-secure-message-encrypt-pgpmime +@findex nntp-open-ssl-stream +@item nntp-open-ssl-stream +Opens a connection to a server over a @dfn{secure} channel. To use +this you must have @uref{http://www.openssl.org, OpenSSL} or +@uref{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL, SSLeay} installed. You +then define a server as follows: -Digitally encrypt current message using @acronym{PGP/MIME}. +@lisp +;; @r{"snews" is port 563 and is predefined in our @file{/etc/services}} +;; @r{however, @samp{openssl s_client -port} doesn't like named ports.} +;; +(nntp "snews.bar.com" + (nntp-open-connection-function nntp-open-ssl-stream) + (nntp-port-number 563) + (nntp-address "snews.bar.com")) +@end lisp -@item C-c C-m C-n -@kindex C-c C-m C-n (Message) -@findex mml-unsecure-message -Remove security related @acronym{MML} tags from message. +@findex nntp-open-netcat-stream +@item nntp-open-netcat-stream +Opens a connection to an @acronym{NNTP} server using the @code{netcat} +program. You might wonder why this function exists, since we have +the default @code{nntp-open-network-stream} which would do the job. (One +of) the reason(s) is that if you are behind a firewall but have direct +connections to the outside world thanks to a command wrapper like +@code{runsocks}, you can use it like this: + +@lisp +(nntp "socksified" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-netcat-stream) + (nntp-address "the.news.server")) +@end lisp + +With the default method, you would need to wrap your whole Emacs +session, which is not a good idea. + +@findex nntp-open-telnet-stream +@item nntp-open-telnet-stream +Like @code{nntp-open-netcat-stream}, but uses @code{telnet} rather than +@code{netcat}. @code{telnet} is a bit less robust because of things +like line-end-conversion, but sometimes netcat is simply +not available. The previous example would turn into: +@lisp +(nntp "socksified" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-telnet-stream) + (nntp-address "the.news.server") + (nntp-end-of-line "\n")) +@end lisp @end table -@xref{Security, ,Security, message, Message Manual}, for more information. -@node Select Methods -@chapter Select Methods -@cindex foreign groups -@cindex select methods +@node Indirect Functions +@subsubsection Indirect Functions +@cindex indirect connection functions -A @dfn{foreign group} is a group not read by the usual (or -default) means. It could be, for instance, a group from a different -@acronym{NNTP} server, it could be a virtual group, or it could be your own -personal mail group. +These functions are called indirect because they connect to an +intermediate host before actually connecting to the @acronym{NNTP} server. +All of these functions and related variables are also said to belong to +the ``via'' family of connection: they're all prefixed with ``via'' to make +things cleaner. The behavior of these functions is also affected by +commonly understood variables (@pxref{Common Variables}). -A foreign group (or any group, really) is specified by a @dfn{name} and -a @dfn{select method}. To take the latter first, a select method is a -list where the first element says what back end to use (e.g. @code{nntp}, -@code{nnspool}, @code{nnml}) and the second element is the @dfn{server -name}. There may be additional elements in the select method, where the -value may have special meaning for the back end in question. +@table @code +@item nntp-open-via-rlogin-and-netcat +@findex nntp-open-via-rlogin-and-netcat +Does an @samp{rlogin} on a remote system, and then uses @code{netcat} to connect +to the real @acronym{NNTP} server from there. This is useful for instance if +you need to connect to a firewall machine first. -One could say that a select method defines a @dfn{virtual server}---so -we do just that (@pxref{Server Buffer}). +@code{nntp-open-via-rlogin-and-netcat}-specific variables: -The @dfn{name} of the group is the name the back end will recognize the -group as. +@table @code +@item nntp-via-rlogin-command +@vindex nntp-via-rlogin-command +Command used to log in on the intermediate host. The default is +@samp{rsh}, but @samp{ssh} is a popular alternative. -For instance, the group @samp{soc.motss} on the @acronym{NNTP} server -@samp{some.where.edu} will have the name @samp{soc.motss} and select -method @code{(nntp "some.where.edu")}. Gnus will call this group -@samp{nntp+some.where.edu:soc.motss}, even though the @code{nntp} -back end just knows this group as @samp{soc.motss}. +@item nntp-via-rlogin-command-switches +@vindex nntp-via-rlogin-command-switches +List of strings to be used as the switches to +@code{nntp-via-rlogin-command}. The default is @code{nil}. If you use +@samp{ssh} for @code{nntp-via-rlogin-command}, you may set this to +@samp{("-C")} in order to compress all data connections. +@end table -The different methods all have their peculiarities, of course. +@item nntp-open-via-rlogin-and-telnet +@findex nntp-open-via-rlogin-and-telnet +Does essentially the same, but uses @code{telnet} instead of @samp{netcat} +to connect to the real @acronym{NNTP} server from the intermediate host. +@code{telnet} is a bit less robust because of things like +line-end-conversion, but sometimes @code{netcat} is simply not available. -@menu -* Server Buffer:: Making and editing virtual servers. -* Getting News:: Reading USENET news with Gnus. -* Using IMAP:: Reading mail from @acronym{IMAP}. -* Getting Mail:: Reading your personal mail with Gnus. -* Browsing the Web:: Getting messages from a plethora of Web sources. -* Other Sources:: Reading directories, files. -* Combined Groups:: Combining groups into one group. -* Email Based Diary:: Using mails to manage diary events in Gnus. -* Gnus Unplugged:: Reading news and mail offline. -@end menu +@code{nntp-open-via-rlogin-and-telnet}-specific variables: +@table @code +@item nntp-telnet-command +@vindex nntp-telnet-command +Command used to connect to the real @acronym{NNTP} server from the +intermediate host. The default is @samp{telnet}. -@node Server Buffer -@section Server Buffer +@item nntp-telnet-switches +@vindex nntp-telnet-switches +List of strings to be used as the switches to the +@code{nntp-telnet-command} command. The default is @code{("-8")}. -Traditionally, a @dfn{server} is a machine or a piece of software that -one connects to, and then requests information from. Gnus does not -connect directly to any real servers, but does all transactions through -one back end or other. But that's just putting one layer more between -the actual media and Gnus, so we might just as well say that each -back end represents a virtual server. +@item nntp-via-rlogin-command +@vindex nntp-via-rlogin-command +Command used to log in on the intermediate host. The default is +@samp{rsh}, but @samp{ssh} is a popular alternative. -For instance, the @code{nntp} back end may be used to connect to several -different actual @acronym{NNTP} servers, or, perhaps, to many different ports -on the same actual @acronym{NNTP} server. You tell Gnus which back end to -use, and what parameters to set by specifying a @dfn{select method}. +@item nntp-via-rlogin-command-switches +@vindex nntp-via-rlogin-command-switches +List of strings to be used as the switches to +@code{nntp-via-rlogin-command}. If you use @samp{ssh}, you may need to set +this to @samp{("-t" "-e" "none")} or @samp{("-C" "-t" "-e" "none")} if +the telnet command requires a pseudo-tty allocation on an intermediate +host. The default is @code{nil}. +@end table -These select method specifications can sometimes become quite -complicated---say, for instance, that you want to read from the -@acronym{NNTP} server @samp{news.funet.fi} on port number 13, which -hangs if queried for @acronym{NOV} headers and has a buggy select. Ahem. -Anyway, if you had to specify that for each group that used this -server, that would be too much work, so Gnus offers a way of naming -select methods, which is what you do in the server buffer. +Note that you may want to change the value for @code{nntp-end-of-line} +to @samp{\n} (@pxref{Common Variables}). -To enter the server buffer, use the @kbd{^} -(@code{gnus-group-enter-server-mode}) command in the group buffer. +@item nntp-open-via-telnet-and-telnet +@findex nntp-open-via-telnet-and-telnet +Does essentially the same, but uses @samp{telnet} instead of +@samp{rlogin} to connect to the intermediate host. -@menu -* Server Buffer Format:: You can customize the look of this buffer. -* Server Commands:: Commands to manipulate servers. -* Example Methods:: Examples server specifications. -* Creating a Virtual Server:: An example session. -* Server Variables:: Which variables to set. -* Servers and Methods:: You can use server names as select methods. -* Unavailable Servers:: Some servers you try to contact may be down. -@end menu +@code{nntp-open-via-telnet-and-telnet}-specific variables: -@vindex gnus-server-mode-hook -@code{gnus-server-mode-hook} is run when creating the server buffer. +@table @code +@item nntp-via-telnet-command +@vindex nntp-via-telnet-command +Command used to @code{telnet} the intermediate host. The default is +@samp{telnet}. +@item nntp-via-telnet-switches +@vindex nntp-via-telnet-switches +List of strings to be used as the switches to the +@code{nntp-via-telnet-command} command. The default is @samp{("-8")}. -@node Server Buffer Format -@subsection Server Buffer Format -@cindex server buffer format +@item nntp-via-user-password +@vindex nntp-via-user-password +Password to use when logging in on the intermediate host. -@vindex gnus-server-line-format -You can change the look of the server buffer lines by changing the -@code{gnus-server-line-format} variable. This is a @code{format}-like -variable, with some simple extensions: +@item nntp-via-envuser +@vindex nntp-via-envuser +If non-@code{nil}, the intermediate @code{telnet} session (client and +server both) will support the @code{ENVIRON} option and not prompt for +login name. This works for Solaris @code{telnet}, for instance. -@table @samp +@item nntp-via-shell-prompt +@vindex nntp-via-shell-prompt +Regexp matching the shell prompt on the intermediate host. The default +is @samp{bash\\|\$ *\r?$\\|> *\r?}. -@item h -How the news is fetched---the back end name. +@end table -@item n -The name of this server. +Note that you may want to change the value for @code{nntp-end-of-line} +to @samp{\n} (@pxref{Common Variables}). +@end table -@item w -Where the news is to be fetched from---the address. -@item s -The opened/closed/denied status of the server. +Here are some additional variables that are understood by all the above +functions: -@item a -Whether this server is agentized. -@end table +@table @code -@vindex gnus-server-mode-line-format -The mode line can also be customized by using the -@code{gnus-server-mode-line-format} variable (@pxref{Mode Line -Formatting}). The following specs are understood: +@item nntp-via-user-name +@vindex nntp-via-user-name +User name to use when connecting to the intermediate host. -@table @samp -@item S -Server name. +@item nntp-via-address +@vindex nntp-via-address +Address of the intermediate host to connect to. -@item M -Server method. @end table -Also @pxref{Formatting Variables}. +@node Common Variables +@subsubsection Common Variables -@node Server Commands -@subsection Server Commands -@cindex server commands +The following variables affect the behavior of all, or several of the +pre-made connection functions. When not specified, all functions are +affected (the values of the following variables will be used as the +default if each virtual @code{nntp} server doesn't specify those server +variables individually). -@table @kbd +@table @code -@item v -@kindex v (Server) -@cindex keys, reserved for users (Server) -The key @kbd{v} is reserved for users. You can bind it to some -command or better use it as a prefix key. +@item nntp-pre-command +@vindex nntp-pre-command +A command wrapper to use when connecting through a non native +connection function (all except @code{nntp-open-network-stream}, +@code{nntp-open-tls-stream}, and @code{nntp-open-ssl-stream}). This is +where you would put a @samp{SOCKS} wrapper for instance. -@item a -@kindex a (Server) -@findex gnus-server-add-server -Add a new server (@code{gnus-server-add-server}). +@item nntp-address +@vindex nntp-address +The address of the @acronym{NNTP} server. -@item e -@kindex e (Server) -@findex gnus-server-edit-server -Edit a server (@code{gnus-server-edit-server}). +@item nntp-port-number +@vindex nntp-port-number +Port number to connect to the @acronym{NNTP} server. The default is +@samp{nntp}. If you use @acronym{NNTP} over +@acronym{TLS}/@acronym{SSL}, you may want to use integer ports rather +than named ports (i.e, use @samp{563} instead of @samp{snews} or +@samp{nntps}), because external @acronym{TLS}/@acronym{SSL} tools may +not work with named ports. -@item S -@kindex S (Server) -@findex gnus-server-show-server -Show the definition of a server (@code{gnus-server-show-server}). +@item nntp-end-of-line +@vindex nntp-end-of-line +String to use as end-of-line marker when talking to the @acronym{NNTP} +server. This is @samp{\r\n} by default, but should be @samp{\n} when +using a non native telnet connection function. -@item SPACE -@kindex SPACE (Server) -@findex gnus-server-read-server -Browse the current server (@code{gnus-server-read-server}). +@item nntp-netcat-command +@vindex nntp-netcat-command +Command to use when connecting to the @acronym{NNTP} server through +@samp{netcat}. This is @emph{not} for an intermediate host. This is +just for the real @acronym{NNTP} server. The default is +@samp{nc}. -@item q -@kindex q (Server) -@findex gnus-server-exit -Return to the group buffer (@code{gnus-server-exit}). +@item nntp-netcat-switches +@vindex nntp-netcat-switches +A list of switches to pass to @code{nntp-netcat-command}. The default +is @samp{()}. -@item k -@kindex k (Server) -@findex gnus-server-kill-server -Kill the current server (@code{gnus-server-kill-server}). +@end table -@item y -@kindex y (Server) -@findex gnus-server-yank-server -Yank the previously killed server (@code{gnus-server-yank-server}). +@node NNTP marks +@subsubsection NNTP marks +@cindex storing NNTP marks -@item c -@kindex c (Server) -@findex gnus-server-copy-server -Copy the current server (@code{gnus-server-copy-server}). +Gnus stores marks (@pxref{Marking Articles}) for @acronym{NNTP} +servers in marks files. A marks file records what marks you have set +in a group and each file is specific to the corresponding server. +Marks files are stored in @file{~/News/marks} +(@code{nntp-marks-directory}) under a classic hierarchy resembling +that of a news server, for example marks for the group +@samp{gmane.discuss} on the news.gmane.org server will be stored in +the file @file{~/News/marks/news.gmane.org/gmane/discuss/.marks}. -@item l -@kindex l (Server) -@findex gnus-server-list-servers -List all servers (@code{gnus-server-list-servers}). +Marks files are useful because you can copy the @file{~/News/marks} +directory (using rsync, scp or whatever) to another Gnus installation, +and it will realize what articles you have read and marked. The data +in @file{~/News/marks} has priority over the same data in +@file{~/.newsrc.eld}. -@item s -@kindex s (Server) -@findex gnus-server-scan-server -Request that the server scan its sources for new articles -(@code{gnus-server-scan-server}). This is mainly sensible with mail -servers. +Note that marks files are very much server-specific: Gnus remembers +the article numbers so if you don't use the same servers on both +installations things are most likely to break (most @acronym{NNTP} +servers do not use the same article numbers as any other server). +However, if you use servers A, B, C on one installation and servers A, +D, E on the other, you can sync the marks files for A and then you'll +get synchronization for that server between the two installations. -@item g -@kindex g (Server) -@findex gnus-server-regenerate-server -Request that the server regenerate all its data structures -(@code{gnus-server-regenerate-server}). This can be useful if you have -a mail back end that has gotten out of sync. +Using @acronym{NNTP} marks can possibly incur a performance penalty so +if Gnus feels sluggish, try setting the @code{nntp-marks-is-evil} +variable to @code{t}. Marks will then be stored in @file{~/.newsrc.eld}. -@item z -@kindex z (Server) -@findex gnus-server-compact-server +Related variables: -Compact all groups in the server under point -(@code{gnus-server-compact-server}). Currently implemented only in -nnml (@pxref{Mail Spool}). This removes gaps between article numbers, -hence getting a correct total article count. +@table @code + +@item nntp-marks-is-evil +@vindex nntp-marks-is-evil +If non-@code{nil}, this back end will ignore any marks files. The +default is @code{nil}. + +@item nntp-marks-directory +@vindex nntp-marks-directory +The directory where marks for nntp groups will be stored. @end table -Some more commands for closing, disabling, and re-opening servers are -listed in @ref{Unavailable Servers}. +@node News Spool +@subsection News Spool +@cindex nnspool +@cindex news spool -@node Example Methods -@subsection Example Methods +Subscribing to a foreign group from the local spool is extremely easy, +and might be useful, for instance, to speed up reading groups that +contain very big articles---@samp{alt.binaries.pictures.furniture}, for +instance. -Most select methods are pretty simple and self-explanatory: +Anyway, you just specify @code{nnspool} as the method and @code{""} (or +anything else) as the address. -@lisp -(nntp "news.funet.fi") -@end lisp +If you have access to a local spool, you should probably use that as the +native select method (@pxref{Finding the News}). It is normally faster +than using an @code{nntp} select method, but might not be. It depends. +You just have to try to find out what's best at your site. -Reading directly from the spool is even simpler: +@table @code -@lisp -(nnspool "") -@end lisp +@item nnspool-inews-program +@vindex nnspool-inews-program +Program used to post an article. -As you can see, the first element in a select method is the name of the -back end, and the second is the @dfn{address}, or @dfn{name}, if you -will. +@item nnspool-inews-switches +@vindex nnspool-inews-switches +Parameters given to the inews program when posting an article. -After these two elements, there may be an arbitrary number of -@code{(@var{variable} @var{form})} pairs. +@item nnspool-spool-directory +@vindex nnspool-spool-directory +Where @code{nnspool} looks for the articles. This is normally +@file{/usr/spool/news/}. -To go back to the first example---imagine that you want to read from -port 15 on that machine. This is what the select method should -look like then: +@item nnspool-nov-directory +@vindex nnspool-nov-directory +Where @code{nnspool} will look for @acronym{NOV} files. This is normally@* +@file{/usr/spool/news/over.view/}. + +@item nnspool-lib-dir +@vindex nnspool-lib-dir +Where the news lib dir is (@file{/usr/lib/news/} by default). + +@item nnspool-active-file +@vindex nnspool-active-file +The name of the active file. -@lisp -(nntp "news.funet.fi" (nntp-port-number 15)) -@end lisp +@item nnspool-newsgroups-file +@vindex nnspool-newsgroups-file +The name of the group descriptions file. -You should read the documentation to each back end to find out what -variables are relevant, but here's an @code{nnmh} example: +@item nnspool-history-file +@vindex nnspool-history-file +The name of the news history file. -@code{nnmh} is a mail back end that reads a spool-like structure. Say -you have two structures that you wish to access: One is your private -mail spool, and the other is a public one. Here's the possible spec for -your private mail: +@item nnspool-active-times-file +@vindex nnspool-active-times-file +The name of the active date file. -@lisp -(nnmh "private" (nnmh-directory "~/private/mail/")) -@end lisp +@item nnspool-nov-is-evil +@vindex nnspool-nov-is-evil +If non-@code{nil}, @code{nnspool} won't try to use any @acronym{NOV} files +that it finds. -(This server is then called @samp{private}, but you may have guessed -that.) +@item nnspool-sift-nov-with-sed +@vindex nnspool-sift-nov-with-sed +@cindex sed +If non-@code{nil}, which is the default, use @code{sed} to get the +relevant portion from the overview file. If @code{nil}, +@code{nnspool} will load the entire file into a buffer and process it +there. -Here's the method for a public spool: +@end table -@lisp -(nnmh "public" - (nnmh-directory "/usr/information/spool/") - (nnmh-get-new-mail nil)) -@end lisp -@cindex proxy -@cindex firewall +@node Using IMAP +@section Using IMAP +@cindex imap -If you are behind a firewall and only have access to the @acronym{NNTP} -server from the firewall machine, you can instruct Gnus to @code{rlogin} -on the firewall machine and connect with -@uref{http://netcat.sourceforge.net/, netcat} from there to the -@acronym{NNTP} server. -Doing this can be rather fiddly, but your virtual server definition -should probably look something like this: +The most popular mail backend is probably @code{nnimap}, which +provides access to @acronym{IMAP} servers. @acronym{IMAP} servers +store mail remotely, so the client doesn't store anything locally. +This means that it's a convenient choice when you're reading your mail +from different locations, or with different user agents. -@lisp -(nntp "firewall" - (nntp-open-connection-function nntp-open-via-rlogin-and-netcat) - (nntp-via-address "the.firewall.machine") - (nntp-address "the.real.nntp.host")) -@end lisp +@menu +* Connecting to an IMAP Server:: Getting started with @acronym{IMAP}. +* Customizing the IMAP Connection:: Variables for @acronym{IMAP} connection. +* Client-Side IMAP Splitting:: Put mail in the correct mail box. +@end menu -If you want to use the wonderful @code{ssh} program to provide a -compressed connection over the modem line, you could add the following -configuration to the example above: -@lisp - (nntp-via-rlogin-command "ssh") -@end lisp +@node Connecting to an IMAP Server +@subsection Connecting to an IMAP Server -See also @code{nntp-via-rlogin-command-switches}. Here's an example for -an indirect connection: +Connecting to an @acronym{IMAP} can be very easy. Type @kbd{B} in the +group buffer, or (if your primary interest is reading email), say +something like: -@lisp +@example (setq gnus-select-method - '(nntp "indirect" - (nntp-address "news.server.example") - (nntp-via-user-name "intermediate_user_name") - (nntp-via-address "intermediate.host.example") - (nntp-via-rlogin-command "ssh") - (nntp-via-rlogin-command-switches ("-C")) - (nntp-open-connection-function nntp-open-via-rlogin-and-netcat))) -@end lisp + '(nnimap "imap.gmail.com")) +@end example -This means that you have to have set up @code{ssh-agent} correctly to -provide automatic authorization, of course. +You'll be prompted for a user name and password. If you grow tired of +that, then add the following to your @file{~/.authinfo} file: -If you're behind a firewall, but have direct access to the outside world -through a wrapper command like "runsocks", you could open a socksified -netcat connection to the news server as follows: +@example +machine imap.gmail.com login password port imap +@end example -@lisp -(nntp "outside" - (nntp-pre-command "runsocks") - (nntp-open-connection-function nntp-open-netcat-stream) - (nntp-address "the.news.server")) -@end lisp +That should basically be it for most users. -@node Creating a Virtual Server -@subsection Creating a Virtual Server +@node Customizing the IMAP Connection +@subsection Customizing the IMAP Connection -If you're saving lots of articles in the cache by using persistent -articles, you may want to create a virtual server to read the cache. +Here's an example method that's more complex: -First you need to add a new server. The @kbd{a} command does that. It -would probably be best to use @code{nnml} to read the cache. You -could also use @code{nnspool} or @code{nnmh}, though. +@example +(nnimap "imap.gmail.com" + (nnimap-inbox "INBOX") + (nnimap-split-methods default) + (nnimap-expunge t) + (nnimap-stream ssl)) +@end example -Type @kbd{a nnml RET cache RET}. +@table @code +@item nnimap-address +The address of the server, like @samp{imap.gmail.com}. -You should now have a brand new @code{nnml} virtual server called -@samp{cache}. You now need to edit it to have the right definitions. -Type @kbd{e} to edit the server. You'll be entered into a buffer that -will contain the following: +@item nnimap-server-port +If the server uses a non-standard port, that can be specified here. A +typical port would be @code{"imap"} or @code{"imaps"}. -@lisp -(nnml "cache") -@end lisp +@item nnimap-stream +How @code{nnimap} should connect to the server. Possible values are: -Change that to: +@table @code +@item undecided +This is the default, and this first tries the @code{ssl} setting, and +then tries the @code{network} setting. -@lisp -(nnml "cache" - (nnml-directory "~/News/cache/") - (nnml-active-file "~/News/cache/active")) -@end lisp +@item ssl +This uses standard @acronym{TLS}/@acronym{SSL} connections. -Type @kbd{C-c C-c} to return to the server buffer. If you now press -@kbd{RET} over this virtual server, you should be entered into a browse -buffer, and you should be able to enter any of the groups displayed. +@item network +Non-encrypted and unsafe straight socket connection, but will upgrade +to encrypted @acronym{STARTTLS} if both Emacs and the server +supports it. +@item starttls +Encrypted @acronym{STARTTLS} over the normal @acronym{IMAP} port. -@node Server Variables -@subsection Server Variables -@cindex server variables -@cindex server parameters +@item shell +If you need to tunnel via other systems to connect to the server, you +can use this option, and customize @code{nnimap-shell-program} to be +what you need. -One sticky point when defining variables (both on back ends and in Emacs -in general) is that some variables are typically initialized from other -variables when the definition of the variables is being loaded. If you -change the ``base'' variable after the variables have been loaded, you -won't change the ``derived'' variables. +@end table -This typically affects directory and file variables. For instance, -@code{nnml-directory} is @file{~/Mail/} by default, and all @code{nnml} -directory variables are initialized from that variable, so -@code{nnml-active-file} will be @file{~/Mail/active}. If you define a -new virtual @code{nnml} server, it will @emph{not} suffice to set just -@code{nnml-directory}---you have to explicitly set all the file -variables to be what you want them to be. For a complete list of -variables for each back end, see each back end's section later in this -manual, but here's an example @code{nnml} definition: +@item nnimap-authenticator +Some @acronym{IMAP} servers allow anonymous logins. In that case, +this should be set to @code{anonymous}. -@lisp -(nnml "public" - (nnml-directory "~/my-mail/") - (nnml-active-file "~/my-mail/active") - (nnml-newsgroups-file "~/my-mail/newsgroups")) -@end lisp +@item nnimap-expunge +If non-@code{nil}, expunge articles after deleting them. This is always done +if the server supports UID EXPUNGE, but it's not done by default on +servers that doesn't support that command. -Server variables are often called @dfn{server parameters}. +@item nnimap-streaming +Virtually all @code{IMAP} server support fast streaming of data. If +you have problems connecting to the server, try setting this to @code{nil}. -@node Servers and Methods -@subsection Servers and Methods +@item nnimap-fetch-partial-articles +If non-@code{nil}, fetch partial articles from the server. If set to +a string, then it's interpreted as a regexp, and parts that have +matching types will be fetched. For instance, @samp{"text/"} will +fetch all textual parts, while leaving the rest on the server. -Wherever you would normally use a select method -(e.g. @code{gnus-secondary-select-method}, in the group select method, -when browsing a foreign server) you can use a virtual server name -instead. This could potentially save lots of typing. And it's nice all -over. +@end table -@node Unavailable Servers -@subsection Unavailable Servers +@node Client-Side IMAP Splitting +@subsection Client-Side IMAP Splitting -If a server seems to be unreachable, Gnus will mark that server as -@code{denied}. That means that any subsequent attempt to make contact -with that server will just be ignored. ``It can't be opened,'' Gnus -will tell you, without making the least effort to see whether that is -actually the case or not. +Many people prefer to do the sorting/splitting of mail into their mail +boxes on the @acronym{IMAP} server. That way they don't have to +download the mail they're not all that interested in. -That might seem quite naughty, but it does make sense most of the time. -Let's say you have 10 groups subscribed to on server -@samp{nephelococcygia.com}. This server is located somewhere quite far -away from you and the machine is quite slow, so it takes 1 minute just -to find out that it refuses connection to you today. If Gnus were to -attempt to do that 10 times, you'd be quite annoyed, so Gnus won't -attempt to do that. Once it has gotten a single ``connection refused'', -it will regard that server as ``down''. +If you do want to do client-side mail splitting, then the following +variables are relevant: -So, what happens if the machine was only feeling unwell temporarily? -How do you test to see whether the machine has come up again? +@table @code +@item nnimap-inbox +This is the @acronym{IMAP} mail box that will be scanned for new mail. -You jump to the server buffer (@pxref{Server Buffer}) and poke it -with the following commands: +@item nnimap-split-methods +Uses the same syntax as @code{nnmail-split-methods} (@pxref{Splitting +Mail}), except the symbol @code{default}, which means that it should +use the value of the @code{nnmail-split-methods} variable. + +@item nnimap-split-fancy +Uses the same syntax as @code{nnmail-split-fancy}. -@table @kbd +@item nnimap-unsplittable-articles +List of flag symbols to ignore when doing splitting. That is, +articles that have these flags won't be considered when splitting. +The default is @samp{(%Deleted %Seen)}. -@item O -@kindex O (Server) -@findex gnus-server-open-server -Try to establish connection to the server on the current line -(@code{gnus-server-open-server}). +@end table -@item C -@kindex C (Server) -@findex gnus-server-close-server -Close the connection (if any) to the server -(@code{gnus-server-close-server}). -@item D -@kindex D (Server) -@findex gnus-server-deny-server -Mark the current server as unreachable -(@code{gnus-server-deny-server}). +@node Getting Mail +@section Getting Mail +@cindex reading mail +@cindex mail -@item M-o -@kindex M-o (Server) -@findex gnus-server-open-all-servers -Open the connections to all servers in the buffer -(@code{gnus-server-open-all-servers}). +Reading mail with a newsreader---isn't that just plain WeIrD? But of +course. -@item M-c -@kindex M-c (Server) -@findex gnus-server-close-all-servers -Close the connections to all servers in the buffer -(@code{gnus-server-close-all-servers}). +@menu +* Mail in a Newsreader:: Important introductory notes. +* Getting Started Reading Mail:: A simple cookbook example. +* Splitting Mail:: How to create mail groups. +* Mail Sources:: How to tell Gnus where to get mail from. +* Mail Back End Variables:: Variables for customizing mail handling. +* Fancy Mail Splitting:: Gnus can do hairy splitting of incoming mail. +* Group Mail Splitting:: Use group customize to drive mail splitting. +* Incorporating Old Mail:: What about the old mail you have? +* Expiring Mail:: Getting rid of unwanted mail. +* Washing Mail:: Removing cruft from the mail you get. +* Duplicates:: Dealing with duplicated mail. +* Not Reading Mail:: Using mail back ends for reading other files. +* Choosing a Mail Back End:: Gnus can read a variety of mail formats. +@end menu -@item R -@kindex R (Server) -@findex gnus-server-remove-denials -Remove all marks to whether Gnus was denied connection from any servers -(@code{gnus-server-remove-denials}). -@item c -@kindex c (Server) -@findex gnus-server-copy-server -Copy a server and give it a new name -(@code{gnus-server-copy-server}). This can be useful if you have a -complex method definition, and want to use the same definition towards -a different (physical) server. +@node Mail in a Newsreader +@subsection Mail in a Newsreader -@item L -@kindex L (Server) -@findex gnus-server-offline-server -Set server status to offline (@code{gnus-server-offline-server}). +If you are used to traditional mail readers, but have decided to switch +to reading mail with Gnus, you may find yourself experiencing something +of a culture shock. -@end table +Gnus does not behave like traditional mail readers. If you want to make +it behave that way, you can, but it's an uphill battle. +Gnus, by default, handles all its groups using the same approach. This +approach is very newsreaderly---you enter a group, see the new/unread +messages, and when you read the messages, they get marked as read, and +you don't see them any more. (Unless you explicitly ask for them.) -@node Getting News -@section Getting News -@cindex reading news -@cindex news back ends +In particular, you do not do anything explicitly to delete messages. -A newsreader is normally used for reading news. Gnus currently provides -only two methods of getting news---it can read from an @acronym{NNTP} server, -or it can read from a local spool. +Does this mean that all the messages that have been marked as read are +deleted? How awful! -@menu -* NNTP:: Reading news from an @acronym{NNTP} server. -* News Spool:: Reading news from the local spool. -@end menu +But, no, it means that old messages are @dfn{expired} according to some +scheme or other. For news messages, the expire process is controlled by +the news administrator; for mail, the expire process is controlled by +you. The expire process for mail is covered in depth in @ref{Expiring +Mail}. +What many Gnus users find, after using it a while for both news and +mail, is that the transport mechanism has very little to do with how +they want to treat a message. -@node NNTP -@subsection NNTP -@cindex nntp +Many people subscribe to several mailing lists. These are transported +via @acronym{SMTP}, and are therefore mail. But we might go for weeks without +answering, or even reading these messages very carefully. We may not +need to save them because if we should need to read one again, they are +archived somewhere else. -Subscribing to a foreign group from an @acronym{NNTP} server is rather easy. -You just specify @code{nntp} as method and the address of the @acronym{NNTP} -server as the, uhm, address. +Some people have local news groups which have only a handful of readers. +These are transported via @acronym{NNTP}, and are therefore news. But we may need +to read and answer a large fraction of the messages very carefully in +order to do our work. And there may not be an archive, so we may need +to save the interesting messages the same way we would personal mail. -If the @acronym{NNTP} server is located at a non-standard port, setting the -third element of the select method to this port number should allow you -to connect to the right port. You'll have to edit the group info for -that (@pxref{Foreign Groups}). +The important distinction turns out to be not the transport mechanism, +but other factors such as how interested we are in the subject matter, +or how easy it is to retrieve the message if we need to read it again. -The name of the foreign group can be the same as a native group. In -fact, you can subscribe to the same group from as many different servers -you feel like. There will be no name collisions. +Gnus provides many options for sorting mail into ``groups'' which behave +like newsgroups, and for treating each group (whether mail or news) +differently. -The following variables can be used to create a virtual @code{nntp} -server: +Some users never get comfortable using the Gnus (ahem) paradigm and wish +that Gnus should grow up and be a male, er, mail reader. It is possible +to whip Gnus into a more mailreaderly being, but, as said before, it's +not easy. People who prefer proper mail readers should try @sc{vm} +instead, which is an excellent, and proper, mail reader. -@table @code +I don't mean to scare anybody off, but I want to make it clear that you +may be required to learn a new way of thinking about messages. After +you've been subjected to The Gnus Way, you will come to love it. I can +guarantee it. (At least the guy who sold me the Emacs Subliminal +Brain-Washing Functions that I've put into Gnus did guarantee it. You +Will Be Assimilated. You Love Gnus. You Love The Gnus Mail Way. +You Do.) -@item nntp-server-opened-hook -@vindex nntp-server-opened-hook -@cindex @sc{mode reader} -@cindex authinfo -@cindex authentication -@cindex nntp authentication -@findex nntp-send-authinfo -@findex nntp-send-mode-reader -is run after a connection has been made. It can be used to send -commands to the @acronym{NNTP} server after it has been contacted. By -default it sends the command @code{MODE READER} to the server with the -@code{nntp-send-mode-reader} function. This function should always be -present in this hook. -@item nntp-authinfo-function -@vindex nntp-authinfo-function -@findex nntp-send-authinfo -@vindex nntp-authinfo-file -This function will be used to send @samp{AUTHINFO} to the @acronym{NNTP} -server. The default function is @code{nntp-send-authinfo}, which looks -through your @file{~/.authinfo} (or whatever you've set the -@code{nntp-authinfo-file} variable to) for applicable entries. If none -are found, it will prompt you for a login name and a password. The -format of the @file{~/.authinfo} file is (almost) the same as the -@code{ftp} @file{~/.netrc} file, which is defined in the @code{ftp} -manual page, but here are the salient facts: +@node Getting Started Reading Mail +@subsection Getting Started Reading Mail -@enumerate -@item -The file contains one or more line, each of which define one server. +It's quite easy to use Gnus to read your new mail. You just plonk the +mail back end of your choice into @code{gnus-secondary-select-methods}, +and things will happen automatically. -@item -Each line may contain an arbitrary number of token/value pairs. +For instance, if you want to use @code{nnml} (which is a ``one file per +mail'' back end), you could put the following in your @file{~/.gnus.el} file: -The valid tokens include @samp{machine}, @samp{login}, @samp{password}, -@samp{default}. In addition Gnus introduces two new tokens, not present -in the original @file{.netrc}/@code{ftp} syntax, namely @samp{port} and -@samp{force}. (This is the only way the @file{.authinfo} file format -deviates from the @file{.netrc} file format.) @samp{port} is used to -indicate what port on the server the credentials apply to and -@samp{force} is explained below. +@lisp +(setq gnus-secondary-select-methods '((nnml ""))) +@end lisp -@end enumerate +Now, the next time you start Gnus, this back end will be queried for new +articles, and it will move all the messages in your spool file to its +directory, which is @file{~/Mail/} by default. The new group that will +be created (@samp{mail.misc}) will be subscribed, and you can read it +like any other group. -Here's an example file: +You will probably want to split the mail into several groups, though: -@example -machine news.uio.no login larsi password geheimnis -machine nntp.ifi.uio.no login larsi force yes -@end example +@lisp +(setq nnmail-split-methods + '(("junk" "^From:.*Lars Ingebrigtsen") + ("crazy" "^Subject:.*die\\|^Organization:.*flabby") + ("other" ""))) +@end lisp -The token/value pairs may appear in any order; @samp{machine} doesn't -have to be first, for instance. +This will result in three new @code{nnml} mail groups being created: +@samp{nnml:junk}, @samp{nnml:crazy}, and @samp{nnml:other}. All the +mail that doesn't fit into the first two groups will be placed in the +last group. -In this example, both login name and password have been supplied for the -former server, while the latter has only the login name listed, and the -user will be prompted for the password. The latter also has the -@samp{force} tag, which means that the authinfo will be sent to the -@var{nntp} server upon connection; the default (i.e., when there is not -@samp{force} tag) is to not send authinfo to the @var{nntp} server -until the @var{nntp} server asks for it. +This should be sufficient for reading mail with Gnus. You might want to +give the other sections in this part of the manual a perusal, though. +Especially @pxref{Choosing a Mail Back End} and @pxref{Expiring Mail}. -You can also add @samp{default} lines that will apply to all servers -that don't have matching @samp{machine} lines. -@example -default force yes -@end example +@node Splitting Mail +@subsection Splitting Mail +@cindex splitting mail +@cindex mail splitting +@cindex mail filtering (splitting) -This will force sending @samp{AUTHINFO} commands to all servers not -previously mentioned. +@vindex nnmail-split-methods +The @code{nnmail-split-methods} variable says how the incoming mail is +to be split into groups. -Remember to not leave the @file{~/.authinfo} file world-readable. +@lisp +(setq nnmail-split-methods + '(("mail.junk" "^From:.*Lars Ingebrigtsen") + ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") + ("mail.other" ""))) +@end lisp -@item nntp-server-action-alist -@vindex nntp-server-action-alist -This is a list of regexps to match on server types and actions to be -taken when matches are made. For instance, if you want Gnus to beep -every time you connect to innd, you could say something like: +This variable is a list of lists, where the first element of each of +these lists is the name of the mail group (they do not have to be called +something beginning with @samp{mail}, by the way), and the second +element is a regular expression used on the header of each mail to +determine if it belongs in this mail group. The first string may +contain @samp{\\1} forms, like the ones used by @code{replace-match} to +insert sub-expressions from the matched text. For instance: @lisp -(setq nntp-server-action-alist - '(("innd" (ding)))) +("list.\\1" "From:.* \\(.*\\)-list@@majordomo.com") @end lisp -You probably don't want to do that, though. +@noindent +In that case, @code{nnmail-split-lowercase-expanded} controls whether +the inserted text should be made lowercase. @xref{Fancy Mail Splitting}. -The default value is +The second element can also be a function. In that case, it will be +called narrowed to the headers with the first element of the rule as the +argument. It should return a non-@code{nil} value if it thinks that the +mail belongs in that group. -@lisp -'(("nntpd 1\\.5\\.11t" - (remove-hook 'nntp-server-opened-hook - 'nntp-send-mode-reader))) -@end lisp +@cindex @samp{bogus} group +The last of these groups should always be a general one, and the regular +expression should @emph{always} be @samp{""} so that it matches any mails +that haven't been matched by any of the other regexps. (These rules are +processed from the beginning of the alist toward the end. The first rule +to make a match will ``win'', unless you have crossposting enabled. In +that case, all matching rules will ``win''.) If no rule matched, the mail +will end up in the @samp{bogus} group. When new groups are created by +splitting mail, you may want to run @code{gnus-group-find-new-groups} to +see the new groups. This also applies to the @samp{bogus} group. -This ensures that Gnus doesn't send the @code{MODE READER} command to -nntpd 1.5.11t, since that command chokes that server, I've been told. +If you like to tinker with this yourself, you can set this variable to a +function of your choice. This function will be called without any +arguments in a buffer narrowed to the headers of an incoming mail +message. The function should return a list of group names that it +thinks should carry this mail message. -@item nntp-maximum-request -@vindex nntp-maximum-request -If the @acronym{NNTP} server doesn't support @acronym{NOV} headers, this back end -will collect headers by sending a series of @code{head} commands. To -speed things up, the back end sends lots of these commands without -waiting for reply, and then reads all the replies. This is controlled -by the @code{nntp-maximum-request} variable, and is 400 by default. If -your network is buggy, you should set this to 1. +This variable can also be a fancy split method. For the syntax, +see @ref{Fancy Mail Splitting}. -@item nntp-connection-timeout -@vindex nntp-connection-timeout -If you have lots of foreign @code{nntp} groups that you connect to -regularly, you're sure to have problems with @acronym{NNTP} servers not -responding properly, or being too loaded to reply within reasonable -time. This is can lead to awkward problems, which can be helped -somewhat by setting @code{nntp-connection-timeout}. This is an integer -that says how many seconds the @code{nntp} back end should wait for a -connection before giving up. If it is @code{nil}, which is the default, -no timeouts are done. +Note that the mail back ends are free to maul the poor, innocent, +incoming headers all they want to. They all add @code{Lines} headers; +some add @code{X-Gnus-Group} headers; most rename the Unix mbox +@code{From} line to something else. -@item nntp-nov-is-evil -@vindex nntp-nov-is-evil -If the @acronym{NNTP} server does not support @acronym{NOV}, you could set this -variable to @code{t}, but @code{nntp} usually checks automatically whether @acronym{NOV} -can be used. +@vindex nnmail-crosspost +The mail back ends all support cross-posting. If several regexps match, +the mail will be ``cross-posted'' to all those groups. +@code{nnmail-crosspost} says whether to use this mechanism or not. Note +that no articles are crossposted to the general (@samp{""}) group. -@item nntp-xover-commands -@vindex nntp-xover-commands -@cindex @acronym{NOV} -@cindex XOVER -List of strings used as commands to fetch @acronym{NOV} lines from a -server. The default value of this variable is @code{("XOVER" -"XOVERVIEW")}. +@vindex nnmail-crosspost-link-function +@cindex crosspost +@cindex links +@code{nnmh} and @code{nnml} makes crossposts by creating hard links to +the crossposted articles. However, not all file systems support hard +links. If that's the case for you, set +@code{nnmail-crosspost-link-function} to @code{copy-file}. (This +variable is @code{add-name-to-file} by default.) -@item nntp-nov-gap -@vindex nntp-nov-gap -@code{nntp} normally sends just one big request for @acronym{NOV} lines to -the server. The server responds with one huge list of lines. However, -if you have read articles 2-5000 in the group, and only want to read -article 1 and 5001, that means that @code{nntp} will fetch 4999 @acronym{NOV} -lines that you will not need. This variable says how -big a gap between two consecutive articles is allowed to be before the -@code{XOVER} request is split into several request. Note that if your -network is fast, setting this variable to a really small number means -that fetching will probably be slower. If this variable is @code{nil}, -@code{nntp} will never split requests. The default is 5. +@kindex M-x nnmail-split-history +@findex nnmail-split-history +If you wish to see where the previous mail split put the messages, you +can use the @kbd{M-x nnmail-split-history} command. If you wish to see +where re-spooling messages would put the messages, you can use +@code{gnus-summary-respool-trace} and related commands (@pxref{Mail +Group Commands}). -@item nntp-xref-number-is-evil -@vindex nntp-xref-number-is-evil -When Gnus refers to an article having the @code{Message-ID} that a user -specifies or having the @code{Message-ID} of the parent article of the -current one (@pxref{Finding the Parent}), Gnus sends a @code{HEAD} -command to the @acronym{NNTP} server to know where it is, and the server -returns the data containing the pairs of a group and an article number -in the @code{Xref} header. Gnus normally uses the article number to -refer to the article if the data shows that that article is in the -current group, while it uses the @code{Message-ID} otherwise. However, -some news servers, e.g., ones running Diablo, run multiple engines -having the same articles but article numbers are not kept synchronized -between them. In that case, the article number that appears in the -@code{Xref} header varies by which engine is chosen, so you cannot refer -to the parent article that is in the current group, for instance. If -you connect to such a server, set this variable to a non-@code{nil} -value, and Gnus never uses article numbers. For example: +@vindex nnmail-split-header-length-limit +Header lines longer than the value of +@code{nnmail-split-header-length-limit} are excluded from the split +function. -@lisp -(setq gnus-select-method - '(nntp "newszilla" - (nntp-address "newszilla.example.com") - (nntp-xref-number-is-evil t) - @dots{})) -@end lisp +@vindex nnmail-mail-splitting-decodes +@vindex nnmail-mail-splitting-charset +By default, splitting does not decode headers, so you can not match on +non-@acronym{ASCII} strings. But it is useful if you want to match +articles based on the raw header data. To enable it, set the +@code{nnmail-mail-splitting-decodes} variable to a non-@code{nil} value. +In addition, the value of the @code{nnmail-mail-splitting-charset} +variable is used for decoding non-@acronym{MIME} encoded string when +@code{nnmail-mail-splitting-decodes} is non-@code{nil}. The default +value is @code{nil} which means not to decode non-@acronym{MIME} encoded +string. A suitable value for you will be @code{undecided} or be the +charset used normally in mails you are interested in. -The default value of this server variable is @code{nil}. +@vindex nnmail-resplit-incoming +By default, splitting is performed on all incoming messages. If you +specify a @code{directory} entry for the variable @code{mail-sources} +(@pxref{Mail Source Specifiers}), however, then splitting does +@emph{not} happen by default. You can set the variable +@code{nnmail-resplit-incoming} to a non-@code{nil} value to make +splitting happen even in this case. (This variable has no effect on +other kinds of entries.) -@item nntp-prepare-server-hook -@vindex nntp-prepare-server-hook -A hook run before attempting to connect to an @acronym{NNTP} server. +Gnus gives you all the opportunity you could possibly want for shooting +yourself in the foot. Let's say you create a group that will contain +all the mail you get from your boss. And then you accidentally +unsubscribe from the group. Gnus will still put all the mail from your +boss in the unsubscribed group, and so, when your boss mails you ``Have +that report ready by Monday or you're fired!'', you'll never see it and, +come Tuesday, you'll still believe that you're gainfully employed while +you really should be out collecting empty bottles to save up for next +month's rent money. -@item nntp-record-commands -@vindex nntp-record-commands -If non-@code{nil}, @code{nntp} will log all commands it sends to the -@acronym{NNTP} server (along with a timestamp) in the @samp{*nntp-log*} -buffer. This is useful if you are debugging a Gnus/@acronym{NNTP} connection -that doesn't seem to work. -@item nntp-open-connection-function -@vindex nntp-open-connection-function -It is possible to customize how the connection to the nntp server will -be opened. If you specify an @code{nntp-open-connection-function} -parameter, Gnus will use that function to establish the connection. -Seven pre-made functions are supplied. These functions can be grouped -in two categories: direct connection functions (four pre-made), and -indirect ones (three pre-made). +@node Mail Sources +@subsection Mail Sources -@item nntp-never-echoes-commands -@vindex nntp-never-echoes-commands -Non-@code{nil} means the nntp server never echoes commands. It is -reported that some nntps server doesn't echo commands. So, you may want -to set this to non-@code{nil} in the method for such a server setting -@code{nntp-open-connection-function} to @code{nntp-open-ssl-stream} for -example. The default value is @code{nil}. Note that the -@code{nntp-open-connection-functions-never-echo-commands} variable -overrides the @code{nil} value of this variable. +Mail can be gotten from many different sources---the mail spool, from +a @acronym{POP} mail server, from a procmail directory, or from a +maildir, for instance. -@item nntp-open-connection-functions-never-echo-commands -@vindex nntp-open-connection-functions-never-echo-commands -List of functions that never echo commands. Add or set a function which -you set to @code{nntp-open-connection-function} to this list if it does -not echo commands. Note that a non-@code{nil} value of the -@code{nntp-never-echoes-commands} variable overrides this variable. The -default value is @code{(nntp-open-network-stream)}. +@menu +* Mail Source Specifiers:: How to specify what a mail source is. +* Mail Source Customization:: Some variables that influence things. +* Fetching Mail:: Using the mail source specifiers. +@end menu -@item nntp-prepare-post-hook -@vindex nntp-prepare-post-hook -A hook run just before posting an article. If there is no -@code{Message-ID} header in the article and the news server provides the -recommended ID, it will be added to the article before running this -hook. It is useful to make @code{Cancel-Lock} headers even if you -inhibit Gnus to add a @code{Message-ID} header, you could say: -@lisp -(add-hook 'nntp-prepare-post-hook 'canlock-insert-header) -@end lisp +@node Mail Source Specifiers +@subsubsection Mail Source Specifiers +@cindex POP +@cindex mail server +@cindex procmail +@cindex mail spool +@cindex mail source -Note that not all servers support the recommended ID. This works for -INN versions 2.3.0 and later, for instance. +You tell Gnus how to fetch mail by setting @code{mail-sources} +(@pxref{Fetching Mail}) to a @dfn{mail source specifier}. -@item nntp-server-list-active-group -If @code{nil}, then always use @samp{GROUP} instead of @samp{LIST -ACTIVE}. This is usually slower, but on misconfigured servers that -don't update their active files often, this can help. +Here's an example: +@lisp +(pop :server "pop3.mailserver.com" :user "myname") +@end lisp -@end table +As can be observed, a mail source specifier is a list where the first +element is a @dfn{mail source type}, followed by an arbitrary number of +@dfn{keywords}. Keywords that are not explicitly specified are given +default values. -@menu -* Direct Functions:: Connecting directly to the server. -* Indirect Functions:: Connecting indirectly to the server. -* Common Variables:: Understood by several connection functions. -* NNTP marks:: Storing marks for @acronym{NNTP} servers. -@end menu +The @code{mail-sources} is global for all mail groups. You can specify +an additional mail source for a particular group by including the +@code{group} mail specifier in @code{mail-sources}, and setting a +@code{mail-source} group parameter (@pxref{Group Parameters}) specifying +a single mail source. When this is used, @code{mail-sources} is +typically just @code{(group)}; the @code{mail-source} parameter for a +group might look like this: +@lisp +(mail-source . (file :path "home/user/spools/foo.spool")) +@end lisp -@node Direct Functions -@subsubsection Direct Functions -@cindex direct connection functions +This means that the group's (and only this group's) messages will be +fetched from the spool file @samp{/user/spools/foo.spool}. -These functions are called direct because they open a direct connection -between your machine and the @acronym{NNTP} server. The behavior of these -functions is also affected by commonly understood variables -(@pxref{Common Variables}). +The following mail source types are available: @table @code -@findex nntp-open-network-stream -@item nntp-open-network-stream -This is the default, and simply connects to some port or other on the -remote system. If both Emacs and the server supports it, the -connection will be upgraded to an encrypted @acronym{STARTTLS} -connection automatically. +@item file +Get mail from a single file; typically from the mail spool. -@item network-only -The same as the above, but don't do automatic @acronym{STARTTLS} upgrades. +Keywords: -@findex nntp-open-tls-stream -@item nntp-open-tls-stream -Opens a connection to a server over a @dfn{secure} channel. To use -this you must have @uref{http://www.gnu.org/software/gnutls/, GNUTLS} -installed. You then define a server as follows: +@table @code +@item :path +The file name. Defaults to the value of the @env{MAIL} +environment variable or the value of @code{rmail-spool-directory} +(usually something like @file{/usr/mail/spool/user-name}). -@lisp -;; @r{"nntps" is port 563 and is predefined in our @file{/etc/services}} -;; @r{however, @samp{gnutls-cli -p} doesn't like named ports.} -;; -(nntp "snews.bar.com" - (nntp-open-connection-function nntp-open-tls-stream) - (nntp-port-number 563) - (nntp-address "snews.bar.com")) -@end lisp +@item :prescript +@itemx :postscript +Script run before/after fetching mail. +@end table -@findex nntp-open-ssl-stream -@item nntp-open-ssl-stream -Opens a connection to a server over a @dfn{secure} channel. To use -this you must have @uref{http://www.openssl.org, OpenSSL} or -@uref{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL, SSLeay} installed. You -then define a server as follows: +An example file mail source: @lisp -;; @r{"snews" is port 563 and is predefined in our @file{/etc/services}} -;; @r{however, @samp{openssl s_client -port} doesn't like named ports.} -;; -(nntp "snews.bar.com" - (nntp-open-connection-function nntp-open-ssl-stream) - (nntp-port-number 563) - (nntp-address "snews.bar.com")) +(file :path "/usr/spool/mail/user-name") @end lisp -@findex nntp-open-netcat-stream -@item nntp-open-netcat-stream -Opens a connection to an @acronym{NNTP} server using the @code{netcat} -program. You might wonder why this function exists, since we have -the default @code{nntp-open-network-stream} which would do the job. (One -of) the reason(s) is that if you are behind a firewall but have direct -connections to the outside world thanks to a command wrapper like -@code{runsocks}, you can use it like this: +Or using the default file name: @lisp -(nntp "socksified" - (nntp-pre-command "runsocks") - (nntp-open-connection-function nntp-open-netcat-stream) - (nntp-address "the.news.server")) +(file) @end lisp -With the default method, you would need to wrap your whole Emacs -session, which is not a good idea. +If the mail spool file is not located on the local machine, it's best +to use @acronym{POP} or @acronym{IMAP} or the like to fetch the mail. +You can not use ange-ftp file names here---it has no way to lock the +mail spool while moving the mail. -@findex nntp-open-telnet-stream -@item nntp-open-telnet-stream -Like @code{nntp-open-netcat-stream}, but uses @code{telnet} rather than -@code{netcat}. @code{telnet} is a bit less robust because of things -like line-end-conversion, but sometimes netcat is simply -not available. The previous example would turn into: +If it's impossible to set up a proper server, you can use ssh instead. @lisp -(nntp "socksified" - (nntp-pre-command "runsocks") - (nntp-open-connection-function nntp-open-telnet-stream) - (nntp-address "the.news.server") - (nntp-end-of-line "\n")) +(setq mail-sources + '((file :prescript "ssh host bin/getmail >%t"))) @end lisp -@end table - -@node Indirect Functions -@subsubsection Indirect Functions -@cindex indirect connection functions +The @samp{getmail} script would look something like the following: -These functions are called indirect because they connect to an -intermediate host before actually connecting to the @acronym{NNTP} server. -All of these functions and related variables are also said to belong to -the ``via'' family of connection: they're all prefixed with ``via'' to make -things cleaner. The behavior of these functions is also affected by -commonly understood variables (@pxref{Common Variables}). +@example +#!/bin/sh +# getmail - move mail from spool to stdout +# flu@@iki.fi -@table @code -@item nntp-open-via-rlogin-and-netcat -@findex nntp-open-via-rlogin-and-netcat -Does an @samp{rlogin} on a remote system, and then uses @code{netcat} to connect -to the real @acronym{NNTP} server from there. This is useful for instance if -you need to connect to a firewall machine first. +MOVEMAIL=/usr/lib/emacs/20.3/i386-redhat-linux/movemail +TMP=$HOME/Mail/tmp +rm -f $TMP; $MOVEMAIL $MAIL $TMP >/dev/null && cat $TMP +@end example -@code{nntp-open-via-rlogin-and-netcat}-specific variables: +Alter this script to fit the @samp{movemail} and temporary +file you want to use. -@table @code -@item nntp-via-rlogin-command -@vindex nntp-via-rlogin-command -Command used to log in on the intermediate host. The default is -@samp{rsh}, but @samp{ssh} is a popular alternative. -@item nntp-via-rlogin-command-switches -@vindex nntp-via-rlogin-command-switches -List of strings to be used as the switches to -@code{nntp-via-rlogin-command}. The default is @code{nil}. If you use -@samp{ssh} for @code{nntp-via-rlogin-command}, you may set this to -@samp{("-C")} in order to compress all data connections. -@end table +@item directory +@vindex nnmail-scan-directory-mail-source-once +Get mail from several files in a directory. This is typically used +when you have procmail split the incoming mail into several files. +That is, there is a one-to-one correspondence between files in that +directory and groups, so that mail from the file @file{foo.bar.spool} +will be put in the group @code{foo.bar}. (You can change the suffix +to be used instead of @code{.spool}.) Setting +@code{nnmail-scan-directory-mail-source-once} to non-@code{nil} forces +Gnus to scan the mail source only once. This is particularly useful +if you want to scan mail groups at a specified level. -@item nntp-open-via-rlogin-and-telnet -@findex nntp-open-via-rlogin-and-telnet -Does essentially the same, but uses @code{telnet} instead of @samp{netcat} -to connect to the real @acronym{NNTP} server from the intermediate host. -@code{telnet} is a bit less robust because of things like -line-end-conversion, but sometimes @code{netcat} is simply not available. +@vindex nnmail-resplit-incoming +There is also the variable @code{nnmail-resplit-incoming}, if you set +that to a non-@code{nil} value, then the normal splitting process is +applied to all the files from the directory, @ref{Splitting Mail}. -@code{nntp-open-via-rlogin-and-telnet}-specific variables: +Keywords: @table @code -@item nntp-telnet-command -@vindex nntp-telnet-command -Command used to connect to the real @acronym{NNTP} server from the -intermediate host. The default is @samp{telnet}. +@item :path +The name of the directory where the files are. There is no default +value. -@item nntp-telnet-switches -@vindex nntp-telnet-switches -List of strings to be used as the switches to the -@code{nntp-telnet-command} command. The default is @code{("-8")}. +@item :suffix +Only files ending with this suffix are used. The default is +@samp{.spool}. -@item nntp-via-rlogin-command -@vindex nntp-via-rlogin-command -Command used to log in on the intermediate host. The default is -@samp{rsh}, but @samp{ssh} is a popular alternative. +@item :predicate +Only files that have this predicate return non-@code{nil} are returned. +The default is @code{identity}. This is used as an additional +filter---only files that have the right suffix @emph{and} satisfy this +predicate are considered. + +@item :prescript +@itemx :postscript +Script run before/after fetching mail. -@item nntp-via-rlogin-command-switches -@vindex nntp-via-rlogin-command-switches -List of strings to be used as the switches to -@code{nntp-via-rlogin-command}. If you use @samp{ssh}, you may need to set -this to @samp{("-t" "-e" "none")} or @samp{("-C" "-t" "-e" "none")} if -the telnet command requires a pseudo-tty allocation on an intermediate -host. The default is @code{nil}. @end table -Note that you may want to change the value for @code{nntp-end-of-line} -to @samp{\n} (@pxref{Common Variables}). +An example directory mail source: -@item nntp-open-via-telnet-and-telnet -@findex nntp-open-via-telnet-and-telnet -Does essentially the same, but uses @samp{telnet} instead of -@samp{rlogin} to connect to the intermediate host. +@lisp +(directory :path "/home/user-name/procmail-dir/" + :suffix ".prcml") +@end lisp -@code{nntp-open-via-telnet-and-telnet}-specific variables: +@item pop +Get mail from a @acronym{POP} server. -@table @code -@item nntp-via-telnet-command -@vindex nntp-via-telnet-command -Command used to @code{telnet} the intermediate host. The default is -@samp{telnet}. +Keywords: -@item nntp-via-telnet-switches -@vindex nntp-via-telnet-switches -List of strings to be used as the switches to the -@code{nntp-via-telnet-command} command. The default is @samp{("-8")}. +@table @code +@item :server +The name of the @acronym{POP} server. The default is taken from the +@env{MAILHOST} environment variable. -@item nntp-via-user-password -@vindex nntp-via-user-password -Password to use when logging in on the intermediate host. +@item :port +The port number of the @acronym{POP} server. This can be a number (eg, +@samp{:port 1234}) or a string (eg, @samp{:port "pop3"}). If it is a +string, it should be a service name as listed in @file{/etc/services} on +Unix systems. The default is @samp{"pop3"}. On some systems you might +need to specify it as @samp{"pop-3"} instead. -@item nntp-via-envuser -@vindex nntp-via-envuser -If non-@code{nil}, the intermediate @code{telnet} session (client and -server both) will support the @code{ENVIRON} option and not prompt for -login name. This works for Solaris @code{telnet}, for instance. +@item :user +The user name to give to the @acronym{POP} server. The default is the login +name. -@item nntp-via-shell-prompt -@vindex nntp-via-shell-prompt -Regexp matching the shell prompt on the intermediate host. The default -is @samp{bash\\|\$ *\r?$\\|> *\r?}. +@item :password +The password to give to the @acronym{POP} server. If not specified, +the user is prompted. -@end table +@item :program +The program to use to fetch mail from the @acronym{POP} server. This +should be a @code{format}-like string. Here's an example: -Note that you may want to change the value for @code{nntp-end-of-line} -to @samp{\n} (@pxref{Common Variables}). -@end table +@example +fetchmail %u@@%s -P %p %t +@end example +The valid format specifier characters are: -Here are some additional variables that are understood by all the above -functions: +@table @samp +@item t +The name of the file the mail is to be moved to. This must always be +included in this string. -@table @code +@item s +The name of the server. -@item nntp-via-user-name -@vindex nntp-via-user-name -User name to use when connecting to the intermediate host. +@item P +The port number of the server. -@item nntp-via-address -@vindex nntp-via-address -Address of the intermediate host to connect to. +@item u +The user name to use. +@item p +The password to use. @end table +The values used for these specs are taken from the values you give the +corresponding keywords. -@node Common Variables -@subsubsection Common Variables - -The following variables affect the behavior of all, or several of the -pre-made connection functions. When not specified, all functions are -affected (the values of the following variables will be used as the -default if each virtual @code{nntp} server doesn't specify those server -variables individually). - -@table @code +@item :prescript +A script to be run before fetching the mail. The syntax is the same as +the @code{:program} keyword. This can also be a function to be run. -@item nntp-pre-command -@vindex nntp-pre-command -A command wrapper to use when connecting through a non native -connection function (all except @code{nntp-open-network-stream}, -@code{nntp-open-tls-stream}, and @code{nntp-open-ssl-stream}). This is -where you would put a @samp{SOCKS} wrapper for instance. +@item :postscript +A script to be run after fetching the mail. The syntax is the same as +the @code{:program} keyword. This can also be a function to be run. -@item nntp-address -@vindex nntp-address -The address of the @acronym{NNTP} server. +@item :function +The function to use to fetch mail from the @acronym{POP} server. The +function is called with one parameter---the name of the file where the +mail should be moved to. -@item nntp-port-number -@vindex nntp-port-number -Port number to connect to the @acronym{NNTP} server. The default is -@samp{nntp}. If you use @acronym{NNTP} over -@acronym{TLS}/@acronym{SSL}, you may want to use integer ports rather -than named ports (i.e, use @samp{563} instead of @samp{snews} or -@samp{nntps}), because external @acronym{TLS}/@acronym{SSL} tools may -not work with named ports. +@item :authentication +This can be either the symbol @code{password} or the symbol @code{apop} +and says what authentication scheme to use. The default is +@code{password}. -@item nntp-end-of-line -@vindex nntp-end-of-line -String to use as end-of-line marker when talking to the @acronym{NNTP} -server. This is @samp{\r\n} by default, but should be @samp{\n} when -using a non native telnet connection function. +@end table -@item nntp-netcat-command -@vindex nntp-netcat-command -Command to use when connecting to the @acronym{NNTP} server through -@samp{netcat}. This is @emph{not} for an intermediate host. This is -just for the real @acronym{NNTP} server. The default is -@samp{nc}. +@vindex pop3-movemail +@vindex pop3-leave-mail-on-server +If the @code{:program} and @code{:function} keywords aren't specified, +@code{pop3-movemail} will be used. If @code{pop3-leave-mail-on-server} +is non-@code{nil} the mail is to be left on the @acronym{POP} server +after fetching when using @code{pop3-movemail}. Note that POP servers +maintain no state information between sessions, so what the client +believes is there and what is actually there may not match up. If they +do not, then you may get duplicate mails or the whole thing can fall +apart and leave you with a corrupt mailbox. -@item nntp-netcat-switches -@vindex nntp-netcat-switches -A list of switches to pass to @code{nntp-netcat-command}. The default -is @samp{()}. +Here are some examples for getting mail from a @acronym{POP} server. +Fetch from the default @acronym{POP} server, using the default user +name, and default fetcher: -@end table +@lisp +(pop) +@end lisp -@node NNTP marks -@subsubsection NNTP marks -@cindex storing NNTP marks +Fetch from a named server with a named user and password: -Gnus stores marks (@pxref{Marking Articles}) for @acronym{NNTP} -servers in marks files. A marks file records what marks you have set -in a group and each file is specific to the corresponding server. -Marks files are stored in @file{~/News/marks} -(@code{nntp-marks-directory}) under a classic hierarchy resembling -that of a news server, for example marks for the group -@samp{gmane.discuss} on the news.gmane.org server will be stored in -the file @file{~/News/marks/news.gmane.org/gmane/discuss/.marks}. +@lisp +(pop :server "my.pop.server" + :user "user-name" :password "secret") +@end lisp -Marks files are useful because you can copy the @file{~/News/marks} -directory (using rsync, scp or whatever) to another Gnus installation, -and it will realize what articles you have read and marked. The data -in @file{~/News/marks} has priority over the same data in -@file{~/.newsrc.eld}. +Use @samp{movemail} to move the mail: -Note that marks files are very much server-specific: Gnus remembers -the article numbers so if you don't use the same servers on both -installations things are most likely to break (most @acronym{NNTP} -servers do not use the same article numbers as any other server). -However, if you use servers A, B, C on one installation and servers A, -D, E on the other, you can sync the marks files for A and then you'll -get synchronization for that server between the two installations. +@lisp +(pop :program "movemail po:%u %t %p") +@end lisp -Using @acronym{NNTP} marks can possibly incur a performance penalty so -if Gnus feels sluggish, try setting the @code{nntp-marks-is-evil} -variable to @code{t}. Marks will then be stored in @file{~/.newsrc.eld}. +@item maildir +Get mail from a maildir. This is a type of mailbox that is supported by +at least qmail and postfix, where each file in a special directory +contains exactly one mail. -Related variables: +Keywords: @table @code +@item :path +The name of the directory where the mails are stored. The default is +taken from the @env{MAILDIR} environment variable or +@file{~/Maildir/}. +@item :subdirs +The subdirectories of the Maildir. The default is +@samp{("new" "cur")}. -@item nntp-marks-is-evil -@vindex nntp-marks-is-evil -If non-@code{nil}, this back end will ignore any marks files. The -default is @code{nil}. +@c If you sometimes look at your mail through a pop3 daemon before fetching +@c them with Gnus, you may also have to fetch your mails from the +@c @code{cur} directory inside the maildir, like in the first example +@c below. -@item nntp-marks-directory -@vindex nntp-marks-directory -The directory where marks for nntp groups will be stored. +You can also get mails from remote hosts (because maildirs don't suffer +from locking problems). @end table +Two example maildir mail sources: -@node News Spool -@subsection News Spool -@cindex nnspool -@cindex news spool +@lisp +(maildir :path "/home/user-name/Maildir/" + :subdirs ("cur" "new")) +@end lisp -Subscribing to a foreign group from the local spool is extremely easy, -and might be useful, for instance, to speed up reading groups that -contain very big articles---@samp{alt.binaries.pictures.furniture}, for -instance. +@lisp +(maildir :path "/user@@remotehost.org:~/Maildir/" + :subdirs ("new")) +@end lisp -Anyway, you just specify @code{nnspool} as the method and @code{""} (or -anything else) as the address. +@item imap +Get mail from a @acronym{IMAP} server. If you don't want to use +@acronym{IMAP} as intended, as a network mail reading protocol (ie +with nnimap), for some reason or other, Gnus let you treat it similar +to a @acronym{POP} server and fetches articles from a given +@acronym{IMAP} mailbox. @xref{Using IMAP}, for more information. -If you have access to a local spool, you should probably use that as the -native select method (@pxref{Finding the News}). It is normally faster -than using an @code{nntp} select method, but might not be. It depends. -You just have to try to find out what's best at your site. +Keywords: @table @code +@item :server +The name of the @acronym{IMAP} server. The default is taken from the +@env{MAILHOST} environment variable. -@item nnspool-inews-program -@vindex nnspool-inews-program -Program used to post an article. - -@item nnspool-inews-switches -@vindex nnspool-inews-switches -Parameters given to the inews program when posting an article. +@item :port +The port number of the @acronym{IMAP} server. The default is @samp{143}, or +@samp{993} for @acronym{TLS}/@acronym{SSL} connections. -@item nnspool-spool-directory -@vindex nnspool-spool-directory -Where @code{nnspool} looks for the articles. This is normally -@file{/usr/spool/news/}. +@item :user +The user name to give to the @acronym{IMAP} server. The default is the login +name. -@item nnspool-nov-directory -@vindex nnspool-nov-directory -Where @code{nnspool} will look for @acronym{NOV} files. This is normally@* -@file{/usr/spool/news/over.view/}. +@item :password +The password to give to the @acronym{IMAP} server. If not specified, the user is +prompted. -@item nnspool-lib-dir -@vindex nnspool-lib-dir -Where the news lib dir is (@file{/usr/lib/news/} by default). +@item :stream +What stream to use for connecting to the server, this is one of the +symbols in @code{imap-stream-alist}. Right now, this means +@samp{gssapi}, @samp{kerberos4}, @samp{starttls}, @samp{tls}, +@samp{ssl}, @samp{shell} or the default @samp{network}. -@item nnspool-active-file -@vindex nnspool-active-file -The name of the active file. +@item :authentication +Which authenticator to use for authenticating to the server, this is +one of the symbols in @code{imap-authenticator-alist}. Right now, +this means @samp{gssapi}, @samp{kerberos4}, @samp{digest-md5}, +@samp{cram-md5}, @samp{anonymous} or the default @samp{login}. -@item nnspool-newsgroups-file -@vindex nnspool-newsgroups-file -The name of the group descriptions file. +@item :program +When using the `shell' :stream, the contents of this variable is +mapped into the @code{imap-shell-program} variable. This should be a +@code{format}-like string (or list of strings). Here's an example: -@item nnspool-history-file -@vindex nnspool-history-file -The name of the news history file. +@example +ssh %s imapd +@end example -@item nnspool-active-times-file -@vindex nnspool-active-times-file -The name of the active date file. +Make sure nothing is interfering with the output of the program, e.g., +don't forget to redirect the error output to the void. The valid format +specifier characters are: -@item nnspool-nov-is-evil -@vindex nnspool-nov-is-evil -If non-@code{nil}, @code{nnspool} won't try to use any @acronym{NOV} files -that it finds. +@table @samp +@item s +The name of the server. -@item nnspool-sift-nov-with-sed -@vindex nnspool-sift-nov-with-sed -@cindex sed -If non-@code{nil}, which is the default, use @code{sed} to get the -relevant portion from the overview file. If @code{nil}, -@code{nnspool} will load the entire file into a buffer and process it -there. +@item l +User name from @code{imap-default-user}. +@item p +The port number of the server. @end table +The values used for these specs are taken from the values you give the +corresponding keywords. -@node Using IMAP -@section Using IMAP -@cindex imap +@item :mailbox +The name of the mailbox to get mail from. The default is @samp{INBOX} +which normally is the mailbox which receives incoming mail. -The most popular mail backend is probably @code{nnimap}, which -provides access to @acronym{IMAP} servers. @acronym{IMAP} servers -store mail remotely, so the client doesn't store anything locally. -This means that it's a convenient choice when you're reading your mail -from different locations, or with different user agents. +@item :predicate +The predicate used to find articles to fetch. The default, @samp{UNSEEN +UNDELETED}, is probably the best choice for most people, but if you +sometimes peek in your mailbox with a @acronym{IMAP} client and mark some +articles as read (or; SEEN) you might want to set this to @samp{1:*}. +Then all articles in the mailbox is fetched, no matter what. For a +complete list of predicates, see RFC 2060 section 6.4.4. -@menu -* Connecting to an IMAP Server:: Getting started with @acronym{IMAP}. -* Customizing the IMAP Connection:: Variables for @acronym{IMAP} connection. -* Client-Side IMAP Splitting:: Put mail in the correct mail box. -@end menu +@item :fetchflag +How to flag fetched articles on the server, the default @samp{\Deleted} +will mark them as deleted, an alternative would be @samp{\Seen} which +would simply mark them as read. These are the two most likely choices, +but more flags are defined in RFC 2060 section 2.3.2. +@item :dontexpunge +If non-@code{nil}, don't remove all articles marked as deleted in the +mailbox after finishing the fetch. -@node Connecting to an IMAP Server -@subsection Connecting to an IMAP Server +@end table -Connecting to an @acronym{IMAP} can be very easy. Type @kbd{B} in the -group buffer, or (if your primary interest is reading email), say -something like: +An example @acronym{IMAP} mail source: -@example -(setq gnus-select-method - '(nnimap "imap.gmail.com")) -@end example +@lisp +(imap :server "mail.mycorp.com" + :stream kerberos4 + :fetchflag "\\Seen") +@end lisp -You'll be prompted for a user name and password. If you grow tired of -that, then add the following to your @file{~/.authinfo} file: +@item group +Get the actual mail source from the @code{mail-source} group parameter, +@xref{Group Parameters}. -@example -machine imap.gmail.com login password port imap -@end example +@end table -That should basically be it for most users. +@table @dfn +@item Common Keywords +Common keywords can be used in any type of mail source. +Keywords: -@node Customizing the IMAP Connection -@subsection Customizing the IMAP Connection +@table @code +@item :plugged +If non-@code{nil}, fetch the mail even when Gnus is unplugged. If you +use directory source to get mail, you can specify it as in this +example: -Here's an example method that's more complex: +@lisp +(setq mail-sources + '((directory :path "/home/pavel/.Spool/" + :suffix "" + :plugged t))) +@end lisp -@example -(nnimap "imap.gmail.com" - (nnimap-inbox "INBOX") - (nnimap-split-methods default) - (nnimap-expunge t) - (nnimap-stream ssl)) -@end example +Gnus will then fetch your mail even when you are unplugged. This is +useful when you use local mail and news. -@table @code -@item nnimap-address -The address of the server, like @samp{imap.gmail.com}. +@end table +@end table -@item nnimap-server-port -If the server uses a non-standard port, that can be specified here. A -typical port would be @code{"imap"} or @code{"imaps"}. +@subsubsection Function Interface -@item nnimap-stream -How @code{nnimap} should connect to the server. Possible values are: +Some of the above keywords specify a Lisp function to be executed. +For each keyword @code{:foo}, the Lisp variable @code{foo} is bound to +the value of the keyword while the function is executing. For example, +consider the following mail-source setting: -@table @code -@item undecided -This is the default, and this first tries the @code{ssl} setting, and -then tries the @code{network} setting. +@lisp +(setq mail-sources '((pop :user "jrl" + :server "pophost" :function fetchfunc))) +@end lisp -@item ssl -This uses standard @acronym{TLS}/@acronym{SSL} connections. +While the function @code{fetchfunc} is executing, the symbol @code{user} +is bound to @code{"jrl"}, and the symbol @code{server} is bound to +@code{"pophost"}. The symbols @code{port}, @code{password}, +@code{program}, @code{prescript}, @code{postscript}, @code{function}, +and @code{authentication} are also bound (to their default values). -@item network -Non-encrypted and unsafe straight socket connection, but will upgrade -to encrypted @acronym{STARTTLS} if both Emacs and the server -supports it. +See above for a list of keywords for each type of mail source. -@item starttls -Encrypted @acronym{STARTTLS} over the normal @acronym{IMAP} port. -@item shell -If you need to tunnel via other systems to connect to the server, you -can use this option, and customize @code{nnimap-shell-program} to be -what you need. +@node Mail Source Customization +@subsubsection Mail Source Customization -@end table +The following is a list of variables that influence how the mail is +fetched. You would normally not need to set or change any of these +variables. -@item nnimap-authenticator -Some @acronym{IMAP} servers allow anonymous logins. In that case, -this should be set to @code{anonymous}. +@table @code +@item mail-source-crash-box +@vindex mail-source-crash-box +File where mail will be stored while processing it. The default is@* +@file{~/.emacs-mail-crash-box}. -@item nnimap-expunge -If non-@code{nil}, expunge articles after deleting them. This is always done -if the server supports UID EXPUNGE, but it's not done by default on -servers that doesn't support that command. +@cindex Incoming* +@item mail-source-delete-incoming +@vindex mail-source-delete-incoming +If non-@code{nil}, delete incoming files after handling them. If +@code{t}, delete the files immediately, if @code{nil}, never delete any +files. If a positive number, delete files older than number of days +(the deletion will only happen when receiving new mail). You may also +set @code{mail-source-delete-incoming} to @code{nil} and call +@code{mail-source-delete-old-incoming} from a hook or interactively. +@code{mail-source-delete-incoming} defaults to @code{10} in alpha Gnusae +and @code{2} in released Gnusae. @xref{Gnus Development}. -@item nnimap-streaming -Virtually all @code{IMAP} server support fast streaming of data. If -you have problems connecting to the server, try setting this to @code{nil}. +@item mail-source-delete-old-incoming-confirm +@vindex mail-source-delete-old-incoming-confirm +If non-@code{nil}, ask for confirmation before deleting old incoming +files. This variable only applies when +@code{mail-source-delete-incoming} is a positive number. -@item nnimap-fetch-partial-articles -If non-@code{nil}, fetch partial articles from the server. If set to -a string, then it's interpreted as a regexp, and parts that have -matching types will be fetched. For instance, @samp{"text/"} will -fetch all textual parts, while leaving the rest on the server. +@item mail-source-ignore-errors +@vindex mail-source-ignore-errors +If non-@code{nil}, ignore errors when reading mail from a mail source. -@end table +@item mail-source-directory +@vindex mail-source-directory +Directory where incoming mail source files (if any) will be stored. The +default is @file{~/Mail/}. At present, the only thing this is used for +is to say where the incoming files will be stored if the variable +@code{mail-source-delete-incoming} is @code{nil} or a number. +@item mail-source-incoming-file-prefix +@vindex mail-source-incoming-file-prefix +Prefix for file name for storing incoming mail. The default is +@file{Incoming}, in which case files will end up with names like +@file{Incoming30630D_} or @file{Incoming298602ZD}. This is really only +relevant if @code{mail-source-delete-incoming} is @code{nil} or a +number. -@node Client-Side IMAP Splitting -@subsection Client-Side IMAP Splitting +@item mail-source-default-file-modes +@vindex mail-source-default-file-modes +All new mail files will get this file mode. The default is 384. -Many people prefer to do the sorting/splitting of mail into their mail -boxes on the @acronym{IMAP} server. That way they don't have to -download the mail they're not all that interested in. +@item mail-source-movemail-program +@vindex mail-source-movemail-program +If non-@code{nil}, name of program for fetching new mail. If +@code{nil}, @code{movemail} in @var{exec-directory}. -If you do want to do client-side mail splitting, then the following -variables are relevant: +@end table -@table @code -@item nnimap-inbox -This is the @acronym{IMAP} mail box that will be scanned for new mail. -@item nnimap-split-methods -Uses the same syntax as @code{nnmail-split-methods} (@pxref{Splitting -Mail}), except the symbol @code{default}, which means that it should -use the value of the @code{nnmail-split-methods} variable. +@node Fetching Mail +@subsubsection Fetching Mail -@item nnimap-split-fancy -Uses the same syntax as @code{nnmail-split-fancy}. +@vindex mail-sources +The way to actually tell Gnus where to get new mail from is to set +@code{mail-sources} to a list of mail source specifiers +(@pxref{Mail Source Specifiers}). -@item nnimap-unsplittable-articles -List of flag symbols to ignore when doing splitting. That is, -articles that have these flags won't be considered when splitting. -The default is @samp{(%Deleted %Seen)}. +If this variable is @code{nil}, the mail back ends will never attempt to +fetch mail by themselves. -@end table +If you want to fetch mail both from your local spool as well as a +@acronym{POP} mail server, you'd say something like: + +@lisp +(setq mail-sources + '((file) + (pop :server "pop3.mail.server" + :password "secret"))) +@end lisp +Or, if you don't want to use any of the keyword defaults: -@node Getting Mail -@section Getting Mail -@cindex reading mail -@cindex mail +@lisp +(setq mail-sources + '((file :path "/var/spool/mail/user-name") + (pop :server "pop3.mail.server" + :user "user-name" + :port "pop3" + :password "secret"))) +@end lisp -Reading mail with a newsreader---isn't that just plain WeIrD? But of -course. -@menu -* Mail in a Newsreader:: Important introductory notes. -* Getting Started Reading Mail:: A simple cookbook example. -* Splitting Mail:: How to create mail groups. -* Mail Sources:: How to tell Gnus where to get mail from. -* Mail Back End Variables:: Variables for customizing mail handling. -* Fancy Mail Splitting:: Gnus can do hairy splitting of incoming mail. -* Group Mail Splitting:: Use group customize to drive mail splitting. -* Incorporating Old Mail:: What about the old mail you have? -* Expiring Mail:: Getting rid of unwanted mail. -* Washing Mail:: Removing cruft from the mail you get. -* Duplicates:: Dealing with duplicated mail. -* Not Reading Mail:: Using mail back ends for reading other files. -* Choosing a Mail Back End:: Gnus can read a variety of mail formats. -@end menu +When you use a mail back end, Gnus will slurp all your mail from your +inbox and plonk it down in your home directory. Gnus doesn't move any +mail if you're not using a mail back end---you have to do a lot of magic +invocations first. At the time when you have finished drawing the +pentagram, lightened the candles, and sacrificed the goat, you really +shouldn't be too surprised when Gnus moves your mail. -@node Mail in a Newsreader -@subsection Mail in a Newsreader -If you are used to traditional mail readers, but have decided to switch -to reading mail with Gnus, you may find yourself experiencing something -of a culture shock. +@node Mail Back End Variables +@subsection Mail Back End Variables -Gnus does not behave like traditional mail readers. If you want to make -it behave that way, you can, but it's an uphill battle. +These variables are (for the most part) pertinent to all the various +mail back ends. -Gnus, by default, handles all its groups using the same approach. This -approach is very newsreaderly---you enter a group, see the new/unread -messages, and when you read the messages, they get marked as read, and -you don't see them any more. (Unless you explicitly ask for them.) +@table @code +@vindex nnmail-read-incoming-hook +@item nnmail-read-incoming-hook +The mail back ends all call this hook after reading new mail. You can +use this hook to notify any mail watch programs, if you want to. -In particular, you do not do anything explicitly to delete messages. +@vindex nnmail-split-hook +@item nnmail-split-hook +@findex gnus-article-decode-encoded-words +@cindex RFC 1522 decoding +@cindex RFC 2047 decoding +Hook run in the buffer where the mail headers of each message is kept +just before the splitting based on these headers is done. The hook is +free to modify the buffer contents in any way it sees fit---the buffer +is discarded after the splitting has been done, and no changes performed +in the buffer will show up in any files. +@code{gnus-article-decode-encoded-words} is one likely function to add +to this hook. -Does this mean that all the messages that have been marked as read are -deleted? How awful! +@vindex nnmail-pre-get-new-mail-hook +@vindex nnmail-post-get-new-mail-hook +@item nnmail-pre-get-new-mail-hook +@itemx nnmail-post-get-new-mail-hook +These are two useful hooks executed when treating new incoming +mail---@code{nnmail-pre-get-new-mail-hook} (is called just before +starting to handle the new mail) and +@code{nnmail-post-get-new-mail-hook} (is called when the mail handling +is done). Here's and example of using these two hooks to change the +default file modes the new mail files get: -But, no, it means that old messages are @dfn{expired} according to some -scheme or other. For news messages, the expire process is controlled by -the news administrator; for mail, the expire process is controlled by -you. The expire process for mail is covered in depth in @ref{Expiring -Mail}. +@lisp +(add-hook 'nnmail-pre-get-new-mail-hook + (lambda () (set-default-file-modes 511))) -What many Gnus users find, after using it a while for both news and -mail, is that the transport mechanism has very little to do with how -they want to treat a message. +(add-hook 'nnmail-post-get-new-mail-hook + (lambda () (set-default-file-modes 551))) +@end lisp -Many people subscribe to several mailing lists. These are transported -via @acronym{SMTP}, and are therefore mail. But we might go for weeks without -answering, or even reading these messages very carefully. We may not -need to save them because if we should need to read one again, they are -archived somewhere else. +@item nnmail-use-long-file-names +@vindex nnmail-use-long-file-names +If non-@code{nil}, the mail back ends will use long file and directory +names. Groups like @samp{mail.misc} will end up in directories +(assuming use of @code{nnml} back end) or files (assuming use of +@code{nnfolder} back end) like @file{mail.misc}. If it is @code{nil}, +the same group will end up in @file{mail/misc}. -Some people have local news groups which have only a handful of readers. -These are transported via @acronym{NNTP}, and are therefore news. But we may need -to read and answer a large fraction of the messages very carefully in -order to do our work. And there may not be an archive, so we may need -to save the interesting messages the same way we would personal mail. +@item nnmail-delete-file-function +@vindex nnmail-delete-file-function +@findex delete-file +Function called to delete files. It is @code{delete-file} by default. -The important distinction turns out to be not the transport mechanism, -but other factors such as how interested we are in the subject matter, -or how easy it is to retrieve the message if we need to read it again. +@item nnmail-cache-accepted-message-ids +@vindex nnmail-cache-accepted-message-ids +If non-@code{nil}, put the @code{Message-ID}s of articles imported into +the back end (via @code{Gcc}, for instance) into the mail duplication +discovery cache. The default is @code{nil}. -Gnus provides many options for sorting mail into ``groups'' which behave -like newsgroups, and for treating each group (whether mail or news) -differently. +@item nnmail-cache-ignore-groups +@vindex nnmail-cache-ignore-groups +This can be a regular expression or a list of regular expressions. +Group names that match any of the regular expressions will never be +recorded in the @code{Message-ID} cache. -Some users never get comfortable using the Gnus (ahem) paradigm and wish -that Gnus should grow up and be a male, er, mail reader. It is possible -to whip Gnus into a more mailreaderly being, but, as said before, it's -not easy. People who prefer proper mail readers should try @sc{vm} -instead, which is an excellent, and proper, mail reader. +This can be useful, for example, when using Fancy Splitting +(@pxref{Fancy Mail Splitting}) together with the function +@code{nnmail-split-fancy-with-parent}. -I don't mean to scare anybody off, but I want to make it clear that you -may be required to learn a new way of thinking about messages. After -you've been subjected to The Gnus Way, you will come to love it. I can -guarantee it. (At least the guy who sold me the Emacs Subliminal -Brain-Washing Functions that I've put into Gnus did guarantee it. You -Will Be Assimilated. You Love Gnus. You Love The Gnus Mail Way. -You Do.) +@end table -@node Getting Started Reading Mail -@subsection Getting Started Reading Mail +@node Fancy Mail Splitting +@subsection Fancy Mail Splitting +@cindex mail splitting +@cindex fancy mail splitting -It's quite easy to use Gnus to read your new mail. You just plonk the -mail back end of your choice into @code{gnus-secondary-select-methods}, -and things will happen automatically. +@vindex nnmail-split-fancy +@findex nnmail-split-fancy +If the rather simple, standard method for specifying how to split mail +doesn't allow you to do what you want, you can set +@code{nnmail-split-methods} to @code{nnmail-split-fancy}. Then you can +play with the @code{nnmail-split-fancy} variable. -For instance, if you want to use @code{nnml} (which is a ``one file per -mail'' back end), you could put the following in your @file{~/.gnus.el} file: +Let's look at an example value of this variable first: @lisp -(setq gnus-secondary-select-methods '((nnml ""))) +;; @r{Messages from the mailer daemon are not crossposted to any of} +;; @r{the ordinary groups. Warnings are put in a separate group} +;; @r{from real errors.} +(| ("from" mail (| ("subject" "warn.*" "mail.warning") + "mail.misc")) + ;; @r{Non-error messages are crossposted to all relevant} + ;; @r{groups, but we don't crosspost between the group for the} + ;; @r{(ding) list and the group for other (ding) related mail.} + (& (| (any "ding@@ifi\\.uio\\.no" "ding.list") + ("subject" "ding" "ding.misc")) + ;; @r{Other mailing lists@dots{}} + (any "procmail@@informatik\\.rwth-aachen\\.de" "procmail.list") + (any "SmartList@@informatik\\.rwth-aachen\\.de" "SmartList.list") + ;; @r{Both lists below have the same suffix, so prevent} + ;; @r{cross-posting to mkpkg.list of messages posted only to} + ;; @r{the bugs- list, but allow cross-posting when the} + ;; @r{message was really cross-posted.} + (any "bugs-mypackage@@somewhere" "mypkg.bugs") + (any "mypackage@@somewhere" - "bugs-mypackage" "mypkg.list") + ;; @r{People@dots{}} + (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) + ;; @r{Unmatched mail goes to the catch all group.} + "misc.misc") @end lisp -Now, the next time you start Gnus, this back end will be queried for new -articles, and it will move all the messages in your spool file to its -directory, which is @file{~/Mail/} by default. The new group that will -be created (@samp{mail.misc}) will be subscribed, and you can read it -like any other group. +This variable has the format of a @dfn{split}. A split is a +(possibly) recursive structure where each split may contain other +splits. Here are the possible split syntaxes: -You will probably want to split the mail into several groups, though: +@table @code -@lisp -(setq nnmail-split-methods - '(("junk" "^From:.*Lars Ingebrigtsen") - ("crazy" "^Subject:.*die\\|^Organization:.*flabby") - ("other" ""))) -@end lisp +@item group +If the split is a string, that will be taken as a group name. Normal +regexp match expansion will be done. See below for examples. -This will result in three new @code{nnml} mail groups being created: -@samp{nnml:junk}, @samp{nnml:crazy}, and @samp{nnml:other}. All the -mail that doesn't fit into the first two groups will be placed in the -last group. +@c Don't fold this line. +@item (@var{field} @var{value} [- @var{restrict} [@dots{}] ] @var{split} [@var{invert-partial}]) +The split can be a list containing at least three elements. If the +first element @var{field} (a regexp matching a header) contains +@var{value} (also a regexp) then store the message as specified by +@var{split}. -This should be sufficient for reading mail with Gnus. You might want to -give the other sections in this part of the manual a perusal, though. -Especially @pxref{Choosing a Mail Back End} and @pxref{Expiring Mail}. +If @var{restrict} (yet another regexp) matches some string after +@var{field} and before the end of the matched @var{value}, the +@var{split} is ignored. If none of the @var{restrict} clauses match, +@var{split} is processed. +The last element @var{invert-partial} is optional. If it is +non-@code{nil}, the match-partial-words behavior controlled by the +variable @code{nnmail-split-fancy-match-partial-words} (see below) is +be inverted. (New in Gnus 5.10.7) -@node Splitting Mail -@subsection Splitting Mail -@cindex splitting mail -@cindex mail splitting -@cindex mail filtering (splitting) +@item (| @var{split} @dots{}) +If the split is a list, and the first element is @code{|} (vertical +bar), then process each @var{split} until one of them matches. A +@var{split} is said to match if it will cause the mail message to be +stored in one or more groups. -@vindex nnmail-split-methods -The @code{nnmail-split-methods} variable says how the incoming mail is -to be split into groups. +@item (& @var{split} @dots{}) +If the split is a list, and the first element is @code{&}, then +process all @var{split}s in the list. -@lisp -(setq nnmail-split-methods - '(("mail.junk" "^From:.*Lars Ingebrigtsen") - ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") - ("mail.other" ""))) -@end lisp +@item junk +If the split is the symbol @code{junk}, then don't save (i.e., delete) +this message. Use with extreme caution. -This variable is a list of lists, where the first element of each of -these lists is the name of the mail group (they do not have to be called -something beginning with @samp{mail}, by the way), and the second -element is a regular expression used on the header of each mail to -determine if it belongs in this mail group. The first string may -contain @samp{\\1} forms, like the ones used by @code{replace-match} to -insert sub-expressions from the matched text. For instance: +@item (: @var{function} @var{arg1} @var{arg2} @dots{}) +If the split is a list, and the first element is @samp{:}, then the +second element will be called as a function with @var{args} given as +arguments. The function should return a @var{split}. + +@cindex body split +For instance, the following function could be used to split based on the +body of the messages: @lisp -("list.\\1" "From:.* \\(.*\\)-list@@majordomo.com") +(defun split-on-body () + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (when (re-search-forward "Some.*string" nil t) + "string.group")))) @end lisp -@noindent -In that case, @code{nnmail-split-lowercase-expanded} controls whether -the inserted text should be made lowercase. @xref{Fancy Mail Splitting}. +The buffer is narrowed to the header of the message in question when +@var{function} is run. That's why @code{(widen)} needs to be called +after @code{save-excursion} and @code{save-restriction} in the example +above. Also note that with the nnimap backend, message bodies will +not be downloaded by default. You need to set +@code{nnimap-split-download-body} to @code{t} to do that +(@pxref{Client-Side IMAP Splitting}). -The second element can also be a function. In that case, it will be -called narrowed to the headers with the first element of the rule as the -argument. It should return a non-@code{nil} value if it thinks that the -mail belongs in that group. +@item (! @var{func} @var{split}) +If the split is a list, and the first element is @code{!}, then +@var{split} will be processed, and @var{func} will be called as a +function with the result of @var{split} as argument. @var{func} +should return a split. -@cindex @samp{bogus} group -The last of these groups should always be a general one, and the regular -expression should @emph{always} be @samp{""} so that it matches any mails -that haven't been matched by any of the other regexps. (These rules are -processed from the beginning of the alist toward the end. The first rule -to make a match will ``win'', unless you have crossposting enabled. In -that case, all matching rules will ``win''.) If no rule matched, the mail -will end up in the @samp{bogus} group. When new groups are created by -splitting mail, you may want to run @code{gnus-group-find-new-groups} to -see the new groups. This also applies to the @samp{bogus} group. +@item nil +If the split is @code{nil}, it is ignored. -If you like to tinker with this yourself, you can set this variable to a -function of your choice. This function will be called without any -arguments in a buffer narrowed to the headers of an incoming mail -message. The function should return a list of group names that it -thinks should carry this mail message. +@end table -This variable can also be a fancy split method. For the syntax, -see @ref{Fancy Mail Splitting}. +In these splits, @var{field} must match a complete field name. -Note that the mail back ends are free to maul the poor, innocent, -incoming headers all they want to. They all add @code{Lines} headers; -some add @code{X-Gnus-Group} headers; most rename the Unix mbox -@code{From} line to something else. +Normally, @var{value} in these splits must match a complete @emph{word} +according to the fundamental mode syntax table. In other words, all +@var{value}'s will be implicitly surrounded by @code{\<...\>} markers, +which are word delimiters. Therefore, if you use the following split, +for example, -@vindex nnmail-crosspost -The mail back ends all support cross-posting. If several regexps match, -the mail will be ``cross-posted'' to all those groups. -@code{nnmail-crosspost} says whether to use this mechanism or not. Note -that no articles are crossposted to the general (@samp{""}) group. +@example +(any "joe" "joemail") +@end example -@vindex nnmail-crosspost-link-function -@cindex crosspost -@cindex links -@code{nnmh} and @code{nnml} makes crossposts by creating hard links to -the crossposted articles. However, not all file systems support hard -links. If that's the case for you, set -@code{nnmail-crosspost-link-function} to @code{copy-file}. (This -variable is @code{add-name-to-file} by default.) +@noindent +messages sent from @samp{joedavis@@foo.org} will normally not be filed +in @samp{joemail}. If you want to alter this behavior, you can use any +of the following three ways: -@kindex M-x nnmail-split-history -@findex nnmail-split-history -If you wish to see where the previous mail split put the messages, you -can use the @kbd{M-x nnmail-split-history} command. If you wish to see -where re-spooling messages would put the messages, you can use -@code{gnus-summary-respool-trace} and related commands (@pxref{Mail -Group Commands}). +@enumerate +@item +@vindex nnmail-split-fancy-match-partial-words +You can set the @code{nnmail-split-fancy-match-partial-words} variable +to non-@code{nil} in order to ignore word boundaries and instead the +match becomes more like a grep. This variable controls whether partial +words are matched during fancy splitting. The default value is +@code{nil}. -@vindex nnmail-split-header-length-limit -Header lines longer than the value of -@code{nnmail-split-header-length-limit} are excluded from the split -function. +Note that it influences all @var{value}'s in your split rules. -@vindex nnmail-mail-splitting-decodes -@vindex nnmail-mail-splitting-charset -By default, splitting does not decode headers, so you can not match on -non-@acronym{ASCII} strings. But it is useful if you want to match -articles based on the raw header data. To enable it, set the -@code{nnmail-mail-splitting-decodes} variable to a non-@code{nil} value. -In addition, the value of the @code{nnmail-mail-splitting-charset} -variable is used for decoding non-@acronym{MIME} encoded string when -@code{nnmail-mail-splitting-decodes} is non-@code{nil}. The default -value is @code{nil} which means not to decode non-@acronym{MIME} encoded -string. A suitable value for you will be @code{undecided} or be the -charset used normally in mails you are interested in. +@item +@var{value} beginning with @code{.*} ignores word boundaries in front of +a word. Similarly, if @var{value} ends with @code{.*}, word boundaries +in the rear of a word will be ignored. For example, the @var{value} +@code{"@@example\\.com"} does not match @samp{foo@@example.com} but +@code{".*@@example\\.com"} does. -@vindex nnmail-resplit-incoming -By default, splitting is performed on all incoming messages. If you -specify a @code{directory} entry for the variable @code{mail-sources} -(@pxref{Mail Source Specifiers}), however, then splitting does -@emph{not} happen by default. You can set the variable -@code{nnmail-resplit-incoming} to a non-@code{nil} value to make -splitting happen even in this case. (This variable has no effect on -other kinds of entries.) +@item +You can set the @var{invert-partial} flag in your split rules of the +@samp{(@var{field} @var{value} @dots{})} types, aforementioned in this +section. If the flag is set, word boundaries on both sides of a word +are ignored even if @code{nnmail-split-fancy-match-partial-words} is +@code{nil}. Contrarily, if the flag is set, word boundaries are not +ignored even if @code{nnmail-split-fancy-match-partial-words} is +non-@code{nil}. (New in Gnus 5.10.7) +@end enumerate -Gnus gives you all the opportunity you could possibly want for shooting -yourself in the foot. Let's say you create a group that will contain -all the mail you get from your boss. And then you accidentally -unsubscribe from the group. Gnus will still put all the mail from your -boss in the unsubscribed group, and so, when your boss mails you ``Have -that report ready by Monday or you're fired!'', you'll never see it and, -come Tuesday, you'll still believe that you're gainfully employed while -you really should be out collecting empty bottles to save up for next -month's rent money. +@vindex nnmail-split-abbrev-alist +@var{field} and @var{value} can also be Lisp symbols, in that case +they are expanded as specified by the variable +@code{nnmail-split-abbrev-alist}. This is an alist of cons cells, +where the @sc{car} of a cell contains the key, and the @sc{cdr} +contains the associated value. Predefined entries in +@code{nnmail-split-abbrev-alist} include: +@table @code +@item from +Matches the @samp{From}, @samp{Sender} and @samp{Resent-From} fields. +@item to +Matches the @samp{To}, @samp{Cc}, @samp{Apparently-To}, +@samp{Resent-To} and @samp{Resent-Cc} fields. +@item any +Is the union of the @code{from} and @code{to} entries. +@end table -@node Mail Sources -@subsection Mail Sources +@vindex nnmail-split-fancy-syntax-table +@code{nnmail-split-fancy-syntax-table} is the syntax table in effect +when all this splitting is performed. -Mail can be gotten from many different sources---the mail spool, from -a @acronym{POP} mail server, from a procmail directory, or from a -maildir, for instance. +If you want to have Gnus create groups dynamically based on some +information in the headers (i.e., do @code{replace-match}-like +substitutions in the group names), you can say things like: -@menu -* Mail Source Specifiers:: How to specify what a mail source is. -* Mail Source Customization:: Some variables that influence things. -* Fetching Mail:: Using the mail source specifiers. -@end menu +@example +(any "debian-\\b\\(\\w+\\)@@lists.debian.org" "mail.debian.\\1") +@end example +In this example, messages sent to @samp{debian-foo@@lists.debian.org} +will be filed in @samp{mail.debian.foo}. -@node Mail Source Specifiers -@subsubsection Mail Source Specifiers -@cindex POP -@cindex mail server -@cindex procmail -@cindex mail spool -@cindex mail source +If the string contains the element @samp{\&}, then the previously +matched string will be substituted. Similarly, the elements @samp{\\1} +up to @samp{\\9} will be substituted with the text matched by the +groupings 1 through 9. -You tell Gnus how to fetch mail by setting @code{mail-sources} -(@pxref{Fetching Mail}) to a @dfn{mail source specifier}. +@vindex nnmail-split-lowercase-expanded +Where @code{nnmail-split-lowercase-expanded} controls whether the +lowercase of the matched string should be used for the substitution. +Setting it as non-@code{nil} is useful to avoid the creation of multiple +groups when users send to an address using different case +(i.e. mailing-list@@domain vs Mailing-List@@Domain). The default value +is @code{t}. -Here's an example: +@findex nnmail-split-fancy-with-parent +@code{nnmail-split-fancy-with-parent} is a function which allows you to +split followups into the same groups their parents are in. Sometimes +you can't make splitting rules for all your mail. For example, your +boss might send you personal mail regarding different projects you are +working on, and as you can't tell your boss to put a distinguishing +string into the subject line, you have to resort to manually moving the +messages into the right group. With this function, you only have to do +it once per thread. +To use this feature, you have to set @code{nnmail-treat-duplicates} +and @code{nnmail-cache-accepted-message-ids} to a non-@code{nil} +value. And then you can include @code{nnmail-split-fancy-with-parent} +using the colon feature, like so: @lisp -(pop :server "pop3.mailserver.com" :user "myname") +(setq nnmail-treat-duplicates 'warn ; @r{or @code{delete}} + nnmail-cache-accepted-message-ids t + nnmail-split-fancy + '(| (: nnmail-split-fancy-with-parent) + ;; @r{other splits go here} + )) @end lisp -As can be observed, a mail source specifier is a list where the first -element is a @dfn{mail source type}, followed by an arbitrary number of -@dfn{keywords}. Keywords that are not explicitly specified are given -default values. +This feature works as follows: when @code{nnmail-treat-duplicates} is +non-@code{nil}, Gnus records the message id of every message it sees +in the file specified by the variable +@code{nnmail-message-id-cache-file}, together with the group it is in +(the group is omitted for non-mail messages). When mail splitting is +invoked, the function @code{nnmail-split-fancy-with-parent} then looks +at the References (and In-Reply-To) header of each message to split +and searches the file specified by @code{nnmail-message-id-cache-file} +for the message ids. When it has found a parent, it returns the +corresponding group name unless the group name matches the regexp +@code{nnmail-split-fancy-with-parent-ignore-groups}. It is +recommended that you set @code{nnmail-message-id-cache-length} to a +somewhat higher number than the default so that the message ids are +still in the cache. (A value of 5000 appears to create a file some +300 kBytes in size.) +@vindex nnmail-cache-accepted-message-ids +When @code{nnmail-cache-accepted-message-ids} is non-@code{nil}, Gnus +also records the message ids of moved articles, so that the followup +messages goes into the new group. -The @code{mail-sources} is global for all mail groups. You can specify -an additional mail source for a particular group by including the -@code{group} mail specifier in @code{mail-sources}, and setting a -@code{mail-source} group parameter (@pxref{Group Parameters}) specifying -a single mail source. When this is used, @code{mail-sources} is -typically just @code{(group)}; the @code{mail-source} parameter for a -group might look like this: +Also see the variable @code{nnmail-cache-ignore-groups} if you don't +want certain groups to be recorded in the cache. For example, if all +outgoing messages are written to an ``outgoing'' group, you could set +@code{nnmail-cache-ignore-groups} to match that group name. +Otherwise, answers to all your messages would end up in the +``outgoing'' group. -@lisp -(mail-source . (file :path "home/user/spools/foo.spool")) -@end lisp -This means that the group's (and only this group's) messages will be -fetched from the spool file @samp{/user/spools/foo.spool}. +@node Group Mail Splitting +@subsection Group Mail Splitting +@cindex mail splitting +@cindex group mail splitting -The following mail source types are available: +@findex gnus-group-split +If you subscribe to dozens of mailing lists but you don't want to +maintain mail splitting rules manually, group mail splitting is for you. +You just have to set @code{to-list} and/or @code{to-address} in group +parameters or group customization and set @code{nnmail-split-methods} to +@code{gnus-group-split}. This splitting function will scan all groups +for those parameters and split mail accordingly, i.e., messages posted +from or to the addresses specified in the parameters @code{to-list} or +@code{to-address} of a mail group will be stored in that group. -@table @code -@item file -Get mail from a single file; typically from the mail spool. +Sometimes, mailing lists have multiple addresses, and you may want mail +splitting to recognize them all: just set the @code{extra-aliases} group +parameter to the list of additional addresses and it's done. If you'd +rather use a regular expression, set @code{split-regexp}. -Keywords: +All these parameters in a group will be used to create an +@code{nnmail-split-fancy} split, in which the @var{field} is @samp{any}, +the @var{value} is a single regular expression that matches +@code{to-list}, @code{to-address}, all of @code{extra-aliases} and all +matches of @code{split-regexp}, and the @var{split} is the name of the +group. @var{restrict}s are also supported: just set the +@code{split-exclude} parameter to a list of regular expressions. -@table @code -@item :path -The file name. Defaults to the value of the @env{MAIL} -environment variable or the value of @code{rmail-spool-directory} -(usually something like @file{/usr/mail/spool/user-name}). +If you can't get the right split to be generated using all these +parameters, or you just need something fancier, you can set the +parameter @code{split-spec} to an @code{nnmail-split-fancy} split. In +this case, all other aforementioned parameters will be ignored by +@code{gnus-group-split}. In particular, @code{split-spec} may be set to +@code{nil}, in which case the group will be ignored by +@code{gnus-group-split}. -@item :prescript -@itemx :postscript -Script run before/after fetching mail. -@end table +@vindex gnus-group-split-default-catch-all-group +@code{gnus-group-split} will do cross-posting on all groups that match, +by defining a single @code{&} fancy split containing one split for each +group. If a message doesn't match any split, it will be stored in the +group named in @code{gnus-group-split-default-catch-all-group}, unless +some group has @code{split-spec} set to @code{catch-all}, in which case +that group is used as the catch-all group. Even though this variable is +often used just to name a group, it may also be set to an arbitrarily +complex fancy split (after all, a group name is a fancy split), and this +may be useful to split mail that doesn't go to any mailing list to +personal mail folders. Note that this fancy split is added as the last +element of a @code{|} split list that also contains a @code{&} split +with the rules extracted from group parameters. -An example file mail source: +It's time for an example. Assume the following group parameters have +been defined: -@lisp -(file :path "/usr/spool/mail/user-name") -@end lisp +@example +nnml:mail.bar: +((to-address . "bar@@femail.com") + (split-regexp . ".*@@femail\\.com")) +nnml:mail.foo: +((to-list . "foo@@nowhere.gov") + (extra-aliases "foo@@localhost" "foo-redist@@home") + (split-exclude "bugs-foo" "rambling-foo") + (admin-address . "foo-request@@nowhere.gov")) +nnml:mail.others: +((split-spec . catch-all)) +@end example -Or using the default file name: +Setting @code{nnmail-split-methods} to @code{gnus-group-split} will +behave as if @code{nnmail-split-fancy} had been selected and variable +@code{nnmail-split-fancy} had been set as follows: @lisp -(file) +(| (& (any "\\(bar@@femail\\.com\\|.*@@femail\\.com\\)" "mail.bar") + (any "\\(foo@@nowhere\\.gov\\|foo@@localhost\\|foo-redist@@home\\)" + - "bugs-foo" - "rambling-foo" "mail.foo")) + "mail.others") @end lisp -If the mail spool file is not located on the local machine, it's best -to use @acronym{POP} or @acronym{IMAP} or the like to fetch the mail. -You can not use ange-ftp file names here---it has no way to lock the -mail spool while moving the mail. - -If it's impossible to set up a proper server, you can use ssh instead. +@findex gnus-group-split-fancy +If you'd rather not use group splitting for all your mail groups, you +may use it for only some of them, by using @code{nnmail-split-fancy} +splits like this: @lisp -(setq mail-sources - '((file :prescript "ssh host bin/getmail >%t"))) +(: gnus-group-split-fancy @var{groups} @var{no-crosspost} @var{catch-all}) @end lisp -The @samp{getmail} script would look something like the following: - -@example -#!/bin/sh -# getmail - move mail from spool to stdout -# flu@@iki.fi - -MOVEMAIL=/usr/lib/emacs/20.3/i386-redhat-linux/movemail -TMP=$HOME/Mail/tmp -rm -f $TMP; $MOVEMAIL $MAIL $TMP >/dev/null && cat $TMP -@end example - -Alter this script to fit the @samp{movemail} and temporary -file you want to use. - +@var{groups} may be a regular expression or a list of group names whose +parameters will be scanned to generate the output split. +@var{no-crosspost} can be used to disable cross-posting; in this case, a +single @code{|} split will be output. @var{catch-all} is the fall back +fancy split, used like @code{gnus-group-split-default-catch-all-group}. +If @var{catch-all} is @code{nil}, or if @code{split-regexp} matches the +empty string in any selected group, no catch-all split will be issued. +Otherwise, if some group has @code{split-spec} set to @code{catch-all}, +this group will override the value of the @var{catch-all} argument. -@item directory -@vindex nnmail-scan-directory-mail-source-once -Get mail from several files in a directory. This is typically used -when you have procmail split the incoming mail into several files. -That is, there is a one-to-one correspondence between files in that -directory and groups, so that mail from the file @file{foo.bar.spool} -will be put in the group @code{foo.bar}. (You can change the suffix -to be used instead of @code{.spool}.) Setting -@code{nnmail-scan-directory-mail-source-once} to non-@code{nil} forces -Gnus to scan the mail source only once. This is particularly useful -if you want to scan mail groups at a specified level. +@findex gnus-group-split-setup +Unfortunately, scanning all groups and their parameters can be quite +slow, especially considering that it has to be done for every message. +But don't despair! The function @code{gnus-group-split-setup} can be +used to enable @code{gnus-group-split} in a much more efficient way. It +sets @code{nnmail-split-methods} to @code{nnmail-split-fancy} and sets +@code{nnmail-split-fancy} to the split produced by +@code{gnus-group-split-fancy}. Thus, the group parameters are only +scanned once, no matter how many messages are split. -@vindex nnmail-resplit-incoming -There is also the variable @code{nnmail-resplit-incoming}, if you set -that to a non-@code{nil} value, then the normal splitting process is -applied to all the files from the directory, @ref{Splitting Mail}. +@findex gnus-group-split-update +However, if you change group parameters, you'd have to update +@code{nnmail-split-fancy} manually. You can do it by running +@code{gnus-group-split-update}. If you'd rather have it updated +automatically, just tell @code{gnus-group-split-setup} to do it for +you. For example, add to your @file{~/.gnus.el}: -Keywords: +@lisp +(gnus-group-split-setup @var{auto-update} @var{catch-all}) +@end lisp -@table @code -@item :path -The name of the directory where the files are. There is no default +If @var{auto-update} is non-@code{nil}, @code{gnus-group-split-update} +will be added to @code{nnmail-pre-get-new-mail-hook}, so you won't ever +have to worry about updating @code{nnmail-split-fancy} again. If you +don't omit @var{catch-all} (it's optional, equivalent to @code{nil}), +@code{gnus-group-split-default-catch-all-group} will be set to its value. -@item :suffix -Only files ending with this suffix are used. The default is -@samp{.spool}. - -@item :predicate -Only files that have this predicate return non-@code{nil} are returned. -The default is @code{identity}. This is used as an additional -filter---only files that have the right suffix @emph{and} satisfy this -predicate are considered. - -@item :prescript -@itemx :postscript -Script run before/after fetching mail. - -@end table - -An example directory mail source: - -@lisp -(directory :path "/home/user-name/procmail-dir/" - :suffix ".prcml") -@end lisp +@vindex gnus-group-split-updated-hook +Because you may want to change @code{nnmail-split-fancy} after it is set +by @code{gnus-group-split-update}, this function will run +@code{gnus-group-split-updated-hook} just before finishing. -@item pop -Get mail from a @acronym{POP} server. +@node Incorporating Old Mail +@subsection Incorporating Old Mail +@cindex incorporating old mail +@cindex import old mail -Keywords: +Most people have lots of old mail stored in various file formats. If +you have set up Gnus to read mail using one of the spiffy Gnus mail +back ends, you'll probably wish to have that old mail incorporated into +your mail groups. -@table @code -@item :server -The name of the @acronym{POP} server. The default is taken from the -@env{MAILHOST} environment variable. +Doing so can be quite easy. -@item :port -The port number of the @acronym{POP} server. This can be a number (eg, -@samp{:port 1234}) or a string (eg, @samp{:port "pop3"}). If it is a -string, it should be a service name as listed in @file{/etc/services} on -Unix systems. The default is @samp{"pop3"}. On some systems you might -need to specify it as @samp{"pop-3"} instead. +To take an example: You're reading mail using @code{nnml} +(@pxref{Mail Spool}), and have set @code{nnmail-split-methods} to a +satisfactory value (@pxref{Splitting Mail}). You have an old Unix mbox +file filled with important, but old, mail. You want to move it into +your @code{nnml} groups. -@item :user -The user name to give to the @acronym{POP} server. The default is the login -name. +Here's how: -@item :password -The password to give to the @acronym{POP} server. If not specified, -the user is prompted. +@enumerate +@item +Go to the group buffer. -@item :program -The program to use to fetch mail from the @acronym{POP} server. This -should be a @code{format}-like string. Here's an example: +@item +Type @kbd{G f} and give the file name to the mbox file when prompted to create an +@code{nndoc} group from the mbox file (@pxref{Foreign Groups}). -@example -fetchmail %u@@%s -P %p %t -@end example +@item +Type @kbd{SPACE} to enter the newly created group. -The valid format specifier characters are: +@item +Type @kbd{M P b} to process-mark all articles in this group's buffer +(@pxref{Setting Process Marks}). -@table @samp -@item t -The name of the file the mail is to be moved to. This must always be -included in this string. +@item +Type @kbd{B r} to respool all the process-marked articles, and answer +@samp{nnml} when prompted (@pxref{Mail Group Commands}). +@end enumerate -@item s -The name of the server. +All the mail messages in the mbox file will now also be spread out over +all your @code{nnml} groups. Try entering them and check whether things +have gone without a glitch. If things look ok, you may consider +deleting the mbox file, but I wouldn't do that unless I was absolutely +sure that all the mail has ended up where it should be. -@item P -The port number of the server. +Respooling is also a handy thing to do if you're switching from one mail +back end to another. Just respool all the mail in the old mail groups +using the new mail back end. -@item u -The user name to use. -@item p -The password to use. -@end table +@node Expiring Mail +@subsection Expiring Mail +@cindex article expiry +@cindex expiring mail -The values used for these specs are taken from the values you give the -corresponding keywords. +Traditional mail readers have a tendency to remove mail articles when +you mark them as read, in some way. Gnus takes a fundamentally +different approach to mail reading. -@item :prescript -A script to be run before fetching the mail. The syntax is the same as -the @code{:program} keyword. This can also be a function to be run. +Gnus basically considers mail just to be news that has been received in +a rather peculiar manner. It does not think that it has the power to +actually change the mail, or delete any mail messages. If you enter a +mail group, and mark articles as ``read'', or kill them in some other +fashion, the mail articles will still exist on the system. I repeat: +Gnus will not delete your old, read mail. Unless you ask it to, of +course. -@item :postscript -A script to be run after fetching the mail. The syntax is the same as -the @code{:program} keyword. This can also be a function to be run. +To make Gnus get rid of your unwanted mail, you have to mark the +articles as @dfn{expirable}. (With the default key bindings, this means +that you have to type @kbd{E}.) This does not mean that the articles +will disappear right away, however. In general, a mail article will be +deleted from your system if, 1) it is marked as expirable, AND 2) it is +more than one week old. If you do not mark an article as expirable, it +will remain on your system until hell freezes over. This bears +repeating one more time, with some spurious capitalizations: IF you do +NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. -@item :function -The function to use to fetch mail from the @acronym{POP} server. The -function is called with one parameter---the name of the file where the -mail should be moved to. +You do not have to mark articles as expirable by hand. Gnus provides +two features, called ``auto-expire'' and ``total-expire'', that can help you +with this. In a nutshell, ``auto-expire'' means that Gnus hits @kbd{E} +for you when you select an article. And ``total-expire'' means that Gnus +considers all articles as expirable that are read. So, in addition to +the articles marked @samp{E}, also the articles marked @samp{r}, +@samp{R}, @samp{O}, @samp{K}, @samp{Y} and so on are considered +expirable. -@item :authentication -This can be either the symbol @code{password} or the symbol @code{apop} -and says what authentication scheme to use. The default is -@code{password}. +When should either auto-expire or total-expire be used? Most people +who are subscribed to mailing lists split each list into its own group +and then turn on auto-expire or total-expire for those groups. +(@xref{Splitting Mail}, for more information on splitting each list +into its own group.) -@end table +Which one is better, auto-expire or total-expire? It's not easy to +answer. Generally speaking, auto-expire is probably faster. Another +advantage of auto-expire is that you get more marks to work with: for +the articles that are supposed to stick around, you can still choose +between tick and dormant and read marks. But with total-expire, you +only have dormant and ticked to choose from. The advantage of +total-expire is that it works well with adaptive scoring (@pxref{Adaptive +Scoring}). Auto-expire works with normal scoring but not with adaptive +scoring. -@vindex pop3-movemail -@vindex pop3-leave-mail-on-server -If the @code{:program} and @code{:function} keywords aren't specified, -@code{pop3-movemail} will be used. If @code{pop3-leave-mail-on-server} -is non-@code{nil} the mail is to be left on the @acronym{POP} server -after fetching when using @code{pop3-movemail}. Note that POP servers -maintain no state information between sessions, so what the client -believes is there and what is actually there may not match up. If they -do not, then you may get duplicate mails or the whole thing can fall -apart and leave you with a corrupt mailbox. +@vindex gnus-auto-expirable-newsgroups +Groups that match the regular expression +@code{gnus-auto-expirable-newsgroups} will have all articles that you +read marked as expirable automatically. All articles marked as +expirable have an @samp{E} in the first column in the summary buffer. -Here are some examples for getting mail from a @acronym{POP} server. -Fetch from the default @acronym{POP} server, using the default user -name, and default fetcher: +By default, if you have auto expiry switched on, Gnus will mark all the +articles you read as expirable, no matter if they were read or unread +before. To avoid having articles marked as read marked as expirable +automatically, you can put something like the following in your +@file{~/.gnus.el} file: +@vindex gnus-mark-article-hook @lisp -(pop) +(remove-hook 'gnus-mark-article-hook + 'gnus-summary-mark-read-and-unread-as-read) +(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read) @end lisp -Fetch from a named server with a named user and password: - -@lisp -(pop :server "my.pop.server" - :user "user-name" :password "secret") -@end lisp +Note that making a group auto-expirable doesn't mean that all read +articles are expired---only the articles marked as expirable +will be expired. Also note that using the @kbd{d} command won't make +articles expirable---only semi-automatic marking of articles as read will +mark the articles as expirable in auto-expirable groups. -Use @samp{movemail} to move the mail: +Let's say you subscribe to a couple of mailing lists, and you want the +articles you have read to disappear after a while: @lisp -(pop :program "movemail po:%u %t %p") +(setq gnus-auto-expirable-newsgroups + "mail.nonsense-list\\|mail.nice-list") @end lisp -@item maildir -Get mail from a maildir. This is a type of mailbox that is supported by -at least qmail and postfix, where each file in a special directory -contains exactly one mail. - -Keywords: - -@table @code -@item :path -The name of the directory where the mails are stored. The default is -taken from the @env{MAILDIR} environment variable or -@file{~/Maildir/}. -@item :subdirs -The subdirectories of the Maildir. The default is -@samp{("new" "cur")}. - -@c If you sometimes look at your mail through a pop3 daemon before fetching -@c them with Gnus, you may also have to fetch your mails from the -@c @code{cur} directory inside the maildir, like in the first example -@c below. - -You can also get mails from remote hosts (because maildirs don't suffer -from locking problems). +Another way to have auto-expiry happen is to have the element +@code{auto-expire} in the group parameters of the group. -@end table +If you use adaptive scoring (@pxref{Adaptive Scoring}) and +auto-expiring, you'll have problems. Auto-expiring and adaptive scoring +don't really mix very well. -Two example maildir mail sources: +@vindex nnmail-expiry-wait +The @code{nnmail-expiry-wait} variable supplies the default time an +expirable article has to live. Gnus starts counting days from when the +message @emph{arrived}, not from when it was sent. The default is seven +days. -@lisp -(maildir :path "/home/user-name/Maildir/" - :subdirs ("cur" "new")) -@end lisp +Gnus also supplies a function that lets you fine-tune how long articles +are to live, based on what group they are in. Let's say you want to +have one month expiry period in the @samp{mail.private} group, a one day +expiry period in the @samp{mail.junk} group, and a six day expiry period +everywhere else: +@vindex nnmail-expiry-wait-function @lisp -(maildir :path "/user@@remotehost.org:~/Maildir/" - :subdirs ("new")) +(setq nnmail-expiry-wait-function + (lambda (group) + (cond ((string= group "mail.private") + 31) + ((string= group "mail.junk") + 1) + ((string= group "important") + 'never) + (t + 6)))) @end lisp -@item imap -Get mail from a @acronym{IMAP} server. If you don't want to use -@acronym{IMAP} as intended, as a network mail reading protocol (ie -with nnimap), for some reason or other, Gnus let you treat it similar -to a @acronym{POP} server and fetches articles from a given -@acronym{IMAP} mailbox. @xref{Using IMAP}, for more information. - -Keywords: - -@table @code -@item :server -The name of the @acronym{IMAP} server. The default is taken from the -@env{MAILHOST} environment variable. - -@item :port -The port number of the @acronym{IMAP} server. The default is @samp{143}, or -@samp{993} for @acronym{TLS}/@acronym{SSL} connections. +The group names this function is fed are ``unadorned'' group +names---no @samp{nnml:} prefixes and the like. -@item :user -The user name to give to the @acronym{IMAP} server. The default is the login -name. +The @code{nnmail-expiry-wait} variable and +@code{nnmail-expiry-wait-function} function can either be a number (not +necessarily an integer) or one of the symbols @code{immediate} or +@code{never}. -@item :password -The password to give to the @acronym{IMAP} server. If not specified, the user is -prompted. +You can also use the @code{expiry-wait} group parameter to selectively +change the expiry period (@pxref{Group Parameters}). -@item :stream -What stream to use for connecting to the server, this is one of the -symbols in @code{imap-stream-alist}. Right now, this means -@samp{gssapi}, @samp{kerberos4}, @samp{starttls}, @samp{tls}, -@samp{ssl}, @samp{shell} or the default @samp{network}. +@vindex nnmail-expiry-target +The normal action taken when expiring articles is to delete them. +However, in some circumstances it might make more sense to move them +to other groups instead of deleting them. The variable +@code{nnmail-expiry-target} (and the @code{expiry-target} group +parameter) controls this. The variable supplies a default value for +all groups, which can be overridden for specific groups by the group +parameter. default value is @code{delete}, but this can also be a +string (which should be the name of the group the message should be +moved to), or a function (which will be called in a buffer narrowed to +the message in question, and with the name of the group being moved +from as its parameter) which should return a target---either a group +name or @code{delete}. -@item :authentication -Which authenticator to use for authenticating to the server, this is -one of the symbols in @code{imap-authenticator-alist}. Right now, -this means @samp{gssapi}, @samp{kerberos4}, @samp{digest-md5}, -@samp{cram-md5}, @samp{anonymous} or the default @samp{login}. +Here's an example for specifying a group name: +@lisp +(setq nnmail-expiry-target "nnml:expired") +@end lisp -@item :program -When using the `shell' :stream, the contents of this variable is -mapped into the @code{imap-shell-program} variable. This should be a -@code{format}-like string (or list of strings). Here's an example: +@findex nnmail-fancy-expiry-target +@vindex nnmail-fancy-expiry-targets +Gnus provides a function @code{nnmail-fancy-expiry-target} which will +expire mail to groups according to the variable +@code{nnmail-fancy-expiry-targets}. Here's an example: -@example -ssh %s imapd -@end example +@lisp + (setq nnmail-expiry-target 'nnmail-fancy-expiry-target + nnmail-fancy-expiry-targets + '((to-from "boss" "nnfolder:Work") + ("subject" "IMPORTANT" "nnfolder:IMPORTANT.%Y.%b") + ("from" ".*" "nnfolder:Archive-%Y"))) +@end lisp -Make sure nothing is interfering with the output of the program, e.g., -don't forget to redirect the error output to the void. The valid format -specifier characters are: +With this setup, any mail that has @code{IMPORTANT} in its Subject +header and was sent in the year @code{YYYY} and month @code{MMM}, will +get expired to the group @code{nnfolder:IMPORTANT.YYYY.MMM}. If its +From or To header contains the string @code{boss}, it will get expired +to @code{nnfolder:Work}. All other mail will get expired to +@code{nnfolder:Archive-YYYY}. -@table @samp -@item s -The name of the server. +@vindex nnmail-keep-last-article +If @code{nnmail-keep-last-article} is non-@code{nil}, Gnus will never +expire the final article in a mail newsgroup. This is to make life +easier for procmail users. -@item l -User name from @code{imap-default-user}. +@vindex gnus-total-expirable-newsgroups +By the way: That line up there, about Gnus never expiring non-expirable +articles, is a lie. If you put @code{total-expire} in the group +parameters, articles will not be marked as expirable, but all read +articles will be put through the expiry process. Use with extreme +caution. Even more dangerous is the +@code{gnus-total-expirable-newsgroups} variable. All groups that match +this regexp will have all read articles put through the expiry process, +which means that @emph{all} old mail articles in the groups in question +will be deleted after a while. Use with extreme caution, and don't come +crying to me when you discover that the regexp you used matched the +wrong group and all your important mail has disappeared. Be a +@emph{man}! Or a @emph{woman}! Whatever you feel more comfortable +with! So there! -@item p -The port number of the server. -@end table +Most people make most of their mail groups total-expirable, though. -The values used for these specs are taken from the values you give the -corresponding keywords. +@vindex gnus-inhibit-user-auto-expire +If @code{gnus-inhibit-user-auto-expire} is non-@code{nil}, user marking +commands will not mark an article as expirable, even if the group has +auto-expire turned on. -@item :mailbox -The name of the mailbox to get mail from. The default is @samp{INBOX} -which normally is the mailbox which receives incoming mail. +@vindex gnus-mark-copied-or-moved-articles-as-expirable +The expirable marks of articles will be removed when copying or moving +them to a group in which auto-expire is not turned on. This is for +preventing articles from being expired unintentionally. On the other +hand, to a group that has turned auto-expire on, the expirable marks of +articles that are copied or moved will not be changed by default. I.e., +when copying or moving to such a group, articles that were expirable +will be left expirable and ones that were not expirable will not be +marked as expirable. So, even though in auto-expire groups, some +articles will never get expired (unless you read them again). If you +don't side with that behavior that unexpirable articles may be mixed +into auto-expire groups, you can set +@code{gnus-mark-copied-or-moved-articles-as-expirable} to a +non-@code{nil} value. In that case, articles that have been read will +be marked as expirable automatically when being copied or moved to a +group that has auto-expire turned on. The default value is @code{nil}. -@item :predicate -The predicate used to find articles to fetch. The default, @samp{UNSEEN -UNDELETED}, is probably the best choice for most people, but if you -sometimes peek in your mailbox with a @acronym{IMAP} client and mark some -articles as read (or; SEEN) you might want to set this to @samp{1:*}. -Then all articles in the mailbox is fetched, no matter what. For a -complete list of predicates, see RFC 2060 section 6.4.4. -@item :fetchflag -How to flag fetched articles on the server, the default @samp{\Deleted} -will mark them as deleted, an alternative would be @samp{\Seen} which -would simply mark them as read. These are the two most likely choices, -but more flags are defined in RFC 2060 section 2.3.2. +@node Washing Mail +@subsection Washing Mail +@cindex mail washing +@cindex list server brain damage +@cindex incoming mail treatment -@item :dontexpunge -If non-@code{nil}, don't remove all articles marked as deleted in the -mailbox after finishing the fetch. +Mailers and list servers are notorious for doing all sorts of really, +really stupid things with mail. ``Hey, RFC 822 doesn't explicitly +prohibit us from adding the string @code{wE aRe ElItE!!!!!1!!} to the +end of all lines passing through our server, so let's do that!!!!1!'' +Yes, but RFC 822 wasn't designed to be read by morons. Things that were +considered to be self-evident were not discussed. So. Here we are. -@end table +Case in point: The German version of Microsoft Exchange adds @samp{AW: +} to the subjects of replies instead of @samp{Re: }. I could pretend to +be shocked and dismayed by this, but I haven't got the energy. It is to +laugh. -An example @acronym{IMAP} mail source: +Gnus provides a plethora of functions for washing articles while +displaying them, but it might be nicer to do the filtering before +storing the mail to disk. For that purpose, we have three hooks and +various functions that can be put in these hooks. -@lisp -(imap :server "mail.mycorp.com" - :stream kerberos4 - :fetchflag "\\Seen") -@end lisp +@table @code +@item nnmail-prepare-incoming-hook +@vindex nnmail-prepare-incoming-hook +This hook is called before doing anything with the mail and is meant for +grand, sweeping gestures. It is called in a buffer that contains all +the new, incoming mail. Functions to be used include: -@item group -Get the actual mail source from the @code{mail-source} group parameter, -@xref{Group Parameters}. +@table @code +@item nnheader-ms-strip-cr +@findex nnheader-ms-strip-cr +Remove trailing carriage returns from each line. This is default on +Emacs running on MS machines. @end table -@table @dfn -@item Common Keywords -Common keywords can be used in any type of mail source. - -Keywords: +@item nnmail-prepare-incoming-header-hook +@vindex nnmail-prepare-incoming-header-hook +This hook is called narrowed to each header. It can be used when +cleaning up the headers. Functions that can be used include: @table @code -@item :plugged -If non-@code{nil}, fetch the mail even when Gnus is unplugged. If you -use directory source to get mail, you can specify it as in this -example: - -@lisp -(setq mail-sources - '((directory :path "/home/pavel/.Spool/" - :suffix "" - :plugged t))) -@end lisp - -Gnus will then fetch your mail even when you are unplugged. This is -useful when you use local mail and news. +@item nnmail-remove-leading-whitespace +@findex nnmail-remove-leading-whitespace +Clear leading white space that ``helpful'' listservs have added to the +headers to make them look nice. Aaah. -@end table -@end table +(Note that this function works on both the header on the body of all +messages, so it is a potentially dangerous function to use (if a body +of a message contains something that looks like a header line). So +rather than fix the bug, it is of course the right solution to make it +into a feature by documenting it.) -@subsubsection Function Interface +@item nnmail-remove-list-identifiers +@findex nnmail-remove-list-identifiers +Some list servers add an identifier---for example, @samp{(idm)}---to the +beginning of all @code{Subject} headers. I'm sure that's nice for +people who use stone age mail readers. This function will remove +strings that match the @code{nnmail-list-identifiers} regexp, which can +also be a list of regexp. @code{nnmail-list-identifiers} may not contain +@code{\\(..\\)}. -Some of the above keywords specify a Lisp function to be executed. -For each keyword @code{:foo}, the Lisp variable @code{foo} is bound to -the value of the keyword while the function is executing. For example, -consider the following mail-source setting: +For instance, if you want to remove the @samp{(idm)} and the +@samp{nagnagnag} identifiers: @lisp -(setq mail-sources '((pop :user "jrl" - :server "pophost" :function fetchfunc))) +(setq nnmail-list-identifiers + '("(idm)" "nagnagnag")) @end lisp -While the function @code{fetchfunc} is executing, the symbol @code{user} -is bound to @code{"jrl"}, and the symbol @code{server} is bound to -@code{"pophost"}. The symbols @code{port}, @code{password}, -@code{program}, @code{prescript}, @code{postscript}, @code{function}, -and @code{authentication} are also bound (to their default values). +This can also be done non-destructively with +@code{gnus-list-identifiers}, @xref{Article Hiding}. -See above for a list of keywords for each type of mail source. +@item nnmail-remove-tabs +@findex nnmail-remove-tabs +Translate all @samp{TAB} characters into @samp{SPACE} characters. +@item nnmail-ignore-broken-references +@findex nnmail-ignore-broken-references +@c @findex nnmail-fix-eudora-headers +@cindex Eudora +@cindex Pegasus +Some mail user agents (e.g. Eudora and Pegasus) produce broken +@code{References} headers, but correct @code{In-Reply-To} headers. This +function will get rid of the @code{References} header if the headers +contain a line matching the regular expression +@code{nnmail-broken-references-mailers}. -@node Mail Source Customization -@subsubsection Mail Source Customization +@end table -The following is a list of variables that influence how the mail is -fetched. You would normally not need to set or change any of these -variables. +@item nnmail-prepare-incoming-message-hook +@vindex nnmail-prepare-incoming-message-hook +This hook is called narrowed to each message. Functions to be used +include: @table @code -@item mail-source-crash-box -@vindex mail-source-crash-box -File where mail will be stored while processing it. The default is@* -@file{~/.emacs-mail-crash-box}. +@item article-de-quoted-unreadable +@findex article-de-quoted-unreadable +Decode Quoted Readable encoding. -@cindex Incoming* -@item mail-source-delete-incoming -@vindex mail-source-delete-incoming -If non-@code{nil}, delete incoming files after handling them. If -@code{t}, delete the files immediately, if @code{nil}, never delete any -files. If a positive number, delete files older than number of days -(the deletion will only happen when receiving new mail). You may also -set @code{mail-source-delete-incoming} to @code{nil} and call -@code{mail-source-delete-old-incoming} from a hook or interactively. -@code{mail-source-delete-incoming} defaults to @code{10} in alpha Gnusae -and @code{2} in released Gnusae. @xref{Gnus Development}. +@end table +@end table -@item mail-source-delete-old-incoming-confirm -@vindex mail-source-delete-old-incoming-confirm -If non-@code{nil}, ask for confirmation before deleting old incoming -files. This variable only applies when -@code{mail-source-delete-incoming} is a positive number. -@item mail-source-ignore-errors -@vindex mail-source-ignore-errors -If non-@code{nil}, ignore errors when reading mail from a mail source. +@node Duplicates +@subsection Duplicates + +@vindex nnmail-treat-duplicates +@vindex nnmail-message-id-cache-length +@vindex nnmail-message-id-cache-file +@cindex duplicate mails +If you are a member of a couple of mailing lists, you will sometimes +receive two copies of the same mail. This can be quite annoying, so +@code{nnmail} checks for and treats any duplicates it might find. To do +this, it keeps a cache of old @code{Message-ID}s--- +@code{nnmail-message-id-cache-file}, which is @file{~/.nnmail-cache} by +default. The approximate maximum number of @code{Message-ID}s stored +there is controlled by the @code{nnmail-message-id-cache-length} +variable, which is 1000 by default. (So 1000 @code{Message-ID}s will be +stored.) If all this sounds scary to you, you can set +@code{nnmail-treat-duplicates} to @code{warn} (which is what it is by +default), and @code{nnmail} won't delete duplicate mails. Instead it +will insert a warning into the head of the mail saying that it thinks +that this is a duplicate of a different message. + +This variable can also be a function. If that's the case, the function +will be called from a buffer narrowed to the message in question with +the @code{Message-ID} as a parameter. The function must return either +@code{nil}, @code{warn}, or @code{delete}. -@item mail-source-directory -@vindex mail-source-directory -Directory where incoming mail source files (if any) will be stored. The -default is @file{~/Mail/}. At present, the only thing this is used for -is to say where the incoming files will be stored if the variable -@code{mail-source-delete-incoming} is @code{nil} or a number. +You can turn this feature off completely by setting the variable to +@code{nil}. -@item mail-source-incoming-file-prefix -@vindex mail-source-incoming-file-prefix -Prefix for file name for storing incoming mail. The default is -@file{Incoming}, in which case files will end up with names like -@file{Incoming30630D_} or @file{Incoming298602ZD}. This is really only -relevant if @code{mail-source-delete-incoming} is @code{nil} or a -number. +If you want all the duplicate mails to be put into a special +@dfn{duplicates} group, you could do that using the normal mail split +methods: -@item mail-source-default-file-modes -@vindex mail-source-default-file-modes -All new mail files will get this file mode. The default is 384. +@lisp +(setq nnmail-split-fancy + '(| ;; @r{Messages duplicates go to a separate group.} + ("gnus-warning" "duplicat\\(e\\|ion\\) of message" "duplicate") + ;; @r{Message from daemons, postmaster, and the like to another.} + (any mail "mail.misc") + ;; @r{Other rules.} + [...] )) +@end lisp +@noindent +Or something like: +@lisp +(setq nnmail-split-methods + '(("duplicates" "^Gnus-Warning:.*duplicate") + ;; @r{Other rules.} + [...])) +@end lisp -@item mail-source-movemail-program -@vindex mail-source-movemail-program -If non-@code{nil}, name of program for fetching new mail. If -@code{nil}, @code{movemail} in @var{exec-directory}. +Here's a neat feature: If you know that the recipient reads her mail +with Gnus, and that she has @code{nnmail-treat-duplicates} set to +@code{delete}, you can send her as many insults as you like, just by +using a @code{Message-ID} of a mail that you know that she's already +received. Think of all the fun! She'll never see any of it! Whee! -@end table +@node Not Reading Mail +@subsection Not Reading Mail -@node Fetching Mail -@subsubsection Fetching Mail +If you start using any of the mail back ends, they have the annoying +habit of assuming that you want to read mail with them. This might not +be unreasonable, but it might not be what you want. -@vindex mail-sources -The way to actually tell Gnus where to get new mail from is to set -@code{mail-sources} to a list of mail source specifiers -(@pxref{Mail Source Specifiers}). +If you set @code{mail-sources} and @code{nnmail-spool-file} to +@code{nil}, none of the back ends will ever attempt to read incoming +mail, which should help. -If this variable is @code{nil}, the mail back ends will never attempt to -fetch mail by themselves. +@vindex nnbabyl-get-new-mail +@vindex nnmbox-get-new-mail +@vindex nnml-get-new-mail +@vindex nnmh-get-new-mail +@vindex nnfolder-get-new-mail +This might be too much, if, for instance, you are reading mail quite +happily with @code{nnml} and just want to peek at some old (pre-Emacs +23) Rmail file you have stashed away with @code{nnbabyl}. All back ends have +variables called back-end-@code{get-new-mail}. If you want to disable +the @code{nnbabyl} mail reading, you edit the virtual server for the +group to have a setting where @code{nnbabyl-get-new-mail} to @code{nil}. -If you want to fetch mail both from your local spool as well as a -@acronym{POP} mail server, you'd say something like: +All the mail back ends will call @code{nn}*@code{-prepare-save-mail-hook} +narrowed to the article to be saved before saving it when reading +incoming mail. -@lisp -(setq mail-sources - '((file) - (pop :server "pop3.mail.server" - :password "secret"))) -@end lisp -Or, if you don't want to use any of the keyword defaults: +@node Choosing a Mail Back End +@subsection Choosing a Mail Back End -@lisp -(setq mail-sources - '((file :path "/var/spool/mail/user-name") - (pop :server "pop3.mail.server" - :user "user-name" - :port "pop3" - :password "secret"))) -@end lisp +Gnus will read the mail spool when you activate a mail group. The mail +file is first copied to your home directory. What happens after that +depends on what format you want to store your mail in. +There are six different mail back ends in the standard Gnus, and more +back ends are available separately. The mail back end most people use +(because it is possibly the fastest) is @code{nnml} (@pxref{Mail +Spool}). -When you use a mail back end, Gnus will slurp all your mail from your -inbox and plonk it down in your home directory. Gnus doesn't move any -mail if you're not using a mail back end---you have to do a lot of magic -invocations first. At the time when you have finished drawing the -pentagram, lightened the candles, and sacrificed the goat, you really -shouldn't be too surprised when Gnus moves your mail. +@menu +* Unix Mail Box:: Using the (quite) standard Un*x mbox. +* Babyl:: Babyl was used by older versions of Rmail. +* Mail Spool:: Store your mail in a private spool? +* MH Spool:: An mhspool-like back end. +* Maildir:: Another one-file-per-message format. +* Mail Folders:: Having one file for each group. +* Comparing Mail Back Ends:: An in-depth looks at pros and cons. +@end menu -@node Mail Back End Variables -@subsection Mail Back End Variables +@node Unix Mail Box +@subsubsection Unix Mail Box +@cindex nnmbox +@cindex unix mail box -These variables are (for the most part) pertinent to all the various -mail back ends. +@vindex nnmbox-active-file +@vindex nnmbox-mbox-file +The @dfn{nnmbox} back end will use the standard Un*x mbox file to store +mail. @code{nnmbox} will add extra headers to each mail article to say +which group it belongs in. -@table @code -@vindex nnmail-read-incoming-hook -@item nnmail-read-incoming-hook -The mail back ends all call this hook after reading new mail. You can -use this hook to notify any mail watch programs, if you want to. +Virtual server settings: -@vindex nnmail-split-hook -@item nnmail-split-hook -@findex gnus-article-decode-encoded-words -@cindex RFC 1522 decoding -@cindex RFC 2047 decoding -Hook run in the buffer where the mail headers of each message is kept -just before the splitting based on these headers is done. The hook is -free to modify the buffer contents in any way it sees fit---the buffer -is discarded after the splitting has been done, and no changes performed -in the buffer will show up in any files. -@code{gnus-article-decode-encoded-words} is one likely function to add -to this hook. +@table @code +@item nnmbox-mbox-file +@vindex nnmbox-mbox-file +The name of the mail box in the user's home directory. Default is +@file{~/mbox}. -@vindex nnmail-pre-get-new-mail-hook -@vindex nnmail-post-get-new-mail-hook -@item nnmail-pre-get-new-mail-hook -@itemx nnmail-post-get-new-mail-hook -These are two useful hooks executed when treating new incoming -mail---@code{nnmail-pre-get-new-mail-hook} (is called just before -starting to handle the new mail) and -@code{nnmail-post-get-new-mail-hook} (is called when the mail handling -is done). Here's and example of using these two hooks to change the -default file modes the new mail files get: +@item nnmbox-active-file +@vindex nnmbox-active-file +The name of the active file for the mail box. Default is +@file{~/.mbox-active}. -@lisp -(add-hook 'nnmail-pre-get-new-mail-hook - (lambda () (set-default-file-modes 511))) +@item nnmbox-get-new-mail +@vindex nnmbox-get-new-mail +If non-@code{nil}, @code{nnmbox} will read incoming mail and split it +into groups. Default is @code{t}. +@end table -(add-hook 'nnmail-post-get-new-mail-hook - (lambda () (set-default-file-modes 551))) -@end lisp -@item nnmail-use-long-file-names -@vindex nnmail-use-long-file-names -If non-@code{nil}, the mail back ends will use long file and directory -names. Groups like @samp{mail.misc} will end up in directories -(assuming use of @code{nnml} back end) or files (assuming use of -@code{nnfolder} back end) like @file{mail.misc}. If it is @code{nil}, -the same group will end up in @file{mail/misc}. +@node Babyl +@subsubsection Babyl +@cindex nnbabyl -@item nnmail-delete-file-function -@vindex nnmail-delete-file-function -@findex delete-file -Function called to delete files. It is @code{delete-file} by default. +@vindex nnbabyl-active-file +@vindex nnbabyl-mbox-file +The @dfn{nnbabyl} back end will use a Babyl mail box to store mail. +@code{nnbabyl} will add extra headers to each mail article to say which +group it belongs in. -@item nnmail-cache-accepted-message-ids -@vindex nnmail-cache-accepted-message-ids -If non-@code{nil}, put the @code{Message-ID}s of articles imported into -the back end (via @code{Gcc}, for instance) into the mail duplication -discovery cache. The default is @code{nil}. +Virtual server settings: -@item nnmail-cache-ignore-groups -@vindex nnmail-cache-ignore-groups -This can be a regular expression or a list of regular expressions. -Group names that match any of the regular expressions will never be -recorded in the @code{Message-ID} cache. +@table @code +@item nnbabyl-mbox-file +@vindex nnbabyl-mbox-file +The name of the Babyl file. The default is @file{~/RMAIL} -This can be useful, for example, when using Fancy Splitting -(@pxref{Fancy Mail Splitting}) together with the function -@code{nnmail-split-fancy-with-parent}. +@item nnbabyl-active-file +@vindex nnbabyl-active-file +The name of the active file for the Babyl file. The default is +@file{~/.rmail-active} +@item nnbabyl-get-new-mail +@vindex nnbabyl-get-new-mail +If non-@code{nil}, @code{nnbabyl} will read incoming mail. Default is +@code{t} @end table -@node Fancy Mail Splitting -@subsection Fancy Mail Splitting -@cindex mail splitting -@cindex fancy mail splitting +@node Mail Spool +@subsubsection Mail Spool +@cindex nnml +@cindex mail @acronym{NOV} spool -@vindex nnmail-split-fancy -@findex nnmail-split-fancy -If the rather simple, standard method for specifying how to split mail -doesn't allow you to do what you want, you can set -@code{nnmail-split-methods} to @code{nnmail-split-fancy}. Then you can -play with the @code{nnmail-split-fancy} variable. +The @dfn{nnml} spool mail format isn't compatible with any other known +format. It should be used with some caution. + +@vindex nnml-directory +If you use this back end, Gnus will split all incoming mail into files, +one file for each mail, and put the articles into the corresponding +directories under the directory specified by the @code{nnml-directory} +variable. The default value is @file{~/Mail/}. + +You do not have to create any directories beforehand; Gnus will take +care of all that. + +If you have a strict limit as to how many files you are allowed to store +in your account, you should not use this back end. As each mail gets its +own file, you might very well occupy thousands of inodes within a few +weeks. If this is no problem for you, and it isn't a problem for you +having your friendly systems administrator walking around, madly, +shouting ``Who is eating all my inodes?! Who? Who!?!'', then you should +know that this is probably the fastest format to use. You do not have +to trudge through a big mbox file just to read your new mail. -Let's look at an example value of this variable first: +@code{nnml} is probably the slowest back end when it comes to article +splitting. It has to create lots of files, and it also generates +@acronym{NOV} databases for the incoming mails. This makes it possibly the +fastest back end when it comes to reading mail. -@lisp -;; @r{Messages from the mailer daemon are not crossposted to any of} -;; @r{the ordinary groups. Warnings are put in a separate group} -;; @r{from real errors.} -(| ("from" mail (| ("subject" "warn.*" "mail.warning") - "mail.misc")) - ;; @r{Non-error messages are crossposted to all relevant} - ;; @r{groups, but we don't crosspost between the group for the} - ;; @r{(ding) list and the group for other (ding) related mail.} - (& (| (any "ding@@ifi\\.uio\\.no" "ding.list") - ("subject" "ding" "ding.misc")) - ;; @r{Other mailing lists@dots{}} - (any "procmail@@informatik\\.rwth-aachen\\.de" "procmail.list") - (any "SmartList@@informatik\\.rwth-aachen\\.de" "SmartList.list") - ;; @r{Both lists below have the same suffix, so prevent} - ;; @r{cross-posting to mkpkg.list of messages posted only to} - ;; @r{the bugs- list, but allow cross-posting when the} - ;; @r{message was really cross-posted.} - (any "bugs-mypackage@@somewhere" "mypkg.bugs") - (any "mypackage@@somewhere" - "bugs-mypackage" "mypkg.list") - ;; @r{People@dots{}} - (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) - ;; @r{Unmatched mail goes to the catch all group.} - "misc.misc") -@end lisp +@cindex self contained nnml servers +@cindex marks +When the marks file is used (which it is by default), @code{nnml} +servers have the property that you may backup them using @code{tar} or +similar, and later be able to restore them into Gnus (by adding the +proper @code{nnml} server) and have all your marks be preserved. Marks +for a group are usually stored in the @code{.marks} file (but see +@code{nnml-marks-file-name}) within each @code{nnml} group's directory. +Individual @code{nnml} groups are also possible to backup, use @kbd{G m} +to restore the group (after restoring the backup into the nnml +directory). -This variable has the format of a @dfn{split}. A split is a -(possibly) recursive structure where each split may contain other -splits. Here are the possible split syntaxes: +If for some reason you believe your @file{.marks} files are screwed +up, you can just delete them all. Gnus will then correctly regenerate +them next time it starts. + +Virtual server settings: @table @code +@item nnml-directory +@vindex nnml-directory +All @code{nnml} directories will be placed under this directory. The +default is the value of @code{message-directory} (whose default value +is @file{~/Mail}). -@item group -If the split is a string, that will be taken as a group name. Normal -regexp match expansion will be done. See below for examples. +@item nnml-active-file +@vindex nnml-active-file +The active file for the @code{nnml} server. The default is +@file{~/Mail/active}. -@c Don't fold this line. -@item (@var{field} @var{value} [- @var{restrict} [@dots{}] ] @var{split} [@var{invert-partial}]) -The split can be a list containing at least three elements. If the -first element @var{field} (a regexp matching a header) contains -@var{value} (also a regexp) then store the message as specified by -@var{split}. +@item nnml-newsgroups-file +@vindex nnml-newsgroups-file +The @code{nnml} group descriptions file. @xref{Newsgroups File +Format}. The default is @file{~/Mail/newsgroups}. -If @var{restrict} (yet another regexp) matches some string after -@var{field} and before the end of the matched @var{value}, the -@var{split} is ignored. If none of the @var{restrict} clauses match, -@var{split} is processed. +@item nnml-get-new-mail +@vindex nnml-get-new-mail +If non-@code{nil}, @code{nnml} will read incoming mail. The default is +@code{t}. -The last element @var{invert-partial} is optional. If it is -non-@code{nil}, the match-partial-words behavior controlled by the -variable @code{nnmail-split-fancy-match-partial-words} (see below) is -be inverted. (New in Gnus 5.10.7) +@item nnml-nov-is-evil +@vindex nnml-nov-is-evil +If non-@code{nil}, this back end will ignore any @acronym{NOV} files. The +default is @code{nil}. -@item (| @var{split} @dots{}) -If the split is a list, and the first element is @code{|} (vertical -bar), then process each @var{split} until one of them matches. A -@var{split} is said to match if it will cause the mail message to be -stored in one or more groups. +@item nnml-nov-file-name +@vindex nnml-nov-file-name +The name of the @acronym{NOV} files. The default is @file{.overview}. -@item (& @var{split} @dots{}) -If the split is a list, and the first element is @code{&}, then -process all @var{split}s in the list. +@item nnml-prepare-save-mail-hook +@vindex nnml-prepare-save-mail-hook +Hook run narrowed to an article before saving. -@item junk -If the split is the symbol @code{junk}, then don't save (i.e., delete) -this message. Use with extreme caution. +@item nnml-marks-is-evil +@vindex nnml-marks-is-evil +If non-@code{nil}, this back end will ignore any @sc{marks} files. The +default is @code{nil}. -@item (: @var{function} @var{arg1} @var{arg2} @dots{}) -If the split is a list, and the first element is @samp{:}, then the -second element will be called as a function with @var{args} given as -arguments. The function should return a @var{split}. +@item nnml-marks-file-name +@vindex nnml-marks-file-name +The name of the @dfn{marks} files. The default is @file{.marks}. -@cindex body split -For instance, the following function could be used to split based on the -body of the messages: +@item nnml-use-compressed-files +@vindex nnml-use-compressed-files +If non-@code{nil}, @code{nnml} will allow using compressed message +files. This requires @code{auto-compression-mode} to be enabled +(@pxref{Compressed Files, ,Compressed Files, emacs, The Emacs Manual}). +If the value of @code{nnml-use-compressed-files} is a string, it is used +as the file extension specifying the compression program. You can set it +to @samp{.bz2} if your Emacs supports it. A value of @code{t} is +equivalent to @samp{.gz}. -@lisp -(defun split-on-body () - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (when (re-search-forward "Some.*string" nil t) - "string.group")))) -@end lisp +@item nnml-compressed-files-size-threshold +@vindex nnml-compressed-files-size-threshold +Default size threshold for compressed message files. Message files with +bodies larger than that many characters will be automatically compressed +if @code{nnml-use-compressed-files} is non-@code{nil}. -The buffer is narrowed to the header of the message in question when -@var{function} is run. That's why @code{(widen)} needs to be called -after @code{save-excursion} and @code{save-restriction} in the example -above. Also note that with the nnimap backend, message bodies will -not be downloaded by default. You need to set -@code{nnimap-split-download-body} to @code{t} to do that -(@pxref{Client-Side IMAP Splitting}). +@end table -@item (! @var{func} @var{split}) -If the split is a list, and the first element is @code{!}, then -@var{split} will be processed, and @var{func} will be called as a -function with the result of @var{split} as argument. @var{func} -should return a split. +@findex nnml-generate-nov-databases +If your @code{nnml} groups and @acronym{NOV} files get totally out of +whack, you can do a complete update by typing @kbd{M-x +nnml-generate-nov-databases}. This command will trawl through the +entire @code{nnml} hierarchy, looking at each and every article, so it +might take a while to complete. A better interface to this +functionality can be found in the server buffer (@pxref{Server +Commands}). -@item nil -If the split is @code{nil}, it is ignored. -@end table +@node MH Spool +@subsubsection MH Spool +@cindex nnmh +@cindex mh-e mail spool -In these splits, @var{field} must match a complete field name. +@code{nnmh} is just like @code{nnml}, except that is doesn't generate +@acronym{NOV} databases and it doesn't keep an active file or marks +file. This makes @code{nnmh} a @emph{much} slower back end than +@code{nnml}, but it also makes it easier to write procmail scripts +for. -Normally, @var{value} in these splits must match a complete @emph{word} -according to the fundamental mode syntax table. In other words, all -@var{value}'s will be implicitly surrounded by @code{\<...\>} markers, -which are word delimiters. Therefore, if you use the following split, -for example, +Virtual server settings: -@example -(any "joe" "joemail") -@end example +@table @code +@item nnmh-directory +@vindex nnmh-directory +All @code{nnmh} directories will be located under this directory. The +default is the value of @code{message-directory} (whose default is +@file{~/Mail}) -@noindent -messages sent from @samp{joedavis@@foo.org} will normally not be filed -in @samp{joemail}. If you want to alter this behavior, you can use any -of the following three ways: +@item nnmh-get-new-mail +@vindex nnmh-get-new-mail +If non-@code{nil}, @code{nnmh} will read incoming mail. The default is +@code{t}. -@enumerate -@item -@vindex nnmail-split-fancy-match-partial-words -You can set the @code{nnmail-split-fancy-match-partial-words} variable -to non-@code{nil} in order to ignore word boundaries and instead the -match becomes more like a grep. This variable controls whether partial -words are matched during fancy splitting. The default value is -@code{nil}. +@item nnmh-be-safe +@vindex nnmh-be-safe +If non-@code{nil}, @code{nnmh} will go to ridiculous lengths to make +sure that the articles in the folder are actually what Gnus thinks +they are. It will check date stamps and stat everything in sight, so +setting this to @code{t} will mean a serious slow-down. If you never +use anything but Gnus to read the @code{nnmh} articles, you do not +have to set this variable to @code{t}. The default is @code{nil}. +@end table -Note that it influences all @var{value}'s in your split rules. -@item -@var{value} beginning with @code{.*} ignores word boundaries in front of -a word. Similarly, if @var{value} ends with @code{.*}, word boundaries -in the rear of a word will be ignored. For example, the @var{value} -@code{"@@example\\.com"} does not match @samp{foo@@example.com} but -@code{".*@@example\\.com"} does. +@node Maildir +@subsubsection Maildir +@cindex nnmaildir +@cindex maildir -@item -You can set the @var{invert-partial} flag in your split rules of the -@samp{(@var{field} @var{value} @dots{})} types, aforementioned in this -section. If the flag is set, word boundaries on both sides of a word -are ignored even if @code{nnmail-split-fancy-match-partial-words} is -@code{nil}. Contrarily, if the flag is set, word boundaries are not -ignored even if @code{nnmail-split-fancy-match-partial-words} is -non-@code{nil}. (New in Gnus 5.10.7) -@end enumerate +@code{nnmaildir} stores mail in the maildir format, with each maildir +corresponding to a group in Gnus. This format is documented here: +@uref{http://cr.yp.to/proto/maildir.html} and here: +@uref{http://www.qmail.org/man/man5/maildir.html}. @code{nnmaildir} +also stores extra information in the @file{.nnmaildir/} directory +within a maildir. -@vindex nnmail-split-abbrev-alist -@var{field} and @var{value} can also be Lisp symbols, in that case -they are expanded as specified by the variable -@code{nnmail-split-abbrev-alist}. This is an alist of cons cells, -where the @sc{car} of a cell contains the key, and the @sc{cdr} -contains the associated value. Predefined entries in -@code{nnmail-split-abbrev-alist} include: +Maildir format was designed to allow concurrent deliveries and +reading, without needing locks. With other back ends, you would have +your mail delivered to a spool of some kind, and then you would +configure Gnus to split mail from that spool into your groups. You +can still do that with @code{nnmaildir}, but the more common +configuration is to have your mail delivered directly to the maildirs +that appear as group in Gnus. -@table @code -@item from -Matches the @samp{From}, @samp{Sender} and @samp{Resent-From} fields. -@item to -Matches the @samp{To}, @samp{Cc}, @samp{Apparently-To}, -@samp{Resent-To} and @samp{Resent-Cc} fields. -@item any -Is the union of the @code{from} and @code{to} entries. -@end table +@code{nnmaildir} is designed to be perfectly reliable: @kbd{C-g} will +never corrupt its data in memory, and @code{SIGKILL} will never +corrupt its data in the filesystem. -@vindex nnmail-split-fancy-syntax-table -@code{nnmail-split-fancy-syntax-table} is the syntax table in effect -when all this splitting is performed. +@code{nnmaildir} stores article marks and @acronym{NOV} data in each +maildir. So you can copy a whole maildir from one Gnus setup to +another, and you will keep your marks. -If you want to have Gnus create groups dynamically based on some -information in the headers (i.e., do @code{replace-match}-like -substitutions in the group names), you can say things like: +Virtual server settings: -@example -(any "debian-\\b\\(\\w+\\)@@lists.debian.org" "mail.debian.\\1") -@end example +@table @code +@item directory +For each of your @code{nnmaildir} servers (it's very unlikely that +you'd need more than one), you need to create a directory and populate +it with maildirs or symlinks to maildirs (and nothing else; do not +choose a directory already used for other purposes). Each maildir +will be represented in Gnus as a newsgroup on that server; the +filename of the symlink will be the name of the group. Any filenames +in the directory starting with @samp{.} are ignored. The directory is +scanned when you first start Gnus, and each time you type @kbd{g} in +the group buffer; if any maildirs have been removed or added, +@code{nnmaildir} notices at these times. -In this example, messages sent to @samp{debian-foo@@lists.debian.org} -will be filed in @samp{mail.debian.foo}. +The value of the @code{directory} parameter should be a Lisp form +which is processed by @code{eval} and @code{expand-file-name} to get +the path of the directory for this server. The form is @code{eval}ed +only when the server is opened; the resulting string is used until the +server is closed. (If you don't know about forms and @code{eval}, +don't worry---a simple string will work.) This parameter is not +optional; you must specify it. I don't recommend using +@code{"~/Mail"} or a subdirectory of it; several other parts of Gnus +use that directory by default for various things, and may get confused +if @code{nnmaildir} uses it too. @code{"~/.nnmaildir"} is a typical +value. -If the string contains the element @samp{\&}, then the previously -matched string will be substituted. Similarly, the elements @samp{\\1} -up to @samp{\\9} will be substituted with the text matched by the -groupings 1 through 9. +@item target-prefix +This should be a Lisp form which is processed by @code{eval} and +@code{expand-file-name}. The form is @code{eval}ed only when the +server is opened; the resulting string is used until the server is +closed. -@vindex nnmail-split-lowercase-expanded -Where @code{nnmail-split-lowercase-expanded} controls whether the -lowercase of the matched string should be used for the substitution. -Setting it as non-@code{nil} is useful to avoid the creation of multiple -groups when users send to an address using different case -(i.e. mailing-list@@domain vs Mailing-List@@Domain). The default value -is @code{t}. +When you create a group on an @code{nnmaildir} server, the maildir is +created with @code{target-prefix} prepended to its name, and a symlink +pointing to that maildir is created, named with the plain group name. +So if @code{directory} is @code{"~/.nnmaildir"} and +@code{target-prefix} is @code{"../maildirs/"}, then when you create +the group @code{foo}, @code{nnmaildir} will create +@file{~/.nnmaildir/../maildirs/foo} as a maildir, and will create +@file{~/.nnmaildir/foo} as a symlink pointing to +@file{../maildirs/foo}. -@findex nnmail-split-fancy-with-parent -@code{nnmail-split-fancy-with-parent} is a function which allows you to -split followups into the same groups their parents are in. Sometimes -you can't make splitting rules for all your mail. For example, your -boss might send you personal mail regarding different projects you are -working on, and as you can't tell your boss to put a distinguishing -string into the subject line, you have to resort to manually moving the -messages into the right group. With this function, you only have to do -it once per thread. +You can set @code{target-prefix} to a string without any slashes to +create both maildirs and symlinks in the same @code{directory}; in +this case, any maildirs found in @code{directory} whose names start +with @code{target-prefix} will not be listed as groups (but the +symlinks pointing to them will be). -To use this feature, you have to set @code{nnmail-treat-duplicates} -and @code{nnmail-cache-accepted-message-ids} to a non-@code{nil} -value. And then you can include @code{nnmail-split-fancy-with-parent} -using the colon feature, like so: -@lisp -(setq nnmail-treat-duplicates 'warn ; @r{or @code{delete}} - nnmail-cache-accepted-message-ids t - nnmail-split-fancy - '(| (: nnmail-split-fancy-with-parent) - ;; @r{other splits go here} - )) -@end lisp +As a special case, if @code{target-prefix} is @code{""} (the default), +then when you create a group, the maildir will be created in +@code{directory} without a corresponding symlink. Beware that you +cannot use @code{gnus-group-delete-group} on such groups without the +@code{force} argument. -This feature works as follows: when @code{nnmail-treat-duplicates} is -non-@code{nil}, Gnus records the message id of every message it sees -in the file specified by the variable -@code{nnmail-message-id-cache-file}, together with the group it is in -(the group is omitted for non-mail messages). When mail splitting is -invoked, the function @code{nnmail-split-fancy-with-parent} then looks -at the References (and In-Reply-To) header of each message to split -and searches the file specified by @code{nnmail-message-id-cache-file} -for the message ids. When it has found a parent, it returns the -corresponding group name unless the group name matches the regexp -@code{nnmail-split-fancy-with-parent-ignore-groups}. It is -recommended that you set @code{nnmail-message-id-cache-length} to a -somewhat higher number than the default so that the message ids are -still in the cache. (A value of 5000 appears to create a file some -300 kBytes in size.) -@vindex nnmail-cache-accepted-message-ids -When @code{nnmail-cache-accepted-message-ids} is non-@code{nil}, Gnus -also records the message ids of moved articles, so that the followup -messages goes into the new group. +@item directory-files +This should be a function with the same interface as +@code{directory-files} (such as @code{directory-files} itself). It is +used to scan the server's @code{directory} for maildirs. This +parameter is optional; the default is +@code{nnheader-directory-files-safe} if +@code{nnheader-directory-files-is-safe} is @code{nil}, and +@code{directory-files} otherwise. +(@code{nnheader-directory-files-is-safe} is checked only once when the +server is opened; if you want to check it each time the directory is +scanned, you'll have to provide your own function that does that.) -Also see the variable @code{nnmail-cache-ignore-groups} if you don't -want certain groups to be recorded in the cache. For example, if all -outgoing messages are written to an ``outgoing'' group, you could set -@code{nnmail-cache-ignore-groups} to match that group name. -Otherwise, answers to all your messages would end up in the -``outgoing'' group. +@item get-new-mail +If non-@code{nil}, then after scanning for new mail in the group +maildirs themselves as usual, this server will also incorporate mail +the conventional Gnus way, from @code{mail-sources} according to +@code{nnmail-split-methods} or @code{nnmail-split-fancy}. The default +value is @code{nil}. +Do @emph{not} use the same maildir both in @code{mail-sources} and as +an @code{nnmaildir} group. The results might happen to be useful, but +that would be by chance, not by design, and the results might be +different in the future. If your split rules create new groups, +remember to supply a @code{create-directory} server parameter. +@end table -@node Group Mail Splitting -@subsection Group Mail Splitting -@cindex mail splitting -@cindex group mail splitting +@subsubsection Group parameters -@findex gnus-group-split -If you subscribe to dozens of mailing lists but you don't want to -maintain mail splitting rules manually, group mail splitting is for you. -You just have to set @code{to-list} and/or @code{to-address} in group -parameters or group customization and set @code{nnmail-split-methods} to -@code{gnus-group-split}. This splitting function will scan all groups -for those parameters and split mail accordingly, i.e., messages posted -from or to the addresses specified in the parameters @code{to-list} or -@code{to-address} of a mail group will be stored in that group. +@code{nnmaildir} uses several group parameters. It's safe to ignore +all this; the default behavior for @code{nnmaildir} is the same as the +default behavior for other mail back ends: articles are deleted after +one week, etc. Except for the expiry parameters, all this +functionality is unique to @code{nnmaildir}, so you can ignore it if +you're just trying to duplicate the behavior you already have with +another back end. -Sometimes, mailing lists have multiple addresses, and you may want mail -splitting to recognize them all: just set the @code{extra-aliases} group -parameter to the list of additional addresses and it's done. If you'd -rather use a regular expression, set @code{split-regexp}. +If the value of any of these parameters is a vector, the first element +is evaluated as a Lisp form and the result is used, rather than the +original value. If the value is not a vector, the value itself is +evaluated as a Lisp form. (This is why these parameters use names +different from those of other, similar parameters supported by other +back ends: they have different, though similar, meanings.) (For +numbers, strings, @code{nil}, and @code{t}, you can ignore the +@code{eval} business again; for other values, remember to use an extra +quote and wrap the value in a vector when appropriate.) -All these parameters in a group will be used to create an -@code{nnmail-split-fancy} split, in which the @var{field} is @samp{any}, -the @var{value} is a single regular expression that matches -@code{to-list}, @code{to-address}, all of @code{extra-aliases} and all -matches of @code{split-regexp}, and the @var{split} is the name of the -group. @var{restrict}s are also supported: just set the -@code{split-exclude} parameter to a list of regular expressions. +@table @code +@item expire-age +An integer specifying the minimum age, in seconds, of an article +before it will be expired, or the symbol @code{never} to specify that +articles should never be expired. If this parameter is not set, +@code{nnmaildir} falls back to the usual +@code{nnmail-expiry-wait}(@code{-function}) variables (the +@code{expiry-wait} group parameter overrides @code{nnmail-expiry-wait} +and makes @code{nnmail-expiry-wait-function} ineffective). If you +wanted a value of 3 days, you could use something like @code{[(* 3 24 +60 60)]}; @code{nnmaildir} will evaluate the form and use the result. +An article's age is measured starting from the article file's +modification time. Normally, this is the same as the article's +delivery time, but editing an article makes it younger. Moving an +article (other than via expiry) may also make an article younger. -If you can't get the right split to be generated using all these -parameters, or you just need something fancier, you can set the -parameter @code{split-spec} to an @code{nnmail-split-fancy} split. In -this case, all other aforementioned parameters will be ignored by -@code{gnus-group-split}. In particular, @code{split-spec} may be set to -@code{nil}, in which case the group will be ignored by -@code{gnus-group-split}. +@item expire-group +If this is set to a string such as a full Gnus group name, like +@example +"backend+server.address.string:group.name" +@end example +and if it is not the name of the same group that the parameter belongs +to, then articles will be moved to the specified group during expiry +before being deleted. @emph{If this is set to an @code{nnmaildir} +group, the article will be just as old in the destination group as it +was in the source group.} So be careful with @code{expire-age} in the +destination group. If this is set to the name of the same group that +the parameter belongs to, then the article is not expired at all. If +you use the vector form, the first element is evaluated once for each +article. So that form can refer to +@code{nnmaildir-article-file-name}, etc., to decide where to put the +article. @emph{Even if this parameter is not set, @code{nnmaildir} +does not fall back to the @code{expiry-target} group parameter or the +@code{nnmail-expiry-target} variable.} -@vindex gnus-group-split-default-catch-all-group -@code{gnus-group-split} will do cross-posting on all groups that match, -by defining a single @code{&} fancy split containing one split for each -group. If a message doesn't match any split, it will be stored in the -group named in @code{gnus-group-split-default-catch-all-group}, unless -some group has @code{split-spec} set to @code{catch-all}, in which case -that group is used as the catch-all group. Even though this variable is -often used just to name a group, it may also be set to an arbitrarily -complex fancy split (after all, a group name is a fancy split), and this -may be useful to split mail that doesn't go to any mailing list to -personal mail folders. Note that this fancy split is added as the last -element of a @code{|} split list that also contains a @code{&} split -with the rules extracted from group parameters. +@item read-only +If this is set to @code{t}, @code{nnmaildir} will treat the articles +in this maildir as read-only. This means: articles are not renamed +from @file{new/} into @file{cur/}; articles are only found in +@file{new/}, not @file{cur/}; articles are never deleted; articles +cannot be edited. @file{new/} is expected to be a symlink to the +@file{new/} directory of another maildir---e.g., a system-wide mailbox +containing a mailing list of common interest. Everything in the +maildir outside @file{new/} is @emph{not} treated as read-only, so for +a shared mailbox, you do still need to set up your own maildir (or +have write permission to the shared mailbox); your maildir just won't +contain extra copies of the articles. -It's time for an example. Assume the following group parameters have -been defined: +@item directory-files +A function with the same interface as @code{directory-files}. It is +used to scan the directories in the maildir corresponding to this +group to find articles. The default is the function specified by the +server's @code{directory-files} parameter. -@example -nnml:mail.bar: -((to-address . "bar@@femail.com") - (split-regexp . ".*@@femail\\.com")) -nnml:mail.foo: -((to-list . "foo@@nowhere.gov") - (extra-aliases "foo@@localhost" "foo-redist@@home") - (split-exclude "bugs-foo" "rambling-foo") - (admin-address . "foo-request@@nowhere.gov")) -nnml:mail.others: -((split-spec . catch-all)) -@end example +@item distrust-Lines: +If non-@code{nil}, @code{nnmaildir} will always count the lines of an +article, rather than use the @code{Lines:} header field. If +@code{nil}, the header field will be used if present. -Setting @code{nnmail-split-methods} to @code{gnus-group-split} will -behave as if @code{nnmail-split-fancy} had been selected and variable -@code{nnmail-split-fancy} had been set as follows: +@item always-marks +A list of mark symbols, such as @code{['(read expire)]}. Whenever +Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will +say that all articles have these marks, regardless of whether the +marks stored in the filesystem say so. This is a proof-of-concept +feature that will probably be removed eventually; it ought to be done +in Gnus proper, or abandoned if it's not worthwhile. -@lisp -(| (& (any "\\(bar@@femail\\.com\\|.*@@femail\\.com\\)" "mail.bar") - (any "\\(foo@@nowhere\\.gov\\|foo@@localhost\\|foo-redist@@home\\)" - - "bugs-foo" - "rambling-foo" "mail.foo")) - "mail.others") -@end lisp +@item never-marks +A list of mark symbols, such as @code{['(tick expire)]}. Whenever +Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will +say that no articles have these marks, regardless of whether the marks +stored in the filesystem say so. @code{never-marks} overrides +@code{always-marks}. This is a proof-of-concept feature that will +probably be removed eventually; it ought to be done in Gnus proper, or +abandoned if it's not worthwhile. -@findex gnus-group-split-fancy -If you'd rather not use group splitting for all your mail groups, you -may use it for only some of them, by using @code{nnmail-split-fancy} -splits like this: +@item nov-cache-size +An integer specifying the size of the @acronym{NOV} memory cache. To +speed things up, @code{nnmaildir} keeps @acronym{NOV} data in memory +for a limited number of articles in each group. (This is probably not +worthwhile, and will probably be removed in the future.) This +parameter's value is noticed only the first time a group is seen after +the server is opened---i.e., when you first start Gnus, typically. +The @acronym{NOV} cache is never resized until the server is closed +and reopened. The default is an estimate of the number of articles +that would be displayed in the summary buffer: a count of articles +that are either marked with @code{tick} or not marked with +@code{read}, plus a little extra. +@end table -@lisp -(: gnus-group-split-fancy @var{groups} @var{no-crosspost} @var{catch-all}) -@end lisp +@subsubsection Article identification +Articles are stored in the @file{cur/} subdirectory of each maildir. +Each article file is named like @code{uniq:info}, where @code{uniq} +contains no colons. @code{nnmaildir} ignores, but preserves, the +@code{:info} part. (Other maildir readers typically use this part of +the filename to store marks.) The @code{uniq} part uniquely +identifies the article, and is used in various places in the +@file{.nnmaildir/} subdirectory of the maildir to store information +about the corresponding article. The full pathname of an article is +available in the variable @code{nnmaildir-article-file-name} after you +request the article in the summary buffer. -@var{groups} may be a regular expression or a list of group names whose -parameters will be scanned to generate the output split. -@var{no-crosspost} can be used to disable cross-posting; in this case, a -single @code{|} split will be output. @var{catch-all} is the fall back -fancy split, used like @code{gnus-group-split-default-catch-all-group}. -If @var{catch-all} is @code{nil}, or if @code{split-regexp} matches the -empty string in any selected group, no catch-all split will be issued. -Otherwise, if some group has @code{split-spec} set to @code{catch-all}, -this group will override the value of the @var{catch-all} argument. +@subsubsection NOV data +An article identified by @code{uniq} has its @acronym{NOV} data (used +to generate lines in the summary buffer) stored in +@code{.nnmaildir/nov/uniq}. There is no +@code{nnmaildir-generate-nov-databases} function. (There isn't much +need for it---an article's @acronym{NOV} data is updated automatically +when the article or @code{nnmail-extra-headers} has changed.) You can +force @code{nnmaildir} to regenerate the @acronym{NOV} data for a +single article simply by deleting the corresponding @acronym{NOV} +file, but @emph{beware}: this will also cause @code{nnmaildir} to +assign a new article number for this article, which may cause trouble +with @code{seen} marks, the Agent, and the cache. -@findex gnus-group-split-setup -Unfortunately, scanning all groups and their parameters can be quite -slow, especially considering that it has to be done for every message. -But don't despair! The function @code{gnus-group-split-setup} can be -used to enable @code{gnus-group-split} in a much more efficient way. It -sets @code{nnmail-split-methods} to @code{nnmail-split-fancy} and sets -@code{nnmail-split-fancy} to the split produced by -@code{gnus-group-split-fancy}. Thus, the group parameters are only -scanned once, no matter how many messages are split. +@subsubsection Article marks +An article identified by @code{uniq} is considered to have the mark +@code{flag} when the file @file{.nnmaildir/marks/flag/uniq} exists. +When Gnus asks @code{nnmaildir} for a group's marks, @code{nnmaildir} +looks for such files and reports the set of marks it finds. When Gnus +asks @code{nnmaildir} to store a new set of marks, @code{nnmaildir} +creates and deletes the corresponding files as needed. (Actually, +rather than create a new file for each mark, it just creates hard +links to @file{.nnmaildir/markfile}, to save inodes.) -@findex gnus-group-split-update -However, if you change group parameters, you'd have to update -@code{nnmail-split-fancy} manually. You can do it by running -@code{gnus-group-split-update}. If you'd rather have it updated -automatically, just tell @code{gnus-group-split-setup} to do it for -you. For example, add to your @file{~/.gnus.el}: +You can invent new marks by creating a new directory in +@file{.nnmaildir/marks/}. You can tar up a maildir and remove it from +your server, untar it later, and keep your marks. You can add and +remove marks yourself by creating and deleting mark files. If you do +this while Gnus is running and your @code{nnmaildir} server is open, +it's best to exit all summary buffers for @code{nnmaildir} groups and +type @kbd{s} in the group buffer first, and to type @kbd{g} or +@kbd{M-g} in the group buffer afterwards. Otherwise, Gnus might not +pick up the changes, and might undo them. -@lisp -(gnus-group-split-setup @var{auto-update} @var{catch-all}) -@end lisp -If @var{auto-update} is non-@code{nil}, @code{gnus-group-split-update} -will be added to @code{nnmail-pre-get-new-mail-hook}, so you won't ever -have to worry about updating @code{nnmail-split-fancy} again. If you -don't omit @var{catch-all} (it's optional, equivalent to @code{nil}), -@code{gnus-group-split-default-catch-all-group} will be set to its -value. +@node Mail Folders +@subsubsection Mail Folders +@cindex nnfolder +@cindex mbox folders +@cindex mail folders -@vindex gnus-group-split-updated-hook -Because you may want to change @code{nnmail-split-fancy} after it is set -by @code{gnus-group-split-update}, this function will run -@code{gnus-group-split-updated-hook} just before finishing. +@code{nnfolder} is a back end for storing each mail group in a +separate file. Each file is in the standard Un*x mbox format. +@code{nnfolder} will add extra headers to keep track of article +numbers and arrival dates. -@node Incorporating Old Mail -@subsection Incorporating Old Mail -@cindex incorporating old mail -@cindex import old mail +@cindex self contained nnfolder servers +@cindex marks +When the marks file is used (which it is by default), @code{nnfolder} +servers have the property that you may backup them using @code{tar} or +similar, and later be able to restore them into Gnus (by adding the +proper @code{nnfolder} server) and have all your marks be preserved. +Marks for a group are usually stored in a file named as the mbox file +with @code{.mrk} concatenated to it (but see +@code{nnfolder-marks-file-suffix}) within the @code{nnfolder} +directory. Individual @code{nnfolder} groups are also possible to +backup, use @kbd{G m} to restore the group (after restoring the backup +into the @code{nnfolder} directory). -Most people have lots of old mail stored in various file formats. If -you have set up Gnus to read mail using one of the spiffy Gnus mail -back ends, you'll probably wish to have that old mail incorporated into -your mail groups. +Virtual server settings: -Doing so can be quite easy. +@table @code +@item nnfolder-directory +@vindex nnfolder-directory +All the @code{nnfolder} mail boxes will be stored under this +directory. The default is the value of @code{message-directory} +(whose default is @file{~/Mail}) -To take an example: You're reading mail using @code{nnml} -(@pxref{Mail Spool}), and have set @code{nnmail-split-methods} to a -satisfactory value (@pxref{Splitting Mail}). You have an old Unix mbox -file filled with important, but old, mail. You want to move it into -your @code{nnml} groups. +@item nnfolder-active-file +@vindex nnfolder-active-file +The name of the active file. The default is @file{~/Mail/active}. -Here's how: +@item nnfolder-newsgroups-file +@vindex nnfolder-newsgroups-file +The name of the group descriptions file. @xref{Newsgroups File +Format}. The default is @file{~/Mail/newsgroups} -@enumerate -@item -Go to the group buffer. +@item nnfolder-get-new-mail +@vindex nnfolder-get-new-mail +If non-@code{nil}, @code{nnfolder} will read incoming mail. The +default is @code{t} -@item -Type @kbd{G f} and give the file name to the mbox file when prompted to create an -@code{nndoc} group from the mbox file (@pxref{Foreign Groups}). +@item nnfolder-save-buffer-hook +@vindex nnfolder-save-buffer-hook +@cindex backup files +Hook run before saving the folders. Note that Emacs does the normal +backup renaming of files even with the @code{nnfolder} buffers. If +you wish to switch this off, you could say something like the +following in your @file{.emacs} file: -@item -Type @kbd{SPACE} to enter the newly created group. +@lisp +(defun turn-off-backup () + (set (make-local-variable 'backup-inhibited) t)) -@item -Type @kbd{M P b} to process-mark all articles in this group's buffer -(@pxref{Setting Process Marks}). +(add-hook 'nnfolder-save-buffer-hook 'turn-off-backup) +@end lisp -@item -Type @kbd{B r} to respool all the process-marked articles, and answer -@samp{nnml} when prompted (@pxref{Mail Group Commands}). -@end enumerate +@item nnfolder-delete-mail-hook +@vindex nnfolder-delete-mail-hook +Hook run in a buffer narrowed to the message that is to be deleted. +This function can be used to copy the message to somewhere else, or to +extract some information from it before removing it. -All the mail messages in the mbox file will now also be spread out over -all your @code{nnml} groups. Try entering them and check whether things -have gone without a glitch. If things look ok, you may consider -deleting the mbox file, but I wouldn't do that unless I was absolutely -sure that all the mail has ended up where it should be. +@item nnfolder-nov-is-evil +@vindex nnfolder-nov-is-evil +If non-@code{nil}, this back end will ignore any @acronym{NOV} files. The +default is @code{nil}. -Respooling is also a handy thing to do if you're switching from one mail -back end to another. Just respool all the mail in the old mail groups -using the new mail back end. +@item nnfolder-nov-file-suffix +@vindex nnfolder-nov-file-suffix +The extension for @acronym{NOV} files. The default is @file{.nov}. + +@item nnfolder-nov-directory +@vindex nnfolder-nov-directory +The directory where the @acronym{NOV} files should be stored. If +@code{nil}, @code{nnfolder-directory} is used. +@item nnfolder-marks-is-evil +@vindex nnfolder-marks-is-evil +If non-@code{nil}, this back end will ignore any @sc{marks} files. The +default is @code{nil}. -@node Expiring Mail -@subsection Expiring Mail -@cindex article expiry -@cindex expiring mail +@item nnfolder-marks-file-suffix +@vindex nnfolder-marks-file-suffix +The extension for @sc{marks} files. The default is @file{.mrk}. -Traditional mail readers have a tendency to remove mail articles when -you mark them as read, in some way. Gnus takes a fundamentally -different approach to mail reading. +@item nnfolder-marks-directory +@vindex nnfolder-marks-directory +The directory where the @sc{marks} files should be stored. If +@code{nil}, @code{nnfolder-directory} is used. -Gnus basically considers mail just to be news that has been received in -a rather peculiar manner. It does not think that it has the power to -actually change the mail, or delete any mail messages. If you enter a -mail group, and mark articles as ``read'', or kill them in some other -fashion, the mail articles will still exist on the system. I repeat: -Gnus will not delete your old, read mail. Unless you ask it to, of -course. +@end table -To make Gnus get rid of your unwanted mail, you have to mark the -articles as @dfn{expirable}. (With the default key bindings, this means -that you have to type @kbd{E}.) This does not mean that the articles -will disappear right away, however. In general, a mail article will be -deleted from your system if, 1) it is marked as expirable, AND 2) it is -more than one week old. If you do not mark an article as expirable, it -will remain on your system until hell freezes over. This bears -repeating one more time, with some spurious capitalizations: IF you do -NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES. -You do not have to mark articles as expirable by hand. Gnus provides -two features, called ``auto-expire'' and ``total-expire'', that can help you -with this. In a nutshell, ``auto-expire'' means that Gnus hits @kbd{E} -for you when you select an article. And ``total-expire'' means that Gnus -considers all articles as expirable that are read. So, in addition to -the articles marked @samp{E}, also the articles marked @samp{r}, -@samp{R}, @samp{O}, @samp{K}, @samp{Y} and so on are considered -expirable. +@findex nnfolder-generate-active-file +@kindex M-x nnfolder-generate-active-file +If you have lots of @code{nnfolder}-like files you'd like to read with +@code{nnfolder}, you can use the @kbd{M-x nnfolder-generate-active-file} +command to make @code{nnfolder} aware of all likely files in +@code{nnfolder-directory}. This only works if you use long file names, +though. -When should either auto-expire or total-expire be used? Most people -who are subscribed to mailing lists split each list into its own group -and then turn on auto-expire or total-expire for those groups. -(@xref{Splitting Mail}, for more information on splitting each list -into its own group.) +@node Comparing Mail Back Ends +@subsubsection Comparing Mail Back Ends -Which one is better, auto-expire or total-expire? It's not easy to -answer. Generally speaking, auto-expire is probably faster. Another -advantage of auto-expire is that you get more marks to work with: for -the articles that are supposed to stick around, you can still choose -between tick and dormant and read marks. But with total-expire, you -only have dormant and ticked to choose from. The advantage of -total-expire is that it works well with adaptive scoring (@pxref{Adaptive -Scoring}). Auto-expire works with normal scoring but not with adaptive -scoring. +First, just for terminology, the @dfn{back end} is the common word for a +low-level access method---a transport, if you will, by which something +is acquired. The sense is that one's mail has to come from somewhere, +and so selection of a suitable back end is required in order to get that +mail within spitting distance of Gnus. -@vindex gnus-auto-expirable-newsgroups -Groups that match the regular expression -@code{gnus-auto-expirable-newsgroups} will have all articles that you -read marked as expirable automatically. All articles marked as -expirable have an @samp{E} in the first column in the summary buffer. +The same concept exists for Usenet itself: Though access to articles is +typically done by @acronym{NNTP} these days, once upon a midnight dreary, everyone +in the world got at Usenet by running a reader on the machine where the +articles lay (the machine which today we call an @acronym{NNTP} server), and +access was by the reader stepping into the articles' directory spool +area directly. One can still select between either the @code{nntp} or +@code{nnspool} back ends, to select between these methods, if one happens +actually to live on the server (or can see its spool directly, anyway, +via NFS). -By default, if you have auto expiry switched on, Gnus will mark all the -articles you read as expirable, no matter if they were read or unread -before. To avoid having articles marked as read marked as expirable -automatically, you can put something like the following in your -@file{~/.gnus.el} file: +The goal in selecting a mail back end is to pick one which +simultaneously represents a suitable way of dealing with the original +format plus leaving mail in a form that is convenient to use in the +future. Here are some high and low points on each: -@vindex gnus-mark-article-hook -@lisp -(remove-hook 'gnus-mark-article-hook - 'gnus-summary-mark-read-and-unread-as-read) -(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read) -@end lisp +@table @code +@item nnmbox -Note that making a group auto-expirable doesn't mean that all read -articles are expired---only the articles marked as expirable -will be expired. Also note that using the @kbd{d} command won't make -articles expirable---only semi-automatic marking of articles as read will -mark the articles as expirable in auto-expirable groups. +UNIX systems have historically had a single, very common, and well- +defined format. All messages arrive in a single @dfn{spool file}, and +they are delineated by a line whose regular expression matches +@samp{^From_}. (My notational use of @samp{_} is to indicate a space, +to make it clear in this instance that this is not the RFC-specified +@samp{From:} header.) Because Emacs and therefore Gnus emanate +historically from the Unix environment, it is simplest if one does not +mess a great deal with the original mailbox format, so if one chooses +this back end, Gnus' primary activity in getting mail from the real spool +area to Gnus' preferred directory is simply to copy it, with no +(appreciable) format change in the process. It is the ``dumbest'' way +to move mail into availability in the Gnus environment. This makes it +fast to move into place, but slow to parse, when Gnus has to look at +what's where. -Let's say you subscribe to a couple of mailing lists, and you want the -articles you have read to disappear after a while: +@item nnbabyl -@lisp -(setq gnus-auto-expirable-newsgroups - "mail.nonsense-list\\|mail.nice-list") -@end lisp +Once upon a time, there was the DEC-10 and DEC-20, running operating +systems called TOPS and related things, and the usual (only?) mail +reading environment was a thing called Babyl. I don't know what format +was used for mail landing on the system, but Babyl had its own internal +format to which mail was converted, primarily involving creating a +spool-file-like entity with a scheme for inserting Babyl-specific +headers and status bits above the top of each message in the file. +Rmail was Emacs' first mail reader, it was written by Richard Stallman, +and Stallman came out of that TOPS/Babyl environment, so he wrote Rmail +to understand the mail files folks already had in existence. Gnus (and +VM, for that matter) continue to support this format because it's +perceived as having some good qualities in those mailer-specific +headers/status bits stuff. Rmail itself still exists as well, of +course, and is still maintained within Emacs. Since Emacs 23, it +uses standard mbox format rather than Babyl. -Another way to have auto-expiry happen is to have the element -@code{auto-expire} in the group parameters of the group. +Both of the above forms leave your mail in a single file on your +file system, and they must parse that entire file each time you take a +look at your mail. -If you use adaptive scoring (@pxref{Adaptive Scoring}) and -auto-expiring, you'll have problems. Auto-expiring and adaptive scoring -don't really mix very well. +@item nnml -@vindex nnmail-expiry-wait -The @code{nnmail-expiry-wait} variable supplies the default time an -expirable article has to live. Gnus starts counting days from when the -message @emph{arrived}, not from when it was sent. The default is seven -days. +@code{nnml} is the back end which smells the most as though you were +actually operating with an @code{nnspool}-accessed Usenet system. (In +fact, I believe @code{nnml} actually derived from @code{nnspool} code, +lo these years ago.) One's mail is taken from the original spool file, +and is then cut up into individual message files, 1:1. It maintains a +Usenet-style active file (analogous to what one finds in an INN- or +CNews-based news system in (for instance) @file{/var/lib/news/active}, +or what is returned via the @samp{NNTP LIST} verb) and also creates +@dfn{overview} files for efficient group entry, as has been defined for +@acronym{NNTP} servers for some years now. It is slower in mail-splitting, +due to the creation of lots of files, updates to the @code{nnml} active +file, and additions to overview files on a per-message basis, but it is +extremely fast on access because of what amounts to the indexing support +provided by the active file and overviews. -Gnus also supplies a function that lets you fine-tune how long articles -are to live, based on what group they are in. Let's say you want to -have one month expiry period in the @samp{mail.private} group, a one day -expiry period in the @samp{mail.junk} group, and a six day expiry period -everywhere else: +@code{nnml} costs @dfn{inodes} in a big way; that is, it soaks up the +resource which defines available places in the file system to put new +files. Sysadmins take a dim view of heavy inode occupation within +tight, shared file systems. But if you live on a personal machine where +the file system is your own and space is not at a premium, @code{nnml} +wins big. -@vindex nnmail-expiry-wait-function -@lisp -(setq nnmail-expiry-wait-function - (lambda (group) - (cond ((string= group "mail.private") - 31) - ((string= group "mail.junk") - 1) - ((string= group "important") - 'never) - (t - 6)))) -@end lisp +It is also problematic using this back end if you are living in a +FAT16-based Windows world, since much space will be wasted on all these +tiny files. -The group names this function is fed are ``unadorned'' group -names---no @samp{nnml:} prefixes and the like. +@item nnmh -The @code{nnmail-expiry-wait} variable and -@code{nnmail-expiry-wait-function} function can either be a number (not -necessarily an integer) or one of the symbols @code{immediate} or -@code{never}. +The Rand MH mail-reading system has been around UNIX systems for a very +long time; it operates by splitting one's spool file of messages into +individual files, but with little or no indexing support---@code{nnmh} +is considered to be semantically equivalent to ``@code{nnml} without +active file or overviews''. This is arguably the worst choice, because +one gets the slowness of individual file creation married to the +slowness of access parsing when learning what's new in one's groups. -You can also use the @code{expiry-wait} group parameter to selectively -change the expiry period (@pxref{Group Parameters}). +@item nnfolder -@vindex nnmail-expiry-target -The normal action taken when expiring articles is to delete them. -However, in some circumstances it might make more sense to move them -to other groups instead of deleting them. The variable -@code{nnmail-expiry-target} (and the @code{expiry-target} group -parameter) controls this. The variable supplies a default value for -all groups, which can be overridden for specific groups by the group -parameter. default value is @code{delete}, but this can also be a -string (which should be the name of the group the message should be -moved to), or a function (which will be called in a buffer narrowed to -the message in question, and with the name of the group being moved -from as its parameter) which should return a target---either a group -name or @code{delete}. +Basically the effect of @code{nnfolder} is @code{nnmbox} (the first +method described above) on a per-group basis. That is, @code{nnmbox} +itself puts @emph{all} one's mail in one file; @code{nnfolder} provides a +little bit of optimization to this so that each of one's mail groups has +a Unix mail box file. It's faster than @code{nnmbox} because each group +can be parsed separately, and still provides the simple Unix mail box +format requiring minimal effort in moving the mail around. In addition, +it maintains an ``active'' file making it much faster for Gnus to figure +out how many messages there are in each separate group. -Here's an example for specifying a group name: -@lisp -(setq nnmail-expiry-target "nnml:expired") -@end lisp +If you have groups that are expected to have a massive amount of +messages, @code{nnfolder} is not the best choice, but if you receive +only a moderate amount of mail, @code{nnfolder} is probably the most +friendly mail back end all over. -@findex nnmail-fancy-expiry-target -@vindex nnmail-fancy-expiry-targets -Gnus provides a function @code{nnmail-fancy-expiry-target} which will -expire mail to groups according to the variable -@code{nnmail-fancy-expiry-targets}. Here's an example: +@item nnmaildir + +For configuring expiry and other things, @code{nnmaildir} uses +incompatible group parameters, slightly different from those of other +mail back ends. -@lisp - (setq nnmail-expiry-target 'nnmail-fancy-expiry-target - nnmail-fancy-expiry-targets - '((to-from "boss" "nnfolder:Work") - ("subject" "IMPORTANT" "nnfolder:IMPORTANT.%Y.%b") - ("from" ".*" "nnfolder:Archive-%Y"))) -@end lisp +@code{nnmaildir} is largely similar to @code{nnml}, with some notable +differences. Each message is stored in a separate file, but the +filename is unrelated to the article number in Gnus. @code{nnmaildir} +also stores the equivalent of @code{nnml}'s overview files in one file +per article, so it uses about twice as many inodes as @code{nnml}. +(Use @code{df -i} to see how plentiful your inode supply is.) If this +slows you down or takes up very much space, a non-block-structured +file system. -With this setup, any mail that has @code{IMPORTANT} in its Subject -header and was sent in the year @code{YYYY} and month @code{MMM}, will -get expired to the group @code{nnfolder:IMPORTANT.YYYY.MMM}. If its -From or To header contains the string @code{boss}, it will get expired -to @code{nnfolder:Work}. All other mail will get expired to -@code{nnfolder:Archive-YYYY}. +Since maildirs don't require locking for delivery, the maildirs you use +as groups can also be the maildirs your mail is directly delivered to. +This means you can skip Gnus' mail splitting if your mail is already +organized into different mailboxes during delivery. A @code{directory} +entry in @code{mail-sources} would have a similar effect, but would +require one set of mailboxes for spooling deliveries (in mbox format, +thus damaging message bodies), and another set to be used as groups (in +whatever format you like). A maildir has a built-in spool, in the +@code{new/} subdirectory. Beware that currently, mail moved from +@code{new/} to @code{cur/} instead of via mail splitting will not +undergo treatment such as duplicate checking. -@vindex nnmail-keep-last-article -If @code{nnmail-keep-last-article} is non-@code{nil}, Gnus will never -expire the final article in a mail newsgroup. This is to make life -easier for procmail users. +@code{nnmaildir} stores article marks for a given group in the +corresponding maildir, in a way designed so that it's easy to manipulate +them from outside Gnus. You can tar up a maildir, unpack it somewhere +else, and still have your marks. @code{nnml} also stores marks, but +it's not as easy to work with them from outside Gnus as with +@code{nnmaildir}. -@vindex gnus-total-expirable-newsgroups -By the way: That line up there, about Gnus never expiring non-expirable -articles, is a lie. If you put @code{total-expire} in the group -parameters, articles will not be marked as expirable, but all read -articles will be put through the expiry process. Use with extreme -caution. Even more dangerous is the -@code{gnus-total-expirable-newsgroups} variable. All groups that match -this regexp will have all read articles put through the expiry process, -which means that @emph{all} old mail articles in the groups in question -will be deleted after a while. Use with extreme caution, and don't come -crying to me when you discover that the regexp you used matched the -wrong group and all your important mail has disappeared. Be a -@emph{man}! Or a @emph{woman}! Whatever you feel more comfortable -with! So there! +@code{nnmaildir} uses a significant amount of memory to speed things up. +(It keeps in memory some of the things that @code{nnml} stores in files +and that @code{nnmh} repeatedly parses out of message files.) If this +is a problem for you, you can set the @code{nov-cache-size} group +parameter to something small (0 would probably not work, but 1 probably +would) to make it use less memory. This caching will probably be +removed in the future. -Most people make most of their mail groups total-expirable, though. +Startup is likely to be slower with @code{nnmaildir} than with other +back ends. Everything else is likely to be faster, depending in part +on your file system. -@vindex gnus-inhibit-user-auto-expire -If @code{gnus-inhibit-user-auto-expire} is non-@code{nil}, user marking -commands will not mark an article as expirable, even if the group has -auto-expire turned on. +@code{nnmaildir} does not use @code{nnoo}, so you cannot use @code{nnoo} +to write an @code{nnmaildir}-derived back end. -@vindex gnus-mark-copied-or-moved-articles-as-expirable -The expirable marks of articles will be removed when copying or moving -them to a group in which auto-expire is not turned on. This is for -preventing articles from being expired unintentionally. On the other -hand, to a group that has turned auto-expire on, the expirable marks of -articles that are copied or moved will not be changed by default. I.e., -when copying or moving to such a group, articles that were expirable -will be left expirable and ones that were not expirable will not be -marked as expirable. So, even though in auto-expire groups, some -articles will never get expired (unless you read them again). If you -don't side with that behavior that unexpirable articles may be mixed -into auto-expire groups, you can set -@code{gnus-mark-copied-or-moved-articles-as-expirable} to a -non-@code{nil} value. In that case, articles that have been read will -be marked as expirable automatically when being copied or moved to a -group that has auto-expire turned on. The default value is @code{nil}. +@end table -@node Washing Mail -@subsection Washing Mail -@cindex mail washing -@cindex list server brain damage -@cindex incoming mail treatment +@node Browsing the Web +@section Browsing the Web +@cindex web +@cindex browsing the web +@cindex www +@cindex http -Mailers and list servers are notorious for doing all sorts of really, -really stupid things with mail. ``Hey, RFC 822 doesn't explicitly -prohibit us from adding the string @code{wE aRe ElItE!!!!!1!!} to the -end of all lines passing through our server, so let's do that!!!!1!'' -Yes, but RFC 822 wasn't designed to be read by morons. Things that were -considered to be self-evident were not discussed. So. Here we are. +Web-based discussion forums are getting more and more popular. On many +subjects, the web-based forums have become the most important forums, +eclipsing the importance of mailing lists and news groups. The reason +is easy to understand---they are friendly to new users; you just point +and click, and there's the discussion. With mailing lists, you have to +go through a cumbersome subscription procedure, and most people don't +even know what a news group is. -Case in point: The German version of Microsoft Exchange adds @samp{AW: -} to the subjects of replies instead of @samp{Re: }. I could pretend to -be shocked and dismayed by this, but I haven't got the energy. It is to -laugh. +The problem with this scenario is that web browsers are not very good at +being newsreaders. They do not keep track of what articles you've read; +they do not allow you to score on subjects you're interested in; they do +not allow off-line browsing; they require you to click around and drive +you mad in the end. -Gnus provides a plethora of functions for washing articles while -displaying them, but it might be nicer to do the filtering before -storing the mail to disk. For that purpose, we have three hooks and -various functions that can be put in these hooks. +So---if web browsers suck at reading discussion forums, why not use Gnus +to do it instead? -@table @code -@item nnmail-prepare-incoming-hook -@vindex nnmail-prepare-incoming-hook -This hook is called before doing anything with the mail and is meant for -grand, sweeping gestures. It is called in a buffer that contains all -the new, incoming mail. Functions to be used include: +Gnus has been getting a bit of a collection of back ends for providing +interfaces to these sources. -@table @code -@item nnheader-ms-strip-cr -@findex nnheader-ms-strip-cr -Remove trailing carriage returns from each line. This is default on -Emacs running on MS machines. +@menu +* Archiving Mail:: +* Web Searches:: Creating groups from articles that match a string. +* RSS:: Reading RDF site summary. +* Customizing W3:: Doing stuff to Emacs/W3 from Gnus. +@end menu -@end table +All the web sources require Emacs/W3 and the url library or those +alternatives to work. -@item nnmail-prepare-incoming-header-hook -@vindex nnmail-prepare-incoming-header-hook -This hook is called narrowed to each header. It can be used when -cleaning up the headers. Functions that can be used include: +The main caveat with all these web sources is that they probably won't +work for a very long time. Gleaning information from the @acronym{HTML} data +is guesswork at best, and when the layout is altered, the Gnus back end +will fail. If you have reasonably new versions of these back ends, +though, you should be ok. -@table @code -@item nnmail-remove-leading-whitespace -@findex nnmail-remove-leading-whitespace -Clear leading white space that ``helpful'' listservs have added to the -headers to make them look nice. Aaah. +One thing all these Web methods have in common is that the Web sources +are often down, unavailable or just plain too slow to be fun. In those +cases, it makes a lot of sense to let the Gnus Agent (@pxref{Gnus +Unplugged}) handle downloading articles, and then you can read them at +leisure from your local disk. No more World Wide Wait for you. -(Note that this function works on both the header on the body of all -messages, so it is a potentially dangerous function to use (if a body -of a message contains something that looks like a header line). So -rather than fix the bug, it is of course the right solution to make it -into a feature by documenting it.) +@node Archiving Mail +@subsection Archiving Mail +@cindex archiving mail +@cindex backup of mail -@item nnmail-remove-list-identifiers -@findex nnmail-remove-list-identifiers -Some list servers add an identifier---for example, @samp{(idm)}---to the -beginning of all @code{Subject} headers. I'm sure that's nice for -people who use stone age mail readers. This function will remove -strings that match the @code{nnmail-list-identifiers} regexp, which can -also be a list of regexp. @code{nnmail-list-identifiers} may not contain -@code{\\(..\\)}. +Some of the back ends, notably @code{nnml}, @code{nnfolder}, and +@code{nnmaildir}, now actually store the article marks with each group. +For these servers, archiving and restoring a group while preserving +marks is fairly simple. -For instance, if you want to remove the @samp{(idm)} and the -@samp{nagnagnag} identifiers: +(Preserving the group level and group parameters as well still +requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity +though.) -@lisp -(setq nnmail-list-identifiers - '("(idm)" "nagnagnag")) -@end lisp +To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir} +server, take a recursive copy of the server directory. There is no need +to shut down Gnus, so archiving may be invoked by @code{cron} or +similar. You restore the data by restoring the directory tree, and +adding a server definition pointing to that directory in Gnus. The +@ref{Article Backlog}, @ref{Asynchronous Fetching} and other things +might interfere with overwriting data, so you may want to shut down Gnus +before you restore the data. -This can also be done non-destructively with -@code{gnus-list-identifiers}, @xref{Article Hiding}. +It is also possible to archive individual @code{nnml}, +@code{nnfolder}, or @code{nnmaildir} groups, while preserving marks. +For @code{nnml} or @code{nnmaildir}, you copy all files in the group's +directory. For @code{nnfolder} you need to copy both the base folder +file itself (@file{FOO}, say), and the marks file (@file{FOO.mrk} in +this example). Restoring the group is done with @kbd{G m} from the Group +buffer. The last step makes Gnus notice the new directory. +@code{nnmaildir} notices the new directory automatically, so @kbd{G m} +is unnecessary in that case. -@item nnmail-remove-tabs -@findex nnmail-remove-tabs -Translate all @samp{TAB} characters into @samp{SPACE} characters. +@node Web Searches +@subsection Web Searches +@cindex nnweb +@cindex Google +@cindex dejanews +@cindex gmane +@cindex Usenet searches +@cindex searching the Usenet -@item nnmail-ignore-broken-references -@findex nnmail-ignore-broken-references -@c @findex nnmail-fix-eudora-headers -@cindex Eudora -@cindex Pegasus -Some mail user agents (e.g. Eudora and Pegasus) produce broken -@code{References} headers, but correct @code{In-Reply-To} headers. This -function will get rid of the @code{References} header if the headers -contain a line matching the regular expression -@code{nnmail-broken-references-mailers}. +It's, like, too neat to search the Usenet for articles that match a +string, but it, like, totally @emph{sucks}, like, totally, to use one of +those, like, Web browsers, and you, like, have to, rilly, like, look at +the commercials, so, like, with Gnus you can do @emph{rad}, rilly, +searches without having to use a browser. -@end table +The @code{nnweb} back end allows an easy interface to the mighty search +engine. You create an @code{nnweb} group, enter a search pattern, and +then enter the group and read the articles like you would any normal +group. The @kbd{G w} command in the group buffer (@pxref{Foreign +Groups}) will do this in an easy-to-use fashion. -@item nnmail-prepare-incoming-message-hook -@vindex nnmail-prepare-incoming-message-hook -This hook is called narrowed to each message. Functions to be used -include: +@code{nnweb} groups don't really lend themselves to being solid +groups---they have a very fleeting idea of article numbers. In fact, +each time you enter an @code{nnweb} group (not even changing the search +pattern), you are likely to get the articles ordered in a different +manner. Not even using duplicate suppression (@pxref{Duplicate +Suppression}) will help, since @code{nnweb} doesn't even know the +@code{Message-ID} of the articles before reading them using some search +engines (Google, for instance). The only possible way to keep track +of which articles you've read is by scoring on the @code{Date} +header---mark all articles posted before the last date you read the +group as read. -@table @code -@item article-de-quoted-unreadable -@findex article-de-quoted-unreadable -Decode Quoted Readable encoding. +If the search engine changes its output substantially, @code{nnweb} +won't be able to parse it and will fail. One could hardly fault the Web +providers if they were to do this---their @emph{raison d'@^etre} is to +make money off of advertisements, not to provide services to the +community. Since @code{nnweb} washes the ads off all the articles, one +might think that the providers might be somewhat miffed. We'll see. -@end table -@end table +You must have the @code{url} and @code{W3} package or those alternatives +(try @code{customize-group} on the @samp{mm-url} variable group) +installed to be able to use @code{nnweb}. +Virtual server variables: -@node Duplicates -@subsection Duplicates +@table @code +@item nnweb-type +@vindex nnweb-type +What search engine type is being used. The currently supported types +are @code{google}, @code{dejanews}, and @code{gmane}. Note that +@code{dejanews} is an alias to @code{google}. -@vindex nnmail-treat-duplicates -@vindex nnmail-message-id-cache-length -@vindex nnmail-message-id-cache-file -@cindex duplicate mails -If you are a member of a couple of mailing lists, you will sometimes -receive two copies of the same mail. This can be quite annoying, so -@code{nnmail} checks for and treats any duplicates it might find. To do -this, it keeps a cache of old @code{Message-ID}s--- -@code{nnmail-message-id-cache-file}, which is @file{~/.nnmail-cache} by -default. The approximate maximum number of @code{Message-ID}s stored -there is controlled by the @code{nnmail-message-id-cache-length} -variable, which is 1000 by default. (So 1000 @code{Message-ID}s will be -stored.) If all this sounds scary to you, you can set -@code{nnmail-treat-duplicates} to @code{warn} (which is what it is by -default), and @code{nnmail} won't delete duplicate mails. Instead it -will insert a warning into the head of the mail saying that it thinks -that this is a duplicate of a different message. +@item nnweb-search +@vindex nnweb-search +The search string to feed to the search engine. -This variable can also be a function. If that's the case, the function -will be called from a buffer narrowed to the message in question with -the @code{Message-ID} as a parameter. The function must return either -@code{nil}, @code{warn}, or @code{delete}. +@item nnweb-max-hits +@vindex nnweb-max-hits +Advisory maximum number of hits per search to display. The default is +999. -You can turn this feature off completely by setting the variable to -@code{nil}. +@item nnweb-type-definition +@vindex nnweb-type-definition +Type-to-definition alist. This alist says what @code{nnweb} should do +with the various search engine types. The following elements must be +present: -If you want all the duplicate mails to be put into a special -@dfn{duplicates} group, you could do that using the normal mail split -methods: +@table @code +@item article +Function to decode the article and provide something that Gnus +understands. -@lisp -(setq nnmail-split-fancy - '(| ;; @r{Messages duplicates go to a separate group.} - ("gnus-warning" "duplicat\\(e\\|ion\\) of message" "duplicate") - ;; @r{Message from daemons, postmaster, and the like to another.} - (any mail "mail.misc") - ;; @r{Other rules.} - [...] )) -@end lisp -@noindent -Or something like: -@lisp -(setq nnmail-split-methods - '(("duplicates" "^Gnus-Warning:.*duplicate") - ;; @r{Other rules.} - [...])) -@end lisp +@item map +Function to create an article number to message header and URL alist. -Here's a neat feature: If you know that the recipient reads her mail -with Gnus, and that she has @code{nnmail-treat-duplicates} set to -@code{delete}, you can send her as many insults as you like, just by -using a @code{Message-ID} of a mail that you know that she's already -received. Think of all the fun! She'll never see any of it! Whee! +@item search +Function to send the search string to the search engine. +@item address +The address the aforementioned function should send the search string +to. -@node Not Reading Mail -@subsection Not Reading Mail +@item id +Format string URL to fetch an article by @code{Message-ID}. +@end table -If you start using any of the mail back ends, they have the annoying -habit of assuming that you want to read mail with them. This might not -be unreasonable, but it might not be what you want. +@end table -If you set @code{mail-sources} and @code{nnmail-spool-file} to -@code{nil}, none of the back ends will ever attempt to read incoming -mail, which should help. -@vindex nnbabyl-get-new-mail -@vindex nnmbox-get-new-mail -@vindex nnml-get-new-mail -@vindex nnmh-get-new-mail -@vindex nnfolder-get-new-mail -This might be too much, if, for instance, you are reading mail quite -happily with @code{nnml} and just want to peek at some old (pre-Emacs -23) Rmail file you have stashed away with @code{nnbabyl}. All back ends have -variables called back-end-@code{get-new-mail}. If you want to disable -the @code{nnbabyl} mail reading, you edit the virtual server for the -group to have a setting where @code{nnbabyl-get-new-mail} to @code{nil}. +@node RSS +@subsection RSS +@cindex nnrss +@cindex RSS -All the mail back ends will call @code{nn}*@code{-prepare-save-mail-hook} -narrowed to the article to be saved before saving it when reading -incoming mail. +Some web sites have an RDF Site Summary (@acronym{RSS}). +@acronym{RSS} is a format for summarizing headlines from news related +sites (such as BBC or CNN). But basically anything list-like can be +presented as an @acronym{RSS} feed: weblogs, changelogs or recent +changes to a wiki (e.g. @url{http://cliki.net/recent-changes.rdf}). +@acronym{RSS} has a quite regular and nice interface, and it's +possible to get the information Gnus needs to keep groups updated. -@node Choosing a Mail Back End -@subsection Choosing a Mail Back End +Note: you had better use Emacs which supports the @code{utf-8} coding +system because @acronym{RSS} uses UTF-8 for encoding non-@acronym{ASCII} +text by default. It is also used by default for non-@acronym{ASCII} +group names. -Gnus will read the mail spool when you activate a mail group. The mail -file is first copied to your home directory. What happens after that -depends on what format you want to store your mail in. +@kindex G R (Group) +Use @kbd{G R} from the group buffer to subscribe to a feed---you will be +prompted for the location, the title and the description of the feed. +The title, which allows any characters, will be used for the group name +and the name of the group data file. The description can be omitted. -There are six different mail back ends in the standard Gnus, and more -back ends are available separately. The mail back end most people use -(because it is possibly the fastest) is @code{nnml} (@pxref{Mail -Spool}). +An easy way to get started with @code{nnrss} is to say something like +the following in the group buffer: @kbd{B nnrss RET RET y}, then +subscribe to groups. -@menu -* Unix Mail Box:: Using the (quite) standard Un*x mbox. -* Babyl:: Babyl was used by older versions of Rmail. -* Mail Spool:: Store your mail in a private spool? -* MH Spool:: An mhspool-like back end. -* Maildir:: Another one-file-per-message format. -* Mail Folders:: Having one file for each group. -* Comparing Mail Back Ends:: An in-depth looks at pros and cons. -@end menu +The @code{nnrss} back end saves the group data file in +@code{nnrss-directory} (see below) for each @code{nnrss} group. File +names containing non-@acronym{ASCII} characters will be encoded by the +coding system specified with the @code{nnmail-pathname-coding-system} +variable or other. Also @xref{Non-ASCII Group Names}, for more +information. +The @code{nnrss} back end generates @samp{multipart/alternative} +@acronym{MIME} articles in which each contains a @samp{text/plain} part +and a @samp{text/html} part. +@cindex OPML +You can also use the following commands to import and export your +subscriptions from a file in @acronym{OPML} format (Outline Processor +Markup Language). -@node Unix Mail Box -@subsubsection Unix Mail Box -@cindex nnmbox -@cindex unix mail box +@defun nnrss-opml-import file +Prompt for an @acronym{OPML} file, and subscribe to each feed in the +file. +@end defun -@vindex nnmbox-active-file -@vindex nnmbox-mbox-file -The @dfn{nnmbox} back end will use the standard Un*x mbox file to store -mail. @code{nnmbox} will add extra headers to each mail article to say -which group it belongs in. +@defun nnrss-opml-export +Write your current @acronym{RSS} subscriptions to a buffer in +@acronym{OPML} format. +@end defun -Virtual server settings: +The following @code{nnrss} variables can be altered: @table @code -@item nnmbox-mbox-file -@vindex nnmbox-mbox-file -The name of the mail box in the user's home directory. Default is -@file{~/mbox}. - -@item nnmbox-active-file -@vindex nnmbox-active-file -The name of the active file for the mail box. Default is -@file{~/.mbox-active}. +@item nnrss-directory +@vindex nnrss-directory +The directory where @code{nnrss} stores its files. The default is +@file{~/News/rss/}. -@item nnmbox-get-new-mail -@vindex nnmbox-get-new-mail -If non-@code{nil}, @code{nnmbox} will read incoming mail and split it -into groups. Default is @code{t}. -@end table +@item nnrss-file-coding-system +@vindex nnrss-file-coding-system +The coding system used when reading and writing the @code{nnrss} groups +data files. The default is the value of +@code{mm-universal-coding-system} (which defaults to @code{emacs-mule} +in Emacs or @code{escape-quoted} in XEmacs). +@item nnrss-ignore-article-fields +@vindex nnrss-ignore-article-fields +Some feeds update constantly article fields during their publications, +e.g. to indicate the number of comments. However, if there is +a difference between the local article and the distant one, the latter +is considered to be new. To avoid this and discard some fields, set this +variable to the list of fields to be ignored. The default is +@code{'(slash:comments)}. -@node Babyl -@subsubsection Babyl -@cindex nnbabyl +@item nnrss-use-local +@vindex nnrss-use-local +@findex nnrss-generate-download-script +If you set @code{nnrss-use-local} to @code{t}, @code{nnrss} will read +the feeds from local files in @code{nnrss-directory}. You can use +the command @code{nnrss-generate-download-script} to generate a +download script using @command{wget}. +@end table -@vindex nnbabyl-active-file -@vindex nnbabyl-mbox-file -The @dfn{nnbabyl} back end will use a Babyl mail box to store mail. -@code{nnbabyl} will add extra headers to each mail article to say which -group it belongs in. +The following code may be helpful, if you want to show the description in +the summary buffer. -Virtual server settings: +@lisp +(add-to-list 'nnmail-extra-headers nnrss-description-field) +(setq gnus-summary-line-format "%U%R%z%I%(%[%4L: %-15,15f%]%) %s%uX\n") -@table @code -@item nnbabyl-mbox-file -@vindex nnbabyl-mbox-file -The name of the Babyl file. The default is @file{~/RMAIL} +(defun gnus-user-format-function-X (header) + (let ((descr + (assq nnrss-description-field (mail-header-extra header)))) + (if descr (concat "\n\t" (cdr descr)) ""))) +@end lisp -@item nnbabyl-active-file -@vindex nnbabyl-active-file -The name of the active file for the Babyl file. The default is -@file{~/.rmail-active} +The following code may be useful to open an nnrss url directly from the +summary buffer. -@item nnbabyl-get-new-mail -@vindex nnbabyl-get-new-mail -If non-@code{nil}, @code{nnbabyl} will read incoming mail. Default is -@code{t} -@end table +@lisp +(require 'browse-url) +(defun browse-nnrss-url (arg) + (interactive "p") + (let ((url (assq nnrss-url-field + (mail-header-extra + (gnus-data-header + (assq (gnus-summary-article-number) + gnus-newsgroup-data)))))) + (if url + (progn + (browse-url (cdr url)) + (gnus-summary-mark-as-read-forward 1)) + (gnus-summary-scroll-up arg)))) -@node Mail Spool -@subsubsection Mail Spool -@cindex nnml -@cindex mail @acronym{NOV} spool +(eval-after-load "gnus" + #'(define-key gnus-summary-mode-map + (kbd "") 'browse-nnrss-url)) +(add-to-list 'nnmail-extra-headers nnrss-url-field) +@end lisp -The @dfn{nnml} spool mail format isn't compatible with any other known -format. It should be used with some caution. +Even if you have added @samp{text/html} to the +@code{mm-discouraged-alternatives} variable (@pxref{Display +Customization, ,Display Customization, emacs-mime, The Emacs MIME +Manual}) since you don't want to see @acronym{HTML} parts, it might be +more useful especially in @code{nnrss} groups to display +@samp{text/html} parts. Here's an example of setting +@code{mm-discouraged-alternatives} as a group parameter (@pxref{Group +Parameters}) in order to display @samp{text/html} parts only in +@code{nnrss} groups: -@vindex nnml-directory -If you use this back end, Gnus will split all incoming mail into files, -one file for each mail, and put the articles into the corresponding -directories under the directory specified by the @code{nnml-directory} -variable. The default value is @file{~/Mail/}. +@lisp +;; @r{Set the default value of @code{mm-discouraged-alternatives}.} +(eval-after-load "gnus-sum" + '(add-to-list + 'gnus-newsgroup-variables + '(mm-discouraged-alternatives + . '("text/html" "image/.*")))) -You do not have to create any directories beforehand; Gnus will take -care of all that. +;; @r{Display @samp{text/html} parts in @code{nnrss} groups.} +(add-to-list + 'gnus-parameters + '("\\`nnrss:" (mm-discouraged-alternatives nil))) +@end lisp -If you have a strict limit as to how many files you are allowed to store -in your account, you should not use this back end. As each mail gets its -own file, you might very well occupy thousands of inodes within a few -weeks. If this is no problem for you, and it isn't a problem for you -having your friendly systems administrator walking around, madly, -shouting ``Who is eating all my inodes?! Who? Who!?!'', then you should -know that this is probably the fastest format to use. You do not have -to trudge through a big mbox file just to read your new mail. -@code{nnml} is probably the slowest back end when it comes to article -splitting. It has to create lots of files, and it also generates -@acronym{NOV} databases for the incoming mails. This makes it possibly the -fastest back end when it comes to reading mail. +@node Customizing W3 +@subsection Customizing W3 +@cindex W3 +@cindex html +@cindex url +@cindex Netscape -@cindex self contained nnml servers -@cindex marks -When the marks file is used (which it is by default), @code{nnml} -servers have the property that you may backup them using @code{tar} or -similar, and later be able to restore them into Gnus (by adding the -proper @code{nnml} server) and have all your marks be preserved. Marks -for a group are usually stored in the @code{.marks} file (but see -@code{nnml-marks-file-name}) within each @code{nnml} group's directory. -Individual @code{nnml} groups are also possible to backup, use @kbd{G m} -to restore the group (after restoring the backup into the nnml -directory). +Gnus uses the url library to fetch web pages and Emacs/W3 (or those +alternatives) to display web pages. Emacs/W3 is documented in its own +manual, but there are some things that may be more relevant for Gnus +users. -If for some reason you believe your @file{.marks} files are screwed -up, you can just delete them all. Gnus will then correctly regenerate -them next time it starts. +For instance, a common question is how to make Emacs/W3 follow links +using the @code{browse-url} functions (which will call some external web +browser like Netscape). Here's one way: -Virtual server settings: +@lisp +(eval-after-load "w3" + '(progn + (fset 'w3-fetch-orig (symbol-function 'w3-fetch)) + (defun w3-fetch (&optional url target) + (interactive (list (w3-read-url-with-default))) + (if (eq major-mode 'gnus-article-mode) + (browse-url url) + (w3-fetch-orig url target))))) +@end lisp -@table @code -@item nnml-directory -@vindex nnml-directory -All @code{nnml} directories will be placed under this directory. The -default is the value of @code{message-directory} (whose default value -is @file{~/Mail}). +Put that in your @file{.emacs} file, and hitting links in W3-rendered +@acronym{HTML} in the Gnus article buffers will use @code{browse-url} to +follow the link. -@item nnml-active-file -@vindex nnml-active-file -The active file for the @code{nnml} server. The default is -@file{~/Mail/active}. -@item nnml-newsgroups-file -@vindex nnml-newsgroups-file -The @code{nnml} group descriptions file. @xref{Newsgroups File -Format}. The default is @file{~/Mail/newsgroups}. +@node Other Sources +@section Other Sources -@item nnml-get-new-mail -@vindex nnml-get-new-mail -If non-@code{nil}, @code{nnml} will read incoming mail. The default is -@code{t}. +Gnus can do more than just read news or mail. The methods described +below allow Gnus to view directories and files as if they were +newsgroups. -@item nnml-nov-is-evil -@vindex nnml-nov-is-evil -If non-@code{nil}, this back end will ignore any @acronym{NOV} files. The -default is @code{nil}. +@menu +* Directory Groups:: You can read a directory as if it was a newsgroup. +* Anything Groups:: Dired? Who needs dired? +* Document Groups:: Single files can be the basis of a group. +* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. +@end menu -@item nnml-nov-file-name -@vindex nnml-nov-file-name -The name of the @acronym{NOV} files. The default is @file{.overview}. -@item nnml-prepare-save-mail-hook -@vindex nnml-prepare-save-mail-hook -Hook run narrowed to an article before saving. +@node Directory Groups +@subsection Directory Groups +@cindex nndir +@cindex directory groups -@item nnml-marks-is-evil -@vindex nnml-marks-is-evil -If non-@code{nil}, this back end will ignore any @sc{marks} files. The -default is @code{nil}. +If you have a directory that has lots of articles in separate files in +it, you might treat it as a newsgroup. The files have to have numerical +names, of course. -@item nnml-marks-file-name -@vindex nnml-marks-file-name -The name of the @dfn{marks} files. The default is @file{.marks}. +This might be an opportune moment to mention @code{ange-ftp} (and its +successor @code{efs}), that most wonderful of all wonderful Emacs +packages. When I wrote @code{nndir}, I didn't think much about it---a +back end to read directories. Big deal. -@item nnml-use-compressed-files -@vindex nnml-use-compressed-files -If non-@code{nil}, @code{nnml} will allow using compressed message -files. This requires @code{auto-compression-mode} to be enabled -(@pxref{Compressed Files, ,Compressed Files, emacs, The Emacs Manual}). -If the value of @code{nnml-use-compressed-files} is a string, it is used -as the file extension specifying the compression program. You can set it -to @samp{.bz2} if your Emacs supports it. A value of @code{t} is -equivalent to @samp{.gz}. +@code{ange-ftp} changes that picture dramatically. For instance, if you +enter the @code{ange-ftp} file name +@file{/ftp.hpc.uh.edu:/pub/emacs/ding-list/} as the directory name, +@code{ange-ftp} or @code{efs} will actually allow you to read this +directory over at @samp{sina} as a newsgroup. Distributed news ahoy! -@item nnml-compressed-files-size-threshold -@vindex nnml-compressed-files-size-threshold -Default size threshold for compressed message files. Message files with -bodies larger than that many characters will be automatically compressed -if @code{nnml-use-compressed-files} is non-@code{nil}. +@code{nndir} will use @acronym{NOV} files if they are present. -@end table +@code{nndir} is a ``read-only'' back end---you can't delete or expire +articles with this method. You can use @code{nnmh} or @code{nnml} for +whatever you use @code{nndir} for, so you could switch to any of those +methods if you feel the need to have a non-read-only @code{nndir}. -@findex nnml-generate-nov-databases -If your @code{nnml} groups and @acronym{NOV} files get totally out of -whack, you can do a complete update by typing @kbd{M-x -nnml-generate-nov-databases}. This command will trawl through the -entire @code{nnml} hierarchy, looking at each and every article, so it -might take a while to complete. A better interface to this -functionality can be found in the server buffer (@pxref{Server -Commands}). +@node Anything Groups +@subsection Anything Groups +@cindex nneething -@node MH Spool -@subsubsection MH Spool -@cindex nnmh -@cindex mh-e mail spool +From the @code{nndir} back end (which reads a single spool-like +directory), it's just a hop and a skip to @code{nneething}, which +pretends that any arbitrary directory is a newsgroup. Strange, but +true. -@code{nnmh} is just like @code{nnml}, except that is doesn't generate -@acronym{NOV} databases and it doesn't keep an active file or marks -file. This makes @code{nnmh} a @emph{much} slower back end than -@code{nnml}, but it also makes it easier to write procmail scripts -for. +When @code{nneething} is presented with a directory, it will scan this +directory and assign article numbers to each file. When you enter such +a group, @code{nneething} must create ``headers'' that Gnus can use. +After all, Gnus is a newsreader, in case you're forgetting. +@code{nneething} does this in a two-step process. First, it snoops each +file in question. If the file looks like an article (i.e., the first +few lines look like headers), it will use this as the head. If this is +just some arbitrary file without a head (e.g. a C source file), +@code{nneething} will cobble up a header out of thin air. It will use +file ownership, name and date and do whatever it can with these +elements. -Virtual server settings: +All this should happen automatically for you, and you will be presented +with something that looks very much like a newsgroup. Totally like a +newsgroup, to be precise. If you select an article, it will be displayed +in the article buffer, just as usual. -@table @code -@item nnmh-directory -@vindex nnmh-directory -All @code{nnmh} directories will be located under this directory. The -default is the value of @code{message-directory} (whose default is -@file{~/Mail}) +If you select a line that represents a directory, Gnus will pop you into +a new summary buffer for this @code{nneething} group. And so on. You can +traverse the entire disk this way, if you feel like, but remember that +Gnus is not dired, really, and does not intend to be, either. -@item nnmh-get-new-mail -@vindex nnmh-get-new-mail -If non-@code{nil}, @code{nnmh} will read incoming mail. The default is -@code{t}. +There are two overall modes to this action---ephemeral or solid. When +doing the ephemeral thing (i.e., @kbd{G D} from the group buffer), Gnus +will not store information on what files you have read, and what files +are new, and so on. If you create a solid @code{nneething} group the +normal way with @kbd{G m}, Gnus will store a mapping table between +article numbers and file names, and you can treat this group like any +other groups. When you activate a solid @code{nneething} group, you will +be told how many unread articles it contains, etc., etc. -@item nnmh-be-safe -@vindex nnmh-be-safe -If non-@code{nil}, @code{nnmh} will go to ridiculous lengths to make -sure that the articles in the folder are actually what Gnus thinks -they are. It will check date stamps and stat everything in sight, so -setting this to @code{t} will mean a serious slow-down. If you never -use anything but Gnus to read the @code{nnmh} articles, you do not -have to set this variable to @code{t}. The default is @code{nil}. -@end table +Some variables: +@table @code +@item nneething-map-file-directory +@vindex nneething-map-file-directory +All the mapping files for solid @code{nneething} groups will be stored +in this directory, which defaults to @file{~/.nneething/}. -@node Maildir -@subsubsection Maildir -@cindex nnmaildir -@cindex maildir +@item nneething-exclude-files +@vindex nneething-exclude-files +All files that match this regexp will be ignored. Nice to use to exclude +auto-save files and the like, which is what it does by default. -@code{nnmaildir} stores mail in the maildir format, with each maildir -corresponding to a group in Gnus. This format is documented here: -@uref{http://cr.yp.to/proto/maildir.html} and here: -@uref{http://www.qmail.org/man/man5/maildir.html}. @code{nnmaildir} -also stores extra information in the @file{.nnmaildir/} directory -within a maildir. +@item nneething-include-files +@vindex nneething-include-files +Regexp saying what files to include in the group. If this variable is +non-@code{nil}, only files matching this regexp will be included. -Maildir format was designed to allow concurrent deliveries and -reading, without needing locks. With other back ends, you would have -your mail delivered to a spool of some kind, and then you would -configure Gnus to split mail from that spool into your groups. You -can still do that with @code{nnmaildir}, but the more common -configuration is to have your mail delivered directly to the maildirs -that appear as group in Gnus. +@item nneething-map-file +@vindex nneething-map-file +Name of the map files. +@end table -@code{nnmaildir} is designed to be perfectly reliable: @kbd{C-g} will -never corrupt its data in memory, and @code{SIGKILL} will never -corrupt its data in the filesystem. -@code{nnmaildir} stores article marks and @acronym{NOV} data in each -maildir. So you can copy a whole maildir from one Gnus setup to -another, and you will keep your marks. +@node Document Groups +@subsection Document Groups +@cindex nndoc +@cindex documentation group +@cindex help group -Virtual server settings: +@code{nndoc} is a cute little thing that will let you read a single file +as a newsgroup. Several files types are supported: @table @code -@item directory -For each of your @code{nnmaildir} servers (it's very unlikely that -you'd need more than one), you need to create a directory and populate -it with maildirs or symlinks to maildirs (and nothing else; do not -choose a directory already used for other purposes). Each maildir -will be represented in Gnus as a newsgroup on that server; the -filename of the symlink will be the name of the group. Any filenames -in the directory starting with @samp{.} are ignored. The directory is -scanned when you first start Gnus, and each time you type @kbd{g} in -the group buffer; if any maildirs have been removed or added, -@code{nnmaildir} notices at these times. +@cindex Babyl +@item babyl +The Babyl format. -The value of the @code{directory} parameter should be a Lisp form -which is processed by @code{eval} and @code{expand-file-name} to get -the path of the directory for this server. The form is @code{eval}ed -only when the server is opened; the resulting string is used until the -server is closed. (If you don't know about forms and @code{eval}, -don't worry---a simple string will work.) This parameter is not -optional; you must specify it. I don't recommend using -@code{"~/Mail"} or a subdirectory of it; several other parts of Gnus -use that directory by default for various things, and may get confused -if @code{nnmaildir} uses it too. @code{"~/.nnmaildir"} is a typical -value. +@cindex mbox +@cindex Unix mbox +@item mbox +The standard Unix mbox file. -@item target-prefix -This should be a Lisp form which is processed by @code{eval} and -@code{expand-file-name}. The form is @code{eval}ed only when the -server is opened; the resulting string is used until the server is -closed. +@cindex MMDF mail box +@item mmdf +The MMDF mail box format. -When you create a group on an @code{nnmaildir} server, the maildir is -created with @code{target-prefix} prepended to its name, and a symlink -pointing to that maildir is created, named with the plain group name. -So if @code{directory} is @code{"~/.nnmaildir"} and -@code{target-prefix} is @code{"../maildirs/"}, then when you create -the group @code{foo}, @code{nnmaildir} will create -@file{~/.nnmaildir/../maildirs/foo} as a maildir, and will create -@file{~/.nnmaildir/foo} as a symlink pointing to -@file{../maildirs/foo}. +@item news +Several news articles appended into a file. -You can set @code{target-prefix} to a string without any slashes to -create both maildirs and symlinks in the same @code{directory}; in -this case, any maildirs found in @code{directory} whose names start -with @code{target-prefix} will not be listed as groups (but the -symlinks pointing to them will be). +@cindex rnews batch files +@item rnews +The rnews batch transport format. -As a special case, if @code{target-prefix} is @code{""} (the default), -then when you create a group, the maildir will be created in -@code{directory} without a corresponding symlink. Beware that you -cannot use @code{gnus-group-delete-group} on such groups without the -@code{force} argument. +@item nsmail +Netscape mail boxes. -@item directory-files -This should be a function with the same interface as -@code{directory-files} (such as @code{directory-files} itself). It is -used to scan the server's @code{directory} for maildirs. This -parameter is optional; the default is -@code{nnheader-directory-files-safe} if -@code{nnheader-directory-files-is-safe} is @code{nil}, and -@code{directory-files} otherwise. -(@code{nnheader-directory-files-is-safe} is checked only once when the -server is opened; if you want to check it each time the directory is -scanned, you'll have to provide your own function that does that.) +@item mime-parts +@acronym{MIME} multipart messages. -@item get-new-mail -If non-@code{nil}, then after scanning for new mail in the group -maildirs themselves as usual, this server will also incorporate mail -the conventional Gnus way, from @code{mail-sources} according to -@code{nnmail-split-methods} or @code{nnmail-split-fancy}. The default -value is @code{nil}. +@item standard-digest +The standard (RFC 1153) digest format. -Do @emph{not} use the same maildir both in @code{mail-sources} and as -an @code{nnmaildir} group. The results might happen to be useful, but -that would be by chance, not by design, and the results might be -different in the future. If your split rules create new groups, -remember to supply a @code{create-directory} server parameter. -@end table +@item mime-digest +A @acronym{MIME} digest of messages. -@subsubsection Group parameters +@item lanl-gov-announce +Announcement messages from LANL Gov Announce. -@code{nnmaildir} uses several group parameters. It's safe to ignore -all this; the default behavior for @code{nnmaildir} is the same as the -default behavior for other mail back ends: articles are deleted after -one week, etc. Except for the expiry parameters, all this -functionality is unique to @code{nnmaildir}, so you can ignore it if -you're just trying to duplicate the behavior you already have with -another back end. +@cindex git commit messages +@item git +@code{git} commit messages. -If the value of any of these parameters is a vector, the first element -is evaluated as a Lisp form and the result is used, rather than the -original value. If the value is not a vector, the value itself is -evaluated as a Lisp form. (This is why these parameters use names -different from those of other, similar parameters supported by other -back ends: they have different, though similar, meanings.) (For -numbers, strings, @code{nil}, and @code{t}, you can ignore the -@code{eval} business again; for other values, remember to use an extra -quote and wrap the value in a vector when appropriate.) +@cindex forwarded messages +@item rfc822-forward +A message forwarded according to RFC822. -@table @code -@item expire-age -An integer specifying the minimum age, in seconds, of an article -before it will be expired, or the symbol @code{never} to specify that -articles should never be expired. If this parameter is not set, -@code{nnmaildir} falls back to the usual -@code{nnmail-expiry-wait}(@code{-function}) variables (the -@code{expiry-wait} group parameter overrides @code{nnmail-expiry-wait} -and makes @code{nnmail-expiry-wait-function} ineffective). If you -wanted a value of 3 days, you could use something like @code{[(* 3 24 -60 60)]}; @code{nnmaildir} will evaluate the form and use the result. -An article's age is measured starting from the article file's -modification time. Normally, this is the same as the article's -delivery time, but editing an article makes it younger. Moving an -article (other than via expiry) may also make an article younger. +@item outlook +The Outlook mail box. -@item expire-group -If this is set to a string such as a full Gnus group name, like -@example -"backend+server.address.string:group.name" -@end example -and if it is not the name of the same group that the parameter belongs -to, then articles will be moved to the specified group during expiry -before being deleted. @emph{If this is set to an @code{nnmaildir} -group, the article will be just as old in the destination group as it -was in the source group.} So be careful with @code{expire-age} in the -destination group. If this is set to the name of the same group that -the parameter belongs to, then the article is not expired at all. If -you use the vector form, the first element is evaluated once for each -article. So that form can refer to -@code{nnmaildir-article-file-name}, etc., to decide where to put the -article. @emph{Even if this parameter is not set, @code{nnmaildir} -does not fall back to the @code{expiry-target} group parameter or the -@code{nnmail-expiry-target} variable.} +@item oe-dbx +The Outlook Express dbx mail box. -@item read-only -If this is set to @code{t}, @code{nnmaildir} will treat the articles -in this maildir as read-only. This means: articles are not renamed -from @file{new/} into @file{cur/}; articles are only found in -@file{new/}, not @file{cur/}; articles are never deleted; articles -cannot be edited. @file{new/} is expected to be a symlink to the -@file{new/} directory of another maildir---e.g., a system-wide mailbox -containing a mailing list of common interest. Everything in the -maildir outside @file{new/} is @emph{not} treated as read-only, so for -a shared mailbox, you do still need to set up your own maildir (or -have write permission to the shared mailbox); your maildir just won't -contain extra copies of the articles. +@item exim-bounce +A bounce message from the Exim MTA. -@item directory-files -A function with the same interface as @code{directory-files}. It is -used to scan the directories in the maildir corresponding to this -group to find articles. The default is the function specified by the -server's @code{directory-files} parameter. +@item forward +A message forwarded according to informal rules. -@item distrust-Lines: -If non-@code{nil}, @code{nnmaildir} will always count the lines of an -article, rather than use the @code{Lines:} header field. If -@code{nil}, the header field will be used if present. +@item rfc934 +An RFC934-forwarded message. + +@item mailman +A mailman digest. -@item always-marks -A list of mark symbols, such as @code{['(read expire)]}. Whenever -Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will -say that all articles have these marks, regardless of whether the -marks stored in the filesystem say so. This is a proof-of-concept -feature that will probably be removed eventually; it ought to be done -in Gnus proper, or abandoned if it's not worthwhile. +@item clari-briefs +A digest of Clarinet brief news items. -@item never-marks -A list of mark symbols, such as @code{['(tick expire)]}. Whenever -Gnus asks @code{nnmaildir} for article marks, @code{nnmaildir} will -say that no articles have these marks, regardless of whether the marks -stored in the filesystem say so. @code{never-marks} overrides -@code{always-marks}. This is a proof-of-concept feature that will -probably be removed eventually; it ought to be done in Gnus proper, or -abandoned if it's not worthwhile. +@item slack-digest +Non-standard digest format---matches most things, but does it badly. -@item nov-cache-size -An integer specifying the size of the @acronym{NOV} memory cache. To -speed things up, @code{nnmaildir} keeps @acronym{NOV} data in memory -for a limited number of articles in each group. (This is probably not -worthwhile, and will probably be removed in the future.) This -parameter's value is noticed only the first time a group is seen after -the server is opened---i.e., when you first start Gnus, typically. -The @acronym{NOV} cache is never resized until the server is closed -and reopened. The default is an estimate of the number of articles -that would be displayed in the summary buffer: a count of articles -that are either marked with @code{tick} or not marked with -@code{read}, plus a little extra. +@item mail-in-mail +The last resort. @end table -@subsubsection Article identification -Articles are stored in the @file{cur/} subdirectory of each maildir. -Each article file is named like @code{uniq:info}, where @code{uniq} -contains no colons. @code{nnmaildir} ignores, but preserves, the -@code{:info} part. (Other maildir readers typically use this part of -the filename to store marks.) The @code{uniq} part uniquely -identifies the article, and is used in various places in the -@file{.nnmaildir/} subdirectory of the maildir to store information -about the corresponding article. The full pathname of an article is -available in the variable @code{nnmaildir-article-file-name} after you -request the article in the summary buffer. +You can also use the special ``file type'' @code{guess}, which means +that @code{nndoc} will try to guess what file type it is looking at. +@code{digest} means that @code{nndoc} should guess what digest type the +file is. -@subsubsection NOV data -An article identified by @code{uniq} has its @acronym{NOV} data (used -to generate lines in the summary buffer) stored in -@code{.nnmaildir/nov/uniq}. There is no -@code{nnmaildir-generate-nov-databases} function. (There isn't much -need for it---an article's @acronym{NOV} data is updated automatically -when the article or @code{nnmail-extra-headers} has changed.) You can -force @code{nnmaildir} to regenerate the @acronym{NOV} data for a -single article simply by deleting the corresponding @acronym{NOV} -file, but @emph{beware}: this will also cause @code{nnmaildir} to -assign a new article number for this article, which may cause trouble -with @code{seen} marks, the Agent, and the cache. +@code{nndoc} will not try to change the file or insert any extra headers into +it---it will simply, like, let you use the file as the basis for a +group. And that's it. -@subsubsection Article marks -An article identified by @code{uniq} is considered to have the mark -@code{flag} when the file @file{.nnmaildir/marks/flag/uniq} exists. -When Gnus asks @code{nnmaildir} for a group's marks, @code{nnmaildir} -looks for such files and reports the set of marks it finds. When Gnus -asks @code{nnmaildir} to store a new set of marks, @code{nnmaildir} -creates and deletes the corresponding files as needed. (Actually, -rather than create a new file for each mark, it just creates hard -links to @file{.nnmaildir/markfile}, to save inodes.) +If you have some old archived articles that you want to insert into your +new & spiffy Gnus mail back end, @code{nndoc} can probably help you with +that. Say you have an old @file{RMAIL} file with mail that you now want +to split into your new @code{nnml} groups. You look at that file using +@code{nndoc} (using the @kbd{G f} command in the group buffer +(@pxref{Foreign Groups})), set the process mark on all the articles in +the buffer (@kbd{M P b}, for instance), and then re-spool (@kbd{B r}) +using @code{nnml}. If all goes well, all the mail in the @file{RMAIL} +file is now also stored in lots of @code{nnml} directories, and you can +delete that pesky @file{RMAIL} file. If you have the guts! -You can invent new marks by creating a new directory in -@file{.nnmaildir/marks/}. You can tar up a maildir and remove it from -your server, untar it later, and keep your marks. You can add and -remove marks yourself by creating and deleting mark files. If you do -this while Gnus is running and your @code{nnmaildir} server is open, -it's best to exit all summary buffers for @code{nnmaildir} groups and -type @kbd{s} in the group buffer first, and to type @kbd{g} or -@kbd{M-g} in the group buffer afterwards. Otherwise, Gnus might not -pick up the changes, and might undo them. +Virtual server variables: +@table @code +@item nndoc-article-type +@vindex nndoc-article-type +This should be one of @code{mbox}, @code{babyl}, @code{digest}, +@code{news}, @code{rnews}, @code{mmdf}, @code{forward}, @code{rfc934}, +@code{rfc822-forward}, @code{mime-parts}, @code{standard-digest}, +@code{slack-digest}, @code{clari-briefs}, @code{nsmail}, @code{outlook}, +@code{oe-dbx}, @code{mailman}, and @code{mail-in-mail} or @code{guess}. -@node Mail Folders -@subsubsection Mail Folders -@cindex nnfolder -@cindex mbox folders -@cindex mail folders +@item nndoc-post-type +@vindex nndoc-post-type +This variable says whether Gnus is to consider the group a news group or +a mail group. There are two valid values: @code{mail} (the default) +and @code{news}. +@end table -@code{nnfolder} is a back end for storing each mail group in a -separate file. Each file is in the standard Un*x mbox format. -@code{nnfolder} will add extra headers to keep track of article -numbers and arrival dates. +@menu +* Document Server Internals:: How to add your own document types. +@end menu -@cindex self contained nnfolder servers -@cindex marks -When the marks file is used (which it is by default), @code{nnfolder} -servers have the property that you may backup them using @code{tar} or -similar, and later be able to restore them into Gnus (by adding the -proper @code{nnfolder} server) and have all your marks be preserved. -Marks for a group are usually stored in a file named as the mbox file -with @code{.mrk} concatenated to it (but see -@code{nnfolder-marks-file-suffix}) within the @code{nnfolder} -directory. Individual @code{nnfolder} groups are also possible to -backup, use @kbd{G m} to restore the group (after restoring the backup -into the @code{nnfolder} directory). -Virtual server settings: +@node Document Server Internals +@subsubsection Document Server Internals -@table @code -@item nnfolder-directory -@vindex nnfolder-directory -All the @code{nnfolder} mail boxes will be stored under this -directory. The default is the value of @code{message-directory} -(whose default is @file{~/Mail}) +Adding new document types to be recognized by @code{nndoc} isn't +difficult. You just have to whip up a definition of what the document +looks like, write a predicate function to recognize that document type, +and then hook into @code{nndoc}. -@item nnfolder-active-file -@vindex nnfolder-active-file -The name of the active file. The default is @file{~/Mail/active}. +First, here's an example document type definition: -@item nnfolder-newsgroups-file -@vindex nnfolder-newsgroups-file -The name of the group descriptions file. @xref{Newsgroups File -Format}. The default is @file{~/Mail/newsgroups} +@example +(mmdf + (article-begin . "^\^A\^A\^A\^A\n") + (body-end . "^\^A\^A\^A\^A\n")) +@end example -@item nnfolder-get-new-mail -@vindex nnfolder-get-new-mail -If non-@code{nil}, @code{nnfolder} will read incoming mail. The -default is @code{t} +The definition is simply a unique @dfn{name} followed by a series of +regexp pseudo-variable settings. Below are the possible +variables---don't be daunted by the number of variables; most document +types can be defined with very few settings: -@item nnfolder-save-buffer-hook -@vindex nnfolder-save-buffer-hook -@cindex backup files -Hook run before saving the folders. Note that Emacs does the normal -backup renaming of files even with the @code{nnfolder} buffers. If -you wish to switch this off, you could say something like the -following in your @file{.emacs} file: +@table @code +@item first-article +If present, @code{nndoc} will skip past all text until it finds +something that match this regexp. All text before this will be +totally ignored. -@lisp -(defun turn-off-backup () - (set (make-local-variable 'backup-inhibited) t)) +@item article-begin +This setting has to be present in all document type definitions. It +says what the beginning of each article looks like. To do more +complicated things that cannot be dealt with a simple regexp, you can +use @code{article-begin-function} instead of this. -(add-hook 'nnfolder-save-buffer-hook 'turn-off-backup) -@end lisp +@item article-begin-function +If present, this should be a function that moves point to the beginning +of each article. This setting overrides @code{article-begin}. -@item nnfolder-delete-mail-hook -@vindex nnfolder-delete-mail-hook -Hook run in a buffer narrowed to the message that is to be deleted. -This function can be used to copy the message to somewhere else, or to -extract some information from it before removing it. +@item head-begin +If present, this should be a regexp that matches the head of the +article. To do more complicated things that cannot be dealt with a +simple regexp, you can use @code{head-begin-function} instead of this. -@item nnfolder-nov-is-evil -@vindex nnfolder-nov-is-evil -If non-@code{nil}, this back end will ignore any @acronym{NOV} files. The -default is @code{nil}. +@item head-begin-function +If present, this should be a function that moves point to the head of +the article. This setting overrides @code{head-begin}. -@item nnfolder-nov-file-suffix -@vindex nnfolder-nov-file-suffix -The extension for @acronym{NOV} files. The default is @file{.nov}. +@item head-end +This should match the end of the head of the article. It defaults to +@samp{^$}---the empty line. -@item nnfolder-nov-directory -@vindex nnfolder-nov-directory -The directory where the @acronym{NOV} files should be stored. If -@code{nil}, @code{nnfolder-directory} is used. +@item body-begin +This should match the beginning of the body of the article. It defaults +to @samp{^\n}. To do more complicated things that cannot be dealt with +a simple regexp, you can use @code{body-begin-function} instead of this. -@item nnfolder-marks-is-evil -@vindex nnfolder-marks-is-evil -If non-@code{nil}, this back end will ignore any @sc{marks} files. The -default is @code{nil}. +@item body-begin-function +If present, this function should move point to the beginning of the body +of the article. This setting overrides @code{body-begin}. -@item nnfolder-marks-file-suffix -@vindex nnfolder-marks-file-suffix -The extension for @sc{marks} files. The default is @file{.mrk}. +@item body-end +If present, this should match the end of the body of the article. To do +more complicated things that cannot be dealt with a simple regexp, you +can use @code{body-end-function} instead of this. -@item nnfolder-marks-directory -@vindex nnfolder-marks-directory -The directory where the @sc{marks} files should be stored. If -@code{nil}, @code{nnfolder-directory} is used. +@item body-end-function +If present, this function should move point to the end of the body of +the article. This setting overrides @code{body-end}. + +@item file-begin +If present, this should match the beginning of the file. All text +before this regexp will be totally ignored. + +@item file-end +If present, this should match the end of the file. All text after this +regexp will be totally ignored. @end table +So, using these variables @code{nndoc} is able to dissect a document +file into a series of articles, each with a head and a body. However, a +few more variables are needed since not all document types are all that +news-like---variables needed to transform the head or the body into +something that's palatable for Gnus: + +@table @code +@item prepare-body-function +If present, this function will be called when requesting an article. It +will be called with point at the start of the body, and is useful if the +document has encoded some parts of its contents. -@findex nnfolder-generate-active-file -@kindex M-x nnfolder-generate-active-file -If you have lots of @code{nnfolder}-like files you'd like to read with -@code{nnfolder}, you can use the @kbd{M-x nnfolder-generate-active-file} -command to make @code{nnfolder} aware of all likely files in -@code{nnfolder-directory}. This only works if you use long file names, -though. +@item article-transform-function +If present, this function is called when requesting an article. It's +meant to be used for more wide-ranging transformation of both head and +body of the article. -@node Comparing Mail Back Ends -@subsubsection Comparing Mail Back Ends +@item generate-head-function +If present, this function is called to generate a head that Gnus can +understand. It is called with the article number as a parameter, and is +expected to generate a nice head for the article in question. It is +called when requesting the headers of all articles. -First, just for terminology, the @dfn{back end} is the common word for a -low-level access method---a transport, if you will, by which something -is acquired. The sense is that one's mail has to come from somewhere, -and so selection of a suitable back end is required in order to get that -mail within spitting distance of Gnus. +@item generate-article-function +If present, this function is called to generate an entire article that +Gnus can understand. It is called with the article number as a +parameter when requesting all articles. -The same concept exists for Usenet itself: Though access to articles is -typically done by @acronym{NNTP} these days, once upon a midnight dreary, everyone -in the world got at Usenet by running a reader on the machine where the -articles lay (the machine which today we call an @acronym{NNTP} server), and -access was by the reader stepping into the articles' directory spool -area directly. One can still select between either the @code{nntp} or -@code{nnspool} back ends, to select between these methods, if one happens -actually to live on the server (or can see its spool directly, anyway, -via NFS). +@item dissection-function +If present, this function is called to dissect a document by itself, +overriding @code{first-article}, @code{article-begin}, +@code{article-begin-function}, @code{head-begin}, +@code{head-begin-function}, @code{head-end}, @code{body-begin}, +@code{body-begin-function}, @code{body-end}, @code{body-end-function}, +@code{file-begin}, and @code{file-end}. -The goal in selecting a mail back end is to pick one which -simultaneously represents a suitable way of dealing with the original -format plus leaving mail in a form that is convenient to use in the -future. Here are some high and low points on each: +@end table -@table @code -@item nnmbox +Let's look at the most complicated example I can come up with---standard +digests: -UNIX systems have historically had a single, very common, and well- -defined format. All messages arrive in a single @dfn{spool file}, and -they are delineated by a line whose regular expression matches -@samp{^From_}. (My notational use of @samp{_} is to indicate a space, -to make it clear in this instance that this is not the RFC-specified -@samp{From:} header.) Because Emacs and therefore Gnus emanate -historically from the Unix environment, it is simplest if one does not -mess a great deal with the original mailbox format, so if one chooses -this back end, Gnus' primary activity in getting mail from the real spool -area to Gnus' preferred directory is simply to copy it, with no -(appreciable) format change in the process. It is the ``dumbest'' way -to move mail into availability in the Gnus environment. This makes it -fast to move into place, but slow to parse, when Gnus has to look at -what's where. +@example +(standard-digest + (first-article . ,(concat "^" (make-string 70 ?-) "\n\n+")) + (article-begin . ,(concat "\n\n" (make-string 30 ?-) "\n\n+")) + (prepare-body-function . nndoc-unquote-dashes) + (body-end-function . nndoc-digest-body-end) + (head-end . "^ ?$") + (body-begin . "^ ?\n") + (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$") + (subtype digest guess)) +@end example -@item nnbabyl +We see that all text before a 70-width line of dashes is ignored; all +text after a line that starts with that @samp{^End of} is also ignored; +each article begins with a 30-width line of dashes; the line separating +the head from the body may contain a single space; and that the body is +run through @code{nndoc-unquote-dashes} before being delivered. -Once upon a time, there was the DEC-10 and DEC-20, running operating -systems called TOPS and related things, and the usual (only?) mail -reading environment was a thing called Babyl. I don't know what format -was used for mail landing on the system, but Babyl had its own internal -format to which mail was converted, primarily involving creating a -spool-file-like entity with a scheme for inserting Babyl-specific -headers and status bits above the top of each message in the file. -Rmail was Emacs' first mail reader, it was written by Richard Stallman, -and Stallman came out of that TOPS/Babyl environment, so he wrote Rmail -to understand the mail files folks already had in existence. Gnus (and -VM, for that matter) continue to support this format because it's -perceived as having some good qualities in those mailer-specific -headers/status bits stuff. Rmail itself still exists as well, of -course, and is still maintained within Emacs. Since Emacs 23, it -uses standard mbox format rather than Babyl. +To hook your own document definition into @code{nndoc}, use the +@code{nndoc-add-type} function. It takes two parameters---the first +is the definition itself and the second (optional) parameter says +where in the document type definition alist to put this definition. +The alist is traversed sequentially, and +@code{nndoc-@var{type}-type-p} is called for a given type @var{type}. +So @code{nndoc-mmdf-type-p} is called to see whether a document is of +@code{mmdf} type, and so on. These type predicates should return +@code{nil} if the document is not of the correct type; @code{t} if it +is of the correct type; and a number if the document might be of the +correct type. A high number means high probability; a low number +means low probability with @samp{0} being the lowest valid number. -Both of the above forms leave your mail in a single file on your -file system, and they must parse that entire file each time you take a -look at your mail. -@item nnml +@node Mail-To-News Gateways +@subsection Mail-To-News Gateways +@cindex mail-to-news gateways +@cindex gateways -@code{nnml} is the back end which smells the most as though you were -actually operating with an @code{nnspool}-accessed Usenet system. (In -fact, I believe @code{nnml} actually derived from @code{nnspool} code, -lo these years ago.) One's mail is taken from the original spool file, -and is then cut up into individual message files, 1:1. It maintains a -Usenet-style active file (analogous to what one finds in an INN- or -CNews-based news system in (for instance) @file{/var/lib/news/active}, -or what is returned via the @samp{NNTP LIST} verb) and also creates -@dfn{overview} files for efficient group entry, as has been defined for -@acronym{NNTP} servers for some years now. It is slower in mail-splitting, -due to the creation of lots of files, updates to the @code{nnml} active -file, and additions to overview files on a per-message basis, but it is -extremely fast on access because of what amounts to the indexing support -provided by the active file and overviews. +If your local @code{nntp} server doesn't allow posting, for some reason +or other, you can post using one of the numerous mail-to-news gateways. +The @code{nngateway} back end provides the interface. -@code{nnml} costs @dfn{inodes} in a big way; that is, it soaks up the -resource which defines available places in the file system to put new -files. Sysadmins take a dim view of heavy inode occupation within -tight, shared file systems. But if you live on a personal machine where -the file system is your own and space is not at a premium, @code{nnml} -wins big. +Note that you can't read anything from this back end---it can only be +used to post with. -It is also problematic using this back end if you are living in a -FAT16-based Windows world, since much space will be wasted on all these -tiny files. +Server variables: -@item nnmh +@table @code +@item nngateway-address +@vindex nngateway-address +This is the address of the mail-to-news gateway. -The Rand MH mail-reading system has been around UNIX systems for a very -long time; it operates by splitting one's spool file of messages into -individual files, but with little or no indexing support---@code{nnmh} -is considered to be semantically equivalent to ``@code{nnml} without -active file or overviews''. This is arguably the worst choice, because -one gets the slowness of individual file creation married to the -slowness of access parsing when learning what's new in one's groups. +@item nngateway-header-transformation +@vindex nngateway-header-transformation +News headers often have to be transformed in some odd way or other +for the mail-to-news gateway to accept it. This variable says what +transformation should be called, and defaults to +@code{nngateway-simple-header-transformation}. The function is called +narrowed to the headers to be transformed and with one parameter---the +gateway address. -@item nnfolder +This default function just inserts a new @code{To} header based on the +@code{Newsgroups} header and the gateway address. +For instance, an article with this @code{Newsgroups} header: -Basically the effect of @code{nnfolder} is @code{nnmbox} (the first -method described above) on a per-group basis. That is, @code{nnmbox} -itself puts @emph{all} one's mail in one file; @code{nnfolder} provides a -little bit of optimization to this so that each of one's mail groups has -a Unix mail box file. It's faster than @code{nnmbox} because each group -can be parsed separately, and still provides the simple Unix mail box -format requiring minimal effort in moving the mail around. In addition, -it maintains an ``active'' file making it much faster for Gnus to figure -out how many messages there are in each separate group. +@example +Newsgroups: alt.religion.emacs +@end example -If you have groups that are expected to have a massive amount of -messages, @code{nnfolder} is not the best choice, but if you receive -only a moderate amount of mail, @code{nnfolder} is probably the most -friendly mail back end all over. +will get this @code{To} header inserted: -@item nnmaildir +@example +To: alt-religion-emacs@@GATEWAY +@end example -For configuring expiry and other things, @code{nnmaildir} uses -incompatible group parameters, slightly different from those of other -mail back ends. +The following pre-defined functions exist: -@code{nnmaildir} is largely similar to @code{nnml}, with some notable -differences. Each message is stored in a separate file, but the -filename is unrelated to the article number in Gnus. @code{nnmaildir} -also stores the equivalent of @code{nnml}'s overview files in one file -per article, so it uses about twice as many inodes as @code{nnml}. -(Use @code{df -i} to see how plentiful your inode supply is.) If this -slows you down or takes up very much space, a non-block-structured -file system. +@findex nngateway-simple-header-transformation +@table @code -Since maildirs don't require locking for delivery, the maildirs you use -as groups can also be the maildirs your mail is directly delivered to. -This means you can skip Gnus' mail splitting if your mail is already -organized into different mailboxes during delivery. A @code{directory} -entry in @code{mail-sources} would have a similar effect, but would -require one set of mailboxes for spooling deliveries (in mbox format, -thus damaging message bodies), and another set to be used as groups (in -whatever format you like). A maildir has a built-in spool, in the -@code{new/} subdirectory. Beware that currently, mail moved from -@code{new/} to @code{cur/} instead of via mail splitting will not -undergo treatment such as duplicate checking. +@item nngateway-simple-header-transformation +Creates a @code{To} header that looks like +@var{newsgroup}@@@code{nngateway-address}. -@code{nnmaildir} stores article marks for a given group in the -corresponding maildir, in a way designed so that it's easy to manipulate -them from outside Gnus. You can tar up a maildir, unpack it somewhere -else, and still have your marks. @code{nnml} also stores marks, but -it's not as easy to work with them from outside Gnus as with -@code{nnmaildir}. +@findex nngateway-mail2news-header-transformation -@code{nnmaildir} uses a significant amount of memory to speed things up. -(It keeps in memory some of the things that @code{nnml} stores in files -and that @code{nnmh} repeatedly parses out of message files.) If this -is a problem for you, you can set the @code{nov-cache-size} group -parameter to something small (0 would probably not work, but 1 probably -would) to make it use less memory. This caching will probably be -removed in the future. +@item nngateway-mail2news-header-transformation +Creates a @code{To} header that looks like +@code{nngateway-address}. +@end table -Startup is likely to be slower with @code{nnmaildir} than with other -back ends. Everything else is likely to be faster, depending in part -on your file system. +@end table -@code{nnmaildir} does not use @code{nnoo}, so you cannot use @code{nnoo} -to write an @code{nnmaildir}-derived back end. +Here's an example: -@end table +@lisp +(setq gnus-post-method + '(nngateway + "mail2news@@replay.com" + (nngateway-header-transformation + nngateway-mail2news-header-transformation))) +@end lisp +So, to use this, simply say something like: -@node Browsing the Web -@section Browsing the Web -@cindex web -@cindex browsing the web -@cindex www -@cindex http +@lisp +(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS")) +@end lisp -Web-based discussion forums are getting more and more popular. On many -subjects, the web-based forums have become the most important forums, -eclipsing the importance of mailing lists and news groups. The reason -is easy to understand---they are friendly to new users; you just point -and click, and there's the discussion. With mailing lists, you have to -go through a cumbersome subscription procedure, and most people don't -even know what a news group is. -The problem with this scenario is that web browsers are not very good at -being newsreaders. They do not keep track of what articles you've read; -they do not allow you to score on subjects you're interested in; they do -not allow off-line browsing; they require you to click around and drive -you mad in the end. -So---if web browsers suck at reading discussion forums, why not use Gnus -to do it instead? +@node Combined Groups +@section Combined Groups -Gnus has been getting a bit of a collection of back ends for providing -interfaces to these sources. +Gnus allows combining a mixture of all the other group types into bigger +groups. @menu -* Archiving Mail:: -* Web Searches:: Creating groups from articles that match a string. -* RSS:: Reading RDF site summary. -* Customizing W3:: Doing stuff to Emacs/W3 from Gnus. +* Virtual Groups:: Combining articles from many groups. @end menu -All the web sources require Emacs/W3 and the url library or those -alternatives to work. - -The main caveat with all these web sources is that they probably won't -work for a very long time. Gleaning information from the @acronym{HTML} data -is guesswork at best, and when the layout is altered, the Gnus back end -will fail. If you have reasonably new versions of these back ends, -though, you should be ok. - -One thing all these Web methods have in common is that the Web sources -are often down, unavailable or just plain too slow to be fun. In those -cases, it makes a lot of sense to let the Gnus Agent (@pxref{Gnus -Unplugged}) handle downloading articles, and then you can read them at -leisure from your local disk. No more World Wide Wait for you. - -@node Archiving Mail -@subsection Archiving Mail -@cindex archiving mail -@cindex backup of mail -Some of the back ends, notably @code{nnml}, @code{nnfolder}, and -@code{nnmaildir}, now actually store the article marks with each group. -For these servers, archiving and restoring a group while preserving -marks is fairly simple. +@node Virtual Groups +@subsection Virtual Groups +@cindex nnvirtual +@cindex virtual groups +@cindex merging groups -(Preserving the group level and group parameters as well still -requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity -though.) +An @dfn{nnvirtual group} is really nothing more than a collection of +other groups. -To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir} -server, take a recursive copy of the server directory. There is no need -to shut down Gnus, so archiving may be invoked by @code{cron} or -similar. You restore the data by restoring the directory tree, and -adding a server definition pointing to that directory in Gnus. The -@ref{Article Backlog}, @ref{Asynchronous Fetching} and other things -might interfere with overwriting data, so you may want to shut down Gnus -before you restore the data. +For instance, if you are tired of reading many small groups, you can +put them all in one big group, and then grow tired of reading one +big, unwieldy group. The joys of computing! -It is also possible to archive individual @code{nnml}, -@code{nnfolder}, or @code{nnmaildir} groups, while preserving marks. -For @code{nnml} or @code{nnmaildir}, you copy all files in the group's -directory. For @code{nnfolder} you need to copy both the base folder -file itself (@file{FOO}, say), and the marks file (@file{FOO.mrk} in -this example). Restoring the group is done with @kbd{G m} from the Group -buffer. The last step makes Gnus notice the new directory. -@code{nnmaildir} notices the new directory automatically, so @kbd{G m} -is unnecessary in that case. +You specify @code{nnvirtual} as the method. The address should be a +regexp to match component groups. -@node Web Searches -@subsection Web Searches -@cindex nnweb -@cindex Google -@cindex dejanews -@cindex gmane -@cindex Usenet searches -@cindex searching the Usenet +All marks in the virtual group will stick to the articles in the +component groups. So if you tick an article in a virtual group, the +article will also be ticked in the component group from whence it +came. (And vice versa---marks from the component groups will also be +shown in the virtual group.). To create an empty virtual group, run +@kbd{G V} (@code{gnus-group-make-empty-virtual}) in the group buffer +and edit the method regexp with @kbd{M-e} +(@code{gnus-group-edit-group-method}) -It's, like, too neat to search the Usenet for articles that match a -string, but it, like, totally @emph{sucks}, like, totally, to use one of -those, like, Web browsers, and you, like, have to, rilly, like, look at -the commercials, so, like, with Gnus you can do @emph{rad}, rilly, -searches without having to use a browser. +Here's an example @code{nnvirtual} method that collects all Andrea Dworkin +newsgroups into one, big, happy newsgroup: -The @code{nnweb} back end allows an easy interface to the mighty search -engine. You create an @code{nnweb} group, enter a search pattern, and -then enter the group and read the articles like you would any normal -group. The @kbd{G w} command in the group buffer (@pxref{Foreign -Groups}) will do this in an easy-to-use fashion. +@lisp +(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*") +@end lisp -@code{nnweb} groups don't really lend themselves to being solid -groups---they have a very fleeting idea of article numbers. In fact, -each time you enter an @code{nnweb} group (not even changing the search -pattern), you are likely to get the articles ordered in a different -manner. Not even using duplicate suppression (@pxref{Duplicate -Suppression}) will help, since @code{nnweb} doesn't even know the -@code{Message-ID} of the articles before reading them using some search -engines (Google, for instance). The only possible way to keep track -of which articles you've read is by scoring on the @code{Date} -header---mark all articles posted before the last date you read the -group as read. +The component groups can be native or foreign; everything should work +smoothly, but if your computer explodes, it was probably my fault. -If the search engine changes its output substantially, @code{nnweb} -won't be able to parse it and will fail. One could hardly fault the Web -providers if they were to do this---their @emph{raison d'@^etre} is to -make money off of advertisements, not to provide services to the -community. Since @code{nnweb} washes the ads off all the articles, one -might think that the providers might be somewhat miffed. We'll see. +Collecting the same group from several servers might actually be a good +idea if users have set the Distribution header to limit distribution. +If you would like to read @samp{soc.motss} both from a server in Japan +and a server in Norway, you could use the following as the group regexp: -You must have the @code{url} and @code{W3} package or those alternatives -(try @code{customize-group} on the @samp{mm-url} variable group) -installed to be able to use @code{nnweb}. +@example +"^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$" +@end example -Virtual server variables: +(Remember, though, that if you're creating the group with @kbd{G m}, you +shouldn't double the backslashes, and you should leave off the quote +characters at the beginning and the end of the string.) -@table @code -@item nnweb-type -@vindex nnweb-type -What search engine type is being used. The currently supported types -are @code{google}, @code{dejanews}, and @code{gmane}. Note that -@code{dejanews} is an alias to @code{google}. +This should work kinda smoothly---all articles from both groups should +end up in this one, and there should be no duplicates. Threading (and +the rest) will still work as usual, but there might be problems with the +sequence of articles. Sorting on date might be an option here +(@pxref{Selecting a Group}). -@item nnweb-search -@vindex nnweb-search -The search string to feed to the search engine. +One limitation, however---all groups included in a virtual +group have to be alive (i.e., subscribed or unsubscribed). Killed or +zombie groups can't be component groups for @code{nnvirtual} groups. -@item nnweb-max-hits -@vindex nnweb-max-hits -Advisory maximum number of hits per search to display. The default is -999. +@vindex nnvirtual-always-rescan +If the @code{nnvirtual-always-rescan} variable is non-@code{nil} (which +is the default), @code{nnvirtual} will always scan groups for unread +articles when entering a virtual group. If this variable is @code{nil} +and you read articles in a component group after the virtual group has +been activated, the read articles from the component group will show up +when you enter the virtual group. You'll also see this effect if you +have two virtual groups that have a component group in common. If +that's the case, you should set this variable to @code{t}. Or you can +just tap @code{M-g} on the virtual group every time before you enter +it---it'll have much the same effect. -@item nnweb-type-definition -@vindex nnweb-type-definition -Type-to-definition alist. This alist says what @code{nnweb} should do -with the various search engine types. The following elements must be -present: +@code{nnvirtual} can have both mail and news groups as component groups. +When responding to articles in @code{nnvirtual} groups, @code{nnvirtual} +has to ask the back end of the component group the article comes from +whether it is a news or mail back end. However, when you do a @kbd{^}, +there is typically no sure way for the component back end to know this, +and in that case @code{nnvirtual} tells Gnus that the article came from a +not-news back end. (Just to be on the safe side.) -@table @code -@item article -Function to decode the article and provide something that Gnus -understands. +@kbd{C-c C-n} in the message buffer will insert the @code{Newsgroups} +line from the article you respond to in these cases. -@item map -Function to create an article number to message header and URL alist. +@code{nnvirtual} groups do not inherit anything but articles and marks +from component groups---group parameters, for instance, are not +inherited. -@item search -Function to send the search string to the search engine. -@item address -The address the aforementioned function should send the search string -to. +@node Email Based Diary +@section Email Based Diary +@cindex diary +@cindex email based diary +@cindex calendar -@item id -Format string URL to fetch an article by @code{Message-ID}. -@end table +This section describes a special mail back end called @code{nndiary}, +and its companion library @code{gnus-diary}. It is ``special'' in the +sense that it is not meant to be one of the standard alternatives for +reading mail with Gnus. See @ref{Choosing a Mail Back End} for that. +Instead, it is used to treat @emph{some} of your mails in a special way, +namely, as event reminders. -@end table +Here is a typical scenario: +@itemize @bullet +@item +You've got a date with Andy Mc Dowell or Bruce Willis (select according +to your sexual preference) in one month. You don't want to forget it. +@item +So you send a ``reminder'' message (actually, a diary one) to yourself. +@item +You forget all about it and keep on getting and reading new mail, as usual. +@item +From time to time, as you type `g' in the group buffer and as the date +is getting closer, the message will pop up again to remind you of your +appointment, just as if it were new and unread. +@item +Read your ``new'' messages, this one included, and start dreaming again +of the night you're gonna have. +@item +Once the date is over (you actually fell asleep just after dinner), the +message will be automatically deleted if it is marked as expirable. +@end itemize -@node RSS -@subsection RSS -@cindex nnrss -@cindex RSS +The Gnus Diary back end has the ability to handle regular appointments +(that wouldn't ever be deleted) as well as punctual ones, operates as a +real mail back end and is configurable in many ways. All of this is +explained in the sections below. -Some web sites have an RDF Site Summary (@acronym{RSS}). -@acronym{RSS} is a format for summarizing headlines from news related -sites (such as BBC or CNN). But basically anything list-like can be -presented as an @acronym{RSS} feed: weblogs, changelogs or recent -changes to a wiki (e.g. @url{http://cliki.net/recent-changes.rdf}). +@menu +* The NNDiary Back End:: Basic setup and usage. +* The Gnus Diary Library:: Utility toolkit on top of nndiary. +* Sending or Not Sending:: A final note on sending diary messages. +@end menu -@acronym{RSS} has a quite regular and nice interface, and it's -possible to get the information Gnus needs to keep groups updated. -Note: you had better use Emacs which supports the @code{utf-8} coding -system because @acronym{RSS} uses UTF-8 for encoding non-@acronym{ASCII} -text by default. It is also used by default for non-@acronym{ASCII} -group names. +@node The NNDiary Back End +@subsection The NNDiary Back End +@cindex nndiary +@cindex the nndiary back end -@kindex G R (Group) -Use @kbd{G R} from the group buffer to subscribe to a feed---you will be -prompted for the location, the title and the description of the feed. -The title, which allows any characters, will be used for the group name -and the name of the group data file. The description can be omitted. +@code{nndiary} is a back end very similar to @code{nnml} (@pxref{Mail +Spool}). Actually, it could appear as a mix of @code{nnml} and +@code{nndraft}. If you know @code{nnml}, you're already familiar with +the message storing scheme of @code{nndiary}: one file per message, one +directory per group. -An easy way to get started with @code{nnrss} is to say something like -the following in the group buffer: @kbd{B nnrss RET RET y}, then -subscribe to groups. + Before anything, there is one requirement to be able to run +@code{nndiary} properly: you @emph{must} use the group timestamp feature +of Gnus. This adds a timestamp to each group's parameters. @ref{Group +Timestamp} to see how it's done. -The @code{nnrss} back end saves the group data file in -@code{nnrss-directory} (see below) for each @code{nnrss} group. File -names containing non-@acronym{ASCII} characters will be encoded by the -coding system specified with the @code{nnmail-pathname-coding-system} -variable or other. Also @xref{Non-ASCII Group Names}, for more -information. +@menu +* Diary Messages:: What makes a message valid for nndiary. +* Running NNDiary:: NNDiary has two modes of operation. +* Customizing NNDiary:: Bells and whistles. +@end menu -The @code{nnrss} back end generates @samp{multipart/alternative} -@acronym{MIME} articles in which each contains a @samp{text/plain} part -and a @samp{text/html} part. +@node Diary Messages +@subsubsection Diary Messages +@cindex nndiary messages +@cindex nndiary mails -@cindex OPML -You can also use the following commands to import and export your -subscriptions from a file in @acronym{OPML} format (Outline Processor -Markup Language). +@code{nndiary} messages are just normal ones, except for the mandatory +presence of 7 special headers. These headers are of the form +@code{X-Diary-}, @code{} being one of +@code{Minute}, @code{Hour}, @code{Dom}, @code{Month}, @code{Year}, +@code{Time-Zone} and @code{Dow}. @code{Dom} means ``Day of Month'', and +@code{dow} means ``Day of Week''. These headers actually behave like +crontab specifications and define the event date(s): -@defun nnrss-opml-import file -Prompt for an @acronym{OPML} file, and subscribe to each feed in the -file. -@end defun +@itemize @bullet +@item +For all headers except the @code{Time-Zone} one, a header value is +either a star (meaning all possible values), or a list of fields +(separated by a comma). +@item +A field is either an integer, or a range. +@item +A range is two integers separated by a dash. +@item +Possible integer values are 0--59 for @code{Minute}, 0--23 for +@code{Hour}, 1--31 for @code{Dom}, 1--12 for @code{Month}, above 1971 +for @code{Year} and 0--6 for @code{Dow} (0 meaning Sunday). +@item +As a special case, a star in either @code{Dom} or @code{Dow} doesn't +mean ``all possible values'', but ``use only the other field''. Note +that if both are star'ed, the use of either one gives the same result. +@item +The @code{Time-Zone} header is special in that it can only have one +value (@code{GMT}, for instance). A star doesn't mean ``all possible +values'' (because it makes no sense), but ``the current local time +zone''. Most of the time, you'll be using a star here. However, for a +list of available time zone values, see the variable +@code{nndiary-headers}. +@end itemize -@defun nnrss-opml-export -Write your current @acronym{RSS} subscriptions to a buffer in -@acronym{OPML} format. -@end defun +As a concrete example, here are the diary headers to add to your message +for specifying ``Each Monday and each 1st of month, at 12:00, 20:00, +21:00, 22:00, 23:00 and 24:00, from 1999 to 2010'' (I'll let you find +what to do then): -The following @code{nnrss} variables can be altered: +@example +X-Diary-Minute: 0 +X-Diary-Hour: 12, 20-24 +X-Diary-Dom: 1 +X-Diary-Month: * +X-Diary-Year: 1999-2010 +X-Diary-Dow: 1 +X-Diary-Time-Zone: * +@end example -@table @code -@item nnrss-directory -@vindex nnrss-directory -The directory where @code{nnrss} stores its files. The default is -@file{~/News/rss/}. +@node Running NNDiary +@subsubsection Running NNDiary +@cindex running nndiary +@cindex nndiary operation modes -@item nnrss-file-coding-system -@vindex nnrss-file-coding-system -The coding system used when reading and writing the @code{nnrss} groups -data files. The default is the value of -@code{mm-universal-coding-system} (which defaults to @code{emacs-mule} -in Emacs or @code{escape-quoted} in XEmacs). +@code{nndiary} has two modes of operation: ``traditional'' (the default) +and ``autonomous''. In traditional mode, @code{nndiary} does not get new +mail by itself. You have to move (@kbd{B m}) or copy (@kbd{B c}) mails +from your primary mail back end to nndiary groups in order to handle them +as diary messages. In autonomous mode, @code{nndiary} retrieves its own +mail and handles it independently from your primary mail back end. -@item nnrss-ignore-article-fields -@vindex nnrss-ignore-article-fields -Some feeds update constantly article fields during their publications, -e.g. to indicate the number of comments. However, if there is -a difference between the local article and the distant one, the latter -is considered to be new. To avoid this and discard some fields, set this -variable to the list of fields to be ignored. The default is -@code{'(slash:comments)}. +One should note that Gnus is not inherently designed to allow several +``master'' mail back ends at the same time. However, this does make +sense with @code{nndiary}: you really want to send and receive diary +messages to your diary groups directly. So, @code{nndiary} supports +being sort of a ``second primary mail back end'' (to my knowledge, it is +the only back end offering this feature). However, there is a limitation +(which I hope to fix some day): respooling doesn't work in autonomous +mode. -@item nnrss-use-local -@vindex nnrss-use-local -@findex nnrss-generate-download-script -If you set @code{nnrss-use-local} to @code{t}, @code{nnrss} will read -the feeds from local files in @code{nnrss-directory}. You can use -the command @code{nnrss-generate-download-script} to generate a -download script using @command{wget}. -@end table +In order to use @code{nndiary} in autonomous mode, you have several +things to do: -The following code may be helpful, if you want to show the description in -the summary buffer. +@itemize @bullet +@item +Allow @code{nndiary} to retrieve new mail by itself. Put the following +line in your @file{~/.gnus.el} file: @lisp -(add-to-list 'nnmail-extra-headers nnrss-description-field) -(setq gnus-summary-line-format "%U%R%z%I%(%[%4L: %-15,15f%]%) %s%uX\n") - -(defun gnus-user-format-function-X (header) - (let ((descr - (assq nnrss-description-field (mail-header-extra header)))) - (if descr (concat "\n\t" (cdr descr)) ""))) +(setq nndiary-get-new-mail t) @end lisp +@item +You must arrange for diary messages (those containing @code{X-Diary-*} +headers) to be split in a private folder @emph{before} Gnus treat them. +Again, this is needed because Gnus cannot (yet ?) properly handle +multiple primary mail back ends. Getting those messages from a separate +source will compensate this misfeature to some extent. -The following code may be useful to open an nnrss url directly from the -summary buffer. +As an example, here's my procmailrc entry to store diary files in +@file{~/.nndiary} (the default @code{nndiary} mail source file): -@lisp -(require 'browse-url) +@example +:0 HD : +* ^X-Diary +.nndiary +@end example +@end itemize -(defun browse-nnrss-url (arg) - (interactive "p") - (let ((url (assq nnrss-url-field - (mail-header-extra - (gnus-data-header - (assq (gnus-summary-article-number) - gnus-newsgroup-data)))))) - (if url - (progn - (browse-url (cdr url)) - (gnus-summary-mark-as-read-forward 1)) - (gnus-summary-scroll-up arg)))) +Once this is done, you might want to customize the following two options +that affect the diary mail retrieval and splitting processes: -(eval-after-load "gnus" - #'(define-key gnus-summary-mode-map - (kbd "") 'browse-nnrss-url)) -(add-to-list 'nnmail-extra-headers nnrss-url-field) -@end lisp +@defvar nndiary-mail-sources +This is the diary-specific replacement for the standard +@code{mail-sources} variable. It obeys the same syntax, and defaults to +@code{(file :path "~/.nndiary")}. +@end defvar -Even if you have added @samp{text/html} to the -@code{mm-discouraged-alternatives} variable (@pxref{Display -Customization, ,Display Customization, emacs-mime, The Emacs MIME -Manual}) since you don't want to see @acronym{HTML} parts, it might be -more useful especially in @code{nnrss} groups to display -@samp{text/html} parts. Here's an example of setting -@code{mm-discouraged-alternatives} as a group parameter (@pxref{Group -Parameters}) in order to display @samp{text/html} parts only in -@code{nnrss} groups: +@defvar nndiary-split-methods +This is the diary-specific replacement for the standard +@code{nnmail-split-methods} variable. It obeys the same syntax. +@end defvar -@lisp -;; @r{Set the default value of @code{mm-discouraged-alternatives}.} -(eval-after-load "gnus-sum" - '(add-to-list - 'gnus-newsgroup-variables - '(mm-discouraged-alternatives - . '("text/html" "image/.*")))) + Finally, you may add a permanent @code{nndiary} virtual server +(something like @code{(nndiary "diary")} should do) to your +@code{gnus-secondary-select-methods}. + + Hopefully, almost everything (see the TODO section in +@file{nndiary.el}) will work as expected when you restart Gnus: in +autonomous mode, typing @kbd{g} and @kbd{M-g} in the group buffer, will +also get your new diary mails and split them according to your +diary-specific rules, @kbd{F} will find your new diary groups etc. + +@node Customizing NNDiary +@subsubsection Customizing NNDiary +@cindex customizing nndiary +@cindex nndiary customization + +Now that @code{nndiary} is up and running, it's time to customize it. +The custom group is called @code{nndiary} (no, really ?!). You should +browse it to figure out which options you'd like to tweak. The following +two variables are probably the only ones you will want to change: -;; @r{Display @samp{text/html} parts in @code{nnrss} groups.} -(add-to-list - 'gnus-parameters - '("\\`nnrss:" (mm-discouraged-alternatives nil))) -@end lisp +@defvar nndiary-reminders +This is the list of times when you want to be reminded of your +appointments (e.g. 3 weeks before, then 2 days before, then 1 hour +before and that's it). Remember that ``being reminded'' means that the +diary message will pop up as brand new and unread again when you get new +mail. +@end defvar +@defvar nndiary-week-starts-on-monday +Rather self-explanatory. Otherwise, Sunday is assumed (this is the +default). +@end defvar -@node Customizing W3 -@subsection Customizing W3 -@cindex W3 -@cindex html -@cindex url -@cindex Netscape -Gnus uses the url library to fetch web pages and Emacs/W3 (or those -alternatives) to display web pages. Emacs/W3 is documented in its own -manual, but there are some things that may be more relevant for Gnus -users. +@node The Gnus Diary Library +@subsection The Gnus Diary Library +@cindex gnus-diary +@cindex the gnus diary library -For instance, a common question is how to make Emacs/W3 follow links -using the @code{browse-url} functions (which will call some external web -browser like Netscape). Here's one way: +Using @code{nndiary} manually (I mean, writing the headers by hand and +so on) would be rather boring. Fortunately, there is a library called +@code{gnus-diary} written on top of @code{nndiary}, that does many +useful things for you. + + In order to use it, add the following line to your @file{~/.gnus.el} file: @lisp -(eval-after-load "w3" - '(progn - (fset 'w3-fetch-orig (symbol-function 'w3-fetch)) - (defun w3-fetch (&optional url target) - (interactive (list (w3-read-url-with-default))) - (if (eq major-mode 'gnus-article-mode) - (browse-url url) - (w3-fetch-orig url target))))) +(require 'gnus-diary) @end lisp -Put that in your @file{.emacs} file, and hitting links in W3-rendered -@acronym{HTML} in the Gnus article buffers will use @code{browse-url} to -follow the link. - - -@node Other Sources -@section Other Sources + Also, you shouldn't use any @code{gnus-user-format-function-[d|D]} +(@pxref{Summary Buffer Lines}). @code{gnus-diary} provides both of these +(sorry if you used them before). -Gnus can do more than just read news or mail. The methods described -below allow Gnus to view directories and files as if they were -newsgroups. @menu -* Directory Groups:: You can read a directory as if it was a newsgroup. -* Anything Groups:: Dired? Who needs dired? -* Document Groups:: Single files can be the basis of a group. -* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. +* Diary Summary Line Format:: A nicer summary buffer line format. +* Diary Articles Sorting:: A nicer way to sort messages. +* Diary Headers Generation:: Not doing it manually. +* Diary Group Parameters:: Not handling them manually. @end menu +@node Diary Summary Line Format +@subsubsection Diary Summary Line Format +@cindex diary summary buffer line +@cindex diary summary line format -@node Directory Groups -@subsection Directory Groups -@cindex nndir -@cindex directory groups +Displaying diary messages in standard summary line format (usually +something like @samp{From Joe: Subject}) is pretty useless. Most of +the time, you're the one who wrote the message, and you mostly want to +see the event's date. -If you have a directory that has lots of articles in separate files in -it, you might treat it as a newsgroup. The files have to have numerical -names, of course. + @code{gnus-diary} provides two supplemental user formats to be used in +summary line formats. @code{D} corresponds to a formatted time string +for the next occurrence of the event (e.g. ``Sat, Sep 22 01, 12:00''), +while @code{d} corresponds to an approximative remaining time until the +next occurrence of the event (e.g. ``in 6 months, 1 week''). -This might be an opportune moment to mention @code{ange-ftp} (and its -successor @code{efs}), that most wonderful of all wonderful Emacs -packages. When I wrote @code{nndir}, I didn't think much about it---a -back end to read directories. Big deal. + For example, here's how Joe's birthday is displayed in my +@code{nndiary+diary:birthdays} summary buffer (note that the message is +expirable, but will never be deleted, as it specifies a periodic event): -@code{ange-ftp} changes that picture dramatically. For instance, if you -enter the @code{ange-ftp} file name -@file{/ftp.hpc.uh.edu:/pub/emacs/ding-list/} as the directory name, -@code{ange-ftp} or @code{efs} will actually allow you to read this -directory over at @samp{sina} as a newsgroup. Distributed news ahoy! +@example + E Sat, Sep 22 01, 12:00: Joe's birthday (in 6 months, 1 week) +@end example -@code{nndir} will use @acronym{NOV} files if they are present. +In order to get something like the above, you would normally add the +following line to your diary groups'parameters: -@code{nndir} is a ``read-only'' back end---you can't delete or expire -articles with this method. You can use @code{nnmh} or @code{nnml} for -whatever you use @code{nndir} for, so you could switch to any of those -methods if you feel the need to have a non-read-only @code{nndir}. +@lisp +(gnus-summary-line-format "%U%R%z %uD: %(%s%) (%ud)\n") +@end lisp +However, @code{gnus-diary} does it automatically (@pxref{Diary Group +Parameters}). You can however customize the provided summary line format +with the following user options: -@node Anything Groups -@subsection Anything Groups -@cindex nneething +@defvar gnus-diary-summary-line-format +Defines the summary line format used for diary groups (@pxref{Summary +Buffer Lines}). @code{gnus-diary} uses it to automatically update the +diary groups'parameters. +@end defvar -From the @code{nndir} back end (which reads a single spool-like -directory), it's just a hop and a skip to @code{nneething}, which -pretends that any arbitrary directory is a newsgroup. Strange, but -true. +@defvar gnus-diary-time-format +Defines the format to display dates in diary summary buffers. This is +used by the @code{D} user format. See the docstring for details. +@end defvar -When @code{nneething} is presented with a directory, it will scan this -directory and assign article numbers to each file. When you enter such -a group, @code{nneething} must create ``headers'' that Gnus can use. -After all, Gnus is a newsreader, in case you're forgetting. -@code{nneething} does this in a two-step process. First, it snoops each -file in question. If the file looks like an article (i.e., the first -few lines look like headers), it will use this as the head. If this is -just some arbitrary file without a head (e.g. a C source file), -@code{nneething} will cobble up a header out of thin air. It will use -file ownership, name and date and do whatever it can with these -elements. +@defvar gnus-diary-delay-format-function +Defines the format function to use for displaying delays (remaining +times) in diary summary buffers. This is used by the @code{d} user +format. There are currently built-in functions for English and French; +you can also define your own. See the docstring for details. +@end defvar -All this should happen automatically for you, and you will be presented -with something that looks very much like a newsgroup. Totally like a -newsgroup, to be precise. If you select an article, it will be displayed -in the article buffer, just as usual. +@node Diary Articles Sorting +@subsubsection Diary Articles Sorting +@cindex diary articles sorting +@cindex diary summary lines sorting +@findex gnus-summary-sort-by-schedule +@findex gnus-thread-sort-by-schedule +@findex gnus-article-sort-by-schedule -If you select a line that represents a directory, Gnus will pop you into -a new summary buffer for this @code{nneething} group. And so on. You can -traverse the entire disk this way, if you feel like, but remember that -Gnus is not dired, really, and does not intend to be, either. +@code{gnus-diary} provides new sorting functions (@pxref{Sorting the +Summary Buffer} ) called @code{gnus-summary-sort-by-schedule}, +@code{gnus-thread-sort-by-schedule} and +@code{gnus-article-sort-by-schedule}. These functions let you organize +your diary summary buffers from the closest event to the farthest one. -There are two overall modes to this action---ephemeral or solid. When -doing the ephemeral thing (i.e., @kbd{G D} from the group buffer), Gnus -will not store information on what files you have read, and what files -are new, and so on. If you create a solid @code{nneething} group the -normal way with @kbd{G m}, Gnus will store a mapping table between -article numbers and file names, and you can treat this group like any -other groups. When you activate a solid @code{nneething} group, you will -be told how many unread articles it contains, etc., etc. +@code{gnus-diary} automatically installs +@code{gnus-summary-sort-by-schedule} as a menu item in the summary +buffer's ``sort'' menu, and the two others as the primary (hence +default) sorting functions in the group parameters (@pxref{Diary Group +Parameters}). -Some variables: +@node Diary Headers Generation +@subsubsection Diary Headers Generation +@cindex diary headers generation +@findex gnus-diary-check-message -@table @code -@item nneething-map-file-directory -@vindex nneething-map-file-directory -All the mapping files for solid @code{nneething} groups will be stored -in this directory, which defaults to @file{~/.nneething/}. +@code{gnus-diary} provides a function called +@code{gnus-diary-check-message} to help you handle the @code{X-Diary-*} +headers. This function ensures that the current message contains all the +required diary headers, and prompts you for values or corrections if +needed. -@item nneething-exclude-files -@vindex nneething-exclude-files -All files that match this regexp will be ignored. Nice to use to exclude -auto-save files and the like, which is what it does by default. + This function is hooked into the @code{nndiary} back end, so that +moving or copying an article to a diary group will trigger it +automatically. It is also bound to @kbd{C-c C-f d} in +@code{message-mode} and @code{article-edit-mode} in order to ease the +process of converting a usual mail to a diary one. -@item nneething-include-files -@vindex nneething-include-files -Regexp saying what files to include in the group. If this variable is -non-@code{nil}, only files matching this regexp will be included. + This function takes a prefix argument which will force prompting of +all diary headers, regardless of their presence or validity. That way, +you can very easily reschedule an already valid diary message, for +instance. -@item nneething-map-file -@vindex nneething-map-file -Name of the map files. -@end table +@node Diary Group Parameters +@subsubsection Diary Group Parameters +@cindex diary group parameters + +When you create a new diary group, or visit one, @code{gnus-diary} +automatically checks your group parameters and if needed, sets the +summary line format to the diary-specific value, installs the +diary-specific sorting functions, and also adds the different +@code{X-Diary-*} headers to the group's posting-style. It is then easier +to send a diary message, because if you use @kbd{C-u a} or @kbd{C-u m} +on a diary group to prepare a message, these headers will be inserted +automatically (although not filled with proper values yet). + +@node Sending or Not Sending +@subsection Sending or Not Sending + +Well, assuming you've read all of the above, here are two final notes on +mail sending with @code{nndiary}: + +@itemize @bullet +@item +@code{nndiary} is a @emph{real} mail back end. You really send real diary +messsages for real. This means for instance that you can give +appointments to anybody (provided they use Gnus and @code{nndiary}) by +sending the diary message to them as well. +@item +However, since @code{nndiary} also has a @code{request-post} method, you +can also use @kbd{C-u a} instead of @kbd{C-u m} on a diary group and the +message won't actually be sent; just stored locally in the group. This +comes in very handy for private appointments. +@end itemize + +@node Gnus Unplugged +@section Gnus Unplugged +@cindex offline +@cindex unplugged +@cindex agent +@cindex Gnus agent +@cindex Gnus unplugged +In olden times (ca. February '88), people used to run their newsreaders +on big machines with permanent connections to the net. News transport +was dealt with by news servers, and all the newsreaders had to do was to +read news. Believe it or not. -@node Document Groups -@subsection Document Groups -@cindex nndoc -@cindex documentation group -@cindex help group +Nowadays most people read news and mail at home, and use some sort of +modem to connect to the net. To avoid running up huge phone bills, it +would be nice to have a way to slurp down all the news and mail, hang up +the phone, read for several hours, and then upload any responses you +have to make. And then you repeat the procedure. -@code{nndoc} is a cute little thing that will let you read a single file -as a newsgroup. Several files types are supported: +Of course, you can use news servers for doing this as well. I've used +@code{inn} together with @code{slurp}, @code{pop} and @code{sendmail} +for some years, but doing that's a bore. Moving the news server +functionality up to the newsreader makes sense if you're the only person +reading news on a machine. -@table @code -@cindex Babyl -@item babyl -The Babyl format. +Setting up Gnus as an ``offline'' newsreader is quite simple. In +fact, you don't have to configure anything as the agent is now enabled +by default (@pxref{Agent Variables, gnus-agent}). -@cindex mbox -@cindex Unix mbox -@item mbox -The standard Unix mbox file. +Of course, to use it as such, you have to learn a few new commands. -@cindex MMDF mail box -@item mmdf -The MMDF mail box format. +@menu +* Agent Basics:: How it all is supposed to work. +* Agent Categories:: How to tell the Gnus Agent what to download. +* Agent Commands:: New commands for all the buffers. +* Agent Visuals:: Ways that the agent may effect your summary buffer. +* Agent as Cache:: The Agent is a big cache too. +* Agent Expiry:: How to make old articles go away. +* Agent Regeneration:: How to recover from lost connections and other accidents. +* Agent and flags:: How the Agent maintains flags. +* Agent and IMAP:: How to use the Agent with @acronym{IMAP}. +* Outgoing Messages:: What happens when you post/mail something? +* Agent Variables:: Customizing is fun. +* Example Setup:: An example @file{~/.gnus.el} file for offline people. +* Batching Agents:: How to fetch news from a @code{cron} job. +* Agent Caveats:: What you think it'll do and what it does. +@end menu -@item news -Several news articles appended into a file. -@cindex rnews batch files -@item rnews -The rnews batch transport format. +@node Agent Basics +@subsection Agent Basics -@item nsmail -Netscape mail boxes. +First, let's get some terminology out of the way. -@item mime-parts -@acronym{MIME} multipart messages. +The Gnus Agent is said to be @dfn{unplugged} when you have severed the +connection to the net (and notified the Agent that this is the case). +When the connection to the net is up again (and Gnus knows this), the +Agent is @dfn{plugged}. -@item standard-digest -The standard (RFC 1153) digest format. +The @dfn{local} machine is the one you're running on, and which isn't +connected to the net continuously. -@item mime-digest -A @acronym{MIME} digest of messages. +@dfn{Downloading} means fetching things from the net to your local +machine. @dfn{Uploading} is doing the opposite. -@item lanl-gov-announce -Announcement messages from LANL Gov Announce. +You know that Gnus gives you all the opportunity you'd ever want for +shooting yourself in the foot. Some people call it flexibility. Gnus +is also customizable to a great extent, which means that the user has a +say on how Gnus behaves. Other newsreaders might unconditionally shoot +you in your foot, but with Gnus, you have a choice! -@cindex git commit messages -@item git -@code{git} commit messages. +Gnus is never really in plugged or unplugged state. Rather, it applies +that state to each server individually. This means that some servers +can be plugged while others can be unplugged. Additionally, some +servers can be ignored by the Agent altogether (which means that +they're kinda like plugged always). -@cindex forwarded messages -@item rfc822-forward -A message forwarded according to RFC822. +So when you unplug the Agent and then wonder why is Gnus opening a +connection to the Net, the next step to do is to look whether all +servers are agentized. If there is an unagentized server, you found +the culprit. -@item outlook -The Outlook mail box. +Another thing is the @dfn{offline} state. Sometimes, servers aren't +reachable. When Gnus notices this, it asks you whether you want the +server to be switched to offline state. If you say yes, then the +server will behave somewhat as if it was unplugged, except that Gnus +will ask you whether you want to switch it back online again. -@item oe-dbx -The Outlook Express dbx mail box. +Let's take a typical Gnus session using the Agent. -@item exim-bounce -A bounce message from the Exim MTA. +@itemize @bullet -@item forward -A message forwarded according to informal rules. +@item +@findex gnus-unplugged +You start Gnus with @code{gnus-unplugged}. This brings up the Gnus +Agent in a disconnected state. You can read all the news that you have +already fetched while in this mode. -@item rfc934 -An RFC934-forwarded message. +@item +You then decide to see whether any new news has arrived. You connect +your machine to the net (using PPP or whatever), and then hit @kbd{J j} +to make Gnus become @dfn{plugged} and use @kbd{g} to check for new mail +as usual. To check for new mail in unplugged mode (@pxref{Mail +Source Specifiers}). -@item mailman -A mailman digest. +@item +You can then read the new news immediately, or you can download the +news onto your local machine. If you want to do the latter, you press +@kbd{g} to check if there are any new news and then @kbd{J s} to fetch +all the eligible articles in all the groups. (To let Gnus know which +articles you want to download, @pxref{Agent Categories}). -@item clari-briefs -A digest of Clarinet brief news items. +@item +After fetching the articles, you press @kbd{J j} to make Gnus become +unplugged again, and you shut down the PPP thing (or whatever). And +then you read the news offline. -@item slack-digest -Non-standard digest format---matches most things, but does it badly. +@item +And then you go to step 2. +@end itemize -@item mail-in-mail -The last resort. -@end table +Here are some things you should do the first time (or so) that you use +the Agent. -You can also use the special ``file type'' @code{guess}, which means -that @code{nndoc} will try to guess what file type it is looking at. -@code{digest} means that @code{nndoc} should guess what digest type the -file is. +@itemize @bullet -@code{nndoc} will not try to change the file or insert any extra headers into -it---it will simply, like, let you use the file as the basis for a -group. And that's it. +@item +Decide which servers should be covered by the Agent. If you have a mail +back end, it would probably be nonsensical to have it covered by the +Agent. Go to the server buffer (@kbd{^} in the group buffer) and press +@kbd{J a} on the server (or servers) that you wish to have covered by the +Agent (@pxref{Server Agent Commands}), or @kbd{J r} on automatically +added servers you do not wish to have covered by the Agent. By default, +all @code{nntp} and @code{nnimap} servers in @code{gnus-select-method} and +@code{gnus-secondary-select-methods} are agentized. -If you have some old archived articles that you want to insert into your -new & spiffy Gnus mail back end, @code{nndoc} can probably help you with -that. Say you have an old @file{RMAIL} file with mail that you now want -to split into your new @code{nnml} groups. You look at that file using -@code{nndoc} (using the @kbd{G f} command in the group buffer -(@pxref{Foreign Groups})), set the process mark on all the articles in -the buffer (@kbd{M P b}, for instance), and then re-spool (@kbd{B r}) -using @code{nnml}. If all goes well, all the mail in the @file{RMAIL} -file is now also stored in lots of @code{nnml} directories, and you can -delete that pesky @file{RMAIL} file. If you have the guts! +@item +Decide on download policy. It's fairly simple once you decide whether +you are going to use agent categories, topic parameters, and/or group +parameters to implement your policy. If you're new to gnus, it +is probably best to start with a category, @xref{Agent Categories}. -Virtual server variables: +Both topic parameters (@pxref{Topic Parameters}) and agent categories +(@pxref{Agent Categories}) provide for setting a policy that applies +to multiple groups. Which you use is entirely up to you. Topic +parameters do override categories so, if you mix the two, you'll have +to take that into account. If you have a few groups that deviate from +your policy, you can use group parameters (@pxref{Group Parameters}) to +configure them. -@table @code -@item nndoc-article-type -@vindex nndoc-article-type -This should be one of @code{mbox}, @code{babyl}, @code{digest}, -@code{news}, @code{rnews}, @code{mmdf}, @code{forward}, @code{rfc934}, -@code{rfc822-forward}, @code{mime-parts}, @code{standard-digest}, -@code{slack-digest}, @code{clari-briefs}, @code{nsmail}, @code{outlook}, -@code{oe-dbx}, @code{mailman}, and @code{mail-in-mail} or @code{guess}. +@item +Uhm@dots{} that's it. +@end itemize -@item nndoc-post-type -@vindex nndoc-post-type -This variable says whether Gnus is to consider the group a news group or -a mail group. There are two valid values: @code{mail} (the default) -and @code{news}. -@end table -@menu -* Document Server Internals:: How to add your own document types. -@end menu +@node Agent Categories +@subsection Agent Categories +One of the main reasons to integrate the news transport layer into the +newsreader is to allow greater control over what articles to download. +There's not much point in downloading huge amounts of articles, just to +find out that you're not interested in reading any of them. It's better +to be somewhat more conservative in choosing what to download, and then +mark the articles for downloading manually if it should turn out that +you're interested in the articles anyway. -@node Document Server Internals -@subsubsection Document Server Internals +One of the more effective methods for controlling what is to be +downloaded is to create a @dfn{category} and then assign some (or all) +groups to this category. Groups that do not belong in any other +category belong to the @code{default} category. Gnus has its own +buffer for creating and managing categories. -Adding new document types to be recognized by @code{nndoc} isn't -difficult. You just have to whip up a definition of what the document -looks like, write a predicate function to recognize that document type, -and then hook into @code{nndoc}. +If you prefer, you can also use group parameters (@pxref{Group +Parameters}) and topic parameters (@pxref{Topic Parameters}) for an +alternative approach to controlling the agent. The only real +difference is that categories are specific to the agent (so there is +less to learn) while group and topic parameters include the kitchen +sink. -First, here's an example document type definition: +Since you can set agent parameters in several different places we have +a rule to decide which source to believe. This rule specifies that +the parameter sources are checked in the following order: group +parameters, topic parameters, agent category, and finally customizable +variables. So you can mix all of these sources to produce a wide range +of behavior, just don't blame me if you don't remember where you put +your settings. -@example -(mmdf - (article-begin . "^\^A\^A\^A\^A\n") - (body-end . "^\^A\^A\^A\^A\n")) -@end example +@menu +* Category Syntax:: What a category looks like. +* Category Buffer:: A buffer for maintaining categories. +* Category Variables:: Customize'r'Us. +@end menu -The definition is simply a unique @dfn{name} followed by a series of -regexp pseudo-variable settings. Below are the possible -variables---don't be daunted by the number of variables; most document -types can be defined with very few settings: +@node Category Syntax +@subsubsection Category Syntax + +A category consists of a name, the list of groups belonging to the +category, and a number of optional parameters that override the +customizable variables. The complete list of agent parameters are +listed below. + +@cindex Agent Parameters @table @code -@item first-article -If present, @code{nndoc} will skip past all text until it finds -something that match this regexp. All text before this will be -totally ignored. +@item agent-groups +The list of groups that are in this category. -@item article-begin -This setting has to be present in all document type definitions. It -says what the beginning of each article looks like. To do more -complicated things that cannot be dealt with a simple regexp, you can -use @code{article-begin-function} instead of this. +@item agent-predicate +A predicate which (generally) gives a rough outline of which articles +are eligible for downloading; and -@item article-begin-function -If present, this should be a function that moves point to the beginning -of each article. This setting overrides @code{article-begin}. +@item agent-score +a score rule which (generally) gives you a finer granularity when +deciding what articles to download. (Note that this @dfn{download +score} is not necessarily related to normal scores.) -@item head-begin -If present, this should be a regexp that matches the head of the -article. To do more complicated things that cannot be dealt with a -simple regexp, you can use @code{head-begin-function} instead of this. +@item agent-enable-expiration +a boolean indicating whether the agent should expire old articles in +this group. Most groups should be expired to conserve disk space. In +fact, its probably safe to say that the gnus.* hierarchy contains the +only groups that should not be expired. -@item head-begin-function -If present, this should be a function that moves point to the head of -the article. This setting overrides @code{head-begin}. +@item agent-days-until-old +an integer indicating the number of days that the agent should wait +before deciding that a read article is safe to expire. -@item head-end -This should match the end of the head of the article. It defaults to -@samp{^$}---the empty line. +@item agent-low-score +an integer that overrides the value of @code{gnus-agent-low-score}. -@item body-begin -This should match the beginning of the body of the article. It defaults -to @samp{^\n}. To do more complicated things that cannot be dealt with -a simple regexp, you can use @code{body-begin-function} instead of this. +@item agent-high-score +an integer that overrides the value of @code{gnus-agent-high-score}. -@item body-begin-function -If present, this function should move point to the beginning of the body -of the article. This setting overrides @code{body-begin}. +@item agent-short-article +an integer that overrides the value of +@code{gnus-agent-short-article}. -@item body-end -If present, this should match the end of the body of the article. To do -more complicated things that cannot be dealt with a simple regexp, you -can use @code{body-end-function} instead of this. +@item agent-long-article +an integer that overrides the value of @code{gnus-agent-long-article}. -@item body-end-function -If present, this function should move point to the end of the body of -the article. This setting overrides @code{body-end}. +@item agent-enable-undownloaded-faces +a symbol indicating whether the summary buffer should display +undownloaded articles using the @code{gnus-summary-*-undownloaded-face} +faces. Any symbol other than @code{nil} will enable the use of +undownloaded faces. +@end table -@item file-begin -If present, this should match the beginning of the file. All text -before this regexp will be totally ignored. +The name of a category can not be changed once the category has been +created. -@item file-end -If present, this should match the end of the file. All text after this -regexp will be totally ignored. +Each category maintains a list of groups that are exclusive members of +that category. The exclusivity rule is automatically enforced, add a +group to a new category and it is automatically removed from its old +category. -@end table +A predicate in its simplest form can be a single predicate such as +@code{true} or @code{false}. These two will download every available +article or nothing respectively. In the case of these two special +predicates an additional score rule is superfluous. -So, using these variables @code{nndoc} is able to dissect a document -file into a series of articles, each with a head and a body. However, a -few more variables are needed since not all document types are all that -news-like---variables needed to transform the head or the body into -something that's palatable for Gnus: +Predicates of @code{high} or @code{low} download articles in respect of +their scores in relationship to @code{gnus-agent-high-score} and +@code{gnus-agent-low-score} as described below. -@table @code -@item prepare-body-function -If present, this function will be called when requesting an article. It -will be called with point at the start of the body, and is useful if the -document has encoded some parts of its contents. +To gain even finer control of what is to be regarded eligible for +download a predicate can consist of a number of predicates with logical +operators sprinkled in between. -@item article-transform-function -If present, this function is called when requesting an article. It's -meant to be used for more wide-ranging transformation of both head and -body of the article. +Perhaps some examples are in order. -@item generate-head-function -If present, this function is called to generate a head that Gnus can -understand. It is called with the article number as a parameter, and is -expected to generate a nice head for the article in question. It is -called when requesting the headers of all articles. +Here's a simple predicate. (It's the default predicate, in fact, used +for all groups that don't belong to any other category.) -@item generate-article-function -If present, this function is called to generate an entire article that -Gnus can understand. It is called with the article number as a -parameter when requesting all articles. +@lisp +short +@end lisp -@item dissection-function -If present, this function is called to dissect a document by itself, -overriding @code{first-article}, @code{article-begin}, -@code{article-begin-function}, @code{head-begin}, -@code{head-begin-function}, @code{head-end}, @code{body-begin}, -@code{body-begin-function}, @code{body-end}, @code{body-end-function}, -@code{file-begin}, and @code{file-end}. +Quite simple, eh? This predicate is true if and only if the article is +short (for some value of ``short''). -@end table +Here's a more complex predicate: -Let's look at the most complicated example I can come up with---standard -digests: +@lisp +(or high + (and + (not low) + (not long))) +@end lisp -@example -(standard-digest - (first-article . ,(concat "^" (make-string 70 ?-) "\n\n+")) - (article-begin . ,(concat "\n\n" (make-string 30 ?-) "\n\n+")) - (prepare-body-function . nndoc-unquote-dashes) - (body-end-function . nndoc-digest-body-end) - (head-end . "^ ?$") - (body-begin . "^ ?\n") - (file-end . "^End of .*digest.*[0-9].*\n\\*\\*\\|^End of.*Digest *$") - (subtype digest guess)) -@end example +This means that an article should be downloaded if it has a high score, +or if the score is not low and the article is not long. You get the +drift. -We see that all text before a 70-width line of dashes is ignored; all -text after a line that starts with that @samp{^End of} is also ignored; -each article begins with a 30-width line of dashes; the line separating -the head from the body may contain a single space; and that the body is -run through @code{nndoc-unquote-dashes} before being delivered. +The available logical operators are @code{or}, @code{and} and +@code{not}. (If you prefer, you can use the more ``C''-ish operators +@samp{|}, @code{&} and @code{!} instead.) -To hook your own document definition into @code{nndoc}, use the -@code{nndoc-add-type} function. It takes two parameters---the first -is the definition itself and the second (optional) parameter says -where in the document type definition alist to put this definition. -The alist is traversed sequentially, and -@code{nndoc-@var{type}-type-p} is called for a given type @var{type}. -So @code{nndoc-mmdf-type-p} is called to see whether a document is of -@code{mmdf} type, and so on. These type predicates should return -@code{nil} if the document is not of the correct type; @code{t} if it -is of the correct type; and a number if the document might be of the -correct type. A high number means high probability; a low number -means low probability with @samp{0} being the lowest valid number. +The following predicates are pre-defined, but if none of these fit what +you want to do, you can write your own. + +When evaluating each of these predicates, the named constant will be +bound to the value determined by calling +@code{gnus-agent-find-parameter} on the appropriate parameter. For +example, gnus-agent-short-article will be bound to +@code{(gnus-agent-find-parameter group 'agent-short-article)}. This +means that you can specify a predicate in your category then tune that +predicate to individual groups. +@table @code +@item short +True if the article is shorter than @code{gnus-agent-short-article} +lines; default 100. -@node Mail-To-News Gateways -@subsection Mail-To-News Gateways -@cindex mail-to-news gateways -@cindex gateways +@item long +True if the article is longer than @code{gnus-agent-long-article} +lines; default 200. -If your local @code{nntp} server doesn't allow posting, for some reason -or other, you can post using one of the numerous mail-to-news gateways. -The @code{nngateway} back end provides the interface. +@item low +True if the article has a download score less than +@code{gnus-agent-low-score}; default 0. -Note that you can't read anything from this back end---it can only be -used to post with. +@item high +True if the article has a download score greater than +@code{gnus-agent-high-score}; default 0. -Server variables: +@item spam +True if the Gnus Agent guesses that the article is spam. The +heuristics may change over time, but at present it just computes a +checksum and sees whether articles match. -@table @code -@item nngateway-address -@vindex nngateway-address -This is the address of the mail-to-news gateway. +@item true +Always true. -@item nngateway-header-transformation -@vindex nngateway-header-transformation -News headers often have to be transformed in some odd way or other -for the mail-to-news gateway to accept it. This variable says what -transformation should be called, and defaults to -@code{nngateway-simple-header-transformation}. The function is called -narrowed to the headers to be transformed and with one parameter---the -gateway address. +@item false +Always false. +@end table -This default function just inserts a new @code{To} header based on the -@code{Newsgroups} header and the gateway address. -For instance, an article with this @code{Newsgroups} header: +If you want to create your own predicate function, here's what you have +to know: The functions are called with no parameters, but the +@code{gnus-headers} and @code{gnus-score} dynamic variables are bound to +useful values. -@example -Newsgroups: alt.religion.emacs -@end example +For example, you could decide that you don't want to download articles +that were posted more than a certain number of days ago (e.g. posted +more than @code{gnus-agent-expire-days} ago) you might write a function +something along the lines of the following: -will get this @code{To} header inserted: +@lisp +(defun my-article-old-p () + "Say whether an article is old." + (< (time-to-days (date-to-time (mail-header-date gnus-headers))) + (- (time-to-days (current-time)) gnus-agent-expire-days))) +@end lisp -@example -To: alt-religion-emacs@@GATEWAY -@end example +with the predicate then defined as: -The following pre-defined functions exist: +@lisp +(not my-article-old-p) +@end lisp -@findex nngateway-simple-header-transformation -@table @code +or you could append your predicate to the predefined +@code{gnus-category-predicate-alist} in your @file{~/.gnus.el} or +wherever. -@item nngateway-simple-header-transformation -Creates a @code{To} header that looks like -@var{newsgroup}@@@code{nngateway-address}. +@lisp +(require 'gnus-agent) +(setq gnus-category-predicate-alist + (append gnus-category-predicate-alist + '((old . my-article-old-p)))) +@end lisp -@findex nngateway-mail2news-header-transformation +and simply specify your predicate as: -@item nngateway-mail2news-header-transformation -Creates a @code{To} header that looks like -@code{nngateway-address}. -@end table +@lisp +(not old) +@end lisp -@end table +If/when using something like the above, be aware that there are many +misconfigured systems/mailers out there and so an article's date is not +always a reliable indication of when it was posted. Hell, some people +just don't give a damn. -Here's an example: +The above predicates apply to @emph{all} the groups which belong to the +category. However, if you wish to have a specific predicate for an +individual group within a category, or you're just too lazy to set up a +new category, you can enter a group's individual predicate in its group +parameters like so: @lisp -(setq gnus-post-method - '(nngateway - "mail2news@@replay.com" - (nngateway-header-transformation - nngateway-mail2news-header-transformation))) +(agent-predicate . short) @end lisp -So, to use this, simply say something like: +This is the group/topic parameter equivalent of the agent category default. +Note that when specifying a single word predicate like this, the +@code{agent-predicate} specification must be in dotted pair notation. + +The equivalent of the longer example from above would be: @lisp -(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS")) +(agent-predicate or high (and (not low) (not long))) @end lisp +The outer parenthesis required in the category specification are not +entered here as, not being in dotted pair notation, the value of the +predicate is assumed to be a list. -@node Combined Groups -@section Combined Groups - -Gnus allows combining a mixture of all the other group types into bigger -groups. +Now, the syntax of the download score is the same as the syntax of +normal score files, except that all elements that require actually +seeing the article itself are verboten. This means that only the +following headers can be scored on: @code{Subject}, @code{From}, +@code{Date}, @code{Message-ID}, @code{References}, @code{Chars}, +@code{Lines}, and @code{Xref}. -@menu -* Virtual Groups:: Combining articles from many groups. -@end menu +As with predicates, the specification of the @code{download score rule} +to use in respect of a group can be in either the category definition if +it's to be applicable to all groups in therein, or a group's parameters +if it's to be specific to that group. +In both of these places the @code{download score rule} can take one of +three forms: -@node Virtual Groups -@subsection Virtual Groups -@cindex nnvirtual -@cindex virtual groups -@cindex merging groups +@enumerate +@item +Score rule -An @dfn{nnvirtual group} is really nothing more than a collection of -other groups. +This has the same syntax as a normal Gnus score file except only a +subset of scoring keywords are available as mentioned above. -For instance, if you are tired of reading many small groups, you can -put them all in one big group, and then grow tired of reading one -big, unwieldy group. The joys of computing! +example: -You specify @code{nnvirtual} as the method. The address should be a -regexp to match component groups. +@itemize @bullet +@item +Category specification -All marks in the virtual group will stick to the articles in the -component groups. So if you tick an article in a virtual group, the -article will also be ticked in the component group from whence it -came. (And vice versa---marks from the component groups will also be -shown in the virtual group.). To create an empty virtual group, run -@kbd{G V} (@code{gnus-group-make-empty-virtual}) in the group buffer -and edit the method regexp with @kbd{M-e} -(@code{gnus-group-edit-group-method}) +@lisp +(("from" + ("Lars Ingebrigtsen" 1000000 nil s)) +("lines" + (500 -100 nil <))) +@end lisp -Here's an example @code{nnvirtual} method that collects all Andrea Dworkin -newsgroups into one, big, happy newsgroup: +@item +Group/Topic Parameter specification @lisp -(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*") +(agent-score ("from" + ("Lars Ingebrigtsen" 1000000 nil s)) + ("lines" + (500 -100 nil <))) @end lisp -The component groups can be native or foreign; everything should work -smoothly, but if your computer explodes, it was probably my fault. +Again, note the omission of the outermost parenthesis here. +@end itemize -Collecting the same group from several servers might actually be a good -idea if users have set the Distribution header to limit distribution. -If you would like to read @samp{soc.motss} both from a server in Japan -and a server in Norway, you could use the following as the group regexp: +@item +Agent score file -@example -"^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$" -@end example +These score files must @emph{only} contain the permitted scoring +keywords stated above. -(Remember, though, that if you're creating the group with @kbd{G m}, you -shouldn't double the backslashes, and you should leave off the quote -characters at the beginning and the end of the string.) +example: -This should work kinda smoothly---all articles from both groups should -end up in this one, and there should be no duplicates. Threading (and -the rest) will still work as usual, but there might be problems with the -sequence of articles. Sorting on date might be an option here -(@pxref{Selecting a Group}). +@itemize @bullet +@item +Category specification -One limitation, however---all groups included in a virtual -group have to be alive (i.e., subscribed or unsubscribed). Killed or -zombie groups can't be component groups for @code{nnvirtual} groups. +@lisp +("~/News/agent.SCORE") +@end lisp -@vindex nnvirtual-always-rescan -If the @code{nnvirtual-always-rescan} variable is non-@code{nil} (which -is the default), @code{nnvirtual} will always scan groups for unread -articles when entering a virtual group. If this variable is @code{nil} -and you read articles in a component group after the virtual group has -been activated, the read articles from the component group will show up -when you enter the virtual group. You'll also see this effect if you -have two virtual groups that have a component group in common. If -that's the case, you should set this variable to @code{t}. Or you can -just tap @code{M-g} on the virtual group every time before you enter -it---it'll have much the same effect. +or perhaps -@code{nnvirtual} can have both mail and news groups as component groups. -When responding to articles in @code{nnvirtual} groups, @code{nnvirtual} -has to ask the back end of the component group the article comes from -whether it is a news or mail back end. However, when you do a @kbd{^}, -there is typically no sure way for the component back end to know this, -and in that case @code{nnvirtual} tells Gnus that the article came from a -not-news back end. (Just to be on the safe side.) +@lisp +("~/News/agent.SCORE" "~/News/agent.group.SCORE") +@end lisp -@kbd{C-c C-n} in the message buffer will insert the @code{Newsgroups} -line from the article you respond to in these cases. +@item +Group Parameter specification -@code{nnvirtual} groups do not inherit anything but articles and marks -from component groups---group parameters, for instance, are not -inherited. +@lisp +(agent-score "~/News/agent.SCORE") +@end lisp +Additional score files can be specified as above. Need I say anything +about parenthesis? +@end itemize -@node Email Based Diary -@section Email Based Diary -@cindex diary -@cindex email based diary -@cindex calendar +@item +Use @code{normal} score files -This section describes a special mail back end called @code{nndiary}, -and its companion library @code{gnus-diary}. It is ``special'' in the -sense that it is not meant to be one of the standard alternatives for -reading mail with Gnus. See @ref{Choosing a Mail Back End} for that. -Instead, it is used to treat @emph{some} of your mails in a special way, -namely, as event reminders. +If you don't want to maintain two sets of scoring rules for a group, and +your desired @code{downloading} criteria for a group are the same as your +@code{reading} criteria then you can tell the agent to refer to your +@code{normal} score files when deciding what to download. -Here is a typical scenario: +These directives in either the category definition or a group's +parameters will cause the agent to read in all the applicable score +files for a group, @emph{filtering out} those sections that do not +relate to one of the permitted subset of scoring keywords. @itemize @bullet @item -You've got a date with Andy Mc Dowell or Bruce Willis (select according -to your sexual preference) in one month. You don't want to forget it. -@item -So you send a ``reminder'' message (actually, a diary one) to yourself. -@item -You forget all about it and keep on getting and reading new mail, as usual. -@item -From time to time, as you type `g' in the group buffer and as the date -is getting closer, the message will pop up again to remind you of your -appointment, just as if it were new and unread. -@item -Read your ``new'' messages, this one included, and start dreaming again -of the night you're gonna have. +Category Specification + +@lisp +file +@end lisp + @item -Once the date is over (you actually fell asleep just after dinner), the -message will be automatically deleted if it is marked as expirable. +Group Parameter specification + +@lisp +(agent-score . file) +@end lisp @end itemize +@end enumerate + +@node Category Buffer +@subsubsection Category Buffer + +You'd normally do all category maintenance from the category buffer. +When you enter it for the first time (with the @kbd{J c} command from +the group buffer), you'll only see the @code{default} category. + +The following commands are available in this buffer: -The Gnus Diary back end has the ability to handle regular appointments -(that wouldn't ever be deleted) as well as punctual ones, operates as a -real mail back end and is configurable in many ways. All of this is -explained in the sections below. +@table @kbd +@item q +@kindex q (Category) +@findex gnus-category-exit +Return to the group buffer (@code{gnus-category-exit}). -@menu -* The NNDiary Back End:: Basic setup and usage. -* The Gnus Diary Library:: Utility toolkit on top of nndiary. -* Sending or Not Sending:: A final note on sending diary messages. -@end menu +@item e +@kindex e (Category) +@findex gnus-category-customize-category +Use a customization buffer to set all of the selected category's +parameters at one time (@code{gnus-category-customize-category}). +@item k +@kindex k (Category) +@findex gnus-category-kill +Kill the current category (@code{gnus-category-kill}). -@node The NNDiary Back End -@subsection The NNDiary Back End -@cindex nndiary -@cindex the nndiary back end +@item c +@kindex c (Category) +@findex gnus-category-copy +Copy the current category (@code{gnus-category-copy}). -@code{nndiary} is a back end very similar to @code{nnml} (@pxref{Mail -Spool}). Actually, it could appear as a mix of @code{nnml} and -@code{nndraft}. If you know @code{nnml}, you're already familiar with -the message storing scheme of @code{nndiary}: one file per message, one -directory per group. +@item a +@kindex a (Category) +@findex gnus-category-add +Add a new category (@code{gnus-category-add}). - Before anything, there is one requirement to be able to run -@code{nndiary} properly: you @emph{must} use the group timestamp feature -of Gnus. This adds a timestamp to each group's parameters. @ref{Group -Timestamp} to see how it's done. +@item p +@kindex p (Category) +@findex gnus-category-edit-predicate +Edit the predicate of the current category +(@code{gnus-category-edit-predicate}). -@menu -* Diary Messages:: What makes a message valid for nndiary. -* Running NNDiary:: NNDiary has two modes of operation. -* Customizing NNDiary:: Bells and whistles. -@end menu +@item g +@kindex g (Category) +@findex gnus-category-edit-groups +Edit the list of groups belonging to the current category +(@code{gnus-category-edit-groups}). -@node Diary Messages -@subsubsection Diary Messages -@cindex nndiary messages -@cindex nndiary mails +@item s +@kindex s (Category) +@findex gnus-category-edit-score +Edit the download score rule of the current category +(@code{gnus-category-edit-score}). -@code{nndiary} messages are just normal ones, except for the mandatory -presence of 7 special headers. These headers are of the form -@code{X-Diary-}, @code{} being one of -@code{Minute}, @code{Hour}, @code{Dom}, @code{Month}, @code{Year}, -@code{Time-Zone} and @code{Dow}. @code{Dom} means ``Day of Month'', and -@code{dow} means ``Day of Week''. These headers actually behave like -crontab specifications and define the event date(s): +@item l +@kindex l (Category) +@findex gnus-category-list +List all the categories (@code{gnus-category-list}). +@end table -@itemize @bullet -@item -For all headers except the @code{Time-Zone} one, a header value is -either a star (meaning all possible values), or a list of fields -(separated by a comma). -@item -A field is either an integer, or a range. -@item -A range is two integers separated by a dash. -@item -Possible integer values are 0--59 for @code{Minute}, 0--23 for -@code{Hour}, 1--31 for @code{Dom}, 1--12 for @code{Month}, above 1971 -for @code{Year} and 0--6 for @code{Dow} (0 meaning Sunday). -@item -As a special case, a star in either @code{Dom} or @code{Dow} doesn't -mean ``all possible values'', but ``use only the other field''. Note -that if both are star'ed, the use of either one gives the same result. -@item -The @code{Time-Zone} header is special in that it can only have one -value (@code{GMT}, for instance). A star doesn't mean ``all possible -values'' (because it makes no sense), but ``the current local time -zone''. Most of the time, you'll be using a star here. However, for a -list of available time zone values, see the variable -@code{nndiary-headers}. -@end itemize -As a concrete example, here are the diary headers to add to your message -for specifying ``Each Monday and each 1st of month, at 12:00, 20:00, -21:00, 22:00, 23:00 and 24:00, from 1999 to 2010'' (I'll let you find -what to do then): +@node Category Variables +@subsubsection Category Variables -@example -X-Diary-Minute: 0 -X-Diary-Hour: 12, 20-24 -X-Diary-Dom: 1 -X-Diary-Month: * -X-Diary-Year: 1999-2010 -X-Diary-Dow: 1 -X-Diary-Time-Zone: * -@end example +@table @code +@item gnus-category-mode-hook +@vindex gnus-category-mode-hook +Hook run in category buffers. -@node Running NNDiary -@subsubsection Running NNDiary -@cindex running nndiary -@cindex nndiary operation modes +@item gnus-category-line-format +@vindex gnus-category-line-format +Format of the lines in the category buffer (@pxref{Formatting +Variables}). Valid elements are: -@code{nndiary} has two modes of operation: ``traditional'' (the default) -and ``autonomous''. In traditional mode, @code{nndiary} does not get new -mail by itself. You have to move (@kbd{B m}) or copy (@kbd{B c}) mails -from your primary mail back end to nndiary groups in order to handle them -as diary messages. In autonomous mode, @code{nndiary} retrieves its own -mail and handles it independently from your primary mail back end. +@table @samp +@item c +The name of the category. -One should note that Gnus is not inherently designed to allow several -``master'' mail back ends at the same time. However, this does make -sense with @code{nndiary}: you really want to send and receive diary -messages to your diary groups directly. So, @code{nndiary} supports -being sort of a ``second primary mail back end'' (to my knowledge, it is -the only back end offering this feature). However, there is a limitation -(which I hope to fix some day): respooling doesn't work in autonomous -mode. +@item g +The number of groups in the category. +@end table -In order to use @code{nndiary} in autonomous mode, you have several -things to do: +@item gnus-category-mode-line-format +@vindex gnus-category-mode-line-format +Format of the category mode line (@pxref{Mode Line Formatting}). -@itemize @bullet -@item -Allow @code{nndiary} to retrieve new mail by itself. Put the following -line in your @file{~/.gnus.el} file: +@item gnus-agent-short-article +@vindex gnus-agent-short-article +Articles that have fewer lines than this are short. Default 100. -@lisp -(setq nndiary-get-new-mail t) -@end lisp -@item -You must arrange for diary messages (those containing @code{X-Diary-*} -headers) to be split in a private folder @emph{before} Gnus treat them. -Again, this is needed because Gnus cannot (yet ?) properly handle -multiple primary mail back ends. Getting those messages from a separate -source will compensate this misfeature to some extent. +@item gnus-agent-long-article +@vindex gnus-agent-long-article +Articles that have more lines than this are long. Default 200. -As an example, here's my procmailrc entry to store diary files in -@file{~/.nndiary} (the default @code{nndiary} mail source file): +@item gnus-agent-low-score +@vindex gnus-agent-low-score +Articles that have a score lower than this have a low score. Default +0. -@example -:0 HD : -* ^X-Diary -.nndiary -@end example -@end itemize +@item gnus-agent-high-score +@vindex gnus-agent-high-score +Articles that have a score higher than this have a high score. Default +0. -Once this is done, you might want to customize the following two options -that affect the diary mail retrieval and splitting processes: +@item gnus-agent-expire-days +@vindex gnus-agent-expire-days +The number of days that a @samp{read} article must stay in the agent's +local disk before becoming eligible for expiration (While the name is +the same, this doesn't mean expiring the article on the server. It +just means deleting the local copy of the article). What is also +important to understand is that the counter starts with the time the +article was written to the local disk and not the time the article was +read. +Default 7. -@defvar nndiary-mail-sources -This is the diary-specific replacement for the standard -@code{mail-sources} variable. It obeys the same syntax, and defaults to -@code{(file :path "~/.nndiary")}. -@end defvar +@item gnus-agent-enable-expiration +@vindex gnus-agent-enable-expiration +Determines whether articles in a group are, by default, expired or +retained indefinitely. The default is @code{ENABLE} which means that +you'll have to disable expiration when desired. On the other hand, +you could set this to @code{DISABLE}. In that case, you would then +have to enable expiration in selected groups. -@defvar nndiary-split-methods -This is the diary-specific replacement for the standard -@code{nnmail-split-methods} variable. It obeys the same syntax. -@end defvar +@end table - Finally, you may add a permanent @code{nndiary} virtual server -(something like @code{(nndiary "diary")} should do) to your -@code{gnus-secondary-select-methods}. - Hopefully, almost everything (see the TODO section in -@file{nndiary.el}) will work as expected when you restart Gnus: in -autonomous mode, typing @kbd{g} and @kbd{M-g} in the group buffer, will -also get your new diary mails and split them according to your -diary-specific rules, @kbd{F} will find your new diary groups etc. +@node Agent Commands +@subsection Agent Commands +@findex gnus-agent-toggle-plugged +@kindex J j (Agent) -@node Customizing NNDiary -@subsubsection Customizing NNDiary -@cindex customizing nndiary -@cindex nndiary customization +All the Gnus Agent commands are on the @kbd{J} submap. The @kbd{J j} +(@code{gnus-agent-toggle-plugged}) command works in all modes, and +toggles the plugged/unplugged state of the Gnus Agent. -Now that @code{nndiary} is up and running, it's time to customize it. -The custom group is called @code{nndiary} (no, really ?!). You should -browse it to figure out which options you'd like to tweak. The following -two variables are probably the only ones you will want to change: -@defvar nndiary-reminders -This is the list of times when you want to be reminded of your -appointments (e.g. 3 weeks before, then 2 days before, then 1 hour -before and that's it). Remember that ``being reminded'' means that the -diary message will pop up as brand new and unread again when you get new -mail. -@end defvar +@menu +* Group Agent Commands:: Configure groups and fetch their contents. +* Summary Agent Commands:: Manually select then fetch specific articles. +* Server Agent Commands:: Select the servers that are supported by the agent. +@end menu -@defvar nndiary-week-starts-on-monday -Rather self-explanatory. Otherwise, Sunday is assumed (this is the -default). -@end defvar -@node The Gnus Diary Library -@subsection The Gnus Diary Library -@cindex gnus-diary -@cindex the gnus diary library -Using @code{nndiary} manually (I mean, writing the headers by hand and -so on) would be rather boring. Fortunately, there is a library called -@code{gnus-diary} written on top of @code{nndiary}, that does many -useful things for you. +@node Group Agent Commands +@subsubsection Group Agent Commands - In order to use it, add the following line to your @file{~/.gnus.el} file: +@table @kbd +@item J u +@kindex J u (Agent Group) +@findex gnus-agent-fetch-groups +Fetch all eligible articles in the current group +(@code{gnus-agent-fetch-groups}). -@lisp -(require 'gnus-diary) -@end lisp +@item J c +@kindex J c (Agent Group) +@findex gnus-enter-category-buffer +Enter the Agent category buffer (@code{gnus-enter-category-buffer}). - Also, you shouldn't use any @code{gnus-user-format-function-[d|D]} -(@pxref{Summary Buffer Lines}). @code{gnus-diary} provides both of these -(sorry if you used them before). +@item J s +@kindex J s (Agent Group) +@findex gnus-agent-fetch-session +Fetch all eligible articles in all groups +(@code{gnus-agent-fetch-session}). +@item J S +@kindex J S (Agent Group) +@findex gnus-group-send-queue +Send all sendable messages in the queue group +(@code{gnus-group-send-queue}). @xref{Drafts}. -@menu -* Diary Summary Line Format:: A nicer summary buffer line format. -* Diary Articles Sorting:: A nicer way to sort messages. -* Diary Headers Generation:: Not doing it manually. -* Diary Group Parameters:: Not handling them manually. -@end menu +@item J a +@kindex J a (Agent Group) +@findex gnus-agent-add-group +Add the current group to an Agent category +(@code{gnus-agent-add-group}). This command understands the +process/prefix convention (@pxref{Process/Prefix}). -@node Diary Summary Line Format -@subsubsection Diary Summary Line Format -@cindex diary summary buffer line -@cindex diary summary line format +@item J r +@kindex J r (Agent Group) +@findex gnus-agent-remove-group +Remove the current group from its category, if any +(@code{gnus-agent-remove-group}). This command understands the +process/prefix convention (@pxref{Process/Prefix}). -Displaying diary messages in standard summary line format (usually -something like @samp{From Joe: Subject}) is pretty useless. Most of -the time, you're the one who wrote the message, and you mostly want to -see the event's date. +@item J Y +@kindex J Y (Agent Group) +@findex gnus-agent-synchronize-flags +Synchronize flags changed while unplugged with remote server, if any. - @code{gnus-diary} provides two supplemental user formats to be used in -summary line formats. @code{D} corresponds to a formatted time string -for the next occurrence of the event (e.g. ``Sat, Sep 22 01, 12:00''), -while @code{d} corresponds to an approximative remaining time until the -next occurrence of the event (e.g. ``in 6 months, 1 week''). - For example, here's how Joe's birthday is displayed in my -@code{nndiary+diary:birthdays} summary buffer (note that the message is -expirable, but will never be deleted, as it specifies a periodic event): +@end table -@example - E Sat, Sep 22 01, 12:00: Joe's birthday (in 6 months, 1 week) -@end example -In order to get something like the above, you would normally add the -following line to your diary groups'parameters: +@node Summary Agent Commands +@subsubsection Summary Agent Commands -@lisp -(gnus-summary-line-format "%U%R%z %uD: %(%s%) (%ud)\n") -@end lisp +@table @kbd +@item J # +@kindex J # (Agent Summary) +@findex gnus-agent-mark-article +Mark the article for downloading (@code{gnus-agent-mark-article}). -However, @code{gnus-diary} does it automatically (@pxref{Diary Group -Parameters}). You can however customize the provided summary line format -with the following user options: +@item J M-# +@kindex J M-# (Agent Summary) +@findex gnus-agent-unmark-article +Remove the downloading mark from the article +(@code{gnus-agent-unmark-article}). -@defvar gnus-diary-summary-line-format -Defines the summary line format used for diary groups (@pxref{Summary -Buffer Lines}). @code{gnus-diary} uses it to automatically update the -diary groups'parameters. -@end defvar +@cindex % +@item @@ +@kindex @@ (Agent Summary) +@findex gnus-agent-toggle-mark +Toggle whether to download the article +(@code{gnus-agent-toggle-mark}). The download mark is @samp{%} by +default. -@defvar gnus-diary-time-format -Defines the format to display dates in diary summary buffers. This is -used by the @code{D} user format. See the docstring for details. -@end defvar +@item J c +@kindex J c (Agent Summary) +@findex gnus-agent-catchup +Mark all articles as read (@code{gnus-agent-catchup}) that are neither cached, downloaded, nor downloadable. -@defvar gnus-diary-delay-format-function -Defines the format function to use for displaying delays (remaining -times) in diary summary buffers. This is used by the @code{d} user -format. There are currently built-in functions for English and French; -you can also define your own. See the docstring for details. -@end defvar +@item J S +@kindex J S (Agent Summary) +@findex gnus-agent-fetch-group +Download all eligible (@pxref{Agent Categories}) articles in this group. +(@code{gnus-agent-fetch-group}). -@node Diary Articles Sorting -@subsubsection Diary Articles Sorting -@cindex diary articles sorting -@cindex diary summary lines sorting -@findex gnus-summary-sort-by-schedule -@findex gnus-thread-sort-by-schedule -@findex gnus-article-sort-by-schedule +@item J s +@kindex J s (Agent Summary) +@findex gnus-agent-summary-fetch-series +Download all processable articles in this group. +(@code{gnus-agent-summary-fetch-series}). -@code{gnus-diary} provides new sorting functions (@pxref{Sorting the -Summary Buffer} ) called @code{gnus-summary-sort-by-schedule}, -@code{gnus-thread-sort-by-schedule} and -@code{gnus-article-sort-by-schedule}. These functions let you organize -your diary summary buffers from the closest event to the farthest one. +@item J u +@kindex J u (Agent Summary) +@findex gnus-agent-summary-fetch-group +Download all downloadable articles in the current group +(@code{gnus-agent-summary-fetch-group}). -@code{gnus-diary} automatically installs -@code{gnus-summary-sort-by-schedule} as a menu item in the summary -buffer's ``sort'' menu, and the two others as the primary (hence -default) sorting functions in the group parameters (@pxref{Diary Group -Parameters}). +@end table -@node Diary Headers Generation -@subsubsection Diary Headers Generation -@cindex diary headers generation -@findex gnus-diary-check-message -@code{gnus-diary} provides a function called -@code{gnus-diary-check-message} to help you handle the @code{X-Diary-*} -headers. This function ensures that the current message contains all the -required diary headers, and prompts you for values or corrections if -needed. +@node Server Agent Commands +@subsubsection Server Agent Commands - This function is hooked into the @code{nndiary} back end, so that -moving or copying an article to a diary group will trigger it -automatically. It is also bound to @kbd{C-c C-f d} in -@code{message-mode} and @code{article-edit-mode} in order to ease the -process of converting a usual mail to a diary one. +@table @kbd +@item J a +@kindex J a (Agent Server) +@findex gnus-agent-add-server +Add the current server to the list of servers covered by the Gnus Agent +(@code{gnus-agent-add-server}). - This function takes a prefix argument which will force prompting of -all diary headers, regardless of their presence or validity. That way, -you can very easily reschedule an already valid diary message, for -instance. +@item J r +@kindex J r (Agent Server) +@findex gnus-agent-remove-server +Remove the current server from the list of servers covered by the Gnus +Agent (@code{gnus-agent-remove-server}). -@node Diary Group Parameters -@subsubsection Diary Group Parameters -@cindex diary group parameters +@end table -When you create a new diary group, or visit one, @code{gnus-diary} -automatically checks your group parameters and if needed, sets the -summary line format to the diary-specific value, installs the -diary-specific sorting functions, and also adds the different -@code{X-Diary-*} headers to the group's posting-style. It is then easier -to send a diary message, because if you use @kbd{C-u a} or @kbd{C-u m} -on a diary group to prepare a message, these headers will be inserted -automatically (although not filled with proper values yet). -@node Sending or Not Sending -@subsection Sending or Not Sending +@node Agent Visuals +@subsection Agent Visuals -Well, assuming you've read all of the above, here are two final notes on -mail sending with @code{nndiary}: +If you open a summary while unplugged and, Gnus knows from the group's +active range that there are more articles than the headers currently +stored in the Agent, you may see some articles whose subject looks +something like @samp{[Undownloaded article #####]}. These are +placeholders for the missing headers. Aside from setting a mark, +there is not much that can be done with one of these placeholders. +When Gnus finally gets a chance to fetch the group's headers, the +placeholders will automatically be replaced by the actual headers. +You can configure the summary buffer's maneuvering to skip over the +placeholders if you care (See @code{gnus-auto-goto-ignores}). -@itemize @bullet -@item -@code{nndiary} is a @emph{real} mail back end. You really send real diary -messsages for real. This means for instance that you can give -appointments to anybody (provided they use Gnus and @code{nndiary}) by -sending the diary message to them as well. -@item -However, since @code{nndiary} also has a @code{request-post} method, you -can also use @kbd{C-u a} instead of @kbd{C-u m} on a diary group and the -message won't actually be sent; just stored locally in the group. This -comes in very handy for private appointments. -@end itemize +While it may be obvious to all, the only headers and articles +available while unplugged are those headers and articles that were +fetched into the Agent while previously plugged. To put it another +way, ``If you forget to fetch something while plugged, you might have a +less than satisfying unplugged session''. For this reason, the Agent +adds two visual effects to your summary buffer. These effects display +the download status of each article so that you always know which +articles will be available when unplugged. + +The first visual effect is the @samp{%O} spec. If you customize +@code{gnus-summary-line-format} to include this specifier, you will add +a single character field that indicates an article's download status. +Articles that have been fetched into either the Agent or the Cache, +will display @code{gnus-downloaded-mark} (defaults to @samp{+}). All +other articles will display @code{gnus-undownloaded-mark} (defaults to +@samp{-}). If you open a group that has not been agentized, a space +(@samp{ }) will be displayed. + +The second visual effect are the undownloaded faces. The faces, there +are three indicating the article's score (low, normal, high), seem to +result in a love/hate response from many Gnus users. The problem is +that the face selection is controlled by a list of condition tests and +face names (See @code{gnus-summary-highlight}). Each condition is +tested in the order in which it appears in the list so early +conditions have precedence over later conditions. All of this means +that, if you tick an undownloaded article, the article will continue +to be displayed in the undownloaded face rather than the ticked face. -@node Gnus Unplugged -@section Gnus Unplugged -@cindex offline -@cindex unplugged -@cindex agent -@cindex Gnus agent -@cindex Gnus unplugged +If you use the Agent as a cache (to avoid downloading the same article +each time you visit it or to minimize your connection time), the +undownloaded face will probably seem like a good idea. The reason +being that you do all of our work (marking, reading, deleting) with +downloaded articles so the normal faces always appear. For those +users using the agent to improve online performance by caching the NOV +database (most users since 5.10.2), the undownloaded faces may appear +to be an absolutely horrible idea. The issue being that, since none +of their articles have been fetched into the Agent, all of the +normal faces will be obscured by the undownloaded faces. -In olden times (ca. February '88), people used to run their newsreaders -on big machines with permanent connections to the net. News transport -was dealt with by news servers, and all the newsreaders had to do was to -read news. Believe it or not. +If you would like to use the undownloaded faces, you must enable the +undownloaded faces by setting the @code{agent-enable-undownloaded-faces} +group parameter to @code{t}. This parameter, like all other agent +parameters, may be set on an Agent Category (@pxref{Agent Categories}), +a Group Topic (@pxref{Topic Parameters}), or an individual group +(@pxref{Group Parameters}). -Nowadays most people read news and mail at home, and use some sort of -modem to connect to the net. To avoid running up huge phone bills, it -would be nice to have a way to slurp down all the news and mail, hang up -the phone, read for several hours, and then upload any responses you -have to make. And then you repeat the procedure. +The one problem common to all users using the agent is how quickly it +can consume disk space. If you using the agent on many groups, it is +even more difficult to effectively recover disk space. One solution +is the @samp{%F} format available in @code{gnus-group-line-format}. +This format will display the actual disk space used by articles +fetched into both the agent and cache. By knowing which groups use +the most space, users know where to focus their efforts when ``agent +expiring'' articles. -Of course, you can use news servers for doing this as well. I've used -@code{inn} together with @code{slurp}, @code{pop} and @code{sendmail} -for some years, but doing that's a bore. Moving the news server -functionality up to the newsreader makes sense if you're the only person -reading news on a machine. +@node Agent as Cache +@subsection Agent as Cache -Setting up Gnus as an ``offline'' newsreader is quite simple. In -fact, you don't have to configure anything as the agent is now enabled -by default (@pxref{Agent Variables, gnus-agent}). +When Gnus is plugged, it is not efficient to download headers or +articles from the server again, if they are already stored in the +Agent. So, Gnus normally only downloads headers once, and stores them +in the Agent. These headers are later used when generating the summary +buffer, regardless of whether you are plugged or unplugged. Articles +are not cached in the Agent by default though (that would potentially +consume lots of disk space), but if you have already downloaded an +article into the Agent, Gnus will not download the article from the +server again but use the locally stored copy instead. -Of course, to use it as such, you have to learn a few new commands. +If you so desire, you can configure the agent (see @code{gnus-agent-cache} +@pxref{Agent Variables}) to always download headers and articles while +plugged. Gnus will almost certainly be slower, but it will be kept +synchronized with the server. That last point probably won't make any +sense if you are using a nntp or nnimap back end. -@menu -* Agent Basics:: How it all is supposed to work. -* Agent Categories:: How to tell the Gnus Agent what to download. -* Agent Commands:: New commands for all the buffers. -* Agent Visuals:: Ways that the agent may effect your summary buffer. -* Agent as Cache:: The Agent is a big cache too. -* Agent Expiry:: How to make old articles go away. -* Agent Regeneration:: How to recover from lost connections and other accidents. -* Agent and flags:: How the Agent maintains flags. -* Agent and IMAP:: How to use the Agent with @acronym{IMAP}. -* Outgoing Messages:: What happens when you post/mail something? -* Agent Variables:: Customizing is fun. -* Example Setup:: An example @file{~/.gnus.el} file for offline people. -* Batching Agents:: How to fetch news from a @code{cron} job. -* Agent Caveats:: What you think it'll do and what it does. -@end menu +@node Agent Expiry +@subsection Agent Expiry +@vindex gnus-agent-expire-days +@findex gnus-agent-expire +@kindex M-x gnus-agent-expire +@kindex M-x gnus-agent-expire-group +@findex gnus-agent-expire-group +@cindex agent expiry +@cindex Gnus agent expiry +@cindex expiry, in Gnus agent -@node Agent Basics -@subsection Agent Basics +The Agent back end, @code{nnagent}, doesn't handle expiry. Well, at +least it doesn't handle it like other back ends. Instead, there are +special @code{gnus-agent-expire} and @code{gnus-agent-expire-group} +commands that will expire all read articles that are older than +@code{gnus-agent-expire-days} days. They can be run whenever you feel +that you're running out of space. Neither are particularly fast or +efficient, and it's not a particularly good idea to interrupt them (with +@kbd{C-g} or anything else) once you've started one of them. -First, let's get some terminology out of the way. +Note that other functions, e.g. @code{gnus-request-expire-articles}, +might run @code{gnus-agent-expire} for you to keep the agent +synchronized with the group. -The Gnus Agent is said to be @dfn{unplugged} when you have severed the -connection to the net (and notified the Agent that this is the case). -When the connection to the net is up again (and Gnus knows this), the -Agent is @dfn{plugged}. +The agent parameter @code{agent-enable-expiration} may be used to +prevent expiration in selected groups. -The @dfn{local} machine is the one you're running on, and which isn't -connected to the net continuously. +@vindex gnus-agent-expire-all +If @code{gnus-agent-expire-all} is non-@code{nil}, the agent +expiration commands will expire all articles---unread, read, ticked +and dormant. If @code{nil} (which is the default), only read articles +are eligible for expiry, and unread, ticked and dormant articles will +be kept indefinitely. -@dfn{Downloading} means fetching things from the net to your local -machine. @dfn{Uploading} is doing the opposite. +If you find that some articles eligible for expiry are never expired, +perhaps some Gnus Agent files are corrupted. There's are special +commands, @code{gnus-agent-regenerate} and +@code{gnus-agent-regenerate-group}, to fix possible problems. -You know that Gnus gives you all the opportunity you'd ever want for -shooting yourself in the foot. Some people call it flexibility. Gnus -is also customizable to a great extent, which means that the user has a -say on how Gnus behaves. Other newsreaders might unconditionally shoot -you in your foot, but with Gnus, you have a choice! +@node Agent Regeneration +@subsection Agent Regeneration -Gnus is never really in plugged or unplugged state. Rather, it applies -that state to each server individually. This means that some servers -can be plugged while others can be unplugged. Additionally, some -servers can be ignored by the Agent altogether (which means that -they're kinda like plugged always). +@cindex agent regeneration +@cindex Gnus agent regeneration +@cindex regeneration -So when you unplug the Agent and then wonder why is Gnus opening a -connection to the Net, the next step to do is to look whether all -servers are agentized. If there is an unagentized server, you found -the culprit. +The local data structures used by @code{nnagent} may become corrupted +due to certain exceptional conditions. When this happens, +@code{nnagent} functionality may degrade or even fail. The solution +to this problem is to repair the local data structures by removing all +internal inconsistencies. -Another thing is the @dfn{offline} state. Sometimes, servers aren't -reachable. When Gnus notices this, it asks you whether you want the -server to be switched to offline state. If you say yes, then the -server will behave somewhat as if it was unplugged, except that Gnus -will ask you whether you want to switch it back online again. +For example, if your connection to your server is lost while +downloaded articles into the agent, the local data structures will not +know about articles successfully downloaded prior to the connection +failure. Running @code{gnus-agent-regenerate} or +@code{gnus-agent-regenerate-group} will update the data structures +such that you don't need to download these articles a second time. -Let's take a typical Gnus session using the Agent. +@findex gnus-agent-regenerate +@kindex M-x gnus-agent-regenerate +The command @code{gnus-agent-regenerate} will perform +@code{gnus-agent-regenerate-group} on every agentized group. While +you can run @code{gnus-agent-regenerate} in any buffer, it is strongly +recommended that you first close all summary buffers. -@itemize @bullet +@findex gnus-agent-regenerate-group +@kindex M-x gnus-agent-regenerate-group +The command @code{gnus-agent-regenerate-group} uses the local copies +of individual articles to repair the local @acronym{NOV}(header) database. It +then updates the internal data structures that document which articles +are stored locally. An optional argument will mark articles in the +agent as unread. -@item -@findex gnus-unplugged -You start Gnus with @code{gnus-unplugged}. This brings up the Gnus -Agent in a disconnected state. You can read all the news that you have -already fetched while in this mode. +@node Agent and flags +@subsection Agent and flags -@item -You then decide to see whether any new news has arrived. You connect -your machine to the net (using PPP or whatever), and then hit @kbd{J j} -to make Gnus become @dfn{plugged} and use @kbd{g} to check for new mail -as usual. To check for new mail in unplugged mode (@pxref{Mail -Source Specifiers}). +The Agent works with any Gnus back end including those, such as +nnimap, that store flags (read, ticked, etc) on the server. Sadly, +the Agent does not actually know which backends keep their flags in +the backend server rather than in @file{.newsrc}. This means that the +Agent, while unplugged or disconnected, will always record all changes +to the flags in its own files. -@item -You can then read the new news immediately, or you can download the -news onto your local machine. If you want to do the latter, you press -@kbd{g} to check if there are any new news and then @kbd{J s} to fetch -all the eligible articles in all the groups. (To let Gnus know which -articles you want to download, @pxref{Agent Categories}). +When you plug back in, Gnus will then check to see if you have any +changed any flags and ask if you wish to synchronize these with the +server. This behavior is customizable by @code{gnus-agent-synchronize-flags}. -@item -After fetching the articles, you press @kbd{J j} to make Gnus become -unplugged again, and you shut down the PPP thing (or whatever). And -then you read the news offline. +@vindex gnus-agent-synchronize-flags +If @code{gnus-agent-synchronize-flags} is @code{nil}, the Agent will +never automatically synchronize flags. If it is @code{ask}, which is +the default, the Agent will check if you made any changes and if so +ask if you wish to synchronize these when you re-connect. If it has +any other value, all flags will be synchronized automatically. -@item -And then you go to step 2. -@end itemize +If you do not wish to synchronize flags automatically when you +re-connect, you can do it manually with the +@code{gnus-agent-synchronize-flags} command that is bound to @kbd{J Y} +in the group buffer. -Here are some things you should do the first time (or so) that you use -the Agent. +Technical note: the synchronization algorithm does not work by ``pushing'' +all local flags to the server, but rather by incrementally updated the +server view of flags by changing only those flags that were changed by +the user. Thus, if you set one flag on an article, quit the group then +re-select the group and remove the flag; the flag will be set and +removed from the server when you ``synchronize''. The queued flag +operations can be found in the per-server @code{flags} file in the Agent +directory. It's emptied when you synchronize flags. -@itemize @bullet +@node Agent and IMAP +@subsection Agent and IMAP -@item -Decide which servers should be covered by the Agent. If you have a mail -back end, it would probably be nonsensical to have it covered by the -Agent. Go to the server buffer (@kbd{^} in the group buffer) and press -@kbd{J a} on the server (or servers) that you wish to have covered by the -Agent (@pxref{Server Agent Commands}), or @kbd{J r} on automatically -added servers you do not wish to have covered by the Agent. By default, -all @code{nntp} and @code{nnimap} servers in @code{gnus-select-method} and -@code{gnus-secondary-select-methods} are agentized. +The Agent works with any Gnus back end, including nnimap. However, +since there are some conceptual differences between @acronym{NNTP} and +@acronym{IMAP}, this section (should) provide you with some information to +make Gnus Agent work smoother as a @acronym{IMAP} Disconnected Mode client. -@item -Decide on download policy. It's fairly simple once you decide whether -you are going to use agent categories, topic parameters, and/or group -parameters to implement your policy. If you're new to gnus, it -is probably best to start with a category, @xref{Agent Categories}. +Some things are currently not implemented in the Agent that you'd might +expect from a disconnected @acronym{IMAP} client, including: -Both topic parameters (@pxref{Topic Parameters}) and agent categories -(@pxref{Agent Categories}) provide for setting a policy that applies -to multiple groups. Which you use is entirely up to you. Topic -parameters do override categories so, if you mix the two, you'll have -to take that into account. If you have a few groups that deviate from -your policy, you can use group parameters (@pxref{Group Parameters}) to -configure them. +@itemize @bullet @item -Uhm@dots{} that's it. +Copying/moving articles into nnimap groups when unplugged. + +@item +Creating/deleting nnimap groups when unplugged. + @end itemize +@node Outgoing Messages +@subsection Outgoing Messages -@node Agent Categories -@subsection Agent Categories +By default, when Gnus is unplugged, all outgoing messages (both mail +and news) are stored in the draft group ``queue'' (@pxref{Drafts}). +You can view them there after posting, and edit them at will. -One of the main reasons to integrate the news transport layer into the -newsreader is to allow greater control over what articles to download. -There's not much point in downloading huge amounts of articles, just to -find out that you're not interested in reading any of them. It's better -to be somewhat more conservative in choosing what to download, and then -mark the articles for downloading manually if it should turn out that -you're interested in the articles anyway. +You can control the circumstances under which outgoing mail is queued +(see @code{gnus-agent-queue-mail}, @pxref{Agent Variables}). Outgoing +news is always queued when Gnus is unplugged, and never otherwise. -One of the more effective methods for controlling what is to be -downloaded is to create a @dfn{category} and then assign some (or all) -groups to this category. Groups that do not belong in any other -category belong to the @code{default} category. Gnus has its own -buffer for creating and managing categories. +You can send the messages either from the draft group with the special +commands available there, or you can use the @kbd{J S} command in the +group buffer to send all the sendable messages in the draft group. +Posting news will only work when Gnus is plugged, but you can send +mail at any time. -If you prefer, you can also use group parameters (@pxref{Group -Parameters}) and topic parameters (@pxref{Topic Parameters}) for an -alternative approach to controlling the agent. The only real -difference is that categories are specific to the agent (so there is -less to learn) while group and topic parameters include the kitchen -sink. +If sending mail while unplugged does not work for you and you worry +about hitting @kbd{J S} by accident when unplugged, you can have Gnus +ask you to confirm your action (see +@code{gnus-agent-prompt-send-queue}, @pxref{Agent Variables}). -Since you can set agent parameters in several different places we have -a rule to decide which source to believe. This rule specifies that -the parameter sources are checked in the following order: group -parameters, topic parameters, agent category, and finally customizable -variables. So you can mix all of these sources to produce a wide range -of behavior, just don't blame me if you don't remember where you put -your settings. +@node Agent Variables +@subsection Agent Variables -@menu -* Category Syntax:: What a category looks like. -* Category Buffer:: A buffer for maintaining categories. -* Category Variables:: Customize'r'Us. -@end menu +@table @code +@item gnus-agent +@vindex gnus-agent +Is the agent enabled? The default is @code{t}. When first enabled, +the agent will use @code{gnus-agent-auto-agentize-methods} to +automatically mark some back ends as agentized. You may change which +back ends are agentized using the agent commands in the server buffer. +To enter the server buffer, use the @kbd{^} +(@code{gnus-group-enter-server-mode}) command in the group buffer. -@node Category Syntax -@subsubsection Category Syntax -A category consists of a name, the list of groups belonging to the -category, and a number of optional parameters that override the -customizable variables. The complete list of agent parameters are -listed below. +@item gnus-agent-directory +@vindex gnus-agent-directory +Where the Gnus Agent will store its files. The default is +@file{~/News/agent/}. -@cindex Agent Parameters -@table @code -@item agent-groups -The list of groups that are in this category. +@item gnus-agent-handle-level +@vindex gnus-agent-handle-level +Groups on levels (@pxref{Group Levels}) higher than this variable will +be ignored by the Agent. The default is @code{gnus-level-subscribed}, +which means that only subscribed group will be considered by the Agent +by default. -@item agent-predicate -A predicate which (generally) gives a rough outline of which articles -are eligible for downloading; and +@item gnus-agent-plugged-hook +@vindex gnus-agent-plugged-hook +Hook run when connecting to the network. -@item agent-score -a score rule which (generally) gives you a finer granularity when -deciding what articles to download. (Note that this @dfn{download -score} is not necessarily related to normal scores.) +@item gnus-agent-unplugged-hook +@vindex gnus-agent-unplugged-hook +Hook run when disconnecting from the network. -@item agent-enable-expiration -a boolean indicating whether the agent should expire old articles in -this group. Most groups should be expired to conserve disk space. In -fact, its probably safe to say that the gnus.* hierarchy contains the -only groups that should not be expired. +@item gnus-agent-fetched-hook +@vindex gnus-agent-fetched-hook +Hook run when finished fetching articles. -@item agent-days-until-old -an integer indicating the number of days that the agent should wait -before deciding that a read article is safe to expire. +@item gnus-agent-cache +@vindex gnus-agent-cache +Variable to control whether use the locally stored @acronym{NOV} and +articles when plugged, e.g. essentially using the Agent as a cache. +The default is non-@code{nil}, which means to use the Agent as a cache. -@item agent-low-score -an integer that overrides the value of @code{gnus-agent-low-score}. +@item gnus-agent-go-online +@vindex gnus-agent-go-online +If @code{gnus-agent-go-online} is @code{nil}, the Agent will never +automatically switch offline servers into online status. If it is +@code{ask}, the default, the Agent will ask if you wish to switch +offline servers into online status when you re-connect. If it has any +other value, all offline servers will be automatically switched into +online status. -@item agent-high-score -an integer that overrides the value of @code{gnus-agent-high-score}. +@item gnus-agent-mark-unread-after-downloaded +@vindex gnus-agent-mark-unread-after-downloaded +If @code{gnus-agent-mark-unread-after-downloaded} is non-@code{nil}, +mark articles as unread after downloading. This is usually a safe +thing to do as the newly downloaded article has obviously not been +read. The default is @code{t}. -@item agent-short-article -an integer that overrides the value of -@code{gnus-agent-short-article}. +@item gnus-agent-synchronize-flags +@vindex gnus-agent-synchronize-flags +If @code{gnus-agent-synchronize-flags} is @code{nil}, the Agent will +never automatically synchronize flags. If it is @code{ask}, which is +the default, the Agent will check if you made any changes and if so +ask if you wish to synchronize these when you re-connect. If it has +any other value, all flags will be synchronized automatically. -@item agent-long-article -an integer that overrides the value of @code{gnus-agent-long-article}. +@item gnus-agent-consider-all-articles +@vindex gnus-agent-consider-all-articles +If @code{gnus-agent-consider-all-articles} is non-@code{nil}, the +agent will let the agent predicate decide whether articles need to be +downloaded or not, for all articles. When @code{nil}, the default, +the agent will only let the predicate decide whether unread articles +are downloaded or not. If you enable this, you may also want to look +into the agent expiry settings (@pxref{Category Variables}), so that +the agent doesn't download articles which the agent will later expire, +over and over again. -@item agent-enable-undownloaded-faces -a symbol indicating whether the summary buffer should display -undownloaded articles using the @code{gnus-summary-*-undownloaded-face} -faces. Any symbol other than @code{nil} will enable the use of -undownloaded faces. -@end table +@item gnus-agent-max-fetch-size +@vindex gnus-agent-max-fetch-size +The agent fetches articles into a temporary buffer prior to parsing +them into individual files. To avoid exceeding the max. buffer size, +the agent alternates between fetching and parsing until all articles +have been fetched. @code{gnus-agent-max-fetch-size} provides a size +limit to control how often the cycling occurs. A large value improves +performance. A small value minimizes the time lost should the +connection be lost while fetching (You may need to run +@code{gnus-agent-regenerate-group} to update the group's state. +However, all articles parsed prior to losing the connection will be +available while unplugged). The default is 10M so it is unusual to +see any cycling. -The name of a category can not be changed once the category has been -created. +@item gnus-server-unopen-status +@vindex gnus-server-unopen-status +Perhaps not an Agent variable, but closely related to the Agent, this +variable says what will happen if Gnus cannot open a server. If the +Agent is enabled, the default, @code{nil}, makes Gnus ask the user +whether to deny the server or whether to unplug the agent. If the +Agent is disabled, Gnus always simply deny the server. Other choices +for this variable include @code{denied} and @code{offline} the latter +is only valid if the Agent is used. -Each category maintains a list of groups that are exclusive members of -that category. The exclusivity rule is automatically enforced, add a -group to a new category and it is automatically removed from its old -category. +@item gnus-auto-goto-ignores +@vindex gnus-auto-goto-ignores +Another variable that isn't an Agent variable, yet so closely related +that most will look for it here, this variable tells the summary +buffer how to maneuver around undownloaded (only headers stored in the +agent) and unfetched (neither article nor headers stored) articles. -A predicate in its simplest form can be a single predicate such as -@code{true} or @code{false}. These two will download every available -article or nothing respectively. In the case of these two special -predicates an additional score rule is superfluous. +The valid values are @code{nil} (maneuver to any article), +@code{undownloaded} (maneuvering while unplugged ignores articles that +have not been fetched), @code{always-undownloaded} (maneuvering always +ignores articles that have not been fetched), @code{unfetched} +(maneuvering ignores articles whose headers have not been fetched). -Predicates of @code{high} or @code{low} download articles in respect of -their scores in relationship to @code{gnus-agent-high-score} and -@code{gnus-agent-low-score} as described below. +@item gnus-agent-queue-mail +@vindex gnus-agent-queue-mail +When @code{gnus-agent-queue-mail} is @code{always}, Gnus will always +queue mail rather than sending it straight away. When @code{t}, Gnus +will queue mail when unplugged only. When @code{nil}, never queue +mail. The default is @code{t}. -To gain even finer control of what is to be regarded eligible for -download a predicate can consist of a number of predicates with logical -operators sprinkled in between. +@item gnus-agent-prompt-send-queue +@vindex gnus-agent-prompt-send-queue +When @code{gnus-agent-prompt-send-queue} is non-@code{nil} Gnus will +prompt you to confirm that you really wish to proceed if you hit +@kbd{J S} while unplugged. The default is @code{nil}. -Perhaps some examples are in order. +@item gnus-agent-auto-agentize-methods +@vindex gnus-agent-auto-agentize-methods +If you have never used the Agent before (or more technically, if +@file{~/News/agent/lib/servers} does not exist), Gnus will +automatically agentize a few servers for you. This variable control +which back ends should be auto-agentized. It is typically only useful +to agentize remote back ends. The auto-agentizing has the same effect +as running @kbd{J a} on the servers (@pxref{Server Agent Commands}). +If the file exist, you must manage the servers manually by adding or +removing them, this variable is only applicable the first time you +start Gnus. The default is @samp{(nntp nnimap)}. -Here's a simple predicate. (It's the default predicate, in fact, used -for all groups that don't belong to any other category.) +@end table -@lisp -short -@end lisp -Quite simple, eh? This predicate is true if and only if the article is -short (for some value of ``short''). +@node Example Setup +@subsection Example Setup -Here's a more complex predicate: +If you don't want to read this manual, and you have a fairly standard +setup, you may be able to use something like the following as your +@file{~/.gnus.el} file to get started. @lisp -(or high - (and - (not low) - (not long))) -@end lisp +;; @r{Define how Gnus is to fetch news. We do this over @acronym{NNTP}} +;; @r{from your ISP's server.} +(setq gnus-select-method '(nntp "news.your-isp.com")) -This means that an article should be downloaded if it has a high score, -or if the score is not low and the article is not long. You get the -drift. +;; @r{Define how Gnus is to read your mail. We read mail from} +;; @r{your ISP's @acronym{POP} server.} +(setq mail-sources '((pop :server "pop.your-isp.com"))) -The available logical operators are @code{or}, @code{and} and -@code{not}. (If you prefer, you can use the more ``C''-ish operators -@samp{|}, @code{&} and @code{!} instead.) +;; @r{Say how Gnus is to store the mail. We use nnml groups.} +(setq gnus-secondary-select-methods '((nnml ""))) -The following predicates are pre-defined, but if none of these fit what -you want to do, you can write your own. +;; @r{Make Gnus into an offline newsreader.} +;; (gnus-agentize) ; @r{The obsolete setting.} +;; (setq gnus-agent t) ; @r{Now the default.} +@end lisp -When evaluating each of these predicates, the named constant will be -bound to the value determined by calling -@code{gnus-agent-find-parameter} on the appropriate parameter. For -example, gnus-agent-short-article will be bound to -@code{(gnus-agent-find-parameter group 'agent-short-article)}. This -means that you can specify a predicate in your category then tune that -predicate to individual groups. +That should be it, basically. Put that in your @file{~/.gnus.el} file, +edit to suit your needs, start up PPP (or whatever), and type @kbd{M-x +gnus}. -@table @code -@item short -True if the article is shorter than @code{gnus-agent-short-article} -lines; default 100. +If this is the first time you've run Gnus, you will be subscribed +automatically to a few default newsgroups. You'll probably want to +subscribe to more groups, and to do that, you have to query the +@acronym{NNTP} server for a complete list of groups with the @kbd{A A} +command. This usually takes quite a while, but you only have to do it +once. -@item long -True if the article is longer than @code{gnus-agent-long-article} -lines; default 200. +After reading and parsing a while, you'll be presented with a list of +groups. Subscribe to the ones you want to read with the @kbd{u} +command. @kbd{l} to make all the killed groups disappear after you've +subscribe to all the groups you want to read. (@kbd{A k} will bring +back all the killed groups.) -@item low -True if the article has a download score less than -@code{gnus-agent-low-score}; default 0. +You can now read the groups at once, or you can download the articles +with the @kbd{J s} command. And then read the rest of this manual to +find out which of the other gazillion things you want to customize. -@item high -True if the article has a download score greater than -@code{gnus-agent-high-score}; default 0. -@item spam -True if the Gnus Agent guesses that the article is spam. The -heuristics may change over time, but at present it just computes a -checksum and sees whether articles match. +@node Batching Agents +@subsection Batching Agents +@findex gnus-agent-batch -@item true -Always true. +Having the Gnus Agent fetch articles (and post whatever messages you've +written) is quite easy once you've gotten things set up properly. The +following shell script will do everything that is necessary: -@item false -Always false. -@end table +You can run a complete batch command from the command line with the +following incantation: -If you want to create your own predicate function, here's what you have -to know: The functions are called with no parameters, but the -@code{gnus-headers} and @code{gnus-score} dynamic variables are bound to -useful values. +@example +#!/bin/sh +emacs -batch -l ~/.emacs -l ~/.gnus.el -f gnus-agent-batch >/dev/null 2>&1 +@end example -For example, you could decide that you don't want to download articles -that were posted more than a certain number of days ago (e.g. posted -more than @code{gnus-agent-expire-days} ago) you might write a function -something along the lines of the following: -@lisp -(defun my-article-old-p () - "Say whether an article is old." - (< (time-to-days (date-to-time (mail-header-date gnus-headers))) - (- (time-to-days (current-time)) gnus-agent-expire-days))) -@end lisp +@node Agent Caveats +@subsection Agent Caveats -with the predicate then defined as: +The Gnus Agent doesn't seem to work like most other offline +newsreaders. Here are some common questions that some imaginary people +may ask: -@lisp -(not my-article-old-p) -@end lisp +@table @dfn +@item If I read an article while plugged, do they get entered into the Agent? -or you could append your predicate to the predefined -@code{gnus-category-predicate-alist} in your @file{~/.gnus.el} or -wherever. +@strong{No}. If you want this behavior, add +@code{gnus-agent-fetch-selected-article} to +@code{gnus-select-article-hook}. -@lisp -(require 'gnus-agent) -(setq gnus-category-predicate-alist - (append gnus-category-predicate-alist - '((old . my-article-old-p)))) -@end lisp +@item If I read an article while plugged, and the article already exists in +the Agent, will it get downloaded once more? -and simply specify your predicate as: +@strong{No}, unless @code{gnus-agent-cache} is @code{nil}. -@lisp -(not old) -@end lisp +@end table -If/when using something like the above, be aware that there are many -misconfigured systems/mailers out there and so an article's date is not -always a reliable indication of when it was posted. Hell, some people -just don't give a damn. +In short, when Gnus is unplugged, it only looks into the locally stored +articles; when it's plugged, it talks to your ISP and may also use the +locally stored articles. -The above predicates apply to @emph{all} the groups which belong to the -category. However, if you wish to have a specific predicate for an -individual group within a category, or you're just too lazy to set up a -new category, you can enter a group's individual predicate in its group -parameters like so: -@lisp -(agent-predicate . short) -@end lisp +@node Scoring +@chapter Scoring +@cindex scoring -This is the group/topic parameter equivalent of the agent category default. -Note that when specifying a single word predicate like this, the -@code{agent-predicate} specification must be in dotted pair notation. +Other people use @dfn{kill files}, but we here at Gnus Towers like +scoring better than killing, so we'd rather switch than fight. They do +something completely different as well, so sit up straight and pay +attention! -The equivalent of the longer example from above would be: +@vindex gnus-summary-mark-below +All articles have a default score (@code{gnus-summary-default-score}), +which is 0 by default. This score may be raised or lowered either +interactively or by score files. Articles that have a score lower than +@code{gnus-summary-mark-below} are marked as read. -@lisp -(agent-predicate or high (and (not low) (not long))) -@end lisp +Gnus will read any @dfn{score files} that apply to the current group +before generating the summary buffer. -The outer parenthesis required in the category specification are not -entered here as, not being in dotted pair notation, the value of the -predicate is assumed to be a list. +There are several commands in the summary buffer that insert score +entries based on the current article. You can, for instance, ask Gnus to +lower or increase the score of all articles with a certain subject. +There are two sorts of scoring entries: Permanent and temporary. +Temporary score entries are self-expiring entries. Any entries that are +temporary and have not been used for, say, a week, will be removed +silently to help keep the sizes of the score files down. -Now, the syntax of the download score is the same as the syntax of -normal score files, except that all elements that require actually -seeing the article itself are verboten. This means that only the -following headers can be scored on: @code{Subject}, @code{From}, -@code{Date}, @code{Message-ID}, @code{References}, @code{Chars}, -@code{Lines}, and @code{Xref}. +@menu +* Summary Score Commands:: Adding score entries for the current group. +* Group Score Commands:: General score commands. +* Score Variables:: Customize your scoring. (My, what terminology). +* Score File Format:: What a score file may contain. +* Score File Editing:: You can edit score files by hand as well. +* Adaptive Scoring:: Big Sister Gnus knows what you read. +* Home Score File:: How to say where new score entries are to go. +* Followups To Yourself:: Having Gnus notice when people answer you. +* Scoring On Other Headers:: Scoring on non-standard headers. +* Scoring Tips:: How to score effectively. +* Reverse Scoring:: That problem child of old is not problem. +* Global Score Files:: Earth-spanning, ear-splitting score files. +* Kill Files:: They are still here, but they can be ignored. +* Converting Kill Files:: Translating kill files to score files. +* Advanced Scoring:: Using logical expressions to build score rules. +* Score Decays:: It can be useful to let scores wither away. +@end menu -As with predicates, the specification of the @code{download score rule} -to use in respect of a group can be in either the category definition if -it's to be applicable to all groups in therein, or a group's parameters -if it's to be specific to that group. -In both of these places the @code{download score rule} can take one of -three forms: +@node Summary Score Commands +@section Summary Score Commands +@cindex score commands -@enumerate -@item -Score rule +The score commands that alter score entries do not actually modify real +score files. That would be too inefficient. Gnus maintains a cache of +previously loaded score files, one of which is considered the +@dfn{current score file alist}. The score commands simply insert +entries into this list, and upon group exit, this list is saved. -This has the same syntax as a normal Gnus score file except only a -subset of scoring keywords are available as mentioned above. +The current score file is by default the group's local score file, even +if no such score file actually exists. To insert score commands into +some other score file (e.g. @file{all.SCORE}), you must first make this +score file the current one. -example: +General score commands that don't actually change the score file: -@itemize @bullet -@item -Category specification +@table @kbd -@lisp -(("from" - ("Lars Ingebrigtsen" 1000000 nil s)) -("lines" - (500 -100 nil <))) -@end lisp +@item V s +@kindex V s (Summary) +@findex gnus-summary-set-score +Set the score of the current article (@code{gnus-summary-set-score}). -@item -Group/Topic Parameter specification +@item V S +@kindex V S (Summary) +@findex gnus-summary-current-score +Display the score of the current article +(@code{gnus-summary-current-score}). -@lisp -(agent-score ("from" - ("Lars Ingebrigtsen" 1000000 nil s)) - ("lines" - (500 -100 nil <))) -@end lisp +@item V t +@kindex V t (Summary) +@findex gnus-score-find-trace +Display all score rules that have been used on the current article +(@code{gnus-score-find-trace}). In the @code{*Score Trace*} buffer, you +may type @kbd{e} to edit score file corresponding to the score rule on +current line and @kbd{f} to format (@code{gnus-score-pretty-print}) the +score file and edit it. -Again, note the omission of the outermost parenthesis here. -@end itemize +@item V w +@kindex V w (Summary) +@findex gnus-score-find-favourite-words +List words used in scoring (@code{gnus-score-find-favourite-words}). -@item -Agent score file +@item V R +@kindex V R (Summary) +@findex gnus-summary-rescore +Run the current summary through the scoring process +(@code{gnus-summary-rescore}). This might be useful if you're playing +around with your score files behind Gnus' back and want to see the +effect you're having. -These score files must @emph{only} contain the permitted scoring -keywords stated above. +@item V c +@kindex V c (Summary) +@findex gnus-score-change-score-file +Make a different score file the current +(@code{gnus-score-change-score-file}). -example: +@item V e +@kindex V e (Summary) +@findex gnus-score-edit-current-scores +Edit the current score file (@code{gnus-score-edit-current-scores}). +You will be popped into a @code{gnus-score-mode} buffer (@pxref{Score +File Editing}). -@itemize @bullet -@item -Category specification +@item V f +@kindex V f (Summary) +@findex gnus-score-edit-file +Edit a score file and make this score file the current one +(@code{gnus-score-edit-file}). -@lisp -("~/News/agent.SCORE") -@end lisp +@item V F +@kindex V F (Summary) +@findex gnus-score-flush-cache +Flush the score cache (@code{gnus-score-flush-cache}). This is useful +after editing score files. -or perhaps +@item V C +@kindex V C (Summary) +@findex gnus-score-customize +Customize a score file in a visually pleasing manner +(@code{gnus-score-customize}). -@lisp -("~/News/agent.SCORE" "~/News/agent.group.SCORE") -@end lisp +@end table -@item -Group Parameter specification +The rest of these commands modify the local score file. -@lisp -(agent-score "~/News/agent.SCORE") -@end lisp +@table @kbd -Additional score files can be specified as above. Need I say anything -about parenthesis? -@end itemize +@item V m +@kindex V m (Summary) +@findex gnus-score-set-mark-below +Prompt for a score, and mark all articles with a score below this as +read (@code{gnus-score-set-mark-below}). -@item -Use @code{normal} score files +@item V x +@kindex V x (Summary) +@findex gnus-score-set-expunge-below +Prompt for a score, and add a score rule to the current score file to +expunge all articles below this score +(@code{gnus-score-set-expunge-below}). +@end table -If you don't want to maintain two sets of scoring rules for a group, and -your desired @code{downloading} criteria for a group are the same as your -@code{reading} criteria then you can tell the agent to refer to your -@code{normal} score files when deciding what to download. +The keystrokes for actually making score entries follow a very regular +pattern, so there's no need to list all the commands. (Hundreds of +them.) -These directives in either the category definition or a group's -parameters will cause the agent to read in all the applicable score -files for a group, @emph{filtering out} those sections that do not -relate to one of the permitted subset of scoring keywords. +@findex gnus-summary-increase-score +@findex gnus-summary-lower-score -@itemize @bullet +@enumerate @item -Category Specification +The first key is either @kbd{I} (upper case i) for increasing the score +or @kbd{L} for lowering the score. +@item +The second key says what header you want to score on. The following +keys are available: +@table @kbd -@lisp -file -@end lisp +@item a +Score on the author name. -@item -Group Parameter specification +@item s +Score on the subject line. -@lisp -(agent-score . file) -@end lisp -@end itemize -@end enumerate +@item x +Score on the @code{Xref} line---i.e., the cross-posting line. -@node Category Buffer -@subsubsection Category Buffer +@item r +Score on the @code{References} line. -You'd normally do all category maintenance from the category buffer. -When you enter it for the first time (with the @kbd{J c} command from -the group buffer), you'll only see the @code{default} category. +@item d +Score on the date. -The following commands are available in this buffer: +@item l +Score on the number of lines. -@table @kbd -@item q -@kindex q (Category) -@findex gnus-category-exit -Return to the group buffer (@code{gnus-category-exit}). +@item i +Score on the @code{Message-ID} header. @item e -@kindex e (Category) -@findex gnus-category-customize-category -Use a customization buffer to set all of the selected category's -parameters at one time (@code{gnus-category-customize-category}). +Score on an ``extra'' header, that is, one of those in gnus-extra-headers, +if your @acronym{NNTP} server tracks additional header data in overviews. -@item k -@kindex k (Category) -@findex gnus-category-kill -Kill the current category (@code{gnus-category-kill}). +@item f +Score on followups---this matches the author name, and adds scores to +the followups to this author. (Using this key leads to the creation of +@file{ADAPT} files.) -@item c -@kindex c (Category) -@findex gnus-category-copy -Copy the current category (@code{gnus-category-copy}). +@item b +Score on the body. -@item a -@kindex a (Category) -@findex gnus-category-add -Add a new category (@code{gnus-category-add}). +@item h +Score on the head. -@item p -@kindex p (Category) -@findex gnus-category-edit-predicate -Edit the predicate of the current category -(@code{gnus-category-edit-predicate}). +@item t +Score on thread. (Using this key leads to the creation of @file{ADAPT} +files.) -@item g -@kindex g (Category) -@findex gnus-category-edit-groups -Edit the list of groups belonging to the current category -(@code{gnus-category-edit-groups}). +@end table -@item s -@kindex s (Category) -@findex gnus-category-edit-score -Edit the download score rule of the current category -(@code{gnus-category-edit-score}). +@item +The third key is the match type. Which match types are valid depends on +what headers you are scoring on. -@item l -@kindex l (Category) -@findex gnus-category-list -List all the categories (@code{gnus-category-list}). -@end table +@table @code +@item strings -@node Category Variables -@subsubsection Category Variables +@table @kbd -@table @code -@item gnus-category-mode-hook -@vindex gnus-category-mode-hook -Hook run in category buffers. +@item e +Exact matching. -@item gnus-category-line-format -@vindex gnus-category-line-format -Format of the lines in the category buffer (@pxref{Formatting -Variables}). Valid elements are: +@item s +Substring matching. -@table @samp -@item c -The name of the category. +@item f +Fuzzy matching (@pxref{Fuzzy Matching}). -@item g -The number of groups in the category. +@item r +Regexp matching @end table -@item gnus-category-mode-line-format -@vindex gnus-category-mode-line-format -Format of the category mode line (@pxref{Mode Line Formatting}). +@item date +@table @kbd -@item gnus-agent-short-article -@vindex gnus-agent-short-article -Articles that have fewer lines than this are short. Default 100. +@item b +Before date. -@item gnus-agent-long-article -@vindex gnus-agent-long-article -Articles that have more lines than this are long. Default 200. +@item a +After date. -@item gnus-agent-low-score -@vindex gnus-agent-low-score -Articles that have a score lower than this have a low score. Default -0. +@item n +This date. +@end table -@item gnus-agent-high-score -@vindex gnus-agent-high-score -Articles that have a score higher than this have a high score. Default -0. +@item number +@table @kbd -@item gnus-agent-expire-days -@vindex gnus-agent-expire-days -The number of days that a @samp{read} article must stay in the agent's -local disk before becoming eligible for expiration (While the name is -the same, this doesn't mean expiring the article on the server. It -just means deleting the local copy of the article). What is also -important to understand is that the counter starts with the time the -article was written to the local disk and not the time the article was -read. -Default 7. +@item < +Less than number. -@item gnus-agent-enable-expiration -@vindex gnus-agent-enable-expiration -Determines whether articles in a group are, by default, expired or -retained indefinitely. The default is @code{ENABLE} which means that -you'll have to disable expiration when desired. On the other hand, -you could set this to @code{DISABLE}. In that case, you would then -have to enable expiration in selected groups. +@item = +Equal to number. +@item > +Greater than number. +@end table @end table +@item +The fourth and usually final key says whether this is a temporary (i.e., +expiring) score entry, or a permanent (i.e., non-expiring) score entry, +or whether it is to be done immediately, without adding to the score +file. +@table @kbd -@node Agent Commands -@subsection Agent Commands -@findex gnus-agent-toggle-plugged -@kindex J j (Agent) - -All the Gnus Agent commands are on the @kbd{J} submap. The @kbd{J j} -(@code{gnus-agent-toggle-plugged}) command works in all modes, and -toggles the plugged/unplugged state of the Gnus Agent. +@item t +Temporary score entry. +@item p +Permanent score entry. -@menu -* Group Agent Commands:: Configure groups and fetch their contents. -* Summary Agent Commands:: Manually select then fetch specific articles. -* Server Agent Commands:: Select the servers that are supported by the agent. -@end menu +@item i +Immediately scoring. +@end table +@item +If you are scoring on `e' (extra) headers, you will then be prompted for +the header name on which you wish to score. This must be a header named +in gnus-extra-headers, and @samp{TAB} completion is available. +@end enumerate +So, let's say you want to increase the score on the current author with +exact matching permanently: @kbd{I a e p}. If you want to lower the +score based on the subject line, using substring matching, and make a +temporary score entry: @kbd{L s s t}. Pretty easy. -@node Group Agent Commands -@subsubsection Group Agent Commands +To make things a bit more complicated, there are shortcuts. If you use +a capital letter on either the second or third keys, Gnus will use +defaults for the remaining one or two keystrokes. The defaults are +``substring'' and ``temporary''. So @kbd{I A} is the same as @kbd{I a s +t}, and @kbd{I a R} is the same as @kbd{I a r t}. -@table @kbd -@item J u -@kindex J u (Agent Group) -@findex gnus-agent-fetch-groups -Fetch all eligible articles in the current group -(@code{gnus-agent-fetch-groups}). +These functions take both the numerical prefix and the symbolic prefix +(@pxref{Symbolic Prefixes}). A numerical prefix says how much to lower +(or increase) the score of the article. A symbolic prefix of @code{a} +says to use the @file{all.SCORE} file for the command instead of the +current score file. -@item J c -@kindex J c (Agent Group) -@findex gnus-enter-category-buffer -Enter the Agent category buffer (@code{gnus-enter-category-buffer}). +@vindex gnus-score-mimic-keymap +The @code{gnus-score-mimic-keymap} says whether these commands will +pretend they are keymaps or not. -@item J s -@kindex J s (Agent Group) -@findex gnus-agent-fetch-session -Fetch all eligible articles in all groups -(@code{gnus-agent-fetch-session}). -@item J S -@kindex J S (Agent Group) -@findex gnus-group-send-queue -Send all sendable messages in the queue group -(@code{gnus-group-send-queue}). @xref{Drafts}. +@node Group Score Commands +@section Group Score Commands +@cindex group score commands -@item J a -@kindex J a (Agent Group) -@findex gnus-agent-add-group -Add the current group to an Agent category -(@code{gnus-agent-add-group}). This command understands the -process/prefix convention (@pxref{Process/Prefix}). +There aren't many of these as yet, I'm afraid. -@item J r -@kindex J r (Agent Group) -@findex gnus-agent-remove-group -Remove the current group from its category, if any -(@code{gnus-agent-remove-group}). This command understands the -process/prefix convention (@pxref{Process/Prefix}). +@table @kbd -@item J Y -@kindex J Y (Agent Group) -@findex gnus-agent-synchronize-flags -Synchronize flags changed while unplugged with remote server, if any. +@item W e +@kindex W e (Group) +@findex gnus-score-edit-all-score +Edit the apply-to-all-groups all.SCORE file. You will be popped into +a @code{gnus-score-mode} buffer (@pxref{Score File Editing}). +@item W f +@kindex W f (Group) +@findex gnus-score-flush-cache +Gnus maintains a cache of score alists to avoid having to reload them +all the time. This command will flush the cache +(@code{gnus-score-flush-cache}). @end table +You can do scoring from the command line by saying something like: -@node Summary Agent Commands -@subsubsection Summary Agent Commands +@findex gnus-batch-score +@cindex batch scoring +@example +$ emacs -batch -l ~/.emacs -l ~/.gnus.el -f gnus-batch-score +@end example -@table @kbd -@item J # -@kindex J # (Agent Summary) -@findex gnus-agent-mark-article -Mark the article for downloading (@code{gnus-agent-mark-article}). -@item J M-# -@kindex J M-# (Agent Summary) -@findex gnus-agent-unmark-article -Remove the downloading mark from the article -(@code{gnus-agent-unmark-article}). +@node Score Variables +@section Score Variables +@cindex score variables -@cindex % -@item @@ -@kindex @@ (Agent Summary) -@findex gnus-agent-toggle-mark -Toggle whether to download the article -(@code{gnus-agent-toggle-mark}). The download mark is @samp{%} by -default. +@table @code -@item J c -@kindex J c (Agent Summary) -@findex gnus-agent-catchup -Mark all articles as read (@code{gnus-agent-catchup}) that are neither cached, downloaded, nor downloadable. +@item gnus-use-scoring +@vindex gnus-use-scoring +If @code{nil}, Gnus will not check for score files, and will not, in +general, do any score-related work. This is @code{t} by default. -@item J S -@kindex J S (Agent Summary) -@findex gnus-agent-fetch-group -Download all eligible (@pxref{Agent Categories}) articles in this group. -(@code{gnus-agent-fetch-group}). +@item gnus-kill-killed +@vindex gnus-kill-killed +If this variable is @code{nil}, Gnus will never apply score files to +articles that have already been through the kill process. While this +may save you lots of time, it also means that if you apply a kill file +to a group, and then change the kill file and want to run it over you +group again to kill more articles, it won't work. You have to set this +variable to @code{t} to do that. (It is @code{t} by default.) -@item J s -@kindex J s (Agent Summary) -@findex gnus-agent-summary-fetch-series -Download all processable articles in this group. -(@code{gnus-agent-summary-fetch-series}). +@item gnus-kill-files-directory +@vindex gnus-kill-files-directory +All kill and score files will be stored in this directory, which is +initialized from the @env{SAVEDIR} environment variable by default. +This is @file{~/News/} by default. -@item J u -@kindex J u (Agent Summary) -@findex gnus-agent-summary-fetch-group -Download all downloadable articles in the current group -(@code{gnus-agent-summary-fetch-group}). +@item gnus-score-file-suffix +@vindex gnus-score-file-suffix +Suffix to add to the group name to arrive at the score file name +(@file{SCORE} by default.) -@end table +@item gnus-score-uncacheable-files +@vindex gnus-score-uncacheable-files +@cindex score cache +All score files are normally cached to avoid excessive re-loading of +score files. However, this might make your Emacs grow big and +bloated, so this regexp can be used to weed out score files unlikely +to be needed again. It would be a bad idea to deny caching of +@file{all.SCORE}, while it might be a good idea to not cache +@file{comp.infosystems.www.authoring.misc.ADAPT}. In fact, this +variable is @samp{ADAPT$} by default, so no adaptive score files will +be cached. +@item gnus-save-score +@vindex gnus-save-score +If you have really complicated score files, and do lots of batch +scoring, then you might set this variable to @code{t}. This will make +Gnus save the scores into the @file{.newsrc.eld} file. -@node Server Agent Commands -@subsubsection Server Agent Commands +If you do not set this to @code{t}, then manual scores (like those set +with @kbd{V s} (@code{gnus-summary-set-score})) will not be preserved +across group visits. -@table @kbd -@item J a -@kindex J a (Agent Server) -@findex gnus-agent-add-server -Add the current server to the list of servers covered by the Gnus Agent -(@code{gnus-agent-add-server}). +@item gnus-score-interactive-default-score +@vindex gnus-score-interactive-default-score +Score used by all the interactive raise/lower commands to raise/lower +score with. Default is 1000, which may seem excessive, but this is to +ensure that the adaptive scoring scheme gets enough room to play with. +We don't want the small changes from the adaptive scoring to overwrite +manually entered data. -@item J r -@kindex J r (Agent Server) -@findex gnus-agent-remove-server -Remove the current server from the list of servers covered by the Gnus -Agent (@code{gnus-agent-remove-server}). +@item gnus-summary-default-score +@vindex gnus-summary-default-score +Default score of an article, which is 0 by default. -@end table +@item gnus-summary-expunge-below +@vindex gnus-summary-expunge-below +Don't display the summary lines of articles that have scores lower than +this variable. This is @code{nil} by default, which means that no +articles will be hidden. This variable is local to the summary buffers, +and has to be set from @code{gnus-summary-mode-hook}. +@item gnus-score-over-mark +@vindex gnus-score-over-mark +Mark (in the third column) used for articles with a score over the +default. Default is @samp{+}. -@node Agent Visuals -@subsection Agent Visuals +@item gnus-score-below-mark +@vindex gnus-score-below-mark +Mark (in the third column) used for articles with a score below the +default. Default is @samp{-}. -If you open a summary while unplugged and, Gnus knows from the group's -active range that there are more articles than the headers currently -stored in the Agent, you may see some articles whose subject looks -something like @samp{[Undownloaded article #####]}. These are -placeholders for the missing headers. Aside from setting a mark, -there is not much that can be done with one of these placeholders. -When Gnus finally gets a chance to fetch the group's headers, the -placeholders will automatically be replaced by the actual headers. -You can configure the summary buffer's maneuvering to skip over the -placeholders if you care (See @code{gnus-auto-goto-ignores}). +@item gnus-score-find-score-files-function +@vindex gnus-score-find-score-files-function +Function used to find score files for the current group. This function +is called with the name of the group as the argument. -While it may be obvious to all, the only headers and articles -available while unplugged are those headers and articles that were -fetched into the Agent while previously plugged. To put it another -way, ``If you forget to fetch something while plugged, you might have a -less than satisfying unplugged session''. For this reason, the Agent -adds two visual effects to your summary buffer. These effects display -the download status of each article so that you always know which -articles will be available when unplugged. +Predefined functions available are: +@table @code -The first visual effect is the @samp{%O} spec. If you customize -@code{gnus-summary-line-format} to include this specifier, you will add -a single character field that indicates an article's download status. -Articles that have been fetched into either the Agent or the Cache, -will display @code{gnus-downloaded-mark} (defaults to @samp{+}). All -other articles will display @code{gnus-undownloaded-mark} (defaults to -@samp{-}). If you open a group that has not been agentized, a space -(@samp{ }) will be displayed. +@item gnus-score-find-single +@findex gnus-score-find-single +Only apply the group's own score file. -The second visual effect are the undownloaded faces. The faces, there -are three indicating the article's score (low, normal, high), seem to -result in a love/hate response from many Gnus users. The problem is -that the face selection is controlled by a list of condition tests and -face names (See @code{gnus-summary-highlight}). Each condition is -tested in the order in which it appears in the list so early -conditions have precedence over later conditions. All of this means -that, if you tick an undownloaded article, the article will continue -to be displayed in the undownloaded face rather than the ticked face. +@item gnus-score-find-bnews +@findex gnus-score-find-bnews +Apply all score files that match, using bnews syntax. This is the +default. If the current group is @samp{gnu.emacs.gnus}, for instance, +@file{all.emacs.all.SCORE}, @file{not.alt.all.SCORE} and +@file{gnu.all.SCORE} would all apply. In short, the instances of +@samp{all} in the score file names are translated into @samp{.*}, and +then a regexp match is done. -If you use the Agent as a cache (to avoid downloading the same article -each time you visit it or to minimize your connection time), the -undownloaded face will probably seem like a good idea. The reason -being that you do all of our work (marking, reading, deleting) with -downloaded articles so the normal faces always appear. For those -users using the agent to improve online performance by caching the NOV -database (most users since 5.10.2), the undownloaded faces may appear -to be an absolutely horrible idea. The issue being that, since none -of their articles have been fetched into the Agent, all of the -normal faces will be obscured by the undownloaded faces. +This means that if you have some score entries that you want to apply to +all groups, then you put those entries in the @file{all.SCORE} file. -If you would like to use the undownloaded faces, you must enable the -undownloaded faces by setting the @code{agent-enable-undownloaded-faces} -group parameter to @code{t}. This parameter, like all other agent -parameters, may be set on an Agent Category (@pxref{Agent Categories}), -a Group Topic (@pxref{Topic Parameters}), or an individual group -(@pxref{Group Parameters}). +The score files are applied in a semi-random order, although Gnus will +try to apply the more general score files before the more specific score +files. It does this by looking at the number of elements in the score +file names---discarding the @samp{all} elements. -The one problem common to all users using the agent is how quickly it -can consume disk space. If you using the agent on many groups, it is -even more difficult to effectively recover disk space. One solution -is the @samp{%F} format available in @code{gnus-group-line-format}. -This format will display the actual disk space used by articles -fetched into both the agent and cache. By knowing which groups use -the most space, users know where to focus their efforts when ``agent -expiring'' articles. +@item gnus-score-find-hierarchical +@findex gnus-score-find-hierarchical +Apply all score files from all the parent groups. This means that you +can't have score files like @file{all.SCORE}, but you can have +@file{SCORE}, @file{comp.SCORE} and @file{comp.emacs.SCORE} for each +server. -@node Agent as Cache -@subsection Agent as Cache +@end table +This variable can also be a list of functions. In that case, all +these functions will be called with the group name as argument, and +all the returned lists of score files will be applied. These +functions can also return lists of lists of score alists directly. In +that case, the functions that return these non-file score alists +should probably be placed before the ``real'' score file functions, to +ensure that the last score file returned is the local score file. +Phu. -When Gnus is plugged, it is not efficient to download headers or -articles from the server again, if they are already stored in the -Agent. So, Gnus normally only downloads headers once, and stores them -in the Agent. These headers are later used when generating the summary -buffer, regardless of whether you are plugged or unplugged. Articles -are not cached in the Agent by default though (that would potentially -consume lots of disk space), but if you have already downloaded an -article into the Agent, Gnus will not download the article from the -server again but use the locally stored copy instead. +For example, to do hierarchical scoring but use a non-server-specific +overall score file, you could use the value +@example +(list (lambda (group) ("all.SCORE")) + 'gnus-score-find-hierarchical) +@end example -If you so desire, you can configure the agent (see @code{gnus-agent-cache} -@pxref{Agent Variables}) to always download headers and articles while -plugged. Gnus will almost certainly be slower, but it will be kept -synchronized with the server. That last point probably won't make any -sense if you are using a nntp or nnimap back end. +@item gnus-score-expiry-days +@vindex gnus-score-expiry-days +This variable says how many days should pass before an unused score file +entry is expired. If this variable is @code{nil}, no score file entries +are expired. It's 7 by default. -@node Agent Expiry -@subsection Agent Expiry +@item gnus-update-score-entry-dates +@vindex gnus-update-score-entry-dates +If this variable is non-@code{nil}, temporary score entries that have +been triggered (matched) will have their dates updated. (This is how Gnus +controls expiry---all non-matched-entries will become too old while +matched entries will stay fresh and young.) However, if you set this +variable to @code{nil}, even matched entries will grow old and will +have to face that oh-so grim reaper. -@vindex gnus-agent-expire-days -@findex gnus-agent-expire -@kindex M-x gnus-agent-expire -@kindex M-x gnus-agent-expire-group -@findex gnus-agent-expire-group -@cindex agent expiry -@cindex Gnus agent expiry -@cindex expiry, in Gnus agent +@item gnus-score-after-write-file-function +@vindex gnus-score-after-write-file-function +Function called with the name of the score file just written. -The Agent back end, @code{nnagent}, doesn't handle expiry. Well, at -least it doesn't handle it like other back ends. Instead, there are -special @code{gnus-agent-expire} and @code{gnus-agent-expire-group} -commands that will expire all read articles that are older than -@code{gnus-agent-expire-days} days. They can be run whenever you feel -that you're running out of space. Neither are particularly fast or -efficient, and it's not a particularly good idea to interrupt them (with -@kbd{C-g} or anything else) once you've started one of them. +@item gnus-score-thread-simplify +@vindex gnus-score-thread-simplify +If this variable is non-@code{nil}, article subjects will be +simplified for subject scoring purposes in the same manner as with +threading---according to the current value of +@code{gnus-simplify-subject-functions}. If the scoring entry uses +@code{substring} or @code{exact} matching, the match will also be +simplified in this manner. -Note that other functions, e.g. @code{gnus-request-expire-articles}, -might run @code{gnus-agent-expire} for you to keep the agent -synchronized with the group. +@end table -The agent parameter @code{agent-enable-expiration} may be used to -prevent expiration in selected groups. -@vindex gnus-agent-expire-all -If @code{gnus-agent-expire-all} is non-@code{nil}, the agent -expiration commands will expire all articles---unread, read, ticked -and dormant. If @code{nil} (which is the default), only read articles -are eligible for expiry, and unread, ticked and dormant articles will -be kept indefinitely. +@node Score File Format +@section Score File Format +@cindex score file format -If you find that some articles eligible for expiry are never expired, -perhaps some Gnus Agent files are corrupted. There's are special -commands, @code{gnus-agent-regenerate} and -@code{gnus-agent-regenerate-group}, to fix possible problems. +A score file is an @code{emacs-lisp} file that normally contains just a +single form. Casual users are not expected to edit these files; +everything can be changed from the summary buffer. -@node Agent Regeneration -@subsection Agent Regeneration +Anyway, if you'd like to dig into it yourself, here's an example: -@cindex agent regeneration -@cindex Gnus agent regeneration -@cindex regeneration +@lisp +(("from" + ("Lars Ingebrigtsen" -10000) + ("Per Abrahamsen") + ("larsi\\|lmi" -50000 nil R)) + ("subject" + ("Ding is Badd" nil 728373)) + ("xref" + ("alt.politics" -1000 728372 s)) + ("lines" + (2 -100 nil <)) + (mark 0) + (expunge -1000) + (mark-and-expunge -10) + (read-only nil) + (orphan -10) + (adapt t) + (files "/hom/larsi/News/gnu.SCORE") + (exclude-files "all.SCORE") + (local (gnus-newsgroup-auto-expire t) + (gnus-summary-make-false-root empty)) + (eval (ding))) +@end lisp -The local data structures used by @code{nnagent} may become corrupted -due to certain exceptional conditions. When this happens, -@code{nnagent} functionality may degrade or even fail. The solution -to this problem is to repair the local data structures by removing all -internal inconsistencies. +This example demonstrates most score file elements. @xref{Advanced +Scoring}, for a different approach. -For example, if your connection to your server is lost while -downloaded articles into the agent, the local data structures will not -know about articles successfully downloaded prior to the connection -failure. Running @code{gnus-agent-regenerate} or -@code{gnus-agent-regenerate-group} will update the data structures -such that you don't need to download these articles a second time. +Even though this looks much like Lisp code, nothing here is actually +@code{eval}ed. The Lisp reader is used to read this form, though, so it +has to be valid syntactically, if not semantically. -@findex gnus-agent-regenerate -@kindex M-x gnus-agent-regenerate -The command @code{gnus-agent-regenerate} will perform -@code{gnus-agent-regenerate-group} on every agentized group. While -you can run @code{gnus-agent-regenerate} in any buffer, it is strongly -recommended that you first close all summary buffers. +Six keys are supported by this alist: -@findex gnus-agent-regenerate-group -@kindex M-x gnus-agent-regenerate-group -The command @code{gnus-agent-regenerate-group} uses the local copies -of individual articles to repair the local @acronym{NOV}(header) database. It -then updates the internal data structures that document which articles -are stored locally. An optional argument will mark articles in the -agent as unread. +@table @code -@node Agent and flags -@subsection Agent and flags +@item STRING +If the key is a string, it is the name of the header to perform the +match on. Scoring can only be performed on these eight headers: +@code{From}, @code{Subject}, @code{References}, @code{Message-ID}, +@code{Xref}, @code{Lines}, @code{Chars} and @code{Date}. In addition to +these headers, there are three strings to tell Gnus to fetch the entire +article and do the match on larger parts of the article: @code{Body} +will perform the match on the body of the article, @code{Head} will +perform the match on the head of the article, and @code{All} will +perform the match on the entire article. Note that using any of these +last three keys will slow down group entry @emph{considerably}. The +final ``header'' you can score on is @code{Followup}. These score +entries will result in new score entries being added for all follow-ups +to articles that matches these score entries. + +Following this key is an arbitrary number of score entries, where each +score entry has one to four elements. +@enumerate + +@item +The first element is the @dfn{match element}. On most headers this will +be a string, but on the Lines and Chars headers, this must be an +integer. -The Agent works with any Gnus back end including those, such as -nnimap, that store flags (read, ticked, etc) on the server. Sadly, -the Agent does not actually know which backends keep their flags in -the backend server rather than in @file{.newsrc}. This means that the -Agent, while unplugged or disconnected, will always record all changes -to the flags in its own files. +@item +If the second element is present, it should be a number---the @dfn{score +element}. This number should be an integer in the neginf to posinf +interval. This number is added to the score of the article if the match +is successful. If this element is not present, the +@code{gnus-score-interactive-default-score} number will be used +instead. This is 1000 by default. -When you plug back in, Gnus will then check to see if you have any -changed any flags and ask if you wish to synchronize these with the -server. This behavior is customizable by @code{gnus-agent-synchronize-flags}. +@item +If the third element is present, it should be a number---the @dfn{date +element}. This date says when the last time this score entry matched, +which provides a mechanism for expiring the score entries. It this +element is not present, the score entry is permanent. The date is +represented by the number of days since December 31, 1 BCE. -@vindex gnus-agent-synchronize-flags -If @code{gnus-agent-synchronize-flags} is @code{nil}, the Agent will -never automatically synchronize flags. If it is @code{ask}, which is -the default, the Agent will check if you made any changes and if so -ask if you wish to synchronize these when you re-connect. If it has -any other value, all flags will be synchronized automatically. +@item +If the fourth element is present, it should be a symbol---the @dfn{type +element}. This element specifies what function should be used to see +whether this score entry matches the article. What match types that can +be used depends on what header you wish to perform the match on. +@table @dfn -If you do not wish to synchronize flags automatically when you -re-connect, you can do it manually with the -@code{gnus-agent-synchronize-flags} command that is bound to @kbd{J Y} -in the group buffer. +@item From, Subject, References, Xref, Message-ID +For most header types, there are the @code{r} and @code{R} (regexp), as +well as @code{s} and @code{S} (substring) types, and @code{e} and +@code{E} (exact match), and @code{w} (word match) types. If this +element is not present, Gnus will assume that substring matching should +be used. @code{R}, @code{S}, and @code{E} differ from the others in +that the matches will be done in a case-sensitive manner. All these +one-letter types are really just abbreviations for the @code{regexp}, +@code{string}, @code{exact}, and @code{word} types, which you can use +instead, if you feel like. -Technical note: the synchronization algorithm does not work by ``pushing'' -all local flags to the server, but rather by incrementally updated the -server view of flags by changing only those flags that were changed by -the user. Thus, if you set one flag on an article, quit the group then -re-select the group and remove the flag; the flag will be set and -removed from the server when you ``synchronize''. The queued flag -operations can be found in the per-server @code{flags} file in the Agent -directory. It's emptied when you synchronize flags. +@item Extra +Just as for the standard string overview headers, if you are using +gnus-extra-headers, you can score on these headers' values. In this +case, there is a 5th element in the score entry, being the name of the +header to be scored. The following entry is useful in your +@file{all.SCORE} file in case of spam attacks from a single origin +host, if your @acronym{NNTP} server tracks @samp{NNTP-Posting-Host} in +overviews: -@node Agent and IMAP -@subsection Agent and IMAP +@lisp +("111.222.333.444" -1000 nil s + "NNTP-Posting-Host") +@end lisp -The Agent works with any Gnus back end, including nnimap. However, -since there are some conceptual differences between @acronym{NNTP} and -@acronym{IMAP}, this section (should) provide you with some information to -make Gnus Agent work smoother as a @acronym{IMAP} Disconnected Mode client. +@item Lines, Chars +These two headers use different match types: @code{<}, @code{>}, +@code{=}, @code{>=} and @code{<=}. -Some things are currently not implemented in the Agent that you'd might -expect from a disconnected @acronym{IMAP} client, including: +These predicates are true if -@itemize @bullet +@example +(PREDICATE HEADER MATCH) +@end example -@item -Copying/moving articles into nnimap groups when unplugged. +evaluates to non-@code{nil}. For instance, the advanced match +@code{("lines" 4 <)} (@pxref{Advanced Scoring}) will result in the +following form: -@item -Creating/deleting nnimap groups when unplugged. +@lisp +(< header-value 4) +@end lisp -@end itemize +Or to put it another way: When using @code{<} on @code{Lines} with 4 as +the match, we get the score added if the article has less than 4 lines. +(It's easy to get confused and think it's the other way around. But +it's not. I think.) -@node Outgoing Messages -@subsection Outgoing Messages +When matching on @code{Lines}, be careful because some back ends (like +@code{nndir}) do not generate @code{Lines} header, so every article ends +up being marked as having 0 lines. This can lead to strange results if +you happen to lower score of the articles with few lines. -By default, when Gnus is unplugged, all outgoing messages (both mail -and news) are stored in the draft group ``queue'' (@pxref{Drafts}). -You can view them there after posting, and edit them at will. +@item Date +For the Date header we have three kinda silly match types: +@code{before}, @code{at} and @code{after}. I can't really imagine this +ever being useful, but, like, it would feel kinda silly not to provide +this function. Just in case. You never know. Better safe than sorry. +Once burnt, twice shy. Don't judge a book by its cover. Never not have +sex on a first date. (I have been told that at least one person, and I +quote, ``found this function indispensable'', however.) -You can control the circumstances under which outgoing mail is queued -(see @code{gnus-agent-queue-mail}, @pxref{Agent Variables}). Outgoing -news is always queued when Gnus is unplugged, and never otherwise. +@cindex ISO8601 +@cindex date +A more useful match type is @code{regexp}. With it, you can match the +date string using a regular expression. The date is normalized to +ISO8601 compact format first---@var{YYYYMMDD}@code{T}@var{HHMMSS}. If +you want to match all articles that have been posted on April 1st in +every year, you could use @samp{....0401.........} as a match string, +for instance. (Note that the date is kept in its original time zone, so +this will match articles that were posted when it was April 1st where +the article was posted from. Time zones are such wholesome fun for the +whole family, eh?) -You can send the messages either from the draft group with the special -commands available there, or you can use the @kbd{J S} command in the -group buffer to send all the sendable messages in the draft group. -Posting news will only work when Gnus is plugged, but you can send -mail at any time. +@item Head, Body, All +These three match keys use the same match types as the @code{From} (etc) +header uses. -If sending mail while unplugged does not work for you and you worry -about hitting @kbd{J S} by accident when unplugged, you can have Gnus -ask you to confirm your action (see -@code{gnus-agent-prompt-send-queue}, @pxref{Agent Variables}). +@item Followup +This match key is somewhat special, in that it will match the +@code{From} header, and affect the score of not only the matching +articles, but also all followups to the matching articles. This allows +you e.g. increase the score of followups to your own articles, or +decrease the score of followups to the articles of some known +trouble-maker. Uses the same match types as the @code{From} header +uses. (Using this match key will lead to creation of @file{ADAPT} +files.) -@node Agent Variables -@subsection Agent Variables +@item Thread +This match key works along the same lines as the @code{Followup} match +key. If you say that you want to score on a (sub-)thread started by an +article with a @code{Message-ID} @var{x}, then you add a @samp{thread} +match. This will add a new @samp{thread} match for each article that +has @var{x} in its @code{References} header. (These new @samp{thread} +matches will use the @code{Message-ID}s of these matching articles.) +This will ensure that you can raise/lower the score of an entire thread, +even though some articles in the thread may not have complete +@code{References} headers. Note that using this may lead to +undeterministic scores of the articles in the thread. (Using this match +key will lead to creation of @file{ADAPT} files.) +@end table +@end enumerate -@table @code -@item gnus-agent -@vindex gnus-agent -Is the agent enabled? The default is @code{t}. When first enabled, -the agent will use @code{gnus-agent-auto-agentize-methods} to -automatically mark some back ends as agentized. You may change which -back ends are agentized using the agent commands in the server buffer. +@cindex score file atoms +@item mark +The value of this entry should be a number. Any articles with a score +lower than this number will be marked as read. -To enter the server buffer, use the @kbd{^} -(@code{gnus-group-enter-server-mode}) command in the group buffer. +@item expunge +The value of this entry should be a number. Any articles with a score +lower than this number will be removed from the summary buffer. +@item mark-and-expunge +The value of this entry should be a number. Any articles with a score +lower than this number will be marked as read and removed from the +summary buffer. -@item gnus-agent-directory -@vindex gnus-agent-directory -Where the Gnus Agent will store its files. The default is -@file{~/News/agent/}. +@item thread-mark-and-expunge +The value of this entry should be a number. All articles that belong to +a thread that has a total score below this number will be marked as read +and removed from the summary buffer. @code{gnus-thread-score-function} +says how to compute the total score for a thread. -@item gnus-agent-handle-level -@vindex gnus-agent-handle-level -Groups on levels (@pxref{Group Levels}) higher than this variable will -be ignored by the Agent. The default is @code{gnus-level-subscribed}, -which means that only subscribed group will be considered by the Agent -by default. +@item files +The value of this entry should be any number of file names. These files +are assumed to be score files as well, and will be loaded the same way +this one was. -@item gnus-agent-plugged-hook -@vindex gnus-agent-plugged-hook -Hook run when connecting to the network. +@item exclude-files +The clue of this entry should be any number of files. These files will +not be loaded, even though they would normally be so, for some reason or +other. -@item gnus-agent-unplugged-hook -@vindex gnus-agent-unplugged-hook -Hook run when disconnecting from the network. +@item eval +The value of this entry will be @code{eval}ed. This element will be +ignored when handling global score files. -@item gnus-agent-fetched-hook -@vindex gnus-agent-fetched-hook -Hook run when finished fetching articles. +@item read-only +Read-only score files will not be updated or saved. Global score files +should feature this atom (@pxref{Global Score Files}). (Note: +@dfn{Global} here really means @dfn{global}; not your personal +apply-to-all-groups score files.) -@item gnus-agent-cache -@vindex gnus-agent-cache -Variable to control whether use the locally stored @acronym{NOV} and -articles when plugged, e.g. essentially using the Agent as a cache. -The default is non-@code{nil}, which means to use the Agent as a cache. +@item orphan +The value of this entry should be a number. Articles that do not have +parents will get this number added to their scores. Imagine you follow +some high-volume newsgroup, like @samp{comp.lang.c}. Most likely you +will only follow a few of the threads, also want to see any new threads. -@item gnus-agent-go-online -@vindex gnus-agent-go-online -If @code{gnus-agent-go-online} is @code{nil}, the Agent will never -automatically switch offline servers into online status. If it is -@code{ask}, the default, the Agent will ask if you wish to switch -offline servers into online status when you re-connect. If it has any -other value, all offline servers will be automatically switched into -online status. +You can do this with the following two score file entries: -@item gnus-agent-mark-unread-after-downloaded -@vindex gnus-agent-mark-unread-after-downloaded -If @code{gnus-agent-mark-unread-after-downloaded} is non-@code{nil}, -mark articles as unread after downloading. This is usually a safe -thing to do as the newly downloaded article has obviously not been -read. The default is @code{t}. +@example + (orphan -500) + (mark-and-expunge -100) +@end example -@item gnus-agent-synchronize-flags -@vindex gnus-agent-synchronize-flags -If @code{gnus-agent-synchronize-flags} is @code{nil}, the Agent will -never automatically synchronize flags. If it is @code{ask}, which is -the default, the Agent will check if you made any changes and if so -ask if you wish to synchronize these when you re-connect. If it has -any other value, all flags will be synchronized automatically. +When you enter the group the first time, you will only see the new +threads. You then raise the score of the threads that you find +interesting (with @kbd{I T} or @kbd{I S}), and ignore (@kbd{c y}) the +rest. Next time you enter the group, you will see new articles in the +interesting threads, plus any new threads. -@item gnus-agent-consider-all-articles -@vindex gnus-agent-consider-all-articles -If @code{gnus-agent-consider-all-articles} is non-@code{nil}, the -agent will let the agent predicate decide whether articles need to be -downloaded or not, for all articles. When @code{nil}, the default, -the agent will only let the predicate decide whether unread articles -are downloaded or not. If you enable this, you may also want to look -into the agent expiry settings (@pxref{Category Variables}), so that -the agent doesn't download articles which the agent will later expire, -over and over again. +I.e.---the orphan score atom is for high-volume groups where a few +interesting threads which can't be found automatically by ordinary +scoring rules exist. -@item gnus-agent-max-fetch-size -@vindex gnus-agent-max-fetch-size -The agent fetches articles into a temporary buffer prior to parsing -them into individual files. To avoid exceeding the max. buffer size, -the agent alternates between fetching and parsing until all articles -have been fetched. @code{gnus-agent-max-fetch-size} provides a size -limit to control how often the cycling occurs. A large value improves -performance. A small value minimizes the time lost should the -connection be lost while fetching (You may need to run -@code{gnus-agent-regenerate-group} to update the group's state. -However, all articles parsed prior to losing the connection will be -available while unplugged). The default is 10M so it is unusual to -see any cycling. +@item adapt +This entry controls the adaptive scoring. If it is @code{t}, the +default adaptive scoring rules will be used. If it is @code{ignore}, no +adaptive scoring will be performed on this group. If it is a list, this +list will be used as the adaptive scoring rules. If it isn't present, +or is something other than @code{t} or @code{ignore}, the default +adaptive scoring rules will be used. If you want to use adaptive +scoring on most groups, you'd set @code{gnus-use-adaptive-scoring} to +@code{t}, and insert an @code{(adapt ignore)} in the groups where you do +not want adaptive scoring. If you only want adaptive scoring in a few +groups, you'd set @code{gnus-use-adaptive-scoring} to @code{nil}, and +insert @code{(adapt t)} in the score files of the groups where you want +it. -@item gnus-server-unopen-status -@vindex gnus-server-unopen-status -Perhaps not an Agent variable, but closely related to the Agent, this -variable says what will happen if Gnus cannot open a server. If the -Agent is enabled, the default, @code{nil}, makes Gnus ask the user -whether to deny the server or whether to unplug the agent. If the -Agent is disabled, Gnus always simply deny the server. Other choices -for this variable include @code{denied} and @code{offline} the latter -is only valid if the Agent is used. +@item adapt-file +All adaptive score entries will go to the file named by this entry. It +will also be applied when entering the group. This atom might be handy +if you want to adapt on several groups at once, using the same adaptive +file for a number of groups. -@item gnus-auto-goto-ignores -@vindex gnus-auto-goto-ignores -Another variable that isn't an Agent variable, yet so closely related -that most will look for it here, this variable tells the summary -buffer how to maneuver around undownloaded (only headers stored in the -agent) and unfetched (neither article nor headers stored) articles. +@item local +@cindex local variables +The value of this entry should be a list of @code{(@var{var} +@var{value})} pairs. Each @var{var} will be made buffer-local to the +current summary buffer, and set to the value specified. This is a +convenient, if somewhat strange, way of setting variables in some +groups if you don't like hooks much. Note that the @var{value} won't +be evaluated. +@end table -The valid values are @code{nil} (maneuver to any article), -@code{undownloaded} (maneuvering while unplugged ignores articles that -have not been fetched), @code{always-undownloaded} (maneuvering always -ignores articles that have not been fetched), @code{unfetched} -(maneuvering ignores articles whose headers have not been fetched). -@item gnus-agent-queue-mail -@vindex gnus-agent-queue-mail -When @code{gnus-agent-queue-mail} is @code{always}, Gnus will always -queue mail rather than sending it straight away. When @code{t}, Gnus -will queue mail when unplugged only. When @code{nil}, never queue -mail. The default is @code{t}. +@node Score File Editing +@section Score File Editing -@item gnus-agent-prompt-send-queue -@vindex gnus-agent-prompt-send-queue -When @code{gnus-agent-prompt-send-queue} is non-@code{nil} Gnus will -prompt you to confirm that you really wish to proceed if you hit -@kbd{J S} while unplugged. The default is @code{nil}. +You normally enter all scoring commands from the summary buffer, but you +might feel the urge to edit them by hand as well, so we've supplied you +with a mode for that. -@item gnus-agent-auto-agentize-methods -@vindex gnus-agent-auto-agentize-methods -If you have never used the Agent before (or more technically, if -@file{~/News/agent/lib/servers} does not exist), Gnus will -automatically agentize a few servers for you. This variable control -which back ends should be auto-agentized. It is typically only useful -to agentize remote back ends. The auto-agentizing has the same effect -as running @kbd{J a} on the servers (@pxref{Server Agent Commands}). -If the file exist, you must manage the servers manually by adding or -removing them, this variable is only applicable the first time you -start Gnus. The default is @samp{(nntp nnimap)}. +It's simply a slightly customized @code{emacs-lisp} mode, with these +additional commands: -@end table +@table @kbd +@item C-c C-c +@kindex C-c C-c (Score) +@findex gnus-score-edit-exit +Save the changes you have made and return to the summary buffer +(@code{gnus-score-edit-exit}). -@node Example Setup -@subsection Example Setup +@item C-c C-d +@kindex C-c C-d (Score) +@findex gnus-score-edit-insert-date +Insert the current date in numerical format +(@code{gnus-score-edit-insert-date}). This is really the day number, if +you were wondering. -If you don't want to read this manual, and you have a fairly standard -setup, you may be able to use something like the following as your -@file{~/.gnus.el} file to get started. +@item C-c C-p +@kindex C-c C-p (Score) +@findex gnus-score-pretty-print +The adaptive score files are saved in an unformatted fashion. If you +intend to read one of these files, you want to @dfn{pretty print} it +first. This command (@code{gnus-score-pretty-print}) does that for +you. -@lisp -;; @r{Define how Gnus is to fetch news. We do this over @acronym{NNTP}} -;; @r{from your ISP's server.} -(setq gnus-select-method '(nntp "news.your-isp.com")) +@end table -;; @r{Define how Gnus is to read your mail. We read mail from} -;; @r{your ISP's @acronym{POP} server.} -(setq mail-sources '((pop :server "pop.your-isp.com"))) +Type @kbd{M-x gnus-score-mode} to use this mode. -;; @r{Say how Gnus is to store the mail. We use nnml groups.} -(setq gnus-secondary-select-methods '((nnml ""))) +@vindex gnus-score-mode-hook +@code{gnus-score-menu-hook} is run in score mode buffers. -;; @r{Make Gnus into an offline newsreader.} -;; (gnus-agentize) ; @r{The obsolete setting.} -;; (setq gnus-agent t) ; @r{Now the default.} -@end lisp +In the summary buffer you can use commands like @kbd{V f}, @kbd{V e} and +@kbd{V t} to begin editing score files. -That should be it, basically. Put that in your @file{~/.gnus.el} file, -edit to suit your needs, start up PPP (or whatever), and type @kbd{M-x -gnus}. -If this is the first time you've run Gnus, you will be subscribed -automatically to a few default newsgroups. You'll probably want to -subscribe to more groups, and to do that, you have to query the -@acronym{NNTP} server for a complete list of groups with the @kbd{A A} -command. This usually takes quite a while, but you only have to do it -once. +@node Adaptive Scoring +@section Adaptive Scoring +@cindex adaptive scoring -After reading and parsing a while, you'll be presented with a list of -groups. Subscribe to the ones you want to read with the @kbd{u} -command. @kbd{l} to make all the killed groups disappear after you've -subscribe to all the groups you want to read. (@kbd{A k} will bring -back all the killed groups.) +If all this scoring is getting you down, Gnus has a way of making it all +happen automatically---as if by magic. Or rather, as if by artificial +stupidity, to be precise. -You can now read the groups at once, or you can download the articles -with the @kbd{J s} command. And then read the rest of this manual to -find out which of the other gazillion things you want to customize. +@vindex gnus-use-adaptive-scoring +When you read an article, or mark an article as read, or kill an +article, you leave marks behind. On exit from the group, Gnus can sniff +these marks and add score elements depending on what marks it finds. +You turn on this ability by setting @code{gnus-use-adaptive-scoring} to +@code{t} or @code{(line)}. If you want score adaptively on separate +words appearing in the subjects, you should set this variable to +@code{(word)}. If you want to use both adaptive methods, set this +variable to @code{(word line)}. +@vindex gnus-default-adaptive-score-alist +To give you complete control over the scoring process, you can customize +the @code{gnus-default-adaptive-score-alist} variable. For instance, it +might look something like this: -@node Batching Agents -@subsection Batching Agents -@findex gnus-agent-batch +@lisp +(setq gnus-default-adaptive-score-alist + '((gnus-unread-mark) + (gnus-ticked-mark (from 4)) + (gnus-dormant-mark (from 5)) + (gnus-del-mark (from -4) (subject -1)) + (gnus-read-mark (from 4) (subject 2)) + (gnus-expirable-mark (from -1) (subject -1)) + (gnus-killed-mark (from -1) (subject -3)) + (gnus-kill-file-mark) + (gnus-ancient-mark) + (gnus-low-score-mark) + (gnus-catchup-mark (from -1) (subject -1)))) +@end lisp -Having the Gnus Agent fetch articles (and post whatever messages you've -written) is quite easy once you've gotten things set up properly. The -following shell script will do everything that is necessary: +As you see, each element in this alist has a mark as a key (either a +variable name or a ``real'' mark---a character). Following this key is +a arbitrary number of header/score pairs. If there are no header/score +pairs following the key, no adaptive scoring will be done on articles +that have that key as the article mark. For instance, articles with +@code{gnus-unread-mark} in the example above will not get adaptive score +entries. -You can run a complete batch command from the command line with the -following incantation: +Each article can have only one mark, so just a single of these rules +will be applied to each article. -@example -#!/bin/sh -emacs -batch -l ~/.emacs -l ~/.gnus.el -f gnus-agent-batch >/dev/null 2>&1 -@end example +To take @code{gnus-del-mark} as an example---this alist says that all +articles that have that mark (i.e., are marked with @samp{e}) will have a +score entry added to lower based on the @code{From} header by -4, and +lowered by @code{Subject} by -1. Change this to fit your prejudices. +If you have marked 10 articles with the same subject with +@code{gnus-del-mark}, the rule for that mark will be applied ten times. +That means that that subject will get a score of ten times -1, which +should be, unless I'm much mistaken, -10. -@node Agent Caveats -@subsection Agent Caveats +If you have auto-expirable (mail) groups (@pxref{Expiring Mail}), all +the read articles will be marked with the @samp{E} mark. This'll +probably make adaptive scoring slightly impossible, so auto-expiring and +adaptive scoring doesn't really mix very well. -The Gnus Agent doesn't seem to work like most other offline -newsreaders. Here are some common questions that some imaginary people -may ask: +The headers you can score on are @code{from}, @code{subject}, +@code{message-id}, @code{references}, @code{xref}, @code{lines}, +@code{chars} and @code{date}. In addition, you can score on +@code{followup}, which will create an adaptive score entry that matches +on the @code{References} header using the @code{Message-ID} of the +current article, thereby matching the following thread. -@table @dfn -@item If I read an article while plugged, do they get entered into the Agent? +If you use this scheme, you should set the score file atom @code{mark} +to something small---like -300, perhaps, to avoid having small random +changes result in articles getting marked as read. -@strong{No}. If you want this behavior, add -@code{gnus-agent-fetch-selected-article} to -@code{gnus-select-article-hook}. +After using adaptive scoring for a week or so, Gnus should start to +become properly trained and enhance the authors you like best, and kill +the authors you like least, without you having to say so explicitly. -@item If I read an article while plugged, and the article already exists in -the Agent, will it get downloaded once more? +You can control what groups the adaptive scoring is to be performed on +by using the score files (@pxref{Score File Format}). This will also +let you use different rules in different groups. -@strong{No}, unless @code{gnus-agent-cache} is @code{nil}. +@vindex gnus-adaptive-file-suffix +The adaptive score entries will be put into a file where the name is the +group name with @code{gnus-adaptive-file-suffix} appended. The default +is @file{ADAPT}. -@end table +@vindex gnus-adaptive-pretty-print +Adaptive score files can get huge and are not meant to be edited by +human hands. If @code{gnus-adaptive-pretty-print} is @code{nil} (the +default) those files will not be written in a human readable way. -In short, when Gnus is unplugged, it only looks into the locally stored -articles; when it's plugged, it talks to your ISP and may also use the -locally stored articles. +@vindex gnus-score-exact-adapt-limit +When doing adaptive scoring, substring or fuzzy matching would probably +give you the best results in most cases. However, if the header one +matches is short, the possibility for false positives is great, so if +the length of the match is less than +@code{gnus-score-exact-adapt-limit}, exact matching will be used. If +this variable is @code{nil}, exact matching will always be used to avoid +this problem. +@vindex gnus-default-adaptive-word-score-alist +As mentioned above, you can adapt either on individual words or entire +headers. If you adapt on words, the +@code{gnus-default-adaptive-word-score-alist} variable says what score +each instance of a word should add given a mark. -@node Scoring -@chapter Scoring -@cindex scoring +@lisp +(setq gnus-default-adaptive-word-score-alist + `((,gnus-read-mark . 30) + (,gnus-catchup-mark . -10) + (,gnus-killed-mark . -20) + (,gnus-del-mark . -15))) +@end lisp -Other people use @dfn{kill files}, but we here at Gnus Towers like -scoring better than killing, so we'd rather switch than fight. They do -something completely different as well, so sit up straight and pay -attention! +This is the default value. If you have adaption on words enabled, every +word that appears in subjects of articles marked with +@code{gnus-read-mark} will result in a score rule that increase the +score with 30 points. -@vindex gnus-summary-mark-below -All articles have a default score (@code{gnus-summary-default-score}), -which is 0 by default. This score may be raised or lowered either -interactively or by score files. Articles that have a score lower than -@code{gnus-summary-mark-below} are marked as read. +@vindex gnus-default-ignored-adaptive-words +@vindex gnus-ignored-adaptive-words +Words that appear in the @code{gnus-default-ignored-adaptive-words} list +will be ignored. If you wish to add more words to be ignored, use the +@code{gnus-ignored-adaptive-words} list instead. -Gnus will read any @dfn{score files} that apply to the current group -before generating the summary buffer. +@vindex gnus-adaptive-word-length-limit +Some may feel that short words shouldn't count when doing adaptive +scoring. If so, you may set @code{gnus-adaptive-word-length-limit} to +an integer. Words shorter than this number will be ignored. This +variable defaults to @code{nil}. -There are several commands in the summary buffer that insert score -entries based on the current article. You can, for instance, ask Gnus to -lower or increase the score of all articles with a certain subject. +@vindex gnus-adaptive-word-syntax-table +When the scoring is done, @code{gnus-adaptive-word-syntax-table} is the +syntax table in effect. It is similar to the standard syntax table, but +it considers numbers to be non-word-constituent characters. -There are two sorts of scoring entries: Permanent and temporary. -Temporary score entries are self-expiring entries. Any entries that are -temporary and have not been used for, say, a week, will be removed -silently to help keep the sizes of the score files down. +@vindex gnus-adaptive-word-minimum +If @code{gnus-adaptive-word-minimum} is set to a number, the adaptive +word scoring process will never bring down the score of an article to +below this number. The default is @code{nil}. -@menu -* Summary Score Commands:: Adding score entries for the current group. -* Group Score Commands:: General score commands. -* Score Variables:: Customize your scoring. (My, what terminology). -* Score File Format:: What a score file may contain. -* Score File Editing:: You can edit score files by hand as well. -* Adaptive Scoring:: Big Sister Gnus knows what you read. -* Home Score File:: How to say where new score entries are to go. -* Followups To Yourself:: Having Gnus notice when people answer you. -* Scoring On Other Headers:: Scoring on non-standard headers. -* Scoring Tips:: How to score effectively. -* Reverse Scoring:: That problem child of old is not problem. -* Global Score Files:: Earth-spanning, ear-splitting score files. -* Kill Files:: They are still here, but they can be ignored. -* Converting Kill Files:: Translating kill files to score files. -* Advanced Scoring:: Using logical expressions to build score rules. -* Score Decays:: It can be useful to let scores wither away. -@end menu +@vindex gnus-adaptive-word-no-group-words +If @code{gnus-adaptive-word-no-group-words} is set to @code{t}, gnus +won't adaptively word score any of the words in the group name. Useful +for groups like @samp{comp.editors.emacs}, where most of the subject +lines contain the word @samp{emacs}. +After using this scheme for a while, it might be nice to write a +@code{gnus-psychoanalyze-user} command to go through the rules and see +what words you like and what words you don't like. Or perhaps not. -@node Summary Score Commands -@section Summary Score Commands -@cindex score commands +Note that the adaptive word scoring thing is highly experimental and is +likely to change in the future. Initial impressions seem to indicate +that it's totally useless as it stands. Some more work (involving more +rigorous statistical methods) will have to be done to make this useful. -The score commands that alter score entries do not actually modify real -score files. That would be too inefficient. Gnus maintains a cache of -previously loaded score files, one of which is considered the -@dfn{current score file alist}. The score commands simply insert -entries into this list, and upon group exit, this list is saved. -The current score file is by default the group's local score file, even -if no such score file actually exists. To insert score commands into -some other score file (e.g. @file{all.SCORE}), you must first make this -score file the current one. +@node Home Score File +@section Home Score File -General score commands that don't actually change the score file: +The score file where new score file entries will go is called the +@dfn{home score file}. This is normally (and by default) the score file +for the group itself. For instance, the home score file for +@samp{gnu.emacs.gnus} is @file{gnu.emacs.gnus.SCORE}. -@table @kbd +However, this may not be what you want. It is often convenient to share +a common home score file among many groups---all @samp{emacs} groups +could perhaps use the same home score file. -@item V s -@kindex V s (Summary) -@findex gnus-summary-set-score -Set the score of the current article (@code{gnus-summary-set-score}). +@vindex gnus-home-score-file +The variable that controls this is @code{gnus-home-score-file}. It can +be: -@item V S -@kindex V S (Summary) -@findex gnus-summary-current-score -Display the score of the current article -(@code{gnus-summary-current-score}). +@enumerate +@item +A string. Then this file will be used as the home score file for all +groups. -@item V t -@kindex V t (Summary) -@findex gnus-score-find-trace -Display all score rules that have been used on the current article -(@code{gnus-score-find-trace}). In the @code{*Score Trace*} buffer, you -may type @kbd{e} to edit score file corresponding to the score rule on -current line and @kbd{f} to format (@code{gnus-score-pretty-print}) the -score file and edit it. +@item +A function. The result of this function will be used as the home score +file. The function will be called with the name of the group as the +parameter. -@item V w -@kindex V w (Summary) -@findex gnus-score-find-favourite-words -List words used in scoring (@code{gnus-score-find-favourite-words}). +@item +A list. The elements in this list can be: -@item V R -@kindex V R (Summary) -@findex gnus-summary-rescore -Run the current summary through the scoring process -(@code{gnus-summary-rescore}). This might be useful if you're playing -around with your score files behind Gnus' back and want to see the -effect you're having. +@enumerate +@item +@code{(@var{regexp} @var{file-name})}. If the @var{regexp} matches the +group name, the @var{file-name} will be used as the home score file. -@item V c -@kindex V c (Summary) -@findex gnus-score-change-score-file -Make a different score file the current -(@code{gnus-score-change-score-file}). +@item +A function. If the function returns non-@code{nil}, the result will +be used as the home score file. The function will be called with the +name of the group as the parameter. -@item V e -@kindex V e (Summary) -@findex gnus-score-edit-current-scores -Edit the current score file (@code{gnus-score-edit-current-scores}). -You will be popped into a @code{gnus-score-mode} buffer (@pxref{Score -File Editing}). +@item +A string. Use the string as the home score file. +@end enumerate -@item V f -@kindex V f (Summary) -@findex gnus-score-edit-file -Edit a score file and make this score file the current one -(@code{gnus-score-edit-file}). +The list will be traversed from the beginning towards the end looking +for matches. -@item V F -@kindex V F (Summary) -@findex gnus-score-flush-cache -Flush the score cache (@code{gnus-score-flush-cache}). This is useful -after editing score files. +@end enumerate -@item V C -@kindex V C (Summary) -@findex gnus-score-customize -Customize a score file in a visually pleasing manner -(@code{gnus-score-customize}). +So, if you want to use just a single score file, you could say: -@end table +@lisp +(setq gnus-home-score-file + "my-total-score-file.SCORE") +@end lisp -The rest of these commands modify the local score file. +If you want to use @file{gnu.SCORE} for all @samp{gnu} groups and +@file{rec.SCORE} for all @samp{rec} groups (and so on), you can say: -@table @kbd +@findex gnus-hierarchial-home-score-file +@lisp +(setq gnus-home-score-file + 'gnus-hierarchial-home-score-file) +@end lisp -@item V m -@kindex V m (Summary) -@findex gnus-score-set-mark-below -Prompt for a score, and mark all articles with a score below this as -read (@code{gnus-score-set-mark-below}). +This is a ready-made function provided for your convenience. +Other functions include -@item V x -@kindex V x (Summary) -@findex gnus-score-set-expunge-below -Prompt for a score, and add a score rule to the current score file to -expunge all articles below this score -(@code{gnus-score-set-expunge-below}). -@end table +@table @code +@item gnus-current-home-score-file +@findex gnus-current-home-score-file +Return the ``current'' regular score file. This will make scoring +commands add entry to the ``innermost'' matching score file. -The keystrokes for actually making score entries follow a very regular -pattern, so there's no need to list all the commands. (Hundreds of -them.) +@end table -@findex gnus-summary-increase-score -@findex gnus-summary-lower-score +If you want to have one score file for the @samp{emacs} groups and +another for the @samp{comp} groups, while letting all other groups use +their own home score files: -@enumerate -@item -The first key is either @kbd{I} (upper case i) for increasing the score -or @kbd{L} for lowering the score. -@item -The second key says what header you want to score on. The following -keys are available: -@table @kbd +@lisp +(setq gnus-home-score-file + ;; @r{All groups that match the regexp @code{"\\.emacs"}} + '(("\\.emacs" "emacs.SCORE") + ;; @r{All the comp groups in one score file} + ("^comp" "comp.SCORE"))) +@end lisp -@item a -Score on the author name. +@vindex gnus-home-adapt-file +@code{gnus-home-adapt-file} works exactly the same way as +@code{gnus-home-score-file}, but says what the home adaptive score file +is instead. All new adaptive file entries will go into the file +specified by this variable, and the same syntax is allowed. -@item s -Score on the subject line. +In addition to using @code{gnus-home-score-file} and +@code{gnus-home-adapt-file}, you can also use group parameters +(@pxref{Group Parameters}) and topic parameters (@pxref{Topic +Parameters}) to achieve much the same. Group and topic parameters take +precedence over this variable. -@item x -Score on the @code{Xref} line---i.e., the cross-posting line. -@item r -Score on the @code{References} line. +@node Followups To Yourself +@section Followups To Yourself -@item d -Score on the date. +Gnus offers two commands for picking out the @code{Message-ID} header in +the current buffer. Gnus will then add a score rule that scores using +this @code{Message-ID} on the @code{References} header of other +articles. This will, in effect, increase the score of all articles that +respond to the article in the current buffer. Quite useful if you want +to easily note when people answer what you've said. -@item l -Score on the number of lines. +@table @code -@item i -Score on the @code{Message-ID} header. +@item gnus-score-followup-article +@findex gnus-score-followup-article +This will add a score to articles that directly follow up your own +article. -@item e -Score on an ``extra'' header, that is, one of those in gnus-extra-headers, -if your @acronym{NNTP} server tracks additional header data in overviews. +@item gnus-score-followup-thread +@findex gnus-score-followup-thread +This will add a score to all articles that appear in a thread ``below'' +your own article. +@end table -@item f -Score on followups---this matches the author name, and adds scores to -the followups to this author. (Using this key leads to the creation of -@file{ADAPT} files.) +@vindex message-sent-hook +These two functions are both primarily meant to be used in hooks like +@code{message-sent-hook}, like this: +@lisp +(add-hook 'message-sent-hook 'gnus-score-followup-thread) +@end lisp -@item b -Score on the body. -@item h -Score on the head. +If you look closely at your own @code{Message-ID}, you'll notice that +the first two or three characters are always the same. Here's two of +mine: -@item t -Score on thread. (Using this key leads to the creation of @file{ADAPT} -files.) +@example + + +@end example -@end table +So ``my'' ident on this machine is @samp{x6}. This can be +exploited---the following rule will raise the score on all followups to +myself: -@item -The third key is the match type. Which match types are valid depends on -what headers you are scoring on. +@lisp +("references" + ("" + 1000 nil r)) +@end lisp -@table @code +Whether it's the first two or first three characters that are ``yours'' +is system-dependent. -@item strings -@table @kbd +@node Scoring On Other Headers +@section Scoring On Other Headers +@cindex scoring on other headers -@item e -Exact matching. +Gnus is quite fast when scoring the ``traditional'' +headers---@samp{From}, @samp{Subject} and so on. However, scoring +other headers requires writing a @code{head} scoring rule, which means +that Gnus has to request every single article from the back end to find +matches. This takes a long time in big groups. -@item s -Substring matching. +@vindex gnus-inhibit-slow-scoring +You can inhibit this slow scoring on headers or body by setting the +variable @code{gnus-inhibit-slow-scoring}. If +@code{gnus-inhibit-slow-scoring} is regexp, slow scoring is inhibited if +the group matches the regexp. If it is t, slow scoring on it is +inhibited for all groups. -@item f -Fuzzy matching (@pxref{Fuzzy Matching}). +Now, there's not much you can do about the slowness for news groups, but for +mail groups, you have greater control. In @ref{To From Newsgroups}, +it's explained in greater detail what this mechanism does, but here's +a cookbook example for @code{nnml} on how to allow scoring on the +@samp{To} and @samp{Cc} headers. -@item r -Regexp matching -@end table +Put the following in your @file{~/.gnus.el} file. -@item date -@table @kbd +@lisp +(setq gnus-extra-headers '(To Cc Newsgroups Keywords) + nnmail-extra-headers gnus-extra-headers) +@end lisp -@item b -Before date. +Restart Gnus and rebuild your @code{nnml} overview files with the +@kbd{M-x nnml-generate-nov-databases} command. This will take a long +time if you have much mail. -@item a -After date. +Now you can score on @samp{To} and @samp{Cc} as ``extra headers'' like +so: @kbd{I e s p To RET RET}. -@item n -This date. -@end table +See? Simple. -@item number -@table @kbd -@item < -Less than number. +@node Scoring Tips +@section Scoring Tips +@cindex scoring tips -@item = -Equal to number. +@table @dfn -@item > -Greater than number. -@end table -@end table +@item Crossposts +@cindex crossposts +@cindex scoring crossposts +If you want to lower the score of crossposts, the line to match on is +the @code{Xref} header. +@lisp +("xref" (" talk.politics.misc:" -1000)) +@end lisp -@item -The fourth and usually final key says whether this is a temporary (i.e., -expiring) score entry, or a permanent (i.e., non-expiring) score entry, -or whether it is to be done immediately, without adding to the score -file. -@table @kbd +@item Multiple crossposts +If you want to lower the score of articles that have been crossposted to +more than, say, 3 groups: +@lisp +("xref" + ("[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+" + -1000 nil r)) +@end lisp -@item t -Temporary score entry. +@item Matching on the body +This is generally not a very good idea---it takes a very long time. +Gnus actually has to fetch each individual article from the server. But +you might want to anyway, I guess. Even though there are three match +keys (@code{Head}, @code{Body} and @code{All}), you should choose one +and stick with it in each score file. If you use any two, each article +will be fetched @emph{twice}. If you want to match a bit on the +@code{Head} and a bit on the @code{Body}, just use @code{All} for all +the matches. -@item p -Permanent score entry. +@item Marking as read +You will probably want to mark articles that have scores below a certain +number as read. This is most easily achieved by putting the following +in your @file{all.SCORE} file: +@lisp +((mark -100)) +@end lisp +You may also consider doing something similar with @code{expunge}. -@item i -Immediately scoring. +@item Negated character classes +If you say stuff like @code{[^abcd]*}, you may get unexpected results. +That will match newlines, which might lead to, well, The Unknown. Say +@code{[^abcd\n]*} instead. @end table -@item -If you are scoring on `e' (extra) headers, you will then be prompted for -the header name on which you wish to score. This must be a header named -in gnus-extra-headers, and @samp{TAB} completion is available. - -@end enumerate -So, let's say you want to increase the score on the current author with -exact matching permanently: @kbd{I a e p}. If you want to lower the -score based on the subject line, using substring matching, and make a -temporary score entry: @kbd{L s s t}. Pretty easy. +@node Reverse Scoring +@section Reverse Scoring +@cindex reverse scoring -To make things a bit more complicated, there are shortcuts. If you use -a capital letter on either the second or third keys, Gnus will use -defaults for the remaining one or two keystrokes. The defaults are -``substring'' and ``temporary''. So @kbd{I A} is the same as @kbd{I a s -t}, and @kbd{I a R} is the same as @kbd{I a r t}. +If you want to keep just articles that have @samp{Sex with Emacs} in the +subject header, and expunge all other articles, you could put something +like this in your score file: -These functions take both the numerical prefix and the symbolic prefix -(@pxref{Symbolic Prefixes}). A numerical prefix says how much to lower -(or increase) the score of the article. A symbolic prefix of @code{a} -says to use the @file{all.SCORE} file for the command instead of the -current score file. +@lisp +(("subject" + ("Sex with Emacs" 2)) + (mark 1) + (expunge 1)) +@end lisp -@vindex gnus-score-mimic-keymap -The @code{gnus-score-mimic-keymap} says whether these commands will -pretend they are keymaps or not. +So, you raise all articles that match @samp{Sex with Emacs} and mark the +rest as read, and expunge them to boot. -@node Group Score Commands -@section Group Score Commands -@cindex group score commands +@node Global Score Files +@section Global Score Files +@cindex global score files -There aren't many of these as yet, I'm afraid. +Sure, other newsreaders have ``global kill files''. These are usually +nothing more than a single kill file that applies to all groups, stored +in the user's home directory. Bah! Puny, weak newsreaders! -@table @kbd +What I'm talking about here are Global Score Files. Score files from +all over the world, from users everywhere, uniting all nations in one +big, happy score file union! Ange-score! New and untested! -@item W e -@kindex W e (Group) -@findex gnus-score-edit-all-score -Edit the apply-to-all-groups all.SCORE file. You will be popped into -a @code{gnus-score-mode} buffer (@pxref{Score File Editing}). +@vindex gnus-global-score-files +All you have to do to use other people's score files is to set the +@code{gnus-global-score-files} variable. One entry for each score file, +or each score file directory. Gnus will decide by itself what score +files are applicable to which group. -@item W f -@kindex W f (Group) -@findex gnus-score-flush-cache -Gnus maintains a cache of score alists to avoid having to reload them -all the time. This command will flush the cache -(@code{gnus-score-flush-cache}). +To use the score file +@file{/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE} and +all score files in the @file{/ftp@@ftp.some-where:/pub/score} directory, +say this: -@end table +@lisp +(setq gnus-global-score-files + '("/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE" + "/ftp@@ftp.some-where:/pub/score/")) +@end lisp -You can do scoring from the command line by saying something like: +@findex gnus-score-search-global-directories +@noindent +Simple, eh? Directory names must end with a @samp{/}. These +directories are typically scanned only once during each Gnus session. +If you feel the need to manually re-scan the remote directories, you can +use the @code{gnus-score-search-global-directories} command. -@findex gnus-batch-score -@cindex batch scoring -@example -$ emacs -batch -l ~/.emacs -l ~/.gnus.el -f gnus-batch-score -@end example +Note that, at present, using this option will slow down group entry +somewhat. (That is---a lot.) +If you want to start maintaining score files for other people to use, +just put your score file up for anonymous ftp and announce it to the +world. Become a retro-moderator! Participate in the retro-moderator +wars sure to ensue, where retro-moderators battle it out for the +sympathy of the people, luring them to use their score files on false +premises! Yay! The net is saved! -@node Score Variables -@section Score Variables -@cindex score variables +Here are some tips for the would-be retro-moderator, off the top of my +head: -@table @code +@itemize @bullet -@item gnus-use-scoring -@vindex gnus-use-scoring -If @code{nil}, Gnus will not check for score files, and will not, in -general, do any score-related work. This is @code{t} by default. +@item +Articles heavily crossposted are probably junk. +@item +To lower a single inappropriate article, lower by @code{Message-ID}. +@item +Particularly brilliant authors can be raised on a permanent basis. +@item +Authors that repeatedly post off-charter for the group can safely be +lowered out of existence. +@item +Set the @code{mark} and @code{expunge} atoms to obliterate the nastiest +articles completely. -@item gnus-kill-killed -@vindex gnus-kill-killed -If this variable is @code{nil}, Gnus will never apply score files to -articles that have already been through the kill process. While this -may save you lots of time, it also means that if you apply a kill file -to a group, and then change the kill file and want to run it over you -group again to kill more articles, it won't work. You have to set this -variable to @code{t} to do that. (It is @code{t} by default.) +@item +Use expiring score entries to keep the size of the file down. You +should probably have a long expiry period, though, as some sites keep +old articles for a long time. +@end itemize -@item gnus-kill-files-directory -@vindex gnus-kill-files-directory -All kill and score files will be stored in this directory, which is -initialized from the @env{SAVEDIR} environment variable by default. -This is @file{~/News/} by default. +@dots{} I wonder whether other newsreaders will support global score files +in the future. @emph{Snicker}. Yup, any day now, newsreaders like Blue +Wave, xrn and 1stReader are bound to implement scoring. Should we start +holding our breath yet? -@item gnus-score-file-suffix -@vindex gnus-score-file-suffix -Suffix to add to the group name to arrive at the score file name -(@file{SCORE} by default.) -@item gnus-score-uncacheable-files -@vindex gnus-score-uncacheable-files -@cindex score cache -All score files are normally cached to avoid excessive re-loading of -score files. However, this might make your Emacs grow big and -bloated, so this regexp can be used to weed out score files unlikely -to be needed again. It would be a bad idea to deny caching of -@file{all.SCORE}, while it might be a good idea to not cache -@file{comp.infosystems.www.authoring.misc.ADAPT}. In fact, this -variable is @samp{ADAPT$} by default, so no adaptive score files will -be cached. +@node Kill Files +@section Kill Files +@cindex kill files -@item gnus-save-score -@vindex gnus-save-score -If you have really complicated score files, and do lots of batch -scoring, then you might set this variable to @code{t}. This will make -Gnus save the scores into the @file{.newsrc.eld} file. +Gnus still supports those pesky old kill files. In fact, the kill file +entries can now be expiring, which is something I wrote before Daniel +Quinlan thought of doing score files, so I've left the code in there. -If you do not set this to @code{t}, then manual scores (like those set -with @kbd{V s} (@code{gnus-summary-set-score})) will not be preserved -across group visits. +In short, kill processing is a lot slower (and I do mean @emph{a lot}) +than score processing, so it might be a good idea to rewrite your kill +files into score files. -@item gnus-score-interactive-default-score -@vindex gnus-score-interactive-default-score -Score used by all the interactive raise/lower commands to raise/lower -score with. Default is 1000, which may seem excessive, but this is to -ensure that the adaptive scoring scheme gets enough room to play with. -We don't want the small changes from the adaptive scoring to overwrite -manually entered data. +Anyway, a kill file is a normal @code{emacs-lisp} file. You can put any +forms into this file, which means that you can use kill files as some +sort of primitive hook function to be run on group entry, even though +that isn't a very good idea. -@item gnus-summary-default-score -@vindex gnus-summary-default-score -Default score of an article, which is 0 by default. +Normal kill files look like this: -@item gnus-summary-expunge-below -@vindex gnus-summary-expunge-below -Don't display the summary lines of articles that have scores lower than -this variable. This is @code{nil} by default, which means that no -articles will be hidden. This variable is local to the summary buffers, -and has to be set from @code{gnus-summary-mode-hook}. +@lisp +(gnus-kill "From" "Lars Ingebrigtsen") +(gnus-kill "Subject" "ding") +(gnus-expunge "X") +@end lisp -@item gnus-score-over-mark -@vindex gnus-score-over-mark -Mark (in the third column) used for articles with a score over the -default. Default is @samp{+}. +This will mark every article written by me as read, and remove the +marked articles from the summary buffer. Very useful, you'll agree. -@item gnus-score-below-mark -@vindex gnus-score-below-mark -Mark (in the third column) used for articles with a score below the -default. Default is @samp{-}. +Other programs use a totally different kill file syntax. If Gnus +encounters what looks like a @code{rn} kill file, it will take a stab at +interpreting it. -@item gnus-score-find-score-files-function -@vindex gnus-score-find-score-files-function -Function used to find score files for the current group. This function -is called with the name of the group as the argument. +Two summary functions for editing a @sc{gnus} kill file: -Predefined functions available are: -@table @code +@table @kbd -@item gnus-score-find-single -@findex gnus-score-find-single -Only apply the group's own score file. +@item M-k +@kindex M-k (Summary) +@findex gnus-summary-edit-local-kill +Edit this group's kill file (@code{gnus-summary-edit-local-kill}). -@item gnus-score-find-bnews -@findex gnus-score-find-bnews -Apply all score files that match, using bnews syntax. This is the -default. If the current group is @samp{gnu.emacs.gnus}, for instance, -@file{all.emacs.all.SCORE}, @file{not.alt.all.SCORE} and -@file{gnu.all.SCORE} would all apply. In short, the instances of -@samp{all} in the score file names are translated into @samp{.*}, and -then a regexp match is done. +@item M-K +@kindex M-K (Summary) +@findex gnus-summary-edit-global-kill +Edit the general kill file (@code{gnus-summary-edit-global-kill}). +@end table -This means that if you have some score entries that you want to apply to -all groups, then you put those entries in the @file{all.SCORE} file. +Two group mode functions for editing the kill files: -The score files are applied in a semi-random order, although Gnus will -try to apply the more general score files before the more specific score -files. It does this by looking at the number of elements in the score -file names---discarding the @samp{all} elements. +@table @kbd -@item gnus-score-find-hierarchical -@findex gnus-score-find-hierarchical -Apply all score files from all the parent groups. This means that you -can't have score files like @file{all.SCORE}, but you can have -@file{SCORE}, @file{comp.SCORE} and @file{comp.emacs.SCORE} for each -server. +@item M-k +@kindex M-k (Group) +@findex gnus-group-edit-local-kill +Edit this group's kill file (@code{gnus-group-edit-local-kill}). +@item M-K +@kindex M-K (Group) +@findex gnus-group-edit-global-kill +Edit the general kill file (@code{gnus-group-edit-global-kill}). @end table -This variable can also be a list of functions. In that case, all -these functions will be called with the group name as argument, and -all the returned lists of score files will be applied. These -functions can also return lists of lists of score alists directly. In -that case, the functions that return these non-file score alists -should probably be placed before the ``real'' score file functions, to -ensure that the last score file returned is the local score file. -Phu. -For example, to do hierarchical scoring but use a non-server-specific -overall score file, you could use the value -@example -(list (lambda (group) ("all.SCORE")) - 'gnus-score-find-hierarchical) -@end example +Kill file variables: -@item gnus-score-expiry-days -@vindex gnus-score-expiry-days -This variable says how many days should pass before an unused score file -entry is expired. If this variable is @code{nil}, no score file entries -are expired. It's 7 by default. +@table @code +@item gnus-kill-file-name +@vindex gnus-kill-file-name +A kill file for the group @samp{soc.motss} is normally called +@file{soc.motss.KILL}. The suffix appended to the group name to get +this file name is detailed by the @code{gnus-kill-file-name} variable. +The ``global'' kill file (not in the score file sense of ``global'', of +course) is just called @file{KILL}. -@item gnus-update-score-entry-dates -@vindex gnus-update-score-entry-dates -If this variable is non-@code{nil}, temporary score entries that have -been triggered (matched) will have their dates updated. (This is how Gnus -controls expiry---all non-matched-entries will become too old while -matched entries will stay fresh and young.) However, if you set this -variable to @code{nil}, even matched entries will grow old and will -have to face that oh-so grim reaper. +@vindex gnus-kill-save-kill-file +@item gnus-kill-save-kill-file +If this variable is non-@code{nil}, Gnus will save the +kill file after processing, which is necessary if you use expiring +kills. -@item gnus-score-after-write-file-function -@vindex gnus-score-after-write-file-function -Function called with the name of the score file just written. +@item gnus-apply-kill-hook +@vindex gnus-apply-kill-hook +@findex gnus-apply-kill-file-unless-scored +@findex gnus-apply-kill-file +A hook called to apply kill files to a group. It is +@code{(gnus-apply-kill-file)} by default. If you want to ignore the +kill file if you have a score file for the same group, you can set this +hook to @code{(gnus-apply-kill-file-unless-scored)}. If you don't want +kill files to be processed, you should set this variable to @code{nil}. -@item gnus-score-thread-simplify -@vindex gnus-score-thread-simplify -If this variable is non-@code{nil}, article subjects will be -simplified for subject scoring purposes in the same manner as with -threading---according to the current value of -@code{gnus-simplify-subject-functions}. If the scoring entry uses -@code{substring} or @code{exact} matching, the match will also be -simplified in this manner. +@item gnus-kill-file-mode-hook +@vindex gnus-kill-file-mode-hook +A hook called in kill-file mode buffers. @end table -@node Score File Format -@section Score File Format -@cindex score file format - -A score file is an @code{emacs-lisp} file that normally contains just a -single form. Casual users are not expected to edit these files; -everything can be changed from the summary buffer. +@node Converting Kill Files +@section Converting Kill Files +@cindex kill files +@cindex converting kill files -Anyway, if you'd like to dig into it yourself, here's an example: +If you have loads of old kill files, you may want to convert them into +score files. If they are ``regular'', you can use +the @file{gnus-kill-to-score.el} package; if not, you'll have to do it +by hand. -@lisp -(("from" - ("Lars Ingebrigtsen" -10000) - ("Per Abrahamsen") - ("larsi\\|lmi" -50000 nil R)) - ("subject" - ("Ding is Badd" nil 728373)) - ("xref" - ("alt.politics" -1000 728372 s)) - ("lines" - (2 -100 nil <)) - (mark 0) - (expunge -1000) - (mark-and-expunge -10) - (read-only nil) - (orphan -10) - (adapt t) - (files "/hom/larsi/News/gnu.SCORE") - (exclude-files "all.SCORE") - (local (gnus-newsgroup-auto-expire t) - (gnus-summary-make-false-root empty)) - (eval (ding))) -@end lisp +The kill to score conversion package isn't included in Emacs by default. +You can fetch it from the contrib directory of the Gnus distribution or +from +@uref{http://heim.ifi.uio.no/~larsi/ding-various/gnus-kill-to-score.el}. -This example demonstrates most score file elements. @xref{Advanced -Scoring}, for a different approach. +If your old kill files are very complex---if they contain more +non-@code{gnus-kill} forms than not, you'll have to convert them by +hand. Or just let them be as they are. Gnus will still use them as +before. -Even though this looks much like Lisp code, nothing here is actually -@code{eval}ed. The Lisp reader is used to read this form, though, so it -has to be valid syntactically, if not semantically. -Six keys are supported by this alist: +@node Advanced Scoring +@section Advanced Scoring -@table @code +Scoring on Subjects and From headers is nice enough, but what if you're +really interested in what a person has to say only when she's talking +about a particular subject? Or what if you really don't want to +read what person A has to say when she's following up to person B, but +want to read what she says when she's following up to person C? -@item STRING -If the key is a string, it is the name of the header to perform the -match on. Scoring can only be performed on these eight headers: -@code{From}, @code{Subject}, @code{References}, @code{Message-ID}, -@code{Xref}, @code{Lines}, @code{Chars} and @code{Date}. In addition to -these headers, there are three strings to tell Gnus to fetch the entire -article and do the match on larger parts of the article: @code{Body} -will perform the match on the body of the article, @code{Head} will -perform the match on the head of the article, and @code{All} will -perform the match on the entire article. Note that using any of these -last three keys will slow down group entry @emph{considerably}. The -final ``header'' you can score on is @code{Followup}. These score -entries will result in new score entries being added for all follow-ups -to articles that matches these score entries. +By using advanced scoring rules you may create arbitrarily complex +scoring patterns. -Following this key is an arbitrary number of score entries, where each -score entry has one to four elements. -@enumerate +@menu +* Advanced Scoring Syntax:: A definition. +* Advanced Scoring Examples:: What they look like. +* Advanced Scoring Tips:: Getting the most out of it. +@end menu -@item -The first element is the @dfn{match element}. On most headers this will -be a string, but on the Lines and Chars headers, this must be an -integer. -@item -If the second element is present, it should be a number---the @dfn{score -element}. This number should be an integer in the neginf to posinf -interval. This number is added to the score of the article if the match -is successful. If this element is not present, the -@code{gnus-score-interactive-default-score} number will be used -instead. This is 1000 by default. +@node Advanced Scoring Syntax +@subsection Advanced Scoring Syntax -@item -If the third element is present, it should be a number---the @dfn{date -element}. This date says when the last time this score entry matched, -which provides a mechanism for expiring the score entries. It this -element is not present, the score entry is permanent. The date is -represented by the number of days since December 31, 1 BCE. +Ordinary scoring rules have a string as the first element in the rule. +Advanced scoring rules have a list as the first element. The second +element is the score to be applied if the first element evaluated to a +non-@code{nil} value. -@item -If the fourth element is present, it should be a symbol---the @dfn{type -element}. This element specifies what function should be used to see -whether this score entry matches the article. What match types that can -be used depends on what header you wish to perform the match on. -@table @dfn +These lists may consist of three logical operators, one redirection +operator, and various match operators. -@item From, Subject, References, Xref, Message-ID -For most header types, there are the @code{r} and @code{R} (regexp), as -well as @code{s} and @code{S} (substring) types, and @code{e} and -@code{E} (exact match), and @code{w} (word match) types. If this -element is not present, Gnus will assume that substring matching should -be used. @code{R}, @code{S}, and @code{E} differ from the others in -that the matches will be done in a case-sensitive manner. All these -one-letter types are really just abbreviations for the @code{regexp}, -@code{string}, @code{exact}, and @code{word} types, which you can use -instead, if you feel like. +Logical operators: -@item Extra -Just as for the standard string overview headers, if you are using -gnus-extra-headers, you can score on these headers' values. In this -case, there is a 5th element in the score entry, being the name of the -header to be scored. The following entry is useful in your -@file{all.SCORE} file in case of spam attacks from a single origin -host, if your @acronym{NNTP} server tracks @samp{NNTP-Posting-Host} in -overviews: +@table @code +@item & +@itemx and +This logical operator will evaluate each of its arguments until it finds +one that evaluates to @code{false}, and then it'll stop. If all arguments +evaluate to @code{true} values, then this operator will return +@code{true}. -@lisp -("111.222.333.444" -1000 nil s - "NNTP-Posting-Host") -@end lisp +@item | +@itemx or +This logical operator will evaluate each of its arguments until it finds +one that evaluates to @code{true}. If no arguments are @code{true}, +then this operator will return @code{false}. -@item Lines, Chars -These two headers use different match types: @code{<}, @code{>}, -@code{=}, @code{>=} and @code{<=}. +@item ! +@itemx not +@itemx ¬ +This logical operator only takes a single argument. It returns the +logical negation of the value of its argument. -These predicates are true if +@end table -@example -(PREDICATE HEADER MATCH) -@end example +There is an @dfn{indirection operator} that will make its arguments +apply to the ancestors of the current article being scored. For +instance, @code{1-} will make score rules apply to the parent of the +current article. @code{2-} will make score rules apply to the +grandparent of the current article. Alternatively, you can write +@code{^^}, where the number of @code{^}s (carets) says how far back into +the ancestry you want to go. -evaluates to non-@code{nil}. For instance, the advanced match -@code{("lines" 4 <)} (@pxref{Advanced Scoring}) will result in the -following form: +Finally, we have the match operators. These are the ones that do the +real work. Match operators are header name strings followed by a match +and a match type. A typical match operator looks like @samp{("from" +"Lars Ingebrigtsen" s)}. The header names are the same as when using +simple scoring, and the match types are also the same. -@lisp -(< header-value 4) -@end lisp -Or to put it another way: When using @code{<} on @code{Lines} with 4 as -the match, we get the score added if the article has less than 4 lines. -(It's easy to get confused and think it's the other way around. But -it's not. I think.) +@node Advanced Scoring Examples +@subsection Advanced Scoring Examples -When matching on @code{Lines}, be careful because some back ends (like -@code{nndir}) do not generate @code{Lines} header, so every article ends -up being marked as having 0 lines. This can lead to strange results if -you happen to lower score of the articles with few lines. +Please note that the following examples are score file rules. To +make a complete score file from them, surround them with another pair +of parentheses. -@item Date -For the Date header we have three kinda silly match types: -@code{before}, @code{at} and @code{after}. I can't really imagine this -ever being useful, but, like, it would feel kinda silly not to provide -this function. Just in case. You never know. Better safe than sorry. -Once burnt, twice shy. Don't judge a book by its cover. Never not have -sex on a first date. (I have been told that at least one person, and I -quote, ``found this function indispensable'', however.) +Let's say you want to increase the score of articles written by Lars +when he's talking about Gnus: -@cindex ISO8601 -@cindex date -A more useful match type is @code{regexp}. With it, you can match the -date string using a regular expression. The date is normalized to -ISO8601 compact format first---@var{YYYYMMDD}@code{T}@var{HHMMSS}. If -you want to match all articles that have been posted on April 1st in -every year, you could use @samp{....0401.........} as a match string, -for instance. (Note that the date is kept in its original time zone, so -this will match articles that were posted when it was April 1st where -the article was posted from. Time zones are such wholesome fun for the -whole family, eh?) +@example +@group +((& + ("from" "Lars Ingebrigtsen") + ("subject" "Gnus")) + 1000) +@end group +@end example -@item Head, Body, All -These three match keys use the same match types as the @code{From} (etc) -header uses. +Quite simple, huh? -@item Followup -This match key is somewhat special, in that it will match the -@code{From} header, and affect the score of not only the matching -articles, but also all followups to the matching articles. This allows -you e.g. increase the score of followups to your own articles, or -decrease the score of followups to the articles of some known -trouble-maker. Uses the same match types as the @code{From} header -uses. (Using this match key will lead to creation of @file{ADAPT} -files.) +When he writes long articles, he sometimes has something nice to say: -@item Thread -This match key works along the same lines as the @code{Followup} match -key. If you say that you want to score on a (sub-)thread started by an -article with a @code{Message-ID} @var{x}, then you add a @samp{thread} -match. This will add a new @samp{thread} match for each article that -has @var{x} in its @code{References} header. (These new @samp{thread} -matches will use the @code{Message-ID}s of these matching articles.) -This will ensure that you can raise/lower the score of an entire thread, -even though some articles in the thread may not have complete -@code{References} headers. Note that using this may lead to -undeterministic scores of the articles in the thread. (Using this match -key will lead to creation of @file{ADAPT} files.) -@end table -@end enumerate +@example +((& + ("from" "Lars Ingebrigtsen") + (| + ("subject" "Gnus") + ("lines" 100 >))) + 1000) +@end example -@cindex score file atoms -@item mark -The value of this entry should be a number. Any articles with a score -lower than this number will be marked as read. +However, when he responds to things written by Reig Eigil Logge, you +really don't want to read what he's written: -@item expunge -The value of this entry should be a number. Any articles with a score -lower than this number will be removed from the summary buffer. +@example +((& + ("from" "Lars Ingebrigtsen") + (1- ("from" "Reig Eigil Logge"))) + -100000) +@end example -@item mark-and-expunge -The value of this entry should be a number. Any articles with a score -lower than this number will be marked as read and removed from the -summary buffer. +Everybody that follows up Redmondo when he writes about disappearing +socks should have their scores raised, but only when they talk about +white socks. However, when Lars talks about socks, it's usually not +very interesting: -@item thread-mark-and-expunge -The value of this entry should be a number. All articles that belong to -a thread that has a total score below this number will be marked as read -and removed from the summary buffer. @code{gnus-thread-score-function} -says how to compute the total score for a thread. +@example +((& + (1- + (& + ("from" "redmondo@@.*no" r) + ("body" "disappearing.*socks" t))) + (! ("from" "Lars Ingebrigtsen")) + ("body" "white.*socks")) + 1000) +@end example -@item files -The value of this entry should be any number of file names. These files -are assumed to be score files as well, and will be loaded the same way -this one was. +Suppose you're reading a high volume group and you're only interested +in replies. The plan is to score down all articles that don't have +subject that begin with "Re:", "Fw:" or "Fwd:" and then score up all +parents of articles that have subjects that begin with reply marks. -@item exclude-files -The clue of this entry should be any number of files. These files will -not be loaded, even though they would normally be so, for some reason or -other. +@example +((! ("subject" "re:\\|fwd?:" r)) + -200) +((1- ("subject" "re:\\|fwd?:" r)) + 200) +@end example -@item eval -The value of this entry will be @code{eval}ed. This element will be -ignored when handling global score files. +The possibilities are endless. -@item read-only -Read-only score files will not be updated or saved. Global score files -should feature this atom (@pxref{Global Score Files}). (Note: -@dfn{Global} here really means @dfn{global}; not your personal -apply-to-all-groups score files.) +@node Advanced Scoring Tips +@subsection Advanced Scoring Tips -@item orphan -The value of this entry should be a number. Articles that do not have -parents will get this number added to their scores. Imagine you follow -some high-volume newsgroup, like @samp{comp.lang.c}. Most likely you -will only follow a few of the threads, also want to see any new threads. +The @code{&} and @code{|} logical operators do short-circuit logic. +That is, they stop processing their arguments when it's clear what the +result of the operation will be. For instance, if one of the arguments +of an @code{&} evaluates to @code{false}, there's no point in evaluating +the rest of the arguments. This means that you should put slow matches +(@samp{body}, @samp{header}) last and quick matches (@samp{from}, +@samp{subject}) first. -You can do this with the following two score file entries: +The indirection arguments (@code{1-} and so on) will make their +arguments work on previous generations of the thread. If you say +something like: @example - (orphan -500) - (mark-and-expunge -100) +... +(1- + (1- + ("from" "lars"))) +... @end example -When you enter the group the first time, you will only see the new -threads. You then raise the score of the threads that you find -interesting (with @kbd{I T} or @kbd{I S}), and ignore (@kbd{c y}) the -rest. Next time you enter the group, you will see new articles in the -interesting threads, plus any new threads. +Then that means ``score on the from header of the grandparent of the +current article''. An indirection is quite fast, but it's better to say: -I.e.---the orphan score atom is for high-volume groups where a few -interesting threads which can't be found automatically by ordinary -scoring rules exist. +@example +(1- + (& + ("from" "Lars") + ("subject" "Gnus"))) +@end example -@item adapt -This entry controls the adaptive scoring. If it is @code{t}, the -default adaptive scoring rules will be used. If it is @code{ignore}, no -adaptive scoring will be performed on this group. If it is a list, this -list will be used as the adaptive scoring rules. If it isn't present, -or is something other than @code{t} or @code{ignore}, the default -adaptive scoring rules will be used. If you want to use adaptive -scoring on most groups, you'd set @code{gnus-use-adaptive-scoring} to -@code{t}, and insert an @code{(adapt ignore)} in the groups where you do -not want adaptive scoring. If you only want adaptive scoring in a few -groups, you'd set @code{gnus-use-adaptive-scoring} to @code{nil}, and -insert @code{(adapt t)} in the score files of the groups where you want -it. +than it is to say: -@item adapt-file -All adaptive score entries will go to the file named by this entry. It -will also be applied when entering the group. This atom might be handy -if you want to adapt on several groups at once, using the same adaptive -file for a number of groups. +@example +(& + (1- ("from" "Lars")) + (1- ("subject" "Gnus"))) +@end example -@item local -@cindex local variables -The value of this entry should be a list of @code{(@var{var} -@var{value})} pairs. Each @var{var} will be made buffer-local to the -current summary buffer, and set to the value specified. This is a -convenient, if somewhat strange, way of setting variables in some -groups if you don't like hooks much. Note that the @var{value} won't -be evaluated. -@end table +@node Score Decays +@section Score Decays +@cindex score decays +@cindex decays -@node Score File Editing -@section Score File Editing +You may find that your scores have a tendency to grow without +bounds, especially if you're using adaptive scoring. If scores get too +big, they lose all meaning---they simply max out and it's difficult to +use them in any sensible way. -You normally enter all scoring commands from the summary buffer, but you -might feel the urge to edit them by hand as well, so we've supplied you -with a mode for that. +@vindex gnus-decay-scores +@findex gnus-decay-score +@vindex gnus-decay-score-function +Gnus provides a mechanism for decaying scores to help with this problem. +When score files are loaded and @code{gnus-decay-scores} is +non-@code{nil}, Gnus will run the score files through the decaying +mechanism thereby lowering the scores of all non-permanent score rules. +If @code{gnus-decay-scores} is a regexp, only score files matching this +regexp are treated. E.g. you may set it to @samp{\\.ADAPT\\'} if only +@emph{adaptive} score files should be decayed. The decay itself if +performed by the @code{gnus-decay-score-function} function, which is +@code{gnus-decay-score} by default. Here's the definition of that +function: -It's simply a slightly customized @code{emacs-lisp} mode, with these -additional commands: +@lisp +(defun gnus-decay-score (score) + "Decay SCORE according to `gnus-score-decay-constant' +and `gnus-score-decay-scale'." + (let ((n (- score + (* (if (< score 0) -1 1) + (min (abs score) + (max gnus-score-decay-constant + (* (abs score) + gnus-score-decay-scale))))))) + (if (and (featurep 'xemacs) + ;; XEmacs' floor can handle only the floating point + ;; number below the half of the maximum integer. + (> (abs n) (lsh -1 -2))) + (string-to-number + (car (split-string (number-to-string n) "\\."))) + (floor n)))) +@end lisp -@table @kbd +@vindex gnus-score-decay-scale +@vindex gnus-score-decay-constant +@code{gnus-score-decay-constant} is 3 by default and +@code{gnus-score-decay-scale} is 0.05. This should cause the following: -@item C-c C-c -@kindex C-c C-c (Score) -@findex gnus-score-edit-exit -Save the changes you have made and return to the summary buffer -(@code{gnus-score-edit-exit}). +@enumerate +@item +Scores between -3 and 3 will be set to 0 when this function is called. -@item C-c C-d -@kindex C-c C-d (Score) -@findex gnus-score-edit-insert-date -Insert the current date in numerical format -(@code{gnus-score-edit-insert-date}). This is really the day number, if -you were wondering. +@item +Scores with magnitudes between 3 and 60 will be shrunk by 3. -@item C-c C-p -@kindex C-c C-p (Score) -@findex gnus-score-pretty-print -The adaptive score files are saved in an unformatted fashion. If you -intend to read one of these files, you want to @dfn{pretty print} it -first. This command (@code{gnus-score-pretty-print}) does that for -you. +@item +Scores with magnitudes greater than 60 will be shrunk by 5% of the +score. +@end enumerate -@end table +If you don't like this decay function, write your own. It is called +with the score to be decayed as its only parameter, and it should return +the new score, which should be an integer. -Type @kbd{M-x gnus-score-mode} to use this mode. +Gnus will try to decay scores once a day. If you haven't run Gnus for +four days, Gnus will decay the scores four times, for instance. -@vindex gnus-score-mode-hook -@code{gnus-score-menu-hook} is run in score mode buffers. +@node Searching +@chapter Searching +@cindex searching -In the summary buffer you can use commands like @kbd{V f}, @kbd{V e} and -@kbd{V t} to begin editing score files. +FIXME: Add a brief overview of Gnus search capabilities. A brief +comparison of nnir, nnmairix, contrib/gnus-namazu would be nice +as well. +This chapter describes tools for searching groups and servers for +articles matching a query and then retrieving those articles. Gnus +provides a simpler mechanism for searching through articles in a summary buffer +to find those matching a pattern. @xref{Searching for Articles}. -@node Adaptive Scoring -@section Adaptive Scoring -@cindex adaptive scoring +@menu +* nnir:: Searching with various engines. +* nnmairix:: Searching with Mairix. +@end menu -If all this scoring is getting you down, Gnus has a way of making it all -happen automatically---as if by magic. Or rather, as if by artificial -stupidity, to be precise. +@node nnir +@section nnir +@cindex nnir -@vindex gnus-use-adaptive-scoring -When you read an article, or mark an article as read, or kill an -article, you leave marks behind. On exit from the group, Gnus can sniff -these marks and add score elements depending on what marks it finds. -You turn on this ability by setting @code{gnus-use-adaptive-scoring} to -@code{t} or @code{(line)}. If you want score adaptively on separate -words appearing in the subjects, you should set this variable to -@code{(word)}. If you want to use both adaptive methods, set this -variable to @code{(word line)}. +This section describes how to use @code{nnir} to search for articles +within gnus. -@vindex gnus-default-adaptive-score-alist -To give you complete control over the scoring process, you can customize -the @code{gnus-default-adaptive-score-alist} variable. For instance, it -might look something like this: +@menu +* What is nnir:: What does nnir do? +* Basic Usage:: How to perform simple searches. +* Setting up nnir:: How to set up nnir. +@end menu -@lisp -(setq gnus-default-adaptive-score-alist - '((gnus-unread-mark) - (gnus-ticked-mark (from 4)) - (gnus-dormant-mark (from 5)) - (gnus-del-mark (from -4) (subject -1)) - (gnus-read-mark (from 4) (subject 2)) - (gnus-expirable-mark (from -1) (subject -1)) - (gnus-killed-mark (from -1) (subject -3)) - (gnus-kill-file-mark) - (gnus-ancient-mark) - (gnus-low-score-mark) - (gnus-catchup-mark (from -1) (subject -1)))) -@end lisp +@node What is nnir +@subsection What is nnir -As you see, each element in this alist has a mark as a key (either a -variable name or a ``real'' mark---a character). Following this key is -a arbitrary number of header/score pairs. If there are no header/score -pairs following the key, no adaptive scoring will be done on articles -that have that key as the article mark. For instance, articles with -@code{gnus-unread-mark} in the example above will not get adaptive score -entries. +@code{nnir} is a gnus interface to a number of tools for searching +through mail and news repositories. Different backends (like +@code{nnimap} and @code{nntp}) work with different tools (called +@dfn{engines} in nnir lingo), but all use the same basic search +interface. -Each article can have only one mark, so just a single of these rules -will be applied to each article. +The @code{nnimap} and @code{gmane} search engines should work with no +configuration. Other engines require a local index that needs to be +created and maintained outside of Gnus. + +@node Basic Usage +@subsection Basic Usage + +In the group buffer typing @kbd{G G} will search the group on the +current line by calling @code{gnus-group-make-nnir-group}. This prompts +for a query string, creates an ephemeral @code{nnir} group containing +the articles that match this query, and takes you to a summary buffer +showing these articles. Articles may then be read, moved and deleted +using the usual commands. + +The @code{nnir} group made in this way is an @code{ephemeral} group, and +some changes are not permanent: aside from reading, moving, and +deleting, you can't act on the original article. But there is an +alternative: you can @emph{warp} to the original group for the article +on the current line with @kbd{A W}, aka +@code{gnus-warp-to-article}. Even better, the function +@code{gnus-summary-refer-thread}, bound by default in summary buffers to +@kbd{A T}, will first warp to the original group before it works its +magic and includes all the articles in the thread. From here you can +read, move and delete articles, but also copy them, alter article marks, +whatever. Go nuts. + +You say you want to search more than just the group on the current line? +No problem: just process-mark the groups you want to search. You want +even more? Calling for an nnir search with the cursor on a topic heading +will search all the groups under that heading. + +Still not enough? OK, in the server buffer +@code{gnus-group-make-nnir-group} (now bound to @kbd{G}) will search all +groups from the server on the current line. Too much? Want to ignore +certain groups when searching, like spam groups? Just customize +@code{nnir-ignored-newsgroups}. + +One more thing: individual search engines may have special search +features. You can access these special features by giving a prefix-arg +to @code{gnus-group-make-nnir-group}. If you are searching multiple +groups with different search engines you will be prompted for the +special search features for each engine separately. + +@node Setting up nnir +@subsection Setting up nnir + +To set up nnir you may need to do some prep work. Firstly, you may need +to configure the search engines you plan to use. Some of them, like +@code{imap} and @code{gmane}, need no special configuration. Others, +like @code{namazu} and @code{swish}, require configuration as described +below. Secondly, you need to associate a search engine with a server or +a backend. + +If you just want to use the @code{imap} engine to search @code{nnimap} +servers, and the @code{gmane} engine to search @code{gmane} then you +don't have to do anything. But you might want to read the details of the +query language anyway. -To take @code{gnus-del-mark} as an example---this alist says that all -articles that have that mark (i.e., are marked with @samp{e}) will have a -score entry added to lower based on the @code{From} header by -4, and -lowered by @code{Subject} by -1. Change this to fit your prejudices. +@menu +* Associating Engines:: How to associate engines. +* The imap Engine:: Imap configuration and usage. +* The gmane Engine:: Gmane configuration and usage. +* The swish++ Engine:: Swish++ configuration and usage. +* The swish-e Engine:: Swish-e configuration and usage. +* The namazu Engine:: Namazu configuration and usage. +* The hyrex Engine:: Hyrex configuration and usage. +* Customizations:: User customizable settings. +@end menu -If you have marked 10 articles with the same subject with -@code{gnus-del-mark}, the rule for that mark will be applied ten times. -That means that that subject will get a score of ten times -1, which -should be, unless I'm much mistaken, -10. +@node Associating Engines +@subsubsection Associating Engines -If you have auto-expirable (mail) groups (@pxref{Expiring Mail}), all -the read articles will be marked with the @samp{E} mark. This'll -probably make adaptive scoring slightly impossible, so auto-expiring and -adaptive scoring doesn't really mix very well. -The headers you can score on are @code{from}, @code{subject}, -@code{message-id}, @code{references}, @code{xref}, @code{lines}, -@code{chars} and @code{date}. In addition, you can score on -@code{followup}, which will create an adaptive score entry that matches -on the @code{References} header using the @code{Message-ID} of the -current article, thereby matching the following thread. +When searching a group, @code{nnir} needs to know which search engine to +use. You can configure a given server to use a particular engine by +setting the server variable @code{nnir-search-engine} to the engine +name. For example to use the @code{namazu} engine to search the server +named @code{home} you can use -If you use this scheme, you should set the score file atom @code{mark} -to something small---like -300, perhaps, to avoid having small random -changes result in articles getting marked as read. +@lisp +(setq gnus-secondary-select-methods '( + (nnml "home" + (nnimap-address "localhost") + (nnir-search-engine namazu)))) +@end lisp -After using adaptive scoring for a week or so, Gnus should start to -become properly trained and enhance the authors you like best, and kill -the authors you like least, without you having to say so explicitly. +Alternatively you might want to use a particular engine for all servers +with a given backend. For example, you might want to use the @code{imap} +engine for all servers using the @code{nnimap} backend. In this case you +can customize the variable @code{nnir-method-default-engines}. This is +an alist of pairs of the form @code{(backend . engine)}. By default this +variable is set to use the @code{imap} engine for all servers using the +@code{nnimap} backend, and the @code{gmane} backend for @code{nntp} +servers. (Don't worry, the @code{gmane} search engine won't actually try +to search non-gmane @code{nntp} servers.) But if you wanted to use +@code{namazu} for all your servers with an @code{nnimap} backend you +could change this to -You can control what groups the adaptive scoring is to be performed on -by using the score files (@pxref{Score File Format}). This will also -let you use different rules in different groups. +@lisp +'((nnimap . namazu) + (nntp . gmane)) +@end lisp -@vindex gnus-adaptive-file-suffix -The adaptive score entries will be put into a file where the name is the -group name with @code{gnus-adaptive-file-suffix} appended. The default -is @file{ADAPT}. +@node The imap Engine +@subsubsection The imap Engine -@vindex gnus-adaptive-pretty-print -Adaptive score files can get huge and are not meant to be edited by -human hands. If @code{gnus-adaptive-pretty-print} is @code{nil} (the -default) those files will not be written in a human readable way. +The @code{imap} engine requires no configuration. -@vindex gnus-score-exact-adapt-limit -When doing adaptive scoring, substring or fuzzy matching would probably -give you the best results in most cases. However, if the header one -matches is short, the possibility for false positives is great, so if -the length of the match is less than -@code{gnus-score-exact-adapt-limit}, exact matching will be used. If -this variable is @code{nil}, exact matching will always be used to avoid -this problem. +Queries using the @code{imap} engine follow a simple query language. +The search is always case-insensitive and supports the following +features (inspired by the Google search input language): -@vindex gnus-default-adaptive-word-score-alist -As mentioned above, you can adapt either on individual words or entire -headers. If you adapt on words, the -@code{gnus-default-adaptive-word-score-alist} variable says what score -each instance of a word should add given a mark. +@table @samp -@lisp -(setq gnus-default-adaptive-word-score-alist - `((,gnus-read-mark . 30) - (,gnus-catchup-mark . -10) - (,gnus-killed-mark . -20) - (,gnus-del-mark . -15))) -@end lisp +@item Boolean query operators +AND, OR, and NOT are supported, and parentheses can be used to control +operator precedence, e.g. (emacs OR xemacs) AND linux. Note that +operators must be written with all capital letters to be +recognised. Also preceding a term with a - sign is equivalent to NOT +term. -This is the default value. If you have adaption on words enabled, every -word that appears in subjects of articles marked with -@code{gnus-read-mark} will result in a score rule that increase the -score with 30 points. +@item Automatic AND queries +If you specify multiple words then they will be treated as an AND +expression intended to match all components. -@vindex gnus-default-ignored-adaptive-words -@vindex gnus-ignored-adaptive-words -Words that appear in the @code{gnus-default-ignored-adaptive-words} list -will be ignored. If you wish to add more words to be ignored, use the -@code{gnus-ignored-adaptive-words} list instead. +@item Phrase searches +If you wrap your query in double-quotes then it will be treated as a +literal string. -@vindex gnus-adaptive-word-length-limit -Some may feel that short words shouldn't count when doing adaptive -scoring. If so, you may set @code{gnus-adaptive-word-length-limit} to -an integer. Words shorter than this number will be ignored. This -variable defaults to @code{nil}. +@end table -@vindex gnus-adaptive-word-syntax-table -When the scoring is done, @code{gnus-adaptive-word-syntax-table} is the -syntax table in effect. It is similar to the standard syntax table, but -it considers numbers to be non-word-constituent characters. +By default the whole message will be searched. The query can be limited +to a specific part of a message by using a prefix-arg. After inputting +the query this will prompt (with completion) for a message part. +Choices include ``Whole message'', ``Subject'', ``From'', and +``To''. Any unrecognized input is interpreted as a header name. For +example, typing @kbd{Message-ID} in response to this prompt will limit +the query to the Message-ID header. -@vindex gnus-adaptive-word-minimum -If @code{gnus-adaptive-word-minimum} is set to a number, the adaptive -word scoring process will never bring down the score of an article to -below this number. The default is @code{nil}. +Finally selecting ``Imap'' will interpret the query as a raw +@acronym{IMAP} search query. The format of such queries can be found in +RFC3501. -@vindex gnus-adaptive-word-no-group-words -If @code{gnus-adaptive-word-no-group-words} is set to @code{t}, gnus -won't adaptively word score any of the words in the group name. Useful -for groups like @samp{comp.editors.emacs}, where most of the subject -lines contain the word @samp{emacs}. +If you don't like the default of searching whole messages you can +customize @code{nnir-imap-default-search-key}. For example to use +@acronym{IMAP} queries by default -After using this scheme for a while, it might be nice to write a -@code{gnus-psychoanalyze-user} command to go through the rules and see -what words you like and what words you don't like. Or perhaps not. +@lisp +(setq nnir-imap-default-search-key "Imap") +@end lisp -Note that the adaptive word scoring thing is highly experimental and is -likely to change in the future. Initial impressions seem to indicate -that it's totally useless as it stands. Some more work (involving more -rigorous statistical methods) will have to be done to make this useful. +@node The gmane Engine +@subsubsection The gmane Engine +The @code{gmane} engine requires no configuration. -@node Home Score File -@section Home Score File +Gmane queries follow a simple query language: -The score file where new score file entries will go is called the -@dfn{home score file}. This is normally (and by default) the score file -for the group itself. For instance, the home score file for -@samp{gnu.emacs.gnus} is @file{gnu.emacs.gnus.SCORE}. +@table @samp +@item Boolean query operators +AND, OR, NOT (or AND NOT), and XOR are supported, and brackets can be +used to control operator precedence, e.g. (emacs OR xemacs) AND linux. +Note that operators must be written with all capital letters to be +recognised. -However, this may not be what you want. It is often convenient to share -a common home score file among many groups---all @samp{emacs} groups -could perhaps use the same home score file. +@item Required and excluded terms ++ and - can be used to require or exclude terms, e.g. football -american -@vindex gnus-home-score-file -The variable that controls this is @code{gnus-home-score-file}. It can -be: +@item Unicode handling +The search engine converts all text to utf-8, so searching should work +in any language. -@enumerate -@item -A string. Then this file will be used as the home score file for all -groups. +@item Stopwords +Common English words (like 'the' and 'a') are ignored by default. You +can override this by prefixing such words with a + (e.g. +the) or +enclosing the word in quotes (e.g. "the"). -@item -A function. The result of this function will be used as the home score -file. The function will be called with the name of the group as the -parameter. +@end table -@item -A list. The elements in this list can be: +The query can be limited to articles by a specific author using a +prefix-arg. After inputting the query this will prompt for an author +name (or part of a name) to match. -@enumerate -@item -@code{(@var{regexp} @var{file-name})}. If the @var{regexp} matches the -group name, the @var{file-name} will be used as the home score file. +@node The swish++ Engine +@subsubsection The swish++ Engine -@item -A function. If the function returns non-@code{nil}, the result will -be used as the home score file. The function will be called with the -name of the group as the parameter. +FIXEM: Say something more here. -@item -A string. Use the string as the home score file. -@end enumerate +Documentation for swish++ may be found at the swish++ sourceforge page: +@uref{http://swishplusplus.sourceforge.net} -The list will be traversed from the beginning towards the end looking -for matches. +@node The swish-e Engine +@subsubsection The swish-e Engine -@end enumerate +FIXEM: Say something more here. -So, if you want to use just a single score file, you could say: +Documentation for swish-e may be found at the swish-e homepage +@uref{http://swish-e.org} -@lisp -(setq gnus-home-score-file - "my-total-score-file.SCORE") -@end lisp +@node The namazu Engine +@subsubsection The namazu Engine -If you want to use @file{gnu.SCORE} for all @samp{gnu} groups and -@file{rec.SCORE} for all @samp{rec} groups (and so on), you can say: +Using the namazu engine requires creating and maintaining index files. +One directory should contain all the index files, and nnir must be told +where to find them by setting the @code{nnir-namazu-index-directory} +variable. -@findex gnus-hierarchial-home-score-file -@lisp -(setq gnus-home-score-file - 'gnus-hierarchial-home-score-file) -@end lisp +To work correctly the @code{nnir-namazu-remove-prefix} variable must +also be correct. This is the prefix to remove from each file name +returned by Namazu in order to get a proper group name (albeit with `/' +instead of `.'). -This is a ready-made function provided for your convenience. -Other functions include +For example, suppose that Namazu returns file names such as +@samp{/home/john/Mail/mail/misc/42}. For this example, use the +following setting: @code{(setq nnir-namazu-remove-prefix +"/home/john/Mail/")} Note the trailing slash. Removing this prefix from +the directory gives @samp{mail/misc/42}. @code{nnir} knows to remove +the @samp{/42} and to replace @samp{/} with @samp{.} to arrive at the +correct group name @samp{mail.misc}. -@table @code -@item gnus-current-home-score-file -@findex gnus-current-home-score-file -Return the ``current'' regular score file. This will make scoring -commands add entry to the ``innermost'' matching score file. +Extra switches may be passed to the namazu search command by setting the +variable @code{nnir-namazu-additional-switches}. It is particularly +important not to pass any any switches to namazu that will change the +output format. Good switches to use include `--sort', `--ascending', +`--early' and `--late'. Refer to the Namazu documentation for further +information on valid switches. -@end table +Mail must first be indexed with the `mknmz' program. Read the documentation +for namazu to create a configuration file. Here is an example: -If you want to have one score file for the @samp{emacs} groups and -another for the @samp{comp} groups, while letting all other groups use -their own home score files: +@cartouche +@example + package conf; # Don't remove this line! -@lisp -(setq gnus-home-score-file - ;; @r{All groups that match the regexp @code{"\\.emacs"}} - '(("\\.emacs" "emacs.SCORE") - ;; @r{All the comp groups in one score file} - ("^comp" "comp.SCORE"))) -@end lisp + # Paths which will not be indexed. Don't use `^' or `$' anchors. + $EXCLUDE_PATH = "spam|sent"; -@vindex gnus-home-adapt-file -@code{gnus-home-adapt-file} works exactly the same way as -@code{gnus-home-score-file}, but says what the home adaptive score file -is instead. All new adaptive file entries will go into the file -specified by this variable, and the same syntax is allowed. + # Header fields which should be searchable. case-insensitive + $REMAIN_HEADER = "from|date|message-id|subject"; -In addition to using @code{gnus-home-score-file} and -@code{gnus-home-adapt-file}, you can also use group parameters -(@pxref{Group Parameters}) and topic parameters (@pxref{Topic -Parameters}) to achieve much the same. Group and topic parameters take -precedence over this variable. + # Searchable fields. case-insensitive + $SEARCH_FIELD = "from|date|message-id|subject"; + # The max length of a word. + $WORD_LENG_MAX = 128; -@node Followups To Yourself -@section Followups To Yourself + # The max length of a field. + $MAX_FIELD_LENGTH = 256; +@end example +@end cartouche -Gnus offers two commands for picking out the @code{Message-ID} header in -the current buffer. Gnus will then add a score rule that scores using -this @code{Message-ID} on the @code{References} header of other -articles. This will, in effect, increase the score of all articles that -respond to the article in the current buffer. Quite useful if you want -to easily note when people answer what you've said. +For this example, mail is stored in the directories @samp{~/Mail/mail/}, +@samp{~/Mail/lists/} and @samp{~/Mail/archive/}, so to index them go to +the index directory set in @code{nnir-namazu-index-directory} and issue +the following command: + +@example +mknmz --mailnews ~/Mail/archive/ ~/Mail/mail/ ~/Mail/lists/ +@end example -@table @code +For maximum searching efficiency you might want to have a cron job run +this command periodically, say every four hours. -@item gnus-score-followup-article -@findex gnus-score-followup-article -This will add a score to articles that directly follow up your own -article. +@node The hyrex Engine +@subsubsection The hyrex Engine +FIXME: Add documentation. -@item gnus-score-followup-thread -@findex gnus-score-followup-thread -This will add a score to all articles that appear in a thread ``below'' -your own article. -@end table +@node Customizations +@subsubsection Custimozations -@vindex message-sent-hook -These two functions are both primarily meant to be used in hooks like -@code{message-sent-hook}, like this: -@lisp -(add-hook 'message-sent-hook 'gnus-score-followup-thread) -@end lisp +@table @code + +@item nnir-method-default-engines +Alist of server backend - search engine pairs. The default associations +are +@example +(nnimap . imap) +(nntp . gmane) +@end example +@item nnir-ignored-newsgroups +A regexp to match newsgroups in the active file that should be skipped +when searching all groups on a server. -If you look closely at your own @code{Message-ID}, you'll notice that -the first two or three characters are always the same. Here's two of -mine: +@item nnir-summary-line-format +The format specification to be used for lines in an nnir summary buffer. +All the items from `gnus-summary-line-format' are available, along with +three items unique to nnir summary buffers: @example - - +%Z Search retrieval score value (integer) +%G Article original full group name (string) +%g Article original short group name (string) @end example -So ``my'' ident on this machine is @samp{x6}. This can be -exploited---the following rule will raise the score on all followups to -myself: +If nil (the default) this will use @code{gnus-summary-line-format}. -@lisp -("references" - ("" - 1000 nil r)) -@end lisp +@item nnir-retrieve-headers-override-function +If non-nil, a function that retrieves article headers rather than using +the gnus built-in function. This function takes an article list and +group as arguments and populates the `nntp-server-buffer' with the +retrieved headers. It should then return either 'nov or 'headers +indicating the retrieved header format. Failure to retrieve headers +should return @code{nil} -Whether it's the first two or first three characters that are ``yours'' -is system-dependent. +If this variable is nil, or if the provided function returns nil for a +search result, @code{gnus-retrieve-headers} will be called instead." -@node Scoring On Other Headers -@section Scoring On Other Headers -@cindex scoring on other headers +@end table -Gnus is quite fast when scoring the ``traditional'' -headers---@samp{From}, @samp{Subject} and so on. However, scoring -other headers requires writing a @code{head} scoring rule, which means -that Gnus has to request every single article from the back end to find -matches. This takes a long time in big groups. -@vindex gnus-inhibit-slow-scoring -You can inhibit this slow scoring on headers or body by setting the -variable @code{gnus-inhibit-slow-scoring}. If -@code{gnus-inhibit-slow-scoring} is regexp, slow scoring is inhibited if -the group matches the regexp. If it is t, slow scoring on it is -inhibited for all groups. +@node nnmairix +@section nnmairix -Now, there's not much you can do about the slowness for news groups, but for -mail groups, you have greater control. In @ref{To From Newsgroups}, -it's explained in greater detail what this mechanism does, but here's -a cookbook example for @code{nnml} on how to allow scoring on the -@samp{To} and @samp{Cc} headers. +@cindex mairix +@cindex nnmairix +This paragraph describes how to set up mairix and the back end +@code{nnmairix} for indexing and searching your mail from within +Gnus. Additionally, you can create permanent ``smart'' groups which are +bound to mairix searches and are automatically updated. -Put the following in your @file{~/.gnus.el} file. +@menu +* About mairix:: About the mairix mail search engine +* nnmairix requirements:: What you will need for using nnmairix +* What nnmairix does:: What does nnmairix actually do? +* Setting up mairix:: Set up your mairix installation +* Configuring nnmairix:: Set up the nnmairix back end +* nnmairix keyboard shortcuts:: List of available keyboard shortcuts +* Propagating marks:: How to propagate marks from nnmairix groups +* nnmairix tips and tricks:: Some tips, tricks and examples +* nnmairix caveats:: Some more stuff you might want to know +@end menu -@lisp -(setq gnus-extra-headers '(To Cc Newsgroups Keywords) - nnmail-extra-headers gnus-extra-headers) -@end lisp +@c FIXME: The markup in this section might need improvement. +@c E.g. adding @samp, @var, @file, @command, etc. +@c Cf. (info "(texinfo)Indicating") -Restart Gnus and rebuild your @code{nnml} overview files with the -@kbd{M-x nnml-generate-nov-databases} command. This will take a long -time if you have much mail. +@node About mairix +@subsection About mairix -Now you can score on @samp{To} and @samp{Cc} as ``extra headers'' like -so: @kbd{I e s p To RET RET}. +Mairix is a tool for indexing and searching words in locally stored +mail. It was written by Richard Curnow and is licensed under the +GPL. Mairix comes with most popular GNU/Linux distributions, but it also +runs under Windows (with cygwin), Mac OS X and Solaris. The homepage can +be found at +@uref{http://www.rpcurnow.force9.co.uk/mairix/index.html} -See? Simple. +Though mairix might not be as flexible as other search tools like +swish++ or namazu, which you can use via the @code{nnir} back end, it +has the prime advantage of being incredibly fast. On current systems, it +can easily search through headers and message bodies of thousands and +thousands of mails in well under a second. Building the database +necessary for searching might take a minute or two, but only has to be +done once fully. Afterwards, the updates are done incrementally and +therefore are really fast, too. Additionally, mairix is very easy to set +up. +For maximum speed though, mairix should be used with mails stored in +@code{Maildir} or @code{MH} format (this includes the @code{nnml} back +end), although it also works with mbox. Mairix presents the search +results by populating a @emph{virtual} maildir/MH folder with symlinks +which point to the ``real'' message files (if mbox is used, copies are +made). Since mairix already presents search results in such a virtual +mail folder, it is very well suited for using it as an external program +for creating @emph{smart} mail folders, which represent certain mail +searches. -@node Scoring Tips -@section Scoring Tips -@cindex scoring tips +@node nnmairix requirements +@subsection nnmairix requirements -@table @dfn +Mairix searches local mail---that means, mairix absolutely must have +direct access to your mail folders. If your mail resides on another +server (e.g. an @acronym{IMAP} server) and you happen to have shell +access, @code{nnmairix} supports running mairix remotely, e.g. via ssh. -@item Crossposts -@cindex crossposts -@cindex scoring crossposts -If you want to lower the score of crossposts, the line to match on is -the @code{Xref} header. -@lisp -("xref" (" talk.politics.misc:" -1000)) -@end lisp +Additionally, @code{nnmairix} only supports the following Gnus back +ends: @code{nnml}, @code{nnmaildir}, and @code{nnimap}. You must use +one of these back ends for using @code{nnmairix}. Other back ends, like +@code{nnmbox}, @code{nnfolder} or @code{nnmh}, won't work. -@item Multiple crossposts -If you want to lower the score of articles that have been crossposted to -more than, say, 3 groups: -@lisp -("xref" - ("[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+ +[^:\n]+:[0-9]+" - -1000 nil r)) -@end lisp +If you absolutely must use mbox and still want to use @code{nnmairix}, +you can set up a local @acronym{IMAP} server, which you then access via +@code{nnimap}. This is a rather massive setup for accessing some mbox +files, so just change to MH or Maildir already... However, if you're +really, really passionate about using mbox, you might want to look into +the package @file{mairix.el}, which comes with Emacs 23. -@item Matching on the body -This is generally not a very good idea---it takes a very long time. -Gnus actually has to fetch each individual article from the server. But -you might want to anyway, I guess. Even though there are three match -keys (@code{Head}, @code{Body} and @code{All}), you should choose one -and stick with it in each score file. If you use any two, each article -will be fetched @emph{twice}. If you want to match a bit on the -@code{Head} and a bit on the @code{Body}, just use @code{All} for all -the matches. +@node What nnmairix does +@subsection What nnmairix does -@item Marking as read -You will probably want to mark articles that have scores below a certain -number as read. This is most easily achieved by putting the following -in your @file{all.SCORE} file: -@lisp -((mark -100)) -@end lisp -You may also consider doing something similar with @code{expunge}. +The back end @code{nnmairix} enables you to call mairix from within Gnus, +either to query mairix with a search term or to update the +database. While visiting a message in the summary buffer, you can use +several pre-defined shortcuts for calling mairix, e.g. to quickly +search for all mails from the sender of the current message or to +display the whole thread associated with the message, even if the +mails are in different folders. -@item Negated character classes -If you say stuff like @code{[^abcd]*}, you may get unexpected results. -That will match newlines, which might lead to, well, The Unknown. Say -@code{[^abcd\n]*} instead. -@end table +Additionally, you can create permanent @code{nnmairix} groups which are bound +to certain mairix searches. This way, you can easily create a group +containing mails from a certain sender, with a certain subject line or +even for one specific thread based on the Message-ID. If you check for +new mail in these folders (e.g. by pressing @kbd{g} or @kbd{M-g}), they +automatically update themselves by calling mairix. + +You might ask why you need @code{nnmairix} at all, since mairix already +creates the group, populates it with links to the mails so that you can +then access it with Gnus, right? Well, this @emph{might} work, but often +does not---at least not without problems. Most probably you will get +strange article counts, and sometimes you might see mails which Gnus +claims have already been canceled and are inaccessible. This is due to +the fact that Gnus isn't really amused when things are happening behind +its back. Another problem can be the mail back end itself, e.g. if you +use mairix with an @acronym{IMAP} server (I had Dovecot complaining +about corrupt index files when mairix changed the contents of the search +group). Using @code{nnmairix} should circumvent these problems. +@code{nnmairix} is not really a mail back end---it's actually more like +a wrapper, sitting between a ``real'' mail back end where mairix stores +the searches and the Gnus front end. You can choose between three +different mail back ends for the mairix folders: @code{nnml}, +@code{nnmaildir} or @code{nnimap}. @code{nnmairix} will call the mairix +binary so that the search results are stored in folders named +@code{zz_mairix--} on this mail back end, but it will +present these folders in the Gnus front end only with @code{}. +You can use an existing mail back end where you already store your mail, +but if you're uncomfortable with @code{nnmairix} creating new mail +groups alongside your other mail, you can also create e.g. a new +@code{nnmaildir} or @code{nnml} server exclusively for mairix, but then +make sure those servers do not accidentally receive your new mail +(@pxref{nnmairix caveats}). A special case exists if you want to use +mairix remotely on an IMAP server with @code{nnimap}---here the mairix +folders and your other mail must be on the same @code{nnimap} back end. -@node Reverse Scoring -@section Reverse Scoring -@cindex reverse scoring +@node Setting up mairix +@subsection Setting up mairix -If you want to keep just articles that have @samp{Sex with Emacs} in the -subject header, and expunge all other articles, you could put something -like this in your score file: +First: create a backup of your mail folders (@pxref{nnmairix caveats}). -@lisp -(("subject" - ("Sex with Emacs" 2)) - (mark 1) - (expunge 1)) -@end lisp +Setting up mairix is easy: simply create a @file{.mairixrc} file with +(at least) the following entries: -So, you raise all articles that match @samp{Sex with Emacs} and mark the -rest as read, and expunge them to boot. +@example +# Your Maildir/MH base folder +base=~/Maildir +@end example +This is the base folder for your mails. All the following directories +are relative to this base folder. If you want to use @code{nnmairix} +with @code{nnimap}, this base directory has to point to the mail +directory where the @acronym{IMAP} server stores the mail folders! -@node Global Score Files -@section Global Score Files -@cindex global score files +@example +maildir= ... your maildir folders which should be indexed ... +mh= ... your nnml/mh folders which should be indexed ... +mbox = ... your mbox files which should be indexed ... +@end example + +This specifies all your mail folders and mbox files (relative to the +base directory!) you want to index with mairix. Note that the +@code{nnml} back end saves mails in MH format, so you have to put those +directories in the @code{mh} line. See the example at the end of this +section and mairixrc's man-page for further details. + +@example +omit=zz_mairix-* +@end example -Sure, other newsreaders have ``global kill files''. These are usually -nothing more than a single kill file that applies to all groups, stored -in the user's home directory. Bah! Puny, weak newsreaders! +@vindex nnmairix-group-prefix +This should make sure that you don't accidentally index the mairix +search results. You can change the prefix of these folders with the +variable @code{nnmairix-group-prefix}. -What I'm talking about here are Global Score Files. Score files from -all over the world, from users everywhere, uniting all nations in one -big, happy score file union! Ange-score! New and untested! +@example +mformat= ... 'maildir' or 'mh' ... +database= ... location of database file ... +@end example -@vindex gnus-global-score-files -All you have to do to use other people's score files is to set the -@code{gnus-global-score-files} variable. One entry for each score file, -or each score file directory. Gnus will decide by itself what score -files are applicable to which group. +The @code{format} setting specifies the output format for the mairix +search folder. Set this to @code{mh} if you want to access search results +with @code{nnml}. Otherwise choose @code{maildir}. -To use the score file -@file{/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE} and -all score files in the @file{/ftp@@ftp.some-where:/pub/score} directory, -say this: +To summarize, here is my shortened @file{.mairixrc} file as an example: -@lisp -(setq gnus-global-score-files - '("/ftp@@ftp.gnus.org:/pub/larsi/ding/score/soc.motss.SCORE" - "/ftp@@ftp.some-where:/pub/score/")) -@end lisp +@example +base=~/Maildir +maildir=.personal:.work:.logcheck:.sent +mh=../Mail/nnml/*... +mbox=../mboxmail/mailarchive_year* +mformat=maildir +omit=zz_mairix-* +database=~/.mairixdatabase +@end example -@findex gnus-score-search-global-directories -@noindent -Simple, eh? Directory names must end with a @samp{/}. These -directories are typically scanned only once during each Gnus session. -If you feel the need to manually re-scan the remote directories, you can -use the @code{gnus-score-search-global-directories} command. +In this case, the base directory is @file{~/Maildir}, where all my Maildir +folders are stored. As you can see, the folders are separated by +colons. If you wonder why every folder begins with a dot: this is +because I use Dovecot as @acronym{IMAP} server, which again uses +@code{Maildir++} folders. For testing nnmairix, I also have some +@code{nnml} mail, which is saved in @file{~/Mail/nnml}. Since this has +to be specified relative to the @code{base} directory, the @code{../Mail} +notation is needed. Note that the line ends in @code{*...}, which means +to recursively scan all files under this directory. Without the three +dots, the wildcard @code{*} will not work recursively. I also have some +old mbox files with archived mail lying around in @file{~/mboxmail}. +The other lines should be obvious. -Note that, at present, using this option will slow down group entry -somewhat. (That is---a lot.) +See the man page for @code{mairixrc} for details and further options, +especially regarding wildcard usage, which may be a little different +than you are used to. -If you want to start maintaining score files for other people to use, -just put your score file up for anonymous ftp and announce it to the -world. Become a retro-moderator! Participate in the retro-moderator -wars sure to ensue, where retro-moderators battle it out for the -sympathy of the people, luring them to use their score files on false -premises! Yay! The net is saved! +Now simply call @code{mairix} to create the index for the first time. +Note that this may take a few minutes, but every following index will do +the updates incrementally and hence is very fast. -Here are some tips for the would-be retro-moderator, off the top of my -head: +@node Configuring nnmairix +@subsection Configuring nnmairix + +In group mode, type @kbd{G b c} +(@code{nnmairix-create-server-and-default-group}). This will ask you for all +necessary information and create a @code{nnmairix} server as a foreign +server. You will have to specify the following: @itemize @bullet @item -Articles heavily crossposted are probably junk. -@item -To lower a single inappropriate article, lower by @code{Message-ID}. -@item -Particularly brilliant authors can be raised on a permanent basis. -@item -Authors that repeatedly post off-charter for the group can safely be -lowered out of existence. -@item -Set the @code{mark} and @code{expunge} atoms to obliterate the nastiest -articles completely. +The @strong{name} of the @code{nnmairix} server---choose whatever you +want. @item -Use expiring score entries to keep the size of the file down. You -should probably have a long expiry period, though, as some sites keep -old articles for a long time. -@end itemize - -@dots{} I wonder whether other newsreaders will support global score files -in the future. @emph{Snicker}. Yup, any day now, newsreaders like Blue -Wave, xrn and 1stReader are bound to implement scoring. Should we start -holding our breath yet? - - -@node Kill Files -@section Kill Files -@cindex kill files +The name of the @strong{back end server} where mairix should store its +searches. This must be a full server name, like @code{nnml:mymail}. +Just hit @kbd{TAB} to see the available servers. Currently, servers +which are accessed through @code{nnmaildir}, @code{nnimap} and +@code{nnml} are supported. As explained above, for locally stored +mails, this can be an existing server where you store your mails. +However, you can also create e.g. a new @code{nnmaildir} or @code{nnml} +server exclusively for @code{nnmairix} in your secondary select methods +(@pxref{Finding the News}). If you use a secondary @code{nnml} server +just for mairix, make sure that you explicitly set the server variable +@code{nnml-get-new-mail} to @code{nil}, or you might lose mail +(@pxref{nnmairix caveats}). If you want to use mairix remotely on an +@acronym{IMAP} server, you have to choose the corresponding +@code{nnimap} server here. -Gnus still supports those pesky old kill files. In fact, the kill file -entries can now be expiring, which is something I wrote before Daniel -Quinlan thought of doing score files, so I've left the code in there. +@item +@vindex nnmairix-mairix-search-options +The @strong{command} to call the mairix binary. This will usually just +be @code{mairix}, but you can also choose something like @code{ssh +SERVER mairix} if you want to call mairix remotely, e.g. on your +@acronym{IMAP} server. If you want to add some default options to +mairix, you could do this here, but better use the variable +@code{nnmairix-mairix-search-options} instead. -In short, kill processing is a lot slower (and I do mean @emph{a lot}) -than score processing, so it might be a good idea to rewrite your kill -files into score files. +@item +The name of the @strong{default search group}. This will be the group +where all temporary mairix searches are stored, i.e. all searches which +are not bound to permanent @code{nnmairix} groups. Choose whatever you +like. -Anyway, a kill file is a normal @code{emacs-lisp} file. You can put any -forms into this file, which means that you can use kill files as some -sort of primitive hook function to be run on group entry, even though -that isn't a very good idea. +@item +If the mail back end is @code{nnimap} or @code{nnmaildir}, you will be +asked if you work with @strong{Maildir++}, i.e. with hidden maildir +folders (=beginning with a dot). For example, you have to answer +@samp{yes} here if you work with the Dovecot @acronym{IMAP} +server. Otherwise, you should answer @samp{no} here. -Normal kill files look like this: +@end itemize -@lisp -(gnus-kill "From" "Lars Ingebrigtsen") -(gnus-kill "Subject" "ding") -(gnus-expunge "X") -@end lisp +@node nnmairix keyboard shortcuts +@subsection nnmairix keyboard shortcuts -This will mark every article written by me as read, and remove the -marked articles from the summary buffer. Very useful, you'll agree. +In group mode: -Other programs use a totally different kill file syntax. If Gnus -encounters what looks like a @code{rn} kill file, it will take a stab at -interpreting it. +@table @kbd -Two summary functions for editing a @sc{gnus} kill file: +@item G b c +@kindex G b c (Group) +@findex nnmairix-create-server-and-default-group +Creates @code{nnmairix} server and default search group for this server +(@code{nnmairix-create-server-and-default-group}). You should have done +this by now (@pxref{Configuring nnmairix}). -@table @kbd +@item G b s +@kindex G b s (Group) +@findex nnmairix-search +Prompts for query which is then sent to the mairix binary. Search +results are put into the default search group which is automatically +displayed (@code{nnmairix-search}). -@item M-k -@kindex M-k (Summary) -@findex gnus-summary-edit-local-kill -Edit this group's kill file (@code{gnus-summary-edit-local-kill}). +@item G b m +@kindex G b m (Group) +@findex nnmairix-widget-search +Allows you to create a mairix search or a permanent group more +comfortably using graphical widgets, similar to a customization +group. Just try it to see how it works (@code{nnmairix-widget-search}). -@item M-K -@kindex M-K (Summary) -@findex gnus-summary-edit-global-kill -Edit the general kill file (@code{gnus-summary-edit-global-kill}). -@end table +@item G b i +@kindex G b i (Group) +@findex nnmairix-search-interactive +Another command for creating a mairix query more comfortably, but uses +only the minibuffer (@code{nnmairix-search-interactive}). -Two group mode functions for editing the kill files: +@item G b g +@kindex G b g (Group) +@findex nnmairix-create-search-group +Creates a permanent group which is associated with a search query +(@code{nnmairix-create-search-group}). The @code{nnmairix} back end +automatically calls mairix when you update this group with @kbd{g} or +@kbd{M-g}. -@table @kbd +@item G b q +@kindex G b q (Group) +@findex nnmairix-group-change-query-this-group +Changes the search query for the @code{nnmairix} group under cursor +(@code{nnmairix-group-change-query-this-group}). -@item M-k -@kindex M-k (Group) -@findex gnus-group-edit-local-kill -Edit this group's kill file (@code{gnus-group-edit-local-kill}). +@item G b t +@kindex G b t (Group) +@findex nnmairix-group-toggle-threads-this-group +Toggles the 'threads' parameter for the @code{nnmairix} group under cursor, +i.e. if you want see the whole threads of the found messages +(@code{nnmairix-group-toggle-threads-this-group}). -@item M-K -@kindex M-K (Group) -@findex gnus-group-edit-global-kill -Edit the general kill file (@code{gnus-group-edit-global-kill}). -@end table +@item G b u +@kindex G b u (Group) +@findex nnmairix-update-database +@vindex nnmairix-mairix-update-options +Calls mairix binary for updating the database +(@code{nnmairix-update-database}). The default parameters are @code{-F} +and @code{-Q} for making this as fast as possible (see variable +@code{nnmairix-mairix-update-options} for defining these default +options). -Kill file variables: +@item G b r +@kindex G b r (Group) +@findex nnmairix-group-toggle-readmarks-this-group +Keep articles in this @code{nnmairix} group always read or unread, or leave the +marks unchanged (@code{nnmairix-group-toggle-readmarks-this-group}). -@table @code -@item gnus-kill-file-name -@vindex gnus-kill-file-name -A kill file for the group @samp{soc.motss} is normally called -@file{soc.motss.KILL}. The suffix appended to the group name to get -this file name is detailed by the @code{gnus-kill-file-name} variable. -The ``global'' kill file (not in the score file sense of ``global'', of -course) is just called @file{KILL}. +@item G b d +@kindex G b d (Group) +@findex nnmairix-group-delete-recreate-this-group +Recreate @code{nnmairix} group on the ``real'' mail back end +(@code{nnmairix-group-delete-recreate-this-group}). You can do this if +you always get wrong article counts with a @code{nnmairix} group. -@vindex gnus-kill-save-kill-file -@item gnus-kill-save-kill-file -If this variable is non-@code{nil}, Gnus will save the -kill file after processing, which is necessary if you use expiring -kills. +@item G b a +@kindex G b a (Group) +@findex nnmairix-group-toggle-allowfast-this-group +Toggles the @code{allow-fast} parameters for group under cursor +(@code{nnmairix-group-toggle-allowfast-this-group}). The default +behavior of @code{nnmairix} is to do a mairix search every time you +update or enter the group. With the @code{allow-fast} parameter set, +mairix will only be called when you explicitly update the group, but not +upon entering. This makes entering the group faster, but it may also +lead to dangling symlinks if something changed between updating and +entering the group which is not yet in the mairix database. -@item gnus-apply-kill-hook -@vindex gnus-apply-kill-hook -@findex gnus-apply-kill-file-unless-scored -@findex gnus-apply-kill-file -A hook called to apply kill files to a group. It is -@code{(gnus-apply-kill-file)} by default. If you want to ignore the -kill file if you have a score file for the same group, you can set this -hook to @code{(gnus-apply-kill-file-unless-scored)}. If you don't want -kill files to be processed, you should set this variable to @code{nil}. +@item G b p +@kindex G b p (Group) +@findex nnmairix-group-toggle-propmarks-this-group +Toggle marks propagation for this group +(@code{nnmairix-group-toggle-propmarks-this-group}). (@pxref{Propagating +marks}). -@item gnus-kill-file-mode-hook -@vindex gnus-kill-file-mode-hook -A hook called in kill-file mode buffers. +@item G b o +@kindex G b o (Group) +@findex nnmairix-propagate-marks +Manually propagate marks (@code{nnmairix-propagate-marks}); needed only when +@code{nnmairix-propagate-marks-upon-close} is set to @code{nil}. @end table +In summary mode: -@node Converting Kill Files -@section Converting Kill Files -@cindex kill files -@cindex converting kill files +@table @kbd -If you have loads of old kill files, you may want to convert them into -score files. If they are ``regular'', you can use -the @file{gnus-kill-to-score.el} package; if not, you'll have to do it -by hand. +@item $ m +@kindex $ m (Summary) +@findex nnmairix-widget-search-from-this-article +Allows you to create a mairix query or group based on the current +message using graphical widgets (same as @code{nnmairix-widget-search}) +(@code{nnmairix-widget-search-from-this-article}). -The kill to score conversion package isn't included in Emacs by default. -You can fetch it from the contrib directory of the Gnus distribution or -from -@uref{http://heim.ifi.uio.no/~larsi/ding-various/gnus-kill-to-score.el}. +@item $ g +@kindex $ g (Summary) +@findex nnmairix-create-search-group-from-message +Interactively creates a new search group with query based on the current +message, but uses the minibuffer instead of graphical widgets +(@code{nnmairix-create-search-group-from-message}). -If your old kill files are very complex---if they contain more -non-@code{gnus-kill} forms than not, you'll have to convert them by -hand. Or just let them be as they are. Gnus will still use them as -before. +@item $ t +@kindex $ t (Summary) +@findex nnmairix-search-thread-this-article +Searches thread for the current article +(@code{nnmairix-search-thread-this-article}). This is effectively a +shortcut for calling @code{nnmairix-search} with @samp{m:msgid} of the +current article and enabled threads. +@item $ f +@kindex $ f (Summary) +@findex nnmairix-search-from-this-article +Searches all messages from sender of the current article +(@code{nnmairix-search-from-this-article}). This is a shortcut for +calling @code{nnmairix-search} with @samp{f:From}. -@node Advanced Scoring -@section Advanced Scoring +@item $ o +@kindex $ o (Summary) +@findex nnmairix-goto-original-article +(Only in @code{nnmairix} groups!) Tries determine the group this article +originally came from and displays the article in this group, so that +e.g. replying to this article the correct posting styles/group +parameters are applied (@code{nnmairix-goto-original-article}). This +function will use the registry if available, but can also parse the +article file name as a fallback method. -Scoring on Subjects and From headers is nice enough, but what if you're -really interested in what a person has to say only when she's talking -about a particular subject? Or what if you really don't want to -read what person A has to say when she's following up to person B, but -want to read what she says when she's following up to person C? +@item $ u +@kindex $ u (Summary) +@findex nnmairix-remove-tick-mark-original-article +Remove possibly existing tick mark from original article +(@code{nnmairix-remove-tick-mark-original-article}). (@pxref{nnmairix +tips and tricks}). -By using advanced scoring rules you may create arbitrarily complex -scoring patterns. +@end table -@menu -* Advanced Scoring Syntax:: A definition. -* Advanced Scoring Examples:: What they look like. -* Advanced Scoring Tips:: Getting the most out of it. -@end menu +@node Propagating marks +@subsection Propagating marks +First of: you really need a patched mairix binary for using the marks +propagation feature efficiently. Otherwise, you would have to update +the mairix database all the time. You can get the patch at -@node Advanced Scoring Syntax -@subsection Advanced Scoring Syntax +@uref{http://www.randomsample.de/mairix-maildir-patch.tar} -Ordinary scoring rules have a string as the first element in the rule. -Advanced scoring rules have a list as the first element. The second -element is the score to be applied if the first element evaluated to a -non-@code{nil} value. +You need the mairix v0.21 source code for this patch; everything else +is explained in the accompanied readme file. If you don't want to use +marks propagation, you don't have to apply these patches, but they also +fix some annoyances regarding changing maildir flags, so it might still +be useful to you. -These lists may consist of three logical operators, one redirection -operator, and various match operators. +With the patched mairix binary, you can use @code{nnmairix} as an +alternative to mail splitting (@pxref{Fancy Mail Splitting}). For +example, instead of splitting all mails from @samp{david@@foobar.com} +into a group, you can simply create a search group with the query +@samp{f:david@@foobar.com}. This is actually what ``smart folders'' are +all about: simply put everything in one mail folder and dynamically +create searches instead of splitting. This is more flexible, since you +can dynamically change your folders any time you want to. This also +implies that you will usually read your mails in the @code{nnmairix} +groups instead of your ``real'' mail groups. -Logical operators: +There is one problem, though: say you got a new mail from +@samp{david@@foobar.com}; it will now show up in two groups, the +``real'' group (your INBOX, for example) and in the @code{nnmairix} +search group (provided you have updated the mairix database). Now you +enter the @code{nnmairix} group and read the mail. The mail will be +marked as read, but only in the @code{nnmairix} group---in the ``real'' +mail group it will be still shown as unread. -@table @code -@item & -@itemx and -This logical operator will evaluate each of its arguments until it finds -one that evaluates to @code{false}, and then it'll stop. If all arguments -evaluate to @code{true} values, then this operator will return -@code{true}. +You could now catch up the mail group (@pxref{Group Data}), but this is +tedious and error prone, since you may overlook mails you don't have +created @code{nnmairix} groups for. Of course, you could first use +@code{nnmairix-goto-original-article} (@pxref{nnmairix keyboard +shortcuts}) and then read the mail in the original group, but that's +even more cumbersome. -@item | -@itemx or -This logical operator will evaluate each of its arguments until it finds -one that evaluates to @code{true}. If no arguments are @code{true}, -then this operator will return @code{false}. +Clearly, the easiest way would be if marks could somehow be +automatically set for the original article. This is exactly what +@emph{marks propagation} is about. -@item ! -@itemx not -@itemx ¬ -This logical operator only takes a single argument. It returns the -logical negation of the value of its argument. +Marks propagation is deactivated by default. You can activate it for a +certain @code{nnmairix} group with +@code{nnmairix-group-toggle-propmarks-this-group} (bound to @kbd{G b +p}). This function will warn you if you try to use it with your default +search group; the reason is that the default search group is used for +temporary searches, and it's easy to accidentally propagate marks from +this group. However, you can ignore this warning if you really want to. -@end table +With marks propagation enabled, all the marks you set in a @code{nnmairix} +group should now be propagated to the original article. For example, +you can now tick an article (by default with @kbd{!}) and this mark should +magically be set for the original article, too. -There is an @dfn{indirection operator} that will make its arguments -apply to the ancestors of the current article being scored. For -instance, @code{1-} will make score rules apply to the parent of the -current article. @code{2-} will make score rules apply to the -grandparent of the current article. Alternatively, you can write -@code{^^}, where the number of @code{^}s (carets) says how far back into -the ancestry you want to go. +A few more remarks which you may or may not want to know: -Finally, we have the match operators. These are the ones that do the -real work. Match operators are header name strings followed by a match -and a match type. A typical match operator looks like @samp{("from" -"Lars Ingebrigtsen" s)}. The header names are the same as when using -simple scoring, and the match types are also the same. +@vindex nnmairix-propagate-marks-upon-close +Marks will not be set immediately, but only upon closing a group. This +not only makes marks propagation faster, it also avoids problems with +dangling symlinks when dealing with maildir files (since changing flags +will change the file name). You can also control when to propagate marks +via @code{nnmairix-propagate-marks-upon-close} (see the doc-string for +details). +Obviously, @code{nnmairix} will have to look up the original group for every +article you want to set marks for. If available, @code{nnmairix} will first use +the registry for determining the original group. The registry is very +fast, hence you should really, really enable the registry when using +marks propagation. If you don't have to worry about RAM and disc space, +set @code{gnus-registry-max-entries} to a large enough value; to be on +the safe side, choose roughly the amount of mails you index with mairix. -@node Advanced Scoring Examples -@subsection Advanced Scoring Examples +@vindex nnmairix-only-use-registry +If you don't want to use the registry or the registry hasn't seen the +original article yet, @code{nnmairix} will use an additional mairix +search for determining the file name of the article. This, of course, is +way slower than the registry---if you set hundreds or even thousands of +marks this way, it might take some time. You can avoid this situation by +setting @code{nnmairix-only-use-registry} to t. -Please note that the following examples are score file rules. To -make a complete score file from them, surround them with another pair -of parentheses. +Maybe you also want to propagate marks the other way round, i.e. if you +tick an article in a "real" mail group, you'd like to have the same +article in a @code{nnmairix} group ticked, too. For several good +reasons, this can only be done efficiently if you use maildir. To +immediately contradict myself, let me mention that it WON'T work with +@code{nnmaildir}, since @code{nnmaildir} stores the marks externally and +not in the file name. Therefore, propagating marks to @code{nnmairix} +groups will usually only work if you use an IMAP server which uses +maildir as its file format. -Let's say you want to increase the score of articles written by Lars -when he's talking about Gnus: +@vindex nnmairix-propagate-marks-to-nnmairix-groups +If you work with this setup, just set +@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t} and see what +happens. If you don't like what you see, just set it to @code{nil} again. One +problem might be that you get a wrong number of unread articles; this +usually happens when you delete or expire articles in the original +groups. When this happens, you can recreate the @code{nnmairix} group on the +back end using @kbd{G b d}. -@example -@group -((& - ("from" "Lars Ingebrigtsen") - ("subject" "Gnus")) - 1000) -@end group -@end example +@node nnmairix tips and tricks +@subsection nnmairix tips and tricks + +@itemize +@item +Checking Mail -Quite simple, huh? +@findex nnmairix-update-groups +I put all my important mail groups at group level 1. The mairix groups +have group level 5, so they do not get checked at start up (@pxref{Group +Levels}). -When he writes long articles, he sometimes has something nice to say: +I use the following to check for mails: -@example -((& - ("from" "Lars Ingebrigtsen") - (| - ("subject" "Gnus") - ("lines" 100 >))) - 1000) -@end example +@lisp +(defun my-check-mail-mairix-update (level) + (interactive "P") + ;; if no prefix given, set level=1 + (gnus-group-get-new-news (or level 1)) + (nnmairix-update-groups "mairixsearch" t t) + (gnus-group-list-groups)) -However, when he responds to things written by Reig Eigil Logge, you -really don't want to read what he's written: +(define-key gnus-group-mode-map "g" 'my-check-mail-mairix-update) +@end lisp -@example -((& - ("from" "Lars Ingebrigtsen") - (1- ("from" "Reig Eigil Logge"))) - -100000) -@end example +Instead of @samp{"mairixsearch"} use the name of your @code{nnmairix} +server. See the doc string for @code{nnmairix-update-groups} for +details. -Everybody that follows up Redmondo when he writes about disappearing -socks should have their scores raised, but only when they talk about -white socks. However, when Lars talks about socks, it's usually not -very interesting: +@item +Example: search group for ticked articles -@example -((& - (1- - (& - ("from" "redmondo@@.*no" r) - ("body" "disappearing.*socks" t))) - (! ("from" "Lars Ingebrigtsen")) - ("body" "white.*socks")) - 1000) -@end example +For example, you can create a group for all ticked articles, where the +articles always stay unread: -Suppose you're reading a high volume group and you're only interested -in replies. The plan is to score down all articles that don't have -subject that begin with "Re:", "Fw:" or "Fwd:" and then score up all -parents of articles that have subjects that begin with reply marks. +Hit @kbd{G b g}, enter group name (e.g. @samp{important}), use +@samp{F:f} as query and do not include threads. -@example -((! ("subject" "re:\\|fwd?:" r)) - -200) -((1- ("subject" "re:\\|fwd?:" r)) - 200) -@end example +Now activate marks propagation for this group by using @kbd{G b p}. Then +activate the always-unread feature by using @kbd{G b r} twice. -The possibilities are endless. +So far so good---but how do you remove the tick marks in the @code{nnmairix} +group? There are two options: You may simply use +@code{nnmairix-remove-tick-mark-original-article} (bound to @kbd{$ u}) to remove +tick marks from the original article. The other possibility is to set +@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t}, but see the above +comments about this option. If it works for you, the tick marks should +also exist in the @code{nnmairix} group and you can remove them as usual, +e.g. by marking an article as read. -@node Advanced Scoring Tips -@subsection Advanced Scoring Tips +When you have removed a tick mark from the original article, this +article should vanish from the @code{nnmairix} group after you have updated the +mairix database and updated the group. Fortunately, there is a function +for doing exactly that: @code{nnmairix-update-groups}. See the previous code +snippet and the doc string for details. -The @code{&} and @code{|} logical operators do short-circuit logic. -That is, they stop processing their arguments when it's clear what the -result of the operation will be. For instance, if one of the arguments -of an @code{&} evaluates to @code{false}, there's no point in evaluating -the rest of the arguments. This means that you should put slow matches -(@samp{body}, @samp{header}) last and quick matches (@samp{from}, -@samp{subject}) first. +@item +Dealing with auto-subscription of mail groups -The indirection arguments (@code{1-} and so on) will make their -arguments work on previous generations of the thread. If you say -something like: +As described before, all @code{nnmairix} groups are in fact stored on +the mail back end in the form @samp{zz_mairix--}. You can +see them when you enter the back end server in the server buffer. You +should not subscribe these groups! Unfortunately, these groups will +usually get @emph{auto-subscribed} when you use @code{nnmaildir} or +@code{nnml}, i.e. you will suddenly see groups of the form +@samp{zz_mairix*} pop up in your group buffer. If this happens to you, +simply kill these groups with C-k. For avoiding this, turn off +auto-subscription completely by setting the variable +@code{gnus-auto-subscribed-groups} to @code{nil} (@pxref{Filtering New +Groups}), or if you like to keep this feature use the following kludge +for turning it off for all groups beginning with @samp{zz_}: -@example -... -(1- - (1- - ("from" "lars"))) -... -@end example +@lisp +(setq gnus-auto-subscribed-groups + "^\\(nnml\\|nnfolder\\|nnmbox\\|nnmh\\|nnbabyl\\|nnmaildir\\).*:\\([^z]\\|z$\\|\\z[^z]\\|zz$\\|zz[^_]\\|zz_$\\).*") +@end lisp -Then that means ``score on the from header of the grandparent of the -current article''. An indirection is quite fast, but it's better to say: +@end itemize -@example -(1- - (& - ("from" "Lars") - ("subject" "Gnus"))) -@end example +@node nnmairix caveats +@subsection nnmairix caveats -than it is to say: +@itemize +@item +You can create a secondary @code{nnml} server just for nnmairix, but then +you have to explicitly set the corresponding server variable +@code{nnml-get-new-mail} to @code{nil}. Otherwise, new mail might get +put into this secondary server (and would never show up again). Here's +an example server definition: -@example -(& - (1- ("from" "Lars")) - (1- ("subject" "Gnus"))) -@end example +@lisp +(nnml "mairix" (nnml-directory "mairix") (nnml-get-new-mail nil)) +@end lisp +(The @code{nnmaildir} back end also has a server variabe +@code{get-new-mail}, but its default value is @code{nil}, so you don't +have to explicitly set it if you use a @code{nnmaildir} server just for +mairix.) -@node Score Decays -@section Score Decays -@cindex score decays -@cindex decays +@item +If you use the Gnus registry: don't use the registry with +@code{nnmairix} groups (put them in +@code{gnus-registry-unfollowed-groups}). Be @emph{extra careful} if +you use @code{gnus-registry-split-fancy-with-parent}; mails which are +split into @code{nnmairix} groups are usually gone for good as soon as +you check the group for new mail (yes, it has happened to me...). -You may find that your scores have a tendency to grow without -bounds, especially if you're using adaptive scoring. If scores get too -big, they lose all meaning---they simply max out and it's difficult to -use them in any sensible way. +@item +Therefore: @emph{Never ever} put ``real'' mails into @code{nnmairix} +groups (you shouldn't be able to, anyway). -@vindex gnus-decay-scores -@findex gnus-decay-score -@vindex gnus-decay-score-function -Gnus provides a mechanism for decaying scores to help with this problem. -When score files are loaded and @code{gnus-decay-scores} is -non-@code{nil}, Gnus will run the score files through the decaying -mechanism thereby lowering the scores of all non-permanent score rules. -If @code{gnus-decay-scores} is a regexp, only score files matching this -regexp are treated. E.g. you may set it to @samp{\\.ADAPT\\'} if only -@emph{adaptive} score files should be decayed. The decay itself if -performed by the @code{gnus-decay-score-function} function, which is -@code{gnus-decay-score} by default. Here's the definition of that -function: +@item +If you use the Gnus agent (@pxref{Gnus Unplugged}): don't agentize +@code{nnmairix} groups (though I have no idea what happens if you do). -@lisp -(defun gnus-decay-score (score) - "Decay SCORE according to `gnus-score-decay-constant' -and `gnus-score-decay-scale'." - (let ((n (- score - (* (if (< score 0) -1 1) - (min (abs score) - (max gnus-score-decay-constant - (* (abs score) - gnus-score-decay-scale))))))) - (if (and (featurep 'xemacs) - ;; XEmacs' floor can handle only the floating point - ;; number below the half of the maximum integer. - (> (abs n) (lsh -1 -2))) - (string-to-number - (car (split-string (number-to-string n) "\\."))) - (floor n)))) -@end lisp +@item +mairix does only support us-ascii characters. -@vindex gnus-score-decay-scale -@vindex gnus-score-decay-constant -@code{gnus-score-decay-constant} is 3 by default and -@code{gnus-score-decay-scale} is 0.05. This should cause the following: +@item +@code{nnmairix} uses a rather brute force method to force Gnus to +completely reread the group on the mail back end after mairix was +called---it simply deletes and re-creates the group on the mail +back end. So far, this has worked for me without any problems, and I +don't see how @code{nnmairix} could delete other mail groups than its +own, but anyway: you really should have a backup of your mail +folders. -@enumerate @item -Scores between -3 and 3 will be set to 0 when this function is called. +All necessary information is stored in the group parameters +(@pxref{Group Parameters}). This has the advantage that no active file +is needed, but also implies that when you kill a @code{nnmairix} group, +it is gone for good. @item -Scores with magnitudes between 3 and 60 will be shrunk by 3. +@findex nnmairix-purge-old-groups +If you create and kill a lot of @code{nnmairix} groups, the +``zz_mairix-*'' groups will accumulate on the mail back end server. To +delete old groups which are no longer needed, call +@code{nnmairix-purge-old-groups}. Note that this assumes that you don't +save any ``real'' mail in folders of the form +@code{zz_mairix--}. You can change the prefix of +@code{nnmairix} groups by changing the variable +@code{nnmairix-group-prefix}. @item -Scores with magnitudes greater than 60 will be shrunk by 5% of the -score. -@end enumerate +The following only applies if you @emph{don't} use the mentioned patch +for mairix (@pxref{Propagating marks}): -If you don't like this decay function, write your own. It is called -with the score to be decayed as its only parameter, and it should return -the new score, which should be an integer. +A problem can occur when using @code{nnmairix} with maildir folders and +comes with the fact that maildir stores mail flags like @samp{Seen} or +@samp{Replied} by appending chars @samp{S} and @samp{R} to the message +file name, respectively. This implies that currently you would have to +update the mairix database not only when new mail arrives, but also when +mail flags are changing. The same applies to new mails which are indexed +while they are still in the @samp{new} folder but then get moved to +@samp{cur} when Gnus has seen the mail. If you don't update the database +after this has happened, a mairix query can lead to symlinks pointing to +non-existing files. In Gnus, these messages will usually appear with +``(none)'' entries in the header and can't be accessed. If this happens +to you, using @kbd{G b u} and updating the group will usually fix this. -Gnus will try to decay scores once a day. If you haven't run Gnus for -four days, Gnus will decay the scores four times, for instance. +@end itemize @iftex @iflatex -- 2.25.1