emacs-diffs
[Top][All Lists]

## [Emacs-diffs] Changes to emacs/man/gnus.texi [gnus-5_10-branch]

 From: Reiner Steib Subject: [Emacs-diffs] Changes to emacs/man/gnus.texi [gnus-5_10-branch] Date: Mon, 02 Aug 2004 09:57:25 -0400

Index: emacs/man/gnus.texi
diff -c /dev/null emacs/man/gnus.texi:1.34.2.1
*** /dev/null   Mon Aug  2 13:38:56 2004
--- emacs/man/gnus.texi Mon Aug  2 13:38:49 2004
***************
*** 0 ****
--- 1,28388 ----
+ \input texinfo
+
+ @setfilename ../info/gnus
+ @settitle Gnus Manual
+ @syncodeindex fn cp
+ @syncodeindex vr cp
+ @syncodeindex pg cp
+ @dircategory Emacs
+ @direntry
+ * Gnus: (gnus).         The newsreader Gnus.
+ @end direntry
+ @iftex
+ @finalout
+ @end iftex
+ @setchapternewpage odd
+
+ @iftex
+ @iflatex
+ \documentclass[twoside,a4paper,openright,11pt]{book}
+ \usepackage[latin1]{inputenc}
+ \usepackage{pagestyle}
+ \usepackage{epsfig}
+ \usepackage{pixidx}
+ \input{gnusconfig.tex}
+
+ \ifx\pdfoutput\undefined
+ \else
+ \usepackage{thumbpdf}
+ \pdfcompresslevel=9
+ \fi
+
+ \makeindex
+ \begin{document}
+
+ \newcommand{\gnusversionname}{Gnus v5.10.6}
+ \newcommand{\gnuschaptername}{}
+ \newcommand{\gnussectionname}{}
+
+ \newcommand{\gnusbackslash}{/}
+
+ \newcommand{\gnusref}[1]{#1'' on page \pageref{#1}}
+ \ifx\pdfoutput\undefined
+ \newcommand{\gnusuref}[1]{\gnustt{#1}}
+ \else
+ \newcommand{\gnusuref}[1]{\href{#1}{\gnustt{#1}}}
+ \fi
+ \newcommand{\gnusxref}[1]{See #1'' on page \pageref{#1}}
+ \newcommand{\gnuspxref}[1]{see #1'' on page \pageref{#1}}
+
+ \newcommand{\gnuskindex}[1]{\index{#1}}
+ \newcommand{\gnusindex}[1]{\index{#1}}
+
+ \newcommand{\gnustt}[1]{{\gnusselectttfont{}#1}}
+ \newcommand{\gnuscode}[1]{\gnustt{#1}}
+ \newcommand{\gnusasis}[1]{\gnustt{#1}}
+ \newcommand{\gnusurl}[1]{\gnustt{#1}}
+ \newcommand{\gnuscommand}[1]{\gnustt{#1}}
+ \newcommand{\gnusenv}[1]{\gnustt{#1}}
+ \newcommand{\gnussamp}[1]{{\fontencoding{OT1}\gnusselectttfont{}#1}''}
+ \newcommand{\gnuslisp}[1]{\gnustt{#1}}
+ \newcommand{\gnuskbd}[1]{\gnustt{#1}'}
+ \newcommand{\gnuskey}[1]{\gnustt{#1}'}
+ \newcommand{\gnusfile}[1]{\gnustt{#1}'}
+ \newcommand{\gnusdfn}[1]{\textit{#1}}
+ \newcommand{\gnusi}[1]{\textit{#1}}
+ \newcommand{\gnusr}[1]{\textrm{#1}}
+ \newcommand{\gnusstrong}[1]{\textbf{#1}}
+ \newcommand{\gnusemph}[1]{\textit{#1}}
+ \newcommand{\gnusvar}[1]{{\fontsize{10pt}{10}\selectfont\textsl{\textsf{#1}}}}
+ \newcommand{\gnussc}[1]{\textsc{#1}}
+ \newcommand{\gnustitle}[1]{{\huge\textbf{#1}}}
+ \newcommand{\gnusversion}[1]{{\small\textit{#1}}}
+ \newcommand{\gnusauthor}[1]{{\large\textbf{#1}}}
+ \newcommand{\gnusresult}[1]{\gnustt{=> #1}}
+ \newcommand{\gnusacronym}[1]{\textsc{#1}}
+ \newcommand{\gnusemail}[1]{\textit{#1}}
+
+ \newcommand{\gnusbullet}{{${\bullet}$}}
+ me.  Usage of the patent (@dfn{Master/Slave Relationships In Computer
+ Applications}) will be much more expensive, of course.)
+
+ @findex gnus-slave
+ Anyway, you start one Gnus up the normal way with @kbd{M-x gnus} (or
+ however you do it).  Each subsequent slave Gnusae should be started with
+ @kbd{M-x gnus-slave}.  These slaves won't save normal @file{.newsrc}
+ files, but instead save @dfn{slave files} that contain information only
+ on what groups have been read in the slave session.  When a master Gnus
+ starts, it will read (and delete) these slave files, incorporating all
+ information from them.  (The slave files will be read in the sequence
+ they were created, so the latest changes will have precedence.)
+
+ Information from the slave files has, of course, precedence over the
+ information in the normal (i.e., master) @file{.newsrc} file.
+
+ If the @file{.newsrc*} files have not been saved in the master when the
+ slave starts, you may be prompted as to whether to read an auto-save
+ file.  If you answer yes'', the unsaved changes to the master will be
+ incorporated into the slave.  If you answer no'', the slave may see some
+
+ @node Fetching a Group
+ @section Fetching a Group
+ @cindex fetching a group
+
+ @findex gnus-fetch-group
+ It is sometimes convenient to be able to just say I want to read this
+ group and I don't care whether Gnus has been started or not''.  This is
+ perhaps more useful for people who write code than for users, but the
+ command @code{gnus-fetch-group} provides this functionality in any case.
+ It takes the group name as a parameter.
+
+
+ @node New Groups
+ @section New Groups
+ @cindex new groups
+ @cindex subscription
+
+ @vindex gnus-check-new-newsgroups
+ If you are satisfied that you really never want to see any new groups,
+ you can set @code{gnus-check-new-newsgroups} to @code{nil}.  This will
+ also save you some time at startup.  Even if this variable is
+ @code{nil}, you can always subscribe to the new groups just by pressing
+ @kbd{U} in the group buffer (@pxref{Group Maintenance}).  This variable
+ is @code{ask-server} by default.  If you set this variable to
+ @code{always}, then Gnus will query the back ends for new groups even
+ when you do the @kbd{g} command (@pxref{Scanning New Messages}).
+
+ * Checking New Groups::         Determining what groups are new.
+ * Subscription Methods::        What Gnus should do with new groups.
+ * Filtering New Groups::        Making Gnus ignore certain new groups.
+
+
+ @node Checking New Groups
+ @subsection Checking New Groups
+
+ Gnus normally determines whether a group is new or not by comparing the
+ list of groups from the active file(s) with the lists of subscribed and
+ dead groups.  This isn't a particularly fast method.  If
+ server for new groups since the last time.  This is both faster and
+ cheaper.  This also means that you can get rid of the list of killed
+ groups altogether, so you may set @code{gnus-save-killed-list} to
+ @code{nil}, which will save time both at startup, at exit, and all over.
+ Saves disk space, too.  Why isn't this the default, then?
+ Unfortunately, not all servers support this command.
+
+ I bet I know what you're thinking now: How do I find out whether my
+ server supports @code{ask-server}?  No?  Good, because I don't have a
+ fail-safe answer.  I would suggest just setting this variable to
+ @code{ask-server} and see whether any new groups appear within the next
+ few days.  If any do, then it works.  If none do, then it doesn't
+ work.  I could write a function to make Gnus guess whether the server
+ supports @code{ask-server}, but it would just be a guess.  So I won't.
+ You could @code{telnet} to the server and say @code{HELP} and see
+ whether it lists @samp{NEWGROUPS} among the commands it understands.  If
+ it does, then it might work.  (But there are servers that lists
+ @samp{NEWGROUPS} without supporting the function properly.)
+
+ This variable can also be a list of select methods.  If so, Gnus will
+ issue an @code{ask-server} command to each of the select methods, and
+ subscribe them (or not) using the normal methods.  This might be handy
+ if you are monitoring a few servers for new groups.  A side effect is
+ that startup will take much longer, so you can meditate while waiting.
+ Use the mantra dingnusdingnusdingnus'' to achieve permanent bliss.
+
+
+ @node Subscription Methods
+ @subsection Subscription Methods
+
+ @vindex gnus-subscribe-newsgroup-method
+ What Gnus does when it encounters a new group is determined by the
+ @code{gnus-subscribe-newsgroup-method} variable.
+
+ This variable should contain a function.  This function will be called
+ with the name of the new group as the only parameter.
+
+ Some handy pre-fab functions are:
+
+ @table @code
+
+ @item gnus-subscribe-zombies
+ @vindex gnus-subscribe-zombies
+ Make all new groups zombies.  This is the default.  You can browse the
+ zombies later (with @kbd{A z}) and either kill them all off properly
+ (with @kbd{S z}), or subscribe to them (with @kbd{u}).
+
+ @item gnus-subscribe-randomly
+ @vindex gnus-subscribe-randomly
+ Subscribe all new groups in arbitrary order.  This really means that all
+ new groups will be added at the top'' of the group buffer.
+
+ @item gnus-subscribe-alphabetically
+ @vindex gnus-subscribe-alphabetically
+ Subscribe all new groups in alphabetical order.
+
+ @item gnus-subscribe-hierarchically
+ @vindex gnus-subscribe-hierarchically
+ Subscribe all new groups hierarchically.  The difference between this
+ function and @code{gnus-subscribe-alphabetically} is slight.
+ @code{gnus-subscribe-alphabetically} will subscribe new groups in a strictly
+ alphabetical fashion, while this function will enter groups into its
+ hierarchy.  So if you want to have the @samp{rec} hierarchy before the
+ @samp{comp} hierarchy, this function will not mess that configuration
+ up.  Or something like that.
+
+ @item gnus-subscribe-interactively
+ @vindex gnus-subscribe-interactively
+ Subscribe new groups interactively.  This means that Gnus will ask
+ you about @strong{all} new groups.  The groups you choose to subscribe
+ to will be subscribed hierarchically.
+
+ @item gnus-subscribe-killed
+ @vindex gnus-subscribe-killed
+ Kill all new groups.
+
+ @item gnus-subscribe-topics
+ @vindex gnus-subscribe-topics
+ Put the groups into the topic that has a matching @code{subscribe} topic
+ parameter (@pxref{Topic Parameters}).  For instance, a @code{subscribe}
+ topic parameter that looks like
+
+ @example
+ "nnslashdot"
+ @end example
+
+ will mean that all groups that match that regex will be subscribed under
+ that topic.
+
+ If no topics match the groups, the groups will be subscribed in the
+ top-level topic.
+
+ @end table
+
+ @vindex gnus-subscribe-hierarchical-interactive
+ A closely related variable is
+ @code{gnus-subscribe-hierarchical-interactive}.  (That's quite a
+ mouthful.)  If this variable is address@hidden, Gnus will ask you in a
+ hierarchical fashion whether to subscribe to new groups or not.  Gnus
+ will ask you for each sub-hierarchy whether you want to descend the
+ hierarchy or not.
+
+ One common mistake is to set the variable a few paragraphs above
+ (@code{gnus-subscribe-newsgroup-method}) to
+ @code{gnus-subscribe-hierarchical-interactive}.  This is an error.  This
+ will not work.  This is ga-ga.  So don't do it.
+
+
+ @node Filtering New Groups
+ @subsection Filtering New Groups
+
+ A nice and portable way to control which new newsgroups should be
+ subscribed (or ignored) is to put an @dfn{options} line at the start of
+ the @file{.newsrc} file.  Here's an example:
+
+ @example
+ options -n !alt.all !rec.all sci.all
+ @end example
+
+ @vindex gnus-subscribe-options-newsgroup-method
+ This line obviously belongs to a serious-minded intellectual scientific
+ person (or she may just be plain old boring), because it says that all
+ groups that have names beginning with @samp{alt} and @samp{rec} should
+ be ignored, and all groups with names beginning with @samp{sci} should
+ be subscribed.  Gnus will not use the normal subscription method for
+ subscribing these groups.
+ @code{gnus-subscribe-options-newsgroup-method} is used instead.  This
+ variable defaults to @code{gnus-subscribe-alphabetically}.
+
+ @vindex gnus-options-not-subscribe
+ @vindex gnus-options-subscribe
+ If you don't want to mess with your @file{.newsrc} file, you can just
+ set the two variables @code{gnus-options-subscribe} and
+ @code{gnus-options-not-subscribe}.  These two variables do exactly the
+ same as the @file{.newsrc} @samp{options -n} trick.  Both are regexps,
+ and if the new group matches the former, it will be unconditionally
+ subscribed, and if it matches the latter, it will be ignored.
+
+ @vindex gnus-auto-subscribed-groups
+ Yet another variable that meddles here is
+ @code{gnus-auto-subscribed-groups}.  It works exactly like
+ @code{gnus-options-subscribe}, and is therefore really superfluous,
+ but I thought it would be nice to have two of these.  This variable is
+ more meant for setting some ground rules, while the other variable is
+ used more for user fiddling.  By default this variable makes all new
+ groups that come from mail back ends (@code{nnml}, @code{nnbabyl},
+ @code{nnfolder}, @code{nnmbox}, @code{nnmh}, and @code{nnmaildir})
+ subscribed.  If you don't like that, just set this variable to
+ @code{nil}.
+
+ New groups that match this regexp are subscribed using
+ @code{gnus-subscribe-options-newsgroup-method}.
+
+
+ @node Changing Servers
+ @section Changing Servers
+ @cindex changing servers
+
+ Sometimes it is necessary to move from one @acronym{NNTP} server to another.
+ This happens very rarely, but perhaps you change jobs, or one server is
+ very flaky and you want to use another.
+
+ Changing the server is pretty easy, right?  You just change
+ @code{gnus-select-method} to point to the new server?
+
+ @emph{Wrong!}
+
+ Article numbers are not (in any way) kept synchronized between different
+ @acronym{NNTP} servers, and the only way Gnus keeps track of what articles
+ you have read is by keeping track of article numbers.  So when you
+ change @code{gnus-select-method}, your @file{.newsrc} file becomes
+ worthless.
+
+ Gnus provides a few functions to attempt to translate a @file{.newsrc}
+ file from one server to another.  They all have one thing in
+ common---they take a looong time to run.  You don't want to use these
+ functions more than absolutely necessary.
+
+ @kindex M-x gnus-change-server
+ @findex gnus-change-server
+ the articles you have read and compare @code{Message-ID}s and map the
+ article numbers of the read articles and article marks.  The @kbd{M-x
+ gnus-change-server} command will do this for all your native groups.  It
+ will prompt for the method you want to move to.
+
+ @kindex M-x gnus-group-move-group-to-server
+ @findex gnus-group-move-group-to-server
+ You can also move individual groups with the @kbd{M-x
+ gnus-group-move-group-to-server} command.  This is useful if you want to
+ move a (foreign) group from one server to another.
+
+ @kindex M-x gnus-group-clear-data-on-native-groups
+ @findex gnus-group-clear-data-on-native-groups
+ and read ranges have become worthless.  You can use the @kbd{M-x
+ gnus-group-clear-data-on-native-groups} command to clear out all data
+ that you have on your native groups.  Use with caution.
+
+ @kindex M-x gnus-group-clear-data
+ @findex gnus-group-clear-data
+ Clear the data from the current group only---nix out marks and the
+ list of read articles (@code{gnus-group-clear-data}).
+
+ After changing servers, you @strong{must} move the cache hierarchy away,
+ since the cached articles will have wrong article numbers, which will
+ affect which articles Gnus thinks are read.
+ @code{gnus-group-clear-data-on-native-groups} will ask you if you want
+ to have it done automatically; for @code{gnus-group-clear-data}, you
+ can use @kbd{M-x gnus-cache-move-cache} (but beware, it will move the
+ cache for all groups).
+
+
+ @node Startup Files
+ @section Startup Files
+ @cindex startup files
+ @cindex .newsrc
+ @cindex .newsrc.el
+ @cindex .newsrc.eld
+
+ Now, you all know about the @file{.newsrc} file.  All subscription
+ information is traditionally stored in this file.
+
+ Things got a bit more complicated with @sc{gnus}.  In addition to
+ keeping the @file{.newsrc} file updated, it also used a file called
+ @file{.newsrc.el} for storing all the information that didn't fit into
+ the @file{.newsrc} file.  (Actually, it also duplicated everything in
+ the @file{.newsrc} file.)  @sc{gnus} would read whichever one of these
+ files was the most recently saved, which enabled people to swap between
+
+ That was kinda silly, so Gnus went one better: In addition to the
+ @file{.newsrc} and @file{.newsrc.el} files, Gnus also has a file called
+ @file{.newsrc.eld}.  It will read whichever of these files that are most
+ recent, but it will never write a @file{.newsrc.el} file.  You should
+ never delete the @file{.newsrc.eld} file---it contains much information
+ not stored in the @file{.newsrc} file.
+
+ @vindex gnus-save-newsrc-file
+ You can turn off writing the @file{.newsrc} file by setting
+ @code{gnus-save-newsrc-file} to @code{nil}, which means you can delete
+ the file and save some space, as well as exiting from Gnus faster.
+ However, this will make it impossible to use other newsreaders than
+ Gnus.  But hey, who would want to, right?  Similarly, setting
+ @code{gnus-read-newsrc-file} to @code{nil} makes Gnus ignore the
+ @file{.newsrc} file and any @file{.newsrc-SERVER} files, which is
+ convenient if you have a tendency to use Netscape once in a while.
+
+ @vindex gnus-save-killed-list
+ If @code{gnus-save-killed-list} (default @code{t}) is @code{nil}, Gnus
+ will not save the list of killed groups to the startup file.  This will
+ save both time (when starting and quitting) and space (on disk).  It
+ will also mean that Gnus has no record of what groups are new or old,
+ so the automatic new groups subscription methods become meaningless.
+ You should always set @code{gnus-check-new-newsgroups} to @code{nil} or
+ @code{ask-server} if you set this variable to @code{nil} (@pxref{New
+ Groups}).  This variable can also be a regular expression.  If that's
+ the case, remove all groups that do not match this regexp before
+ saving.  This can be useful in certain obscure situations that involve
+ several servers where not all servers support @code{ask-server}.
+
+ @vindex gnus-startup-file
+ @vindex gnus-backup-startup-file
+ @vindex version-control
+ The @code{gnus-startup-file} variable says where the startup files are.
+ The default value is @file{~/.newsrc}, with the Gnus (El Dingo) startup
+ file being whatever that one is, with a @samp{.eld} appended.
+ If you want version control for this file, set
+ @code{gnus-backup-startup-file}.  It respects the same values as the
+ @code{version-control} variable.
+
+ @vindex gnus-save-newsrc-hook
+ @vindex gnus-save-quick-newsrc-hook
+ @vindex gnus-save-standard-newsrc-hook
+ @code{gnus-save-newsrc-hook} is called before saving any of the newsrc
+ files, while @code{gnus-save-quick-newsrc-hook} is called just before
+ saving the @file{.newsrc.eld} file, and
+ @code{gnus-save-standard-newsrc-hook} is called just before saving the
+ @file{.newsrc} file.  The latter two are commonly used to turn version
+ control on or off.  Version control is on by default when saving the
+ startup files.  If you want to turn backup creation off, say something like:
+
+ @lisp
+ (defun turn-off-backup ()
+   (set (make-local-variable 'backup-inhibited) t))
+
+ @end lisp
+
+ @vindex gnus-init-file
+ @vindex gnus-site-init-file
+ When Gnus starts, it will read the @code{gnus-site-init-file}
+ (@file{.../site-lisp/gnus} by default) and @code{gnus-init-file}
+ (@file{~/.gnus} by default) files.  These are normal Emacs Lisp files
+ and can be used to avoid cluttering your @file{~/.emacs} and
+ @file{site-init} files with Gnus stuff.  Gnus will also check for files
+ with the same names as these, but with @file{.elc} and @file{.el}
+ suffixes.  In other words, if you have set @code{gnus-init-file} to
+ @file{~/.gnus}, it will look for @file{~/.gnus.elc}, @file{~/.gnus.el},
+ and finally @file{~/.gnus} (in this order).
+
+
+
+ @node Auto Save
+ @section Auto Save
+ @cindex dribble file
+ @cindex auto-save
+
+ Whenever you do something that changes the Gnus data (reading articles,
+ catching up, killing/subscribing groups), the change is added to a
+ special @dfn{dribble buffer}.  This buffer is auto-saved the normal
+ Emacs way.  If your Emacs should crash before you have saved the
+ @file{.newsrc} files, all changes you have made can be recovered from
+ this file.
+
+ If Gnus detects this file at startup, it will ask the user whether to
+ read it.  The auto save file is deleted whenever the real startup file is
+ saved.
+
+ @vindex gnus-use-dribble-file
+ If @code{gnus-use-dribble-file} is @code{nil}, Gnus won't create and
+ maintain a dribble buffer.  The default is @code{t}.
+
+ @vindex gnus-dribble-directory
+ Gnus will put the dribble file(s) in @code{gnus-dribble-directory}.  If
+ this variable is @code{nil}, which it is by default, Gnus will dribble
+ into the directory where the @file{.newsrc} file is located.  (This is
+ normally the user's home directory.)  The dribble file will get the same
+ file permissions as the @file{.newsrc} file.
+
+ read the dribble file on startup without querying the user.
+
+
+ @node The Active File
+ @section The Active File
+ @cindex active file
+ @cindex ignored groups
+
+ When Gnus starts, or indeed whenever it tries to determine whether new
+ articles have arrived, it reads the active file.  This is a very large
+ file that lists all the active groups and articles on the server.
+
+ @vindex gnus-ignored-newsgroups
+ Before examining the active file, Gnus deletes all lines that match the
+ regexp @code{gnus-ignored-newsgroups}.  This is done primarily to reject
+ any groups with bogus names, but you can use this variable to make Gnus
+ ignore hierarchies you aren't ever interested in.  However, this is not
+ recommended.  In fact, it's highly discouraged.  Instead, @pxref{New
+ Groups} for an overview of other variables that can be used instead.
+
+ @c This variable is
+ @c @code{nil} by default, and will slow down active file handling somewhat
+ @c if you set it to anything else.
+
+ The active file can be rather Huge, so if you have a slow network, you
+ can set @code{gnus-read-active-file} to @code{nil} to prevent Gnus from
+ reading the active file.  This variable is @code{some} by default.
+
+ Gnus will try to make do by getting information just on the groups that
+ you actually subscribe to.
+
+ Note that if you subscribe to lots and lots of groups, setting this
+ variable to @code{nil} will probably make Gnus slower, not faster.  At
+ present, having this variable @code{nil} will slow Gnus down
+ considerably, unless you read news over a 2400 baud modem.
+
+ This variable can also have the value @code{some}.  Gnus will then
+ attempt to read active info only on the subscribed groups.  On some
+ servers this is quite fast (on sparkling, brand new INN servers that
+ support the @code{LIST ACTIVE group} command), on others this isn't fast
+ at all.  In any case, @code{some} should be faster than @code{nil}, and
+ is certainly faster than @code{t} over slow lines.
+
+ Some news servers (old versions of Leafnode and old versions of INN, for
+ instance) do not support the @code{LIST ACTIVE group}.  For these
+ servers, @code{nil} is probably the most efficient value for this
+ variable.
+
+ If this variable is @code{nil}, Gnus will ask for group info in total
+ lock-step, which isn't very fast.  If it is @code{some} and you use an
+ @acronym{NNTP} server, Gnus will pump out commands as fast as it can, and
+ read all the replies in one swoop.  This will normally result in better
+ performance, but if the server does not support the aforementioned
+ @code{LIST ACTIVE group} command, this isn't very nice to the server.
+
+ If you think that starting up Gnus takes too long, try all the three
+ different values for this variable and see what works best for you.
+
+ In any case, if you use @code{some} or @code{nil}, you should definitely
+ kill all groups that you aren't interested in to speed things up.
+
+ Note that this variable also affects active file retrieval from
+ secondary select methods.
+
+
+ @node Startup Variables
+ @section Startup Variables
+
+ @table @code
+
+ A hook run while Gnus is being loaded.  Note that this hook will
+ normally be run just once in each Emacs session, no matter how many
+ times you start Gnus.
+
+ @item gnus-before-startup-hook
+ @vindex gnus-before-startup-hook
+ A hook run after starting up Gnus successfully.
+
+ @item gnus-startup-hook
+ @vindex gnus-startup-hook
+ A hook run as the very last thing after starting up Gnus
+
+ @item gnus-started-hook
+ @vindex gnus-started-hook
+ A hook that is run as the very last thing after starting up Gnus
+ successfully.
+
+ @item gnus-setup-news-hook
+ @vindex gnus-setup-news-hook
+ A hook that is run after reading the @file{.newsrc} file(s), but before
+ generating the group buffer.
+
+ @item gnus-check-bogus-newsgroups
+ @vindex gnus-check-bogus-newsgroups
+ If address@hidden, Gnus will check for and delete all bogus groups at
+ startup.  A @dfn{bogus group} is a group that you have in your
+ @file{.newsrc} file, but doesn't exist on the news server.  Checking for
+ bogus groups can take quite a while, so to save time and resources it's
+ best to leave this option off, and do the checking for bogus groups once
+ in a while from the group buffer instead (@pxref{Group Maintenance}).
+
+ @item gnus-inhibit-startup-message
+ @vindex gnus-inhibit-startup-message
+ If address@hidden, the startup message won't be displayed.  That way,
+ of doing your job.  Note that this variable is used before
+ @file{~/.gnus.el} is loaded, so it should be set in @file{.emacs} instead.
+
+ @item gnus-no-groups-message
+ @vindex gnus-no-groups-message
+ Message displayed by Gnus when no groups are available.
+
+ @item gnus-play-startup-jingle
+ @vindex gnus-play-startup-jingle
+ If address@hidden, play the Gnus jingle at startup.
+
+ @item gnus-startup-jingle
+ @vindex gnus-startup-jingle
+ Jingle to be played if the above variable is address@hidden  The
+ default is @samp{Tuxedomoon.Jingle4.au}.
+
+ @end table
+
+
+ @node Group Buffer
+ @chapter Group Buffer
+ @cindex group buffer
+
+ @c Alex Schroeder suggests to rearrange this as follows:
+ @c
+ @c <kensanata> ok, just save it for reference.  I'll go to bed in a minute.
+ @c   1. Selecting a Group, 2. (new) Finding a Group, 3. Group Levels,
+ @c   4. Subscription Commands, 5. Group Maneuvering, 6. Group Data,
+ @c   7. Group Score, 8. Group Buffer Format
+ @c <kensanata> Group Levels should have more information on levels 5 to 9.  I
+ @c   suggest to split the 4th paragraph ("Gnus considers groups...") as
follows:
+ @c <kensanata> First, "Gnus considers groups... (default 9)."
+ @c <kensanata> New, a table summarizing what levels 1 to 9 mean.
+ @c <kensanata> Third, "Gnus treats subscribed ... reasons of efficiency"
+ @c <kensanata> Then expand the next paragraph or add some more to it.
+ @c    This short one sentence explains levels 1 and 2, therefore I understand
+ @c    that I should keep important news at 3 and boring news at 4.
+ @c    Say so!  Then go on to explain why I should bother with levels 6 to 9.
+ @c    Maybe keep those that you don't want to read temporarily at 6,
+ @c    those that you never want to read at 8, those that offend your
+ @c    human rights at 9...
+
+
+ The @dfn{group buffer} lists all (or parts) of the available groups.  It
+ is the first buffer shown when Gnus starts, and will never be killed as
+ long as Gnus is active.
+
+ @iftex
+ @iflatex
+ \gnusfigure{The Group Buffer}{320}{
+ \put(75,50){\epsfig{figure=ps/group,height=9cm}}
+ \put(120,37){\makebox(0,0)[t]{Buffer name}}
+ \put(120,38){\vector(1,2){10}}
+ \put(40,60){\makebox(0,0)[r]{Mode line}}
+ \put(40,58){\vector(1,0){30}}
+ \put(200,28){\makebox(0,0)[t]{Native select method}}
+ \put(200,26){\vector(-1,2){15}}
+ }
+ @end iflatex
+ @end iftex
+
+ * Group Buffer Format::         Information listed and how you can change it.
+ * Group Maneuvering::           Commands for moving in the group buffer.
+ * Selecting a Group::           Actually reading news.
+ * Subscription Commands::       Unsubscribing, killing, subscribing.
+ * Group Data::                  Changing the info for a group.
+ * Group Levels::                Levels? What are those, then?
+ * Group Score::                 A mechanism for finding out what groups you
like.
+ * Marking Groups::              You can mark groups for later processing.
+ * Foreign Groups::              Creating and editing groups.
+ * Group Parameters::            Each group may have different parameters set.
+ * Listing Groups::              Gnus can list various subsets of the groups.
+ * Sorting Groups::              Re-arrange the group order.
+ * Group Maintenance::           Maintaining a tidy @file{.newsrc} file.
+ * Browse Foreign Server::       You can browse a server.  See what it has to
offer.
+ * Exiting Gnus::                Stop reading news and get some work done.
+ * Group Topics::                A folding group mode divided into topics.
+ * Misc Group Stuff::            Other stuff that you can to do.
+
+
+ @node Group Buffer Format
+ @section Group Buffer Format
+
+ * Group Line Specification::    Deciding how the group buffer is to look.
+ * Group Mode Line Specification::  The group buffer mode line.
+ * Group Highlighting::          Having nice colors in the group buffer.
+
+
+ @node Group Line Specification
+ @subsection Group Line Specification
+ @cindex group buffer format
+
+ The default format of the group buffer is nice and dull, but you can
+ make it as exciting and ugly as you feel like.
+
+ Here's a couple of example group lines:
+
+ @example
+      25: news.announce.newusers
+  *    0: alt.fan.andrea-dworkin
+ @end example
+
+ Quite simple, huh?
+
+ You can see that there are 25 unread articles in
+ @samp{news.announce.newusers}.  There are no unread articles, but some
+ ticked articles, in @samp{alt.fan.andrea-dworkin} (see that little
+ asterisk at the beginning of the line?).
+
+ @vindex gnus-group-line-format
+ You can change that format to whatever you want by fiddling with the
+ @code{gnus-group-line-format} variable.  This variable works along the
+ lines of a @code{format} specification, which is pretty much the same as
+ a @code{printf} specifications, for those of you who use (feh!) C.
+ @xref{Formatting Variables}.
+
+ @samp{%M%S%5y:%B%(%g%)\n} is the value that produced those lines above.
+
+ There should always be a colon on the line; the cursor always moves to
+ the colon after performing an operation.  @xref{Positioning
+ Point}.  Nothing else is required---not even the group name.  All
+ displayed text is just window dressing, and is never examined by Gnus.
+ Gnus stores all real information it needs using text properties.
+
+ (Note that if you make a really strange, wonderful, spreadsheet-like
+ layout, everybody will believe you are hard at work with the accounting
+
+ Here's a list of all available format characters:
+
+ @table @samp
+
+ @item M
+ An asterisk if the group only has marked articles.
+
+ @item S
+ Whether the group is subscribed.
+
+ @item L
+ Level of subscribedness.
+
+ @item N
+
+ @item I
+ Number of dormant articles.
+
+ @item T
+ Number of ticked articles.
+
+ @item R
+
+ @item U
+ Number of unseen articles.
+
+ @item t
+ Estimated total number of articles.  (This is really @var{max-number}
+ minus @var{min-number} plus 1.)
+
+ Gnus uses this estimation because the @acronym{NNTP} protocol provides
+ the true unread message count is not possible efficiently.  For
+ hysterical raisins, even the mail back ends, where the true number of
+ unread messages might be available efficiently, use the same limited
+ interface.  To remove this restriction from Gnus means that the back
+ end interface has to be changed, which is not an easy job.  If you
+
+ @item y
+ Number of unread, unticked, non-dormant articles.
+
+ @item i
+ Number of ticked and dormant articles.
+
+ @item g
+ Full group name.
+
+ @item G
+ Group name.
+
+ @item C
+ Group comment (@pxref{Group Parameters}) or group name if there is no
+ comment element in the group parameters.
+
+ @item D
+ Newsgroup description.  You need to read the group descriptions
+ before these will appear, and to do that, you either have to set
+ @code{gnus-read-active-file} or use the group buffer @kbd{M-d}
+ command.
+
+ @item o
+ @samp{m} if moderated.
+
+ @item O
+ @samp{(m)} if moderated.
+
+ @item s
+ Select method.
+
+ @item B
+ If the summary buffer for the group is open or not.
+
+ @item n
+ Select from where.
+
+ @item z
+ A string that looks like @samp{<%s:%n>} if a foreign select method is
+ used.
+
+ @item P
+ Indentation based on the level of the topic (@pxref{Group Topics}).
+
+ @item c
+ @vindex gnus-group-uncollapsed-levels
+ Short (collapsed) group name.  The @code{gnus-group-uncollapsed-levels}
+ variable says how many levels to leave at the end of the group name.
+ The default is 1---this will mean that group names like
+ @samp{gnu.emacs.gnus} will be shortened to @samp{g.e.gnus}.
+
+ @item m
+ @vindex gnus-new-mail-mark
+ @cindex %
+ @samp{%} (@code{gnus-new-mail-mark}) if there has arrived new mail to
+ the group lately.
+
+ @item p
+ @samp{#} (@code{gnus-process-mark}) if the group is process marked.
+
+ @item d
+ A string that says when you last read the group (@pxref{Group
+ Timestamp}).
+
+ @item u
+ User defined specifier.  The next character in the format string should
+ be a letter.  Gnus will call the function
+ @address@hidden, where @samp{X} is the letter
+ following @samp{%u}.  The function will be passed a single dummy
+ parameter as argument.  The function should return a string, which will
+ be inserted into the buffer just like information from any other
+ specifier.
+ @end table
+
+ @cindex *
+ All the number-of'' specs will be filled with an asterisk (@samp{*})
+ if no info is available---for instance, if it is a non-activated foreign
+ group, or a bogus native group.
+
+
+ @node Group Mode Line Specification
+ @subsection Group Mode Line Specification
+ @cindex group mode line
+
+ @vindex gnus-group-mode-line-format
+ The mode line can be changed by setting
+ @code{gnus-group-mode-line-format} (@pxref{Mode Line Formatting}).  It
+ doesn't understand that many format specifiers:
+
+ @table @samp
+ @item S
+ The native news server.
+ @item M
+ The native select method.
+ @end table
+
+
+ @node Group Highlighting
+ @subsection Group Highlighting
+ @cindex highlighting
+ @cindex group highlighting
+
+ @vindex gnus-group-highlight
+ Highlighting in the group buffer is controlled by the
+ @code{gnus-group-highlight} variable.  This is an alist with elements
+ that look like @code{(@var{form} . @var{face})}.  If @var{form} evaluates to
+ something address@hidden, the @var{face} will be used on the line.
+
+ Here's an example value for this variable that might look nice if the
+ background is dark:
+
+ @lisp
+ (cond (window-system
+        (setq custom-background-mode 'light)
+        (defface my-group-face-1
+          '((t (:foreground "Red" :bold t))) "First group face")
+        (defface my-group-face-2
+          '((t (:foreground "DarkSeaGreen4" :bold t)))
+          "Second group face")
+        (defface my-group-face-3
+          '((t (:foreground "Green4" :bold t))) "Third group face")
+        (defface my-group-face-4
+          '((t (:foreground "SteelBlue" :bold t))) "Fourth group face")
+        (defface my-group-face-5
+          '((t (:foreground "Blue" :bold t))) "Fifth group face")))
+
+ (setq gnus-group-highlight
+       '(((> unread 200) . my-group-face-1)
+         ((and (< level 3) (zerop unread)) . my-group-face-2)
+         ((< level 3) . my-group-face-3)
+         (t . my-group-face-5)))
+ @end lisp
+
+ Also @pxref{Faces and Fonts}.
+
+ Variables that are dynamically bound when the forms are evaluated
+ include:
+
+ @table @code
+ @item group
+ The group name.
+ The number of unread articles in the group.
+ @item method
+ The select method.
+ @item mailp
+ Whether the group is a mail group.
+ @item level
+ The level of the group.
+ @item score
+ The score of the group.
+ @item ticked
+ The number of ticked articles in the group.
+ @item total
+ The total number of articles in the group.  Or rather,
+ @var{max-number} minus @var{min-number} plus one.
+ @item topic
+ When using the topic minor mode, this variable is bound to the current
+ topic being inserted.
+ @end table
+
+ When the forms are @code{eval}ed, point is at the beginning of the line
+ of the group in question, so you can use many of the normal Gnus
+ functions for snarfing info on the group.
+
+ @vindex gnus-group-update-hook
+ @findex gnus-group-highlight-line
+ @code{gnus-group-update-hook} is called when a group line is changed.
+ It will not be called when @code{gnus-visual} is @code{nil}.  This hook
+ calls @code{gnus-group-highlight-line} by default.
+
+
+ @node Group Maneuvering
+ @section Group Maneuvering
+ @cindex group movement
+
+ All movement commands understand the numeric prefix and will behave as
+ expected, hopefully.
+
+ @table @kbd
+
+ @item n
+ @kindex n (Group)
+ Go to the next group that has unread articles
+
+ @item p
+ @itemx DEL
+ @kindex DEL (Group)
+ @kindex p (Group)
+ Go to the previous group that has unread articles
+
+ @item N
+ @kindex N (Group)
+ @findex gnus-group-next-group
+ Go to the next group (@code{gnus-group-next-group}).
+
+ @item P
+ @kindex P (Group)
+ @findex gnus-group-prev-group
+ Go to the previous group (@code{gnus-group-prev-group}).
+
+ @item M-n
+ @kindex M-n (Group)
+ Go to the next unread group on the same (or lower) level
+
+ @item M-p
+ @kindex M-p (Group)
+ Go to the previous unread group on the same (or lower) level
+ @end table
+
+ Three commands for jumping to groups:
+
+ @table @kbd
+
+ @item j
+ @kindex j (Group)
+ @findex gnus-group-jump-to-group
+ (@code{gnus-group-jump-to-group}).  Killed groups can be jumped to, just
+ like living groups.
+
+ @item ,
+ @kindex , (Group)
+
+ @item .
+ @kindex . (Group)
+ @end table
+
+ If @code{gnus-group-goto-unread} is @code{nil}, all the movement
+ commands will move to the next group, not the next unread group.  Even
+ the commands that say they move to the next unread group.  The default
+ is @code{t}.
+
+
+ @node Selecting a Group
+ @section Selecting a Group
+ @cindex group selection
+
+ @table @kbd
+
+ @item SPACE
+ @kindex SPACE (Group)
+ Select the current group, switch to the summary buffer and display the
+ unread articles in the group, or if you give a non-numerical prefix to
+ this command, Gnus will offer to fetch all the old articles in this
+ group from the server.  If you give a numerical prefix @var{n}, @var{n}
+ determines the number of articles Gnus will fetch.  If @var{n} is
+ positive, Gnus fetches the @var{n} newest articles, if @var{n} is
+ negative, Gnus fetches the @code{abs(@var{n})} oldest articles.
+
+ Thus, @kbd{SPC} enters the group normally, @kbd{C-u SPC} offers old
+ articles, @kbd{C-u 4 2 SPC} fetches the 42 newest articles, and @kbd{C-u
+ - 4 2 SPC} fetches the 42 oldest ones.
+
+ When you are in the group (in the Summary buffer), you can type
+ @kbd{M-g} to fetch new articles, or @kbd{C-u M-g} to also show the old
+ ones.
+
+ @item RET
+ @kindex RET (Group)
+ @findex gnus-group-select-group
+ Select the current group and switch to the summary buffer
+ (@code{gnus-group-select-group}).  Takes the same arguments as
+ @code{gnus-group-read-group}---the only difference is that this command
+ does not display the first unread article automatically upon group
+ entry.
+
+ @item M-RET
+ @kindex M-RET (Group)
+ @findex gnus-group-quick-select-group
+ This does the same as the command above, but tries to do it with the
+ minimum amount of fuzz (@code{gnus-group-quick-select-group}).  No
+ scoring/killing will be performed, there will be no highlights and no
+ expunging.  This might be useful if you're in a real hurry and have to
+ enter some humongous group.  If you give a 0 prefix to this command
+ (i.e., @kbd{0 M-RET}), Gnus won't even generate the summary buffer,
+ which is useful if you want to toggle threading before generating the
+ summary buffer (@pxref{Summary Generation Commands}).
+
+ @item M-SPACE
+ @kindex M-SPACE (Group)
+ @findex gnus-group-visible-select-group
+ This is yet one more command that does the same as the @kbd{RET}
+ command, but this one does it without expunging and hiding dormants
+ (@code{gnus-group-visible-select-group}).
+
+ @item C-M-RET
+ @kindex C-M-RET (Group)
+ @findex gnus-group-select-group-ephemerally
+ Finally, this command selects the current group ephemerally without
+ doing any processing of its contents
+ (@code{gnus-group-select-group-ephemerally}).  Even threading has been
+ turned off.  Everything you do in the group after selecting it in this
+ manner will have no permanent effects.
+
+ @end table
+
+ @vindex gnus-large-newsgroup
+ The @code{gnus-large-newsgroup} variable says what Gnus should
+ consider to be a big group.  If it is @code{nil}, no groups are
+ considered big.  The default value is 200.  If the group has more
+ (unread and/or ticked) articles than this, Gnus will query the user
+ before entering the group.  The user can then specify how many
+ articles should be fetched from the server.  If the user specifies a
+ negative number (@var{-n}), the @var{n} oldest articles will be
+ fetched.  If it is positive, the @var{n} articles that have arrived
+ most recently will be fetched.
+
+ @vindex gnus-large-ephemeral-newsgroup
+ @code{gnus-large-ephemeral-newsgroup} is the same as
+ @code{gnus-large-newsgroup}, but is only used for ephemeral
+ newsgroups.
+
+ @vindex gnus-select-group-hook
+ @vindex gnus-auto-select-first
+ @vindex gnus-auto-select-subject
+ If @code{gnus-auto-select-first} is address@hidden, select an article
+ automatically when entering a group with the @kbd{SPACE} command.
+ Which article this is is controlled by the
+ @code{gnus-auto-select-subject} variable.  Valid values for this
+ variable is:
+
+ @table @code
+
+ Place point on the subject line of the first unread article.
+
+ @item first
+ Place point on the subject line of the first article.
+
+ @item unseen
+ Place point on the subject line of the first unseen article.
+
+ Place point on the subject line of the first unseen article, and if
+ there is no such article, place point on the subject line of the first
+
+ @item best
+ Place point on the subject line of the highest-scored unread article.
+
+ @end table
+
+ This variable can also be a function.  In that case, that function
+ will be called to place point on a subject line.
+
+ If you want to prevent automatic selection in some group (say, in a
+ binary group with Huge articles) you can set the
+ @code{gnus-auto-select-first} variable to @code{nil} in
+ @code{gnus-select-group-hook}, which is called when a group is
+ selected.
+
+
+ @node Subscription Commands
+ @section Subscription Commands
+ @cindex subscription
+
+ @table @kbd
+
+ @item S t
+ @itemx u
+ @kindex S t (Group)
+ @kindex u (Group)
+ @findex gnus-group-unsubscribe-current-group
+ @c @icon{gnus-group-unsubscribe}
+ Toggle subscription to the current group
+ (@code{gnus-group-unsubscribe-current-group}).
+
+ @item S s
+ @itemx U
+ @kindex S s (Group)
+ @kindex U (Group)
+ @findex gnus-group-unsubscribe-group
+ Prompt for a group to subscribe, and then subscribe it.  If it was
+ (@code{gnus-group-unsubscribe-group}).
+
+ @item S k
+ @itemx C-k
+ @kindex S k (Group)
+ @kindex C-k (Group)
+ @findex gnus-group-kill-group
+ @c @icon{gnus-group-kill-group}
+ Kill the current group (@code{gnus-group-kill-group}).
+
+ @item S y
+ @itemx C-y
+ @kindex S y (Group)
+ @kindex C-y (Group)
+ @findex gnus-group-yank-group
+ Yank the last killed group (@code{gnus-group-yank-group}).
+
+ @item C-x C-t
+ @kindex C-x C-t (Group)
+ @findex gnus-group-transpose-groups
+ Transpose two groups (@code{gnus-group-transpose-groups}).  This isn't
+ really a subscription command, but you can use it instead of a
+ kill-and-yank sequence sometimes.
+
+ @item S w
+ @itemx C-w
+ @kindex S w (Group)
+ @kindex C-w (Group)
+ @findex gnus-group-kill-region
+ Kill all groups in the region (@code{gnus-group-kill-region}).
+
+ @item S z
+ @kindex S z (Group)
+ @findex gnus-group-kill-all-zombies
+ Kill all zombie groups (@code{gnus-group-kill-all-zombies}).
+
+ @item S C-k
+ @kindex S C-k (Group)
+ @findex gnus-group-kill-level
+ Kill all groups on a certain level (@code{gnus-group-kill-level}).
+ These groups can't be yanked back after killing, so this command should
+ be used with some caution.  The only time where this command comes in
+ really handy is when you have a @file{.newsrc} with lots of unsubscribed
+ groups that you want to get rid off.  @kbd{S C-k} on level 7 will
+ kill off all unsubscribed groups that do not have message numbers in the
+ @file{.newsrc} file.
+
+ @end table
+
+ Also @pxref{Group Levels}.
+
+
+ @node Group Data
+ @section Group Data
+
+ @table @kbd
+
+ @item c
+ @kindex c (Group)
+ @findex gnus-group-catchup-current
+ @vindex gnus-group-catchup-group-hook
+ @c @icon{gnus-group-catchup-current}
+ Mark all unticked articles in this group as read
+ (@code{gnus-group-catchup-current}).
+ @code{gnus-group-catchup-group-hook} is called when catching up a group from
+ the group buffer.
+
+ @item C
+ @kindex C (Group)
+ @findex gnus-group-catchup-current-all
+ Mark all articles in this group, even the ticked ones, as read
+ (@code{gnus-group-catchup-current-all}).
+
+ @item M-c
+ @kindex M-c (Group)
+ @findex gnus-group-clear-data
+ Clear the data from the current group---nix out marks and the list of
+
+ @item M-x gnus-group-clear-data-on-native-groups
+ @kindex M-x gnus-group-clear-data-on-native-groups
+ @findex gnus-group-clear-data-on-native-groups
+ If you have switched from one @acronym{NNTP} server to another, all your marks
+ and read ranges have become worthless.  You can use this command to
+ clear out all data that you have on your native groups.  Use with
+ caution.
+
+ @end table
+
+
+ @node Group Levels
+ @section Group Levels
+ @cindex group level
+ @cindex level
+
+ All groups have a level of @dfn{subscribedness}.  For instance, if a
+ group is on level 2, it is more subscribed than a group on level 5.  You
+ can ask Gnus to just list groups on a given level or lower
+ (@pxref{Listing Groups}), or to just check for new articles in groups on
+ a given level or lower (@pxref{Scanning New Messages}).
+
+ Remember:  The higher the level of the group, the less important it is.
+
+ @table @kbd
+
+ @item S l
+ @kindex S l (Group)
+ @findex gnus-group-set-current-level
+ Set the level of the current group.  If a numeric prefix is given, the
+ next @var{n} groups will have their levels set.  The user will be
+ prompted for a level.
+ @end table
+
+ @vindex gnus-level-killed
+ @vindex gnus-level-zombie
+ @vindex gnus-level-unsubscribed
+ @vindex gnus-level-subscribed
+ Gnus considers groups from levels 1 to
+ @code{gnus-level-subscribed} (inclusive) (default 5) to be subscribed,
+ @code{gnus-level-subscribed} (exclusive) and
+ @code{gnus-level-unsubscribed} (inclusive) (default 7) to be
+ unsubscribed, @code{gnus-level-zombie} to be zombies (walking dead)
+ (default 8) and @code{gnus-level-killed} to be killed (completely dead)
+ (default 9).  Gnus treats subscribed and unsubscribed groups exactly the
+ same, but zombie and killed groups have no information on what articles
+ you have read, etc, stored.  This distinction between dead and living
+ groups isn't done because it is nice or clever, it is done purely for
+ reasons of efficiency.
+
+ It is recommended that you keep all your mail groups (if any) on quite
+ low levels (e.g. 1 or 2).
+
+ Maybe the following description of the default behavior of Gnus helps to
+ understand what these levels are all about.  By default, Gnus shows you
+ subscribed nonempty groups, but by hitting @kbd{L} you can have it show
+ empty subscribed groups and unsubscribed groups, too.  Type @kbd{l} to
+ go back to showing nonempty subscribed groups again.  Thus, unsubscribed
+ groups are hidden, in a way.
+
+ Zombie and killed groups are similar to unsubscribed groups in that they
+ are hidden by default.  But they are different from subscribed and
+ unsubscribed groups in that Gnus doesn't ask the news server for
+ information (number of messages, number of unread messages) on zombie
+ and killed groups.  Normally, you use @kbd{C-k} to kill the groups you
+ aren't interested in.  If most groups are killed, Gnus is faster.
+
+ Why does Gnus distinguish between zombie and killed groups?  Well, when
+ a new group arrives on the server, Gnus by default makes it a zombie
+ group.  This means that you are normally not bothered with new groups,
+ but you can type @kbd{A z} to get a list of all new groups.  Subscribe
+ the ones you like and kill the ones you don't want.  (@kbd{A k} shows a
+ list of killed groups.)
+
+ If you want to play with the level variables, you should show some care.
+ Set them once, and don't touch them ever again.  Better yet, don't touch
+ them at all unless you know exactly what you're doing.
+
+ @vindex gnus-level-default-unsubscribed
+ @vindex gnus-level-default-subscribed
+ Two closely related variables are @code{gnus-level-default-subscribed}
+ (default 3) and @code{gnus-level-default-unsubscribed} (default 6),
+ which are the levels that new groups will be put on if they are
+ (un)subscribed.  These two variables should, of course, be inside the
+ relevant valid ranges.
+
+ @vindex gnus-keep-same-level
+ If @code{gnus-keep-same-level} is address@hidden, some movement commands
+ will only move to groups of the same level (or lower).  In
+ particular, going from the last article in one group to the next group
+ will go to the next group of the same level (or lower).  This might be
+ handy if you want to read the most important groups before you read the
+ rest.
+
+ If this variable is @code{best}, Gnus will make the next newsgroup the
+ one with the best level.
+
+ @vindex gnus-group-default-list-level
+ All groups with a level less than or equal to
+ @code{gnus-group-default-list-level} will be listed in the group buffer
+ by default.
+
+ @vindex gnus-group-list-inactive-groups
+ If @code{gnus-group-list-inactive-groups} is address@hidden, non-active
+ groups will be listed along with the unread groups.  This variable is
+ @code{t} by default.  If it is @code{nil}, inactive groups won't be
+ listed.
+
+ @vindex gnus-group-use-permanent-levels
+ If @code{gnus-group-use-permanent-levels} is address@hidden, once you
+ give a level prefix to @kbd{g} or @kbd{l}, all subsequent commands will
+ use this level as the work'' level.
+
+ @vindex gnus-activate-level
+ Gnus will normally just activate (i. e., query the server about) groups
+ on level @code{gnus-activate-level} or less.  If you don't want to
+ activate unsubscribed groups, for instance, you might set this variable
+ to 5.  The default is 6.
+
+
+ @node Group Score
+ @section Group Score
+ @cindex group score
+ @cindex group rank
+ @cindex rank
+
+ You would normally keep important groups on high levels, but that scheme
+ is somewhat restrictive.  Don't you wish you could have Gnus sort the
+ group buffer according to how often you read groups, perhaps?  Within
+ reason?
+
+ This is what @dfn{group score} is for.  You can have Gnus assign a score
+ to each group through the mechanism described below.  You can then sort
+ the group buffer based on this score.  Alternatively, you can sort on
+ score and then level.  (Taken together, the level and the score is
+ called the @dfn{rank} of the group.  A group that is on level 4 and has
+ a score of 1 has a higher rank than a group on level 5 that has a score
+ of 300.  (The level is the most significant part and the score is the
+ least significant part.))
+
+ @findex gnus-summary-bubble-group
+ If you want groups you read often to get higher scores than groups you
+ the @code{gnus-summary-exit-hook} hook.  This will result (after
+ sorting) in a bubbling sort of action.  If you want to see that in
+ action after each summary exit, you can add
+ @code{gnus-group-sort-groups-by-rank} or
+ @code{gnus-group-sort-groups-by-score} to the same hook, but that will
+ slow things down somewhat.
+
+
+ @node Marking Groups
+ @section Marking Groups
+ @cindex marking groups
+
+ If you want to perform some command on several groups, and they appear
+ subsequently in the group buffer, you would normally just give a
+ numerical prefix to the command.  Most group commands will then do your
+ bidding on those groups.
+
+ However, if the groups are not in sequential order, you can still
+ perform a command on several groups.  You simply mark the groups first
+ with the process mark and then execute the command.
+
+ @table @kbd
+
+ @item #
+ @kindex # (Group)
+ @itemx M m
+ @kindex M m (Group)
+ @findex gnus-group-mark-group
+ Set the mark on the current group (@code{gnus-group-mark-group}).
+
+ @item M-#
+ @kindex M-# (Group)
+ @itemx M u
+ @kindex M u (Group)
+ @findex gnus-group-unmark-group
+ Remove the mark from the current group
+ (@code{gnus-group-unmark-group}).
+
+ @item M U
+ @kindex M U (Group)
+ @findex gnus-group-unmark-all-groups
+ Remove the mark from all groups (@code{gnus-group-unmark-all-groups}).
+
+ @item M w
+ @kindex M w (Group)
+ @findex gnus-group-mark-region
+ Mark all groups between point and mark (@code{gnus-group-mark-region}).
+
+ @item M b
+ @kindex M b (Group)
+ @findex gnus-group-mark-buffer
+ Mark all groups in the buffer (@code{gnus-group-mark-buffer}).
+
+ @item M r
+ @kindex M r (Group)
+ @findex gnus-group-mark-regexp
+ Mark all groups that match some regular expression
+ (@code{gnus-group-mark-regexp}).
+ @end table
+
+ Also @pxref{Process/Prefix}.
+
+ @findex gnus-group-universal-argument
+ If you want to execute some command on all groups that have been marked
+ with the process mark, you can use the @kbd{M-&}
+ (@code{gnus-group-universal-argument}) command.  It will prompt you for
+ the command to be executed.
+
+
+ @node Foreign Groups
+ @section Foreign Groups
+ @cindex foreign groups
+
+ Below are some group mode commands for making and editing general foreign
+ groups, as well as commands to ease the creation of a few
+ special-purpose groups.  All these commands insert the newly created
+ groups under address@hidden is not
+ consulted.
+
+ @table @kbd
+
+ @item G m
+ @kindex G m (Group)
+ @findex gnus-group-make-group
+ @cindex making groups
+ Make a new group (@code{gnus-group-make-group}).  Gnus will prompt you
+ for a name, a method and possibly an @dfn{address}.  For an easier way
+ to subscribe to @acronym{NNTP} groups (@pxref{Browse Foreign Server}).
+
+ @item G M
+ @kindex G M (Group)
+ Make an ephemeral group (@code{gnus-group-read-ephemeral-group}).  Gnus
+ will prompt you for a name, a method and an @dfn{address}.
+
+ @item G r
+ @kindex G r (Group)
+ @findex gnus-group-rename-group
+ @cindex renaming groups
+ Rename the current group to something else
+ (@code{gnus-group-rename-group}).  This is valid only on some
+ groups---mail groups mostly.  This command might very well be quite slow
+ on some back ends.
+
+ @item G c
+ @kindex G c (Group)
+ @cindex customizing
+ @findex gnus-group-customize
+ Customize the group parameters (@code{gnus-group-customize}).
+
+ @item G e
+ @kindex G e (Group)
+ @findex gnus-group-edit-group-method
+ @cindex renaming groups
+ Enter a buffer where you can edit the select method of the current
+ group (@code{gnus-group-edit-group-method}).
+
+ @item G p
+ @kindex G p (Group)
+ @findex gnus-group-edit-group-parameters
+ Enter a buffer where you can edit the group parameters
+ (@code{gnus-group-edit-group-parameters}).
+
+ @item G E
+ @kindex G E (Group)
+ @findex gnus-group-edit-group
+ Enter a buffer where you can edit the group info
+ (@code{gnus-group-edit-group}).
+
+ @item G d
+ @kindex G d (Group)
+ @findex gnus-group-make-directory-group
+ @cindex nndir
+ Make a directory group (@pxref{Directory Groups}).  You will be prompted
+ for a directory name (@code{gnus-group-make-directory-group}).
+
+ @item G h
+ @kindex G h (Group)
+ @cindex help group
+ @findex gnus-group-make-help-group
+ Make the Gnus help group (@code{gnus-group-make-help-group}).
+
+ @item G a
+ @kindex G a (Group)
+ @cindex (ding) archive
+ @cindex archive group
+ @findex gnus-group-make-archive-group
+ @vindex gnus-group-archive-directory
+ @vindex gnus-group-recent-archive-directory
+ Make a Gnus archive group (@code{gnus-group-make-archive-group}).  By
+ default a group pointing to the most recent articles will be created
+ (@code{gnus-group-recent-archive-directory}), but given a prefix, a full
+ group will be created from @code{gnus-group-archive-directory}.
+
+ @item G k
+ @kindex G k (Group)
+ @findex gnus-group-make-kiboze-group
+ @cindex nnkiboze
+ Make a kiboze group.  You will be prompted for a name, for a regexp to
+ match groups to be included'' in the kiboze group, and a series of
+ strings to match on headers (@code{gnus-group-make-kiboze-group}).
+ @xref{Kibozed Groups}.
+
+ @item G D
+ @kindex G D (Group)
+ @findex gnus-group-enter-directory
+ @cindex nneething
+ Read an arbitrary directory as if it were a newsgroup with the
+ @code{nneething} back end (@code{gnus-group-enter-directory}).
+ @xref{Anything Groups}.
+
+ @item G f
+ @kindex G f (Group)
+ @findex gnus-group-make-doc-group
+ @cindex ClariNet Briefs
+ @cindex nndoc
+ Make a group based on some file or other
+ (@code{gnus-group-make-doc-group}).  If you give a prefix to this
+ command, you will be prompted for a file name and a file type.
+ Currently supported types are @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}, and @code{mailman}.  If
+ you run this command without a prefix, Gnus will guess at the file
+ type.  @xref{Document Groups}.
+
+ @item G u
+ @kindex G u (Group)
+ @vindex gnus-useful-groups
+ @findex gnus-group-make-useful-group
+ Create one of the groups mentioned in @code{gnus-useful-groups}
+ (@code{gnus-group-make-useful-group}).
+
+ @item G w
+ @kindex G w (Group)
+ @findex gnus-group-make-web-group
+ @cindex nnweb
+ @cindex gmane
+ Make an ephemeral group based on a web search
+ (@code{gnus-group-make-web-group}).  If you give a prefix to this
+ command, make a solid group instead.  You will be prompted for the
+ search engine type and the search string.  Valid search engine types
+ include @code{google}, @code{dejanews}, and @code{gmane}.
+ @xref{Web Searches}.
+
+ If you use the @code{google} search engine, you can limit the search
+ to a particular group by using a match string like
+
+ @item G R
+ @kindex G R (Group)
+ Make a group based on an @acronym{RSS} feed
+ (@code{gnus-group-make-rss-group}).  You will be prompted for an URL.
+
+ @item G DEL
+ @kindex G DEL (Group)
+ @findex gnus-group-delete-group
+ This function will delete the current group
+ (@code{gnus-group-delete-group}).  If given a prefix, this function will
+ actually delete all the articles in the group, and forcibly remove the
+ group itself from the face of the Earth.  Use a prefix only if you are
+ absolutely sure of what you are doing.  This command can't be used on
+ read-only groups (like @code{nntp} groups), though.
+
+ @item G V
+ @kindex G V (Group)
+ @findex gnus-group-make-empty-virtual
+ Make a new, fresh, empty @code{nnvirtual} group
+ (@code{gnus-group-make-empty-virtual}).  @xref{Virtual Groups}.
+
+ @item G v
+ @kindex G v (Group)
+ Add the current group to an @code{nnvirtual} group
+ (@code{gnus-group-add-to-virtual}).  Uses the process/prefix convention.
+ @end table
+
+ methods.
+
+ @vindex gnus-activate-foreign-newsgroups
+ If @code{gnus-activate-foreign-newsgroups} is a positive number,
+ Gnus will check all foreign groups with this level or lower at startup.
+ This might take quite a while, especially if you subscribe to lots of
+ groups from different @acronym{NNTP} servers.  Also @pxref{Group Levels};
+ @code{gnus-activate-level} also affects activation of foreign
+ newsgroups.
+
+
+ @node Group Parameters
+ @section Group Parameters
+ @cindex group parameters
+
+ The group parameters store information local to a particular group.
+ Here's an example group parameter list:
+
+ @example
+  (auto-expire . t))
+ @end example
+
+ We see that each element consists of a dotted pair''---the thing before
+ the dot is the key, while the thing after the dot is the value.  All the
+ parameters have this form @emph{except} local variable specs, which are
+ not dotted pairs, but proper lists.
+
+ Some parameters have correspondent customizable variables, each of which
+ is an alist of regexps and values.
+
+ The following group parameters can be used:
+
+ @table @code
+ Address used by when doing followups and new posts.
+
+ @example
+ @end example
+
+ This is primarily useful in mail groups that represent closed mailing
+ lists---mailing lists where it's expected that everybody that writes to
+ the mailing list is subscribed to it.  Since using this parameter
+ ensures that the mail only goes to the mailing list itself, it means
+
+ Using @code{to-address} will actually work whether the group is foreign
+ or not.  Let's say there's a group on the server that is called
+ @samp{fa.4ad-l}.  This is a real newsgroup, but the server has gotten
+ the articles from a mail-to-news gateway.  Posting directly to this
+ group is therefore impossible---you have to send mail to the mailing
+
+
+ @item to-list
+ @cindex to-list
+ Address used when doing @kbd{a} in that group.
+
+ @example
+ (to-list . "some@@where.com")
+ @end example
+
+ It is totally ignored
+ when doing a followup---except that if it is present in a news group,
+ you'll get mail group semantics when doing @kbd{f}.
+
+ If you do an @kbd{a} command in a mail group and you have neither a
+ @code{to-list} group parameter nor a @code{to-address} group parameter,
+ then a @code{to-list} group parameter will be added automatically upon
+ sending the message if @code{gnus-add-to-list} is set to @code{t}.
+
+ @findex gnus-mailing-list-mode
+ @cindex mail list groups
+ If this variable is set, @code{gnus-mailing-list-mode} is turned on when
+ entering summary buffer.
+
+
+ @anchor{subscribed}
+ @item subscribed
+ @cindex subscribed
+ @cindex Mail-Followup-To
+ If this parameter is set to @code{t}, Gnus will consider the
+ mailing lists you are subscribed to.  Giving Gnus this information is
+ (only) a first step in getting it to generate correct Mail-Followup-To
+ headers for your posts to these lists.  The second step is to put the
+
+ @lisp
+ @end lisp
+
+ @xref{Mailing Lists, ,Mailing Lists, message, The Message Manual}, for
+ a complete treatment of available MFT support.
+
+ @item visible
+ @cindex visible
+ If the group parameter list has the element @code{(visible . t)},
+ that group will always be visible in the Group buffer, regardless
+ of whether it has any unread articles.
+
+ headers in this group are to be ignored, and for the header to be hidden
+ can be useful if you're reading a mailing list group where the listserv
+ itself.  That is broken behavior.  So there!
+
+ @item to-group
+ @cindex to-group
+ Elements like @code{(to-group . "some.group.name")} means that all
+ posts in that group will be sent to @code{some.group.name}.
+
+ @item newsgroup
+ @cindex newsgroup
+ If you have @code{(newsgroup . t)} in the group parameter list, Gnus
+ will treat all responses as if they were responses to news articles.
+ This can be useful if you have a mail group that's really a mirror of a
+ news group.
+
+ @item gcc-self
+ @cindex gcc-self
+ If @code{(gcc-self . t)} is present in the group parameter list, newly
+ composed messages will be @code{Gcc}'d to the current group.  If
+ @code{(gcc-self . none)} is present, no @code{Gcc:} header will be
+ generated, if @code{(gcc-self . "string")} is present, this string will
+ be inserted literally as a @code{gcc} header.  This parameter takes
+ precedence over any default @code{Gcc} rules as described later
+ (@pxref{Archived Messages}).
+
+ @strong{Caveat}: Adding @code{(gcc-self . t)} to the parameter list of
+ @code{nntp} groups (or the like) isn't valid.  An @code{nntp} server
+ doesn't accept articles.
+
+ @item auto-expire
+ @cindex auto-expire
+ If the group parameter has an element that looks like @code{(auto-expire
+ . t)}, all articles read will be marked as expirable.  For an
+ alternative approach, @pxref{Expiring Mail}.
+
+
+ @item total-expire
+ @cindex total-expire
+ If the group parameter has an element that looks like
+ @code{(total-expire . t)}, all read articles will be put through the
+ expiry process, even if they are not marked as expirable.  Use with
+ caution.  Unread, ticked and dormant articles are not eligible for
+ expiry.
+
+
+ @item expiry-wait
+ @cindex expiry-wait
+ @vindex nnmail-expiry-wait-function
+ If the group parameter has an element that looks like
+ @code{(expiry-wait . 10)}, this value will override any
+ @code{nnmail-expiry-wait} and @code{nnmail-expiry-wait-function}
+ (@pxref{Expiring Mail}) when expiring expirable messages.  The value
+ can either be a number of days (not necessarily an integer) or the
+ symbols @code{never} or @code{immediate}.
+
+ @item expiry-target
+ @cindex expiry-target
+ Where expired messages end up.  This parameter overrides
+ @code{nnmail-expiry-target}.
+
+ @item score-file
+ @cindex score file group parameter
+ Elements that look like @code{(score-file . "file")} will make
+ @file{file} into the current score file for the group in question.  All
+ interactive score entries will be put into this file.
+
+ @cindex adapt file group parameter
+ Elements that look like @code{(adapt-file . "file")} will make
+ @file{file} into the current adaptive file for the group in question.
+ All adaptive score entries will be put into this file.
+
+ When unsubscribing from a mailing list you should never send the
+ unsubscription notice to the mailing list itself.  Instead, you'd send
+
+ @item display
+ @cindex display
+ Elements that look like @code{(display . MODE)} say which articles to
+ display on entering the group.  Valid values are:
+
+ @table @code
+ @item all
+
+ @item an integer
+ Display the last @var{integer} articles in the group.  This is the same as
+ entering the group with @kbd{C-u @var{integer}}.
+
+ @item default
+ Display the default visible articles, which normally includes unread and
+ ticked articles.
+
+ @item an array
+ Display articles that satisfy a predicate.
+
+ Here are some examples:
+
+ @table @code
+
+ @item [not expire]
+ Display everything except expirable articles.
+
+ @item [and (not reply) (not expire)]
+ Display everything except expirable and articles you've already
+ responded to.
+ @end table
+
+ The available operators are @code{not}, @code{and} and @code{or}.
+ @code{killed}, @code{bookmark}, @code{score}, @code{save},
+ @code{cache}, @code{forward}, @code{unseen} and @code{recent}.
+
+ @end table
+
+ The @code{display} parameter works by limiting the summary buffer to
+ the subset specified.  You can pop the limit by using the @kbd{/ w}
+ command (@pxref{Limiting}).
+
+ @item comment
+ @cindex comment
+ Elements that look like @code{(comment . "This is a comment")} are
+ arbitrary comments on the group.  You can display comments in the
+ group line (@pxref{Group Line Specification}).
+
+ @item charset
+ @cindex charset
+ Elements that look like @code{(charset . iso-8859-1)} will make
+ @code{iso-8859-1} the default charset; that is, the charset that will be
+ used for all articles that do not specify a charset.
+
+
+ @item ignored-charsets
+ @cindex ignored-charset
+ Elements that look like @code{(ignored-charsets x-unknown iso-8859-1)}
+ will make @code{iso-8859-1} and @code{x-unknown} ignored; that is, the
+ default charset will be used for decoding articles.
+
+
+ @item posting-style
+ @cindex posting-style
+ You can store additional posting style information for this group
+ here (@pxref{Posting Styles}).  The format is that of an entry in the
+ @code{gnus-posting-styles} alist, except that there's no regexp matching
+ the group name (of course).  Style elements in this group parameter will
+ take precedence over the ones found in @code{gnus-posting-styles}.
+
+ For instance, if you want a funky name and signature in this group only,
+ instead of hacking @code{gnus-posting-styles}, you could put something
+ like this in the group parameters:
+
+ @example
+ (posting-style
+   (name "Funky Name")
+   (signature "Funky Signature"))
+ @end example
+
+ @item post-method
+ @cindex post-method
+ If it is set, the value is used as the method for posting message
+
+ @item banner
+ @cindex banner
+ An item like @code{(banner . @var{regexp})} causes any part of an article
+ that matches the regular expression @var{regexp} to be stripped.  Instead of
+ @var{regexp}, you can also use the symbol @code{signature} which strips the
+ last signature or any of the elements of the alist
+ @code{gnus-article-banner-alist}.
+
+ @item sieve
+ @cindex sieve
+ This parameter contains a Sieve test that should match incoming mail
+ that should be placed in this group.  From this group parameter, a
+ Sieve @samp{IF} control structure is generated, having the test as the
+ condition and @samp{fileinto "group.name";} as the body.
+
+ For example, if the @samp{INBOX.list.sieve} group has the @code{(sieve
+ translating the group parameter into a Sieve script (@pxref{Sieve
+ Commands}) the following Sieve code is generated:
+
+ @example
+         fileinto \"INBOX.list.sieve\";
+ @}
+ @end example
+
+ The Sieve language is described in RFC 3028.  @xref{Top, Emacs Sieve,
+ Top, sieve, Emacs Sieve}.
+
+ @item (agent parameters)
+ If the agent has been enabled, you can set any of the its parameters
+ to control the behavior of the agent in individual groups. See Agent
+ Parameters in @ref{Category Syntax}.  Most users will choose to set
+ agent parameters in either an agent category or group topic to
+ minimize the configuration effort.
+
+ @item (@var{variable} @var{form})
+ You can use the group parameters to set variables local to the group you
+ are entering.  If you want to turn threading off in @samp{news.answers},
+ you could put @code{(gnus-show-threads nil)} in the group parameters of
+ in the summary buffer you enter, and the form @code{nil} will be
+ @code{eval}ed there.
+
+ Note that this feature sets the variable locally to the summary buffer.
+ But some variables are evaluated in the article buffer, or in the
+ message buffer (of a reply or followup or otherwise newly created
+ message).  As a workaround, it might help to add the variable in
+ question to @code{gnus-newsgroup-variables}.  @xref{Various Summary
+ Stuff}.  So if you want to set @code{message-from-style} via the group
+ parameters, then you may need the following statement elsewhere in your
+ @file{~/.gnus} file:
+
+ @lisp
+ @end lisp
+
+ @vindex gnus-list-identifiers
+ A use for this feature is to remove a mailing list identifier tag in
+ the subject fields of articles.  E.g. if the news group
+
+ @example
+ nntp+news.gnus.org:gmane.text.docbook.apps
+ @end example
+
+ has the tag @samp{DOC-BOOK-APPS:} in the subject of all articles, this
+ tag can be removed from the article subjects in the summary buffer for
+ the group by putting @code{(gnus-list-identifiers "DOCBOOK-APPS:")}
+ into the group parameters for the group.
+
+ This can also be used as a group-specific hook function, if you'd like.
+ If you want to hear a beep when you enter a group, you could put
+ something like @code{(dummy-variable (ding))} in the parameters of that
+ group.  @code{dummy-variable} will be set to the result of the
+ @code{(ding)} form, but who cares?
+
+ @end table
+
+ Use the @kbd{G p} or the @kbd{G c} command to edit group parameters of a
+ group.  (@kbd{G p} presents you with a Lisp-based interface, @kbd{G c}
+ presents you with a Customize-like interface.  The latter helps avoid
+ silly Lisp errors.)  You might also be interested in reading about topic
+ parameters (@pxref{Topic Parameters}).
+
+ @vindex gnus-parameters
+ Group parameters can be set via the @code{gnus-parameters} variable too.
+ But some variables, such as @code{visible}, have no effect.  For
+ example:
+
+ @lisp
+ (setq gnus-parameters
+       '(("mail\\..*"
+          (gnus-use-scoring nil)
+          (gnus-summary-line-format
+           "%U%R%z%I%(%[%d:%ub%-23,23f%]%) %s\n")
+          (gcc-self . t)
+          (display . all))
+
+         ("^nnimap:\$$foo.bar\$$$" + (to-group . "\\1")) + + ("mail\\.me" + (gnus-use-scoring t)) + + ("list\\..*" + (total-expire . t) + (broken-reply-to . t)))) + @end lisp + + String value of parameters will be subjected to regexp substitution, as + the @code{to-group} example shows. + + + @node Listing Groups + @section Listing Groups + @cindex group listing + + These commands all list various slices of the groups available. + + @table @kbd + + @item l + @itemx A s + @kindex A s (Group) + @kindex l (Group) + @findex gnus-group-list-groups + List all groups that have unread articles + (@code{gnus-group-list-groups}). If the numeric prefix is used, this + command will list only groups of level ARG and lower. By default, it + only lists groups of level five (i.e., + @code{gnus-group-default-list-level}) or lower (i.e., just subscribed + groups). + + @item L + @itemx A u + @kindex A u (Group) + @kindex L (Group) + @findex gnus-group-list-all-groups + List all groups, whether they have unread articles or not + (@code{gnus-group-list-all-groups}). If the numeric prefix is used, + this command will list only groups of level ARG and lower. By default, + it lists groups of level seven or lower (i.e., just subscribed and + unsubscribed groups). + + @item A l + @kindex A l (Group) + @findex gnus-group-list-level + List all unread groups on a specific level + (@code{gnus-group-list-level}). If given a prefix, also list the groups + with no unread articles. + + @item A k + @kindex A k (Group) + @findex gnus-group-list-killed + List all killed groups (@code{gnus-group-list-killed}). If given a + prefix argument, really list all groups that are available, but aren't + currently (un)subscribed. This could entail reading the active file + from the server. + + @item A z + @kindex A z (Group) + @findex gnus-group-list-zombies + List all zombie groups (@code{gnus-group-list-zombies}). + + @item A m + @kindex A m (Group) + @findex gnus-group-list-matching + List all unread, subscribed groups with names that match a regexp + (@code{gnus-group-list-matching}). + + @item A M + @kindex A M (Group) + @findex gnus-group-list-all-matching + List groups that match a regexp (@code{gnus-group-list-all-matching}). + + @item A A + @kindex A A (Group) + @findex gnus-group-list-active + List absolutely all groups in the active file(s) of the + server(s) you are connected to (@code{gnus-group-list-active}). This + might very well take quite a while. It might actually be a better idea + to do a @kbd{A M} to list all matching, and just give @samp{.} as the + thing to match on. Also note that this command may list groups that + don't exist (yet)---these will be listed as if they were killed groups. + Take the output with some grains of salt. + + @item A a + @kindex A a (Group) + @findex gnus-group-apropos + List all groups that have names that match a regexp + (@code{gnus-group-apropos}). + + @item A d + @kindex A d (Group) + @findex gnus-group-description-apropos + List all groups that have names or descriptions that match a regexp + (@code{gnus-group-description-apropos}). + + @item A c + @kindex A c (Group) + @findex gnus-group-list-cached + List all groups with cached articles (@code{gnus-group-list-cached}). + + @item A ? + @kindex A ? (Group) + @findex gnus-group-list-dormant + List all groups with dormant articles (@code{gnus-group-list-dormant}). + + @item A / + @kindex A / (Group) + @findex gnus-group-list-limit + List groups limited within the current selection + (@code{gnus-group-list-limit}). + + @item A f + @kindex A f (Group) + @findex gnus-group-list-flush + Flush groups from the current selection (@code{gnus-group-list-flush}). + + @item A p + @kindex A p (Group) + @findex gnus-group-list-plus + List groups plus the current selection (@code{gnus-group-list-plus}). + + @end table + + @vindex gnus-permanently-visible-groups + @cindex visible group parameter + Groups that match the @code{gnus-permanently-visible-groups} regexp will + always be shown, whether they have unread articles or not. You can also + add the @code{visible} element to the group parameters in question to + get the same effect. + + @vindex gnus-list-groups-with-ticked-articles + Groups that have just ticked articles in it are normally listed in the + group buffer. If @code{gnus-list-groups-with-ticked-articles} is + @code{nil}, these groups will be treated just like totally empty + groups. It is @code{t} by default. + + + @node Sorting Groups + @section Sorting Groups + @cindex sorting groups + + @kindex C-c C-s (Group) + @findex gnus-group-sort-groups + @vindex gnus-group-sort-function + The @kbd{C-c C-s} (@code{gnus-group-sort-groups}) command sorts the + group buffer according to the function(s) given by the + @code{gnus-group-sort-function} variable. Available sorting functions + include: + + @table @code + + @item gnus-group-sort-by-alphabet + @findex gnus-group-sort-by-alphabet + Sort the group names alphabetically. This is the default. + + @item gnus-group-sort-by-real-name + @findex gnus-group-sort-by-real-name + Sort the group alphabetically on the real (unprefixed) group names. + + @item gnus-group-sort-by-level + @findex gnus-group-sort-by-level + Sort by group level. + + @item gnus-group-sort-by-score + @findex gnus-group-sort-by-score + Sort by group score. @xref{Group Score}. + + @item gnus-group-sort-by-rank + @findex gnus-group-sort-by-rank + Sort by group score and then the group level. The level and the score + are, when taken together, the group's @dfn{rank}. @xref{Group Score}. + + @item gnus-group-sort-by-unread + @findex gnus-group-sort-by-unread + Sort by number of unread articles. + + @item gnus-group-sort-by-method + @findex gnus-group-sort-by-method + Sort alphabetically on the select method. + + @item gnus-group-sort-by-server + @findex gnus-group-sort-by-server + Sort alphabetically on the Gnus server name. + + + @end table + + @code{gnus-group-sort-function} can also be a list of sorting + functions. In that case, the most significant sort key function must be + the last one. + + + There are also a number of commands for sorting directly according to + some sorting criteria: + + @table @kbd + @item G S a + @kindex G S a (Group) + @findex gnus-group-sort-groups-by-alphabet + Sort the group buffer alphabetically by group name + (@code{gnus-group-sort-groups-by-alphabet}). + + @item G S u + @kindex G S u (Group) + @findex gnus-group-sort-groups-by-unread + Sort the group buffer by the number of unread articles + (@code{gnus-group-sort-groups-by-unread}). + + @item G S l + @kindex G S l (Group) + @findex gnus-group-sort-groups-by-level + Sort the group buffer by group level + (@code{gnus-group-sort-groups-by-level}). + + @item G S v + @kindex G S v (Group) + @findex gnus-group-sort-groups-by-score + Sort the group buffer by group score + (@code{gnus-group-sort-groups-by-score}). @xref{Group Score}. + + @item G S r + @kindex G S r (Group) + @findex gnus-group-sort-groups-by-rank + Sort the group buffer by group rank + (@code{gnus-group-sort-groups-by-rank}). @xref{Group Score}. + + @item G S m + @kindex G S m (Group) + @findex gnus-group-sort-groups-by-method + Sort the group buffer alphabetically by back end address@hidden + (@code{gnus-group-sort-groups-by-method}). + + @item G S n + @kindex G S n (Group) + @findex gnus-group-sort-groups-by-real-name + Sort the group buffer alphabetically by real (unprefixed) group name + (@code{gnus-group-sort-groups-by-real-name}). + + @end table + + All the commands below obey the process/prefix convention + (@pxref{Process/Prefix}). + + When given a symbolic prefix (@pxref{Symbolic Prefixes}), all these + commands will sort in reverse order. + + You can also sort a subset of the groups: + + @table @kbd + @item G P a + @kindex G P a (Group) + @findex gnus-group-sort-selected-groups-by-alphabet + Sort the groups alphabetically by group name + (@code{gnus-group-sort-selected-groups-by-alphabet}). + + @item G P u + @kindex G P u (Group) + @findex gnus-group-sort-selected-groups-by-unread + Sort the groups by the number of unread articles + (@code{gnus-group-sort-selected-groups-by-unread}). + + @item G P l + @kindex G P l (Group) + @findex gnus-group-sort-selected-groups-by-level + Sort the groups by group level + (@code{gnus-group-sort-selected-groups-by-level}). + + @item G P v + @kindex G P v (Group) + @findex gnus-group-sort-selected-groups-by-score + Sort the groups by group score + (@code{gnus-group-sort-selected-groups-by-score}). @xref{Group Score}. + + @item G P r + @kindex G P r (Group) + @findex gnus-group-sort-selected-groups-by-rank + Sort the groups by group rank + (@code{gnus-group-sort-selected-groups-by-rank}). @xref{Group Score}. + + @item G P m + @kindex G P m (Group) + @findex gnus-group-sort-selected-groups-by-method + Sort the groups alphabetically by back end address@hidden + (@code{gnus-group-sort-selected-groups-by-method}). + + @item G P n + @kindex G P n (Group) + @findex gnus-group-sort-selected-groups-by-real-name + Sort the groups alphabetically by real (unprefixed) group name + (@code{gnus-group-sort-selected-groups-by-real-name}). + + @item G P s + @kindex G P s (Group) + @findex gnus-group-sort-selected-groups + Sort the groups according to @code{gnus-group-sort-function}. + + @end table + + And finally, note that you can use @kbd{C-k} and @kbd{C-y} to manually + move groups around. + + + @node Group Maintenance + @section Group Maintenance + @cindex bogus groups + + @table @kbd + @item b + @kindex b (Group) + @findex gnus-group-check-bogus-groups + Find bogus groups and delete them + (@code{gnus-group-check-bogus-groups}). + + @item F + @kindex F (Group) + @findex gnus-group-find-new-groups + Find new groups and process them (@code{gnus-group-find-new-groups}). + With 1 @kbd{C-u}, use the @code{ask-server} method to query the server + for new groups. With 2 @kbd{C-u}'s, use most complete method possible + to query the server for new groups, and subscribe the new groups as + zombies. + + @item C-c C-x + @kindex C-c C-x (Group) + @findex gnus-group-expire-articles + Run all expirable articles in the current group through the expiry + process (if any) (@code{gnus-group-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-M-x + @kindex C-c C-M-x (Group) + @findex gnus-group-expire-all-groups + Run all expirable articles in all groups through the expiry process + (@code{gnus-group-expire-all-groups}). + + @end table + + + @node Browse Foreign Server + @section Browse Foreign Server + @cindex foreign servers + @cindex browsing servers + + @table @kbd + @item B + @kindex B (Group) + @findex gnus-group-browse-foreign-server + You will be queried for a select method and a server name. Gnus will + then attempt to contact this server and let you browse the groups there + (@code{gnus-group-browse-foreign-server}). + @end table + + @findex gnus-browse-mode + A new buffer with a list of available groups will appear. This buffer + will use the @code{gnus-browse-mode}. This buffer looks a bit (well, + a lot) like a normal group buffer. + + Here's a list of keystrokes available in the browse mode: + + @table @kbd + @item n + @kindex n (Browse) + @findex gnus-group-next-group + Go to the next group (@code{gnus-group-next-group}). + + @item p + @kindex p (Browse) + @findex gnus-group-prev-group + Go to the previous group (@code{gnus-group-prev-group}). + + @item SPACE + @kindex SPACE (Browse) + @findex gnus-browse-read-group + Enter the current group and display the first article + (@code{gnus-browse-read-group}). + + @item RET + @kindex RET (Browse) + @findex gnus-browse-select-group + Enter the current group (@code{gnus-browse-select-group}). + + @item u + @kindex u (Browse) + @findex gnus-browse-unsubscribe-current-group + Unsubscribe to the current group, or, as will be the case here, + subscribe to it (@code{gnus-browse-unsubscribe-current-group}). + + @item l + @itemx q + @kindex q (Browse) + @kindex l (Browse) + @findex gnus-browse-exit + Exit browse mode (@code{gnus-browse-exit}). + + @item d + @kindex d (Browse) + @findex gnus-browse-describe-group + Describe the current group (@code{gnus-browse-describe-group}). + + @item ? + @kindex ? (Browse) + @findex gnus-browse-describe-briefly + Describe browse mode briefly (well, there's not much to describe, is + there) (@code{gnus-browse-describe-briefly}). + @end table + + + @node Exiting Gnus + @section Exiting Gnus + @cindex exiting Gnus + + Yes, Gnus is ex(c)iting. + + @table @kbd + @item z + @kindex z (Group) + @findex gnus-group-suspend + Suspend Gnus (@code{gnus-group-suspend}). This doesn't really exit Gnus, + but it kills all buffers except the Group buffer. I'm not sure why this + is a gain, but then who am I to judge? + + @item q + @kindex q (Group) + @findex gnus-group-exit + @c @icon{gnus-group-exit} + Quit Gnus (@code{gnus-group-exit}). + + @item Q + @kindex Q (Group) + @findex gnus-group-quit + Quit Gnus without saving the @file{.newsrc} files (@code{gnus-group-quit}). + The dribble file will be saved, though (@pxref{Auto Save}). + @end table + + @vindex gnus-exit-gnus-hook + @vindex gnus-suspend-gnus-hook + @vindex gnus-after-exiting-gnus-hook + @code{gnus-suspend-gnus-hook} is called when you suspend Gnus and + @code{gnus-exit-gnus-hook} is called when you quit Gnus, while + @code{gnus-after-exiting-gnus-hook} is called as the final item when + exiting Gnus. + + Note: + + @quotation + Miss Lisa Cannifax, while sitting in English class, felt her feet go + numbly heavy and herself fall into a hazy trance as the boy sitting + behind her drew repeated lines with his pencil across the back of her + plastic chair. + @end quotation + + + @node Group Topics + @section Group Topics + @cindex topics + + If you read lots and lots of groups, it might be convenient to group + them hierarchically according to topics. You put your Emacs groups over + here, your sex groups over there, and the rest (what, two groups or so?) + you put in some misc section that you never bother with anyway. You can + even group the Emacs sex groups as a sub-topic to either the Emacs + groups or the sex groups---or both! Go wild! + + @iftex + @iflatex + \gnusfigure{Group Topics}{400}{ + \put(75,50){\epsfig{figure=ps/group-topic,height=9cm}} + } + @end iflatex + @end iftex + + Here's an example: + + @example + Gnus + Emacs -- I wuw it! + 3: comp.emacs + 2: alt.religion.emacs + Naughty Emacs + 452: alt.sex.emacs + 0: comp.talk.emacs.recovery + Misc + 8: comp.binaries.fractals + 13: comp.sources.unix + @end example + + @findex gnus-topic-mode + @kindex t (Group) + To get this @emph{fab} functionality you simply turn on (ooh!) the + @code{gnus-topic} minor mode---type @kbd{t} in the group buffer. (This + is a toggling command.) + + Go ahead, just try it. I'll still be here when you get back. La de + address@hidden Nice tune, address@hidden la la address@hidden What, you're back? + Yes, and now press @kbd{l}. There. All your groups are now listed + under @samp{misc}. Doesn't that make you feel all warm and fuzzy? + Hot and bothered? + + If you want this permanently enabled, you should add that minor mode to + the hook for the group mode. Put the following line in your + @file{~/.gnus.el} file: + + @lisp + (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) + @end lisp + + @menu + * Topic Commands:: Interactive E-Z commands. + * Topic Variables:: How to customize the topics the Lisp Way. + * Topic Sorting:: Sorting each topic individually. + * Topic Topology:: A map of the world. + * Topic Parameters:: Parameters that apply to all groups in a topic. + @end menu + + + @node Topic Commands + @subsection Topic Commands + @cindex topic commands + + When the topic minor mode is turned on, a new @kbd{T} submap will be + available. In addition, a few of the standard keys change their + definitions slightly. + + In general, the following kinds of operations are possible on topics. + First of all, you want to create topics. Secondly, you want to put + groups in topics and to move them around until you have an order you + like. The third kind of operation is to show/hide parts of the whole + shebang. You might want to hide a topic including its subtopics and + groups, to get a better overview of the other groups. + + Here is a list of the basic keys that you might need to set up topics + the way you like. + + @table @kbd + + @item T n + @kindex T n (Topic) + @findex gnus-topic-create-topic + Prompt for a new topic name and create it + (@code{gnus-topic-create-topic}). + + @item T TAB + @itemx TAB + @kindex T TAB (Topic) + @kindex TAB (Topic) + @findex gnus-topic-indent + Indent'' the current topic so that it becomes a sub-topic of the + previous topic (@code{gnus-topic-indent}). If given a prefix, + un-indent'' the topic instead. + + @item M-TAB + @kindex M-TAB (Topic) + @findex gnus-topic-unindent + Un-indent'' the current topic so that it becomes a sub-topic of the + parent of its current parent (@code{gnus-topic-unindent}). + + @end table + + The following two keys can be used to move groups and topics around. + They work like the well-known cut and paste. @kbd{C-k} is like cut and + @kbd{C-y} is like paste. Of course, this being Emacs, we use the terms + kill and yank rather than cut and paste. + + @table @kbd + + @item C-k + @kindex C-k (Topic) + @findex gnus-topic-kill-group + Kill a group or topic (@code{gnus-topic-kill-group}). All groups in the + topic will be removed along with the topic. + + @item C-y + @kindex C-y (Topic) + @findex gnus-topic-yank-group + Yank the previously killed group or topic + (@code{gnus-topic-yank-group}). Note that all topics will be yanked + before all groups. + + So, to move a topic to the beginning of the list of topics, just hit + @kbd{C-k} on it. This is like the cut'' part of cut and paste. Then, + move the cursor to the beginning of the buffer (just below the Gnus'' + topic) and hit @kbd{C-y}. This is like the paste'' part of cut and + paste. Like I said -- E-Z. + + You can use @kbd{C-k} and @kbd{C-y} on groups as well as on topics. So + you can move topics around as well as groups. + + @end table + + After setting up the topics the way you like them, you might wish to + hide a topic, or to show it again. That's why we have the following + key. + + @table @kbd + + @item RET + @kindex RET (Topic) + @findex gnus-topic-select-group + @itemx SPACE + Either select a group or fold a topic (@code{gnus-topic-select-group}). + When you perform this command on a group, you'll enter the group, as + usual. When done on a topic line, the topic will be folded (if it was + visible) or unfolded (if it was folded already). So it's basically a + toggling command on topics. In addition, if you give a numerical + prefix, group on that level (and lower) will be displayed. + + @end table + + Now for a list of other commands, in no particular order. + + @table @kbd + + @item T m + @kindex T m (Topic) + @findex gnus-topic-move-group + Move the current group to some other topic + (@code{gnus-topic-move-group}). This command uses the process/prefix + convention (@pxref{Process/Prefix}). + + @item T j + @kindex T j (Topic) + @findex gnus-topic-jump-to-topic + Go to a topic (@code{gnus-topic-jump-to-topic}). + + @item T c + @kindex T c (Topic) + @findex gnus-topic-copy-group + Copy the current group to some other topic + (@code{gnus-topic-copy-group}). This command uses the process/prefix + convention (@pxref{Process/Prefix}). + + @item T h + @kindex T h (Topic) + @findex gnus-topic-hide-topic + Hide the current topic (@code{gnus-topic-hide-topic}). If given + a prefix, hide the topic permanently. + + @item T s + @kindex T s (Topic) + @findex gnus-topic-show-topic + Show the current topic (@code{gnus-topic-show-topic}). If given + a prefix, show the topic permanently. + + @item T D + @kindex T D (Topic) + @findex gnus-topic-remove-group + Remove a group from the current topic (@code{gnus-topic-remove-group}). + This command is mainly useful if you have the same group in several + topics and wish to remove it from one of the topics. You may also + remove a group from all topics, but in that case, Gnus will add it to + the root topic the next time you start Gnus. In fact, all new groups + (which, naturally, don't belong to any topic) will show up in the root + topic. + + This command uses the process/prefix convention + (@pxref{Process/Prefix}). + + @item T M + @kindex T M (Topic) + @findex gnus-topic-move-matching + Move all groups that match some regular expression to a topic + (@code{gnus-topic-move-matching}). + + @item T C + @kindex T C (Topic) + @findex gnus-topic-copy-matching + Copy all groups that match some regular expression to a topic + (@code{gnus-topic-copy-matching}). + + @item T H + @kindex T H (Topic) + @findex gnus-topic-toggle-display-empty-topics + Toggle hiding empty topics + (@code{gnus-topic-toggle-display-empty-topics}). + + @item T # + @kindex T # (Topic) + @findex gnus-topic-mark-topic + Mark all groups in the current topic with the process mark + (@code{gnus-topic-mark-topic}). This command works recursively on + sub-topics unless given a prefix. + + @item T M-# + @kindex T M-# (Topic) + @findex gnus-topic-unmark-topic + Remove the process mark from all groups in the current topic + (@code{gnus-topic-unmark-topic}). This command works recursively on + sub-topics unless given a prefix. + + @item C-c C-x + @kindex C-c C-x (Topic) + @findex gnus-topic-expire-articles + Run all expirable articles in the current group or topic through the + expiry process (if any) + (@code{gnus-topic-expire-articles}). (@pxref{Expiring Mail}). + + @item T r + @kindex T r (Topic) + @findex gnus-topic-rename + Rename a topic (@code{gnus-topic-rename}). + + @item T DEL + @kindex T DEL (Topic) + @findex gnus-topic-delete + Delete an empty topic (@code{gnus-topic-delete}). + + @item A T + @kindex A T (Topic) + @findex gnus-topic-list-active + List all groups that Gnus knows about in a topics-ified way + (@code{gnus-topic-list-active}). + + @item T M-n + @kindex T M-n (Topic) + @findex gnus-topic-goto-next-topic + Go to the next topic (@code{gnus-topic-goto-next-topic}). + + @item T M-p + @kindex T M-p (Topic) + @findex gnus-topic-goto-previous-topic + Go to the next topic (@code{gnus-topic-goto-previous-topic}). + + @item G p + @kindex G p (Topic) + @findex gnus-topic-edit-parameters + @cindex group parameters + @cindex topic parameters + @cindex parameters + Edit the topic parameters (@code{gnus-topic-edit-parameters}). + @xref{Topic Parameters}. + + @end table + + + @node Topic Variables + @subsection Topic Variables + @cindex topic variables + + The previous section told you how to tell Gnus which topics to display. + This section explains how to tell Gnus what to display about each topic. + + @vindex gnus-topic-line-format + The topic lines themselves are created according to the + @code{gnus-topic-line-format} variable (@pxref{Formatting Variables}). + Valid elements are: + + @table @samp + @item i + Indentation. + @item n + Topic name. + @item v + Visibility. + @item l + Level. + @item g + Number of groups in the topic. + @item a + Number of unread articles in the topic. + @item A + Number of unread articles in the topic and all its subtopics. + @end table + + @vindex gnus-topic-indent-level + Each sub-topic (and the groups in the sub-topics) will be indented with + @code{gnus-topic-indent-level} times the topic level number of spaces. + The default is 2. + + @vindex gnus-topic-mode-hook + @code{gnus-topic-mode-hook} is called in topic minor mode buffers. + + @vindex gnus-topic-display-empty-topics + The @code{gnus-topic-display-empty-topics} says whether to display even + topics that have no unread articles in them. The default is @code{t}. + + + @node Topic Sorting + @subsection Topic Sorting + @cindex topic sorting + + You can sort the groups in each topic individually with the following + commands: + + + @table @kbd + @item T S a + @kindex T S a (Topic) + @findex gnus-topic-sort-groups-by-alphabet + Sort the current topic alphabetically by group name + (@code{gnus-topic-sort-groups-by-alphabet}). + + @item T S u + @kindex T S u (Topic) + @findex gnus-topic-sort-groups-by-unread + Sort the current topic by the number of unread articles + (@code{gnus-topic-sort-groups-by-unread}). + + @item T S l + @kindex T S l (Topic) + @findex gnus-topic-sort-groups-by-level + Sort the current topic by group level + (@code{gnus-topic-sort-groups-by-level}). + + @item T S v + @kindex T S v (Topic) + @findex gnus-topic-sort-groups-by-score + Sort the current topic by group score + (@code{gnus-topic-sort-groups-by-score}). @xref{Group Score}. + + @item T S r + @kindex T S r (Topic) + @findex gnus-topic-sort-groups-by-rank + Sort the current topic by group rank + (@code{gnus-topic-sort-groups-by-rank}). @xref{Group Score}. + + @item T S m + @kindex T S m (Topic) + @findex gnus-topic-sort-groups-by-method + Sort the current topic alphabetically by back end name + (@code{gnus-topic-sort-groups-by-method}). + + @item T S e + @kindex T S e (Topic) + @findex gnus-topic-sort-groups-by-server + Sort the current topic alphabetically by server name + (@code{gnus-topic-sort-groups-by-server}). + + @item T S s + @kindex T S s (Topic) + @findex gnus-topic-sort-groups + Sort the current topic according to the function(s) given by the + @code{gnus-group-sort-function} variable + (@code{gnus-topic-sort-groups}). + + @end table + + When given a prefix argument, all these commands will sort in reverse + order. @xref{Sorting Groups}, for more information about group + sorting. + + + @node Topic Topology + @subsection Topic Topology + @cindex topic topology + @cindex topology + + So, let's have a look at an example group buffer: + + @example + @group + Gnus + Emacs -- I wuw it! + 3: comp.emacs + 2: alt.religion.emacs + Naughty Emacs + 452: alt.sex.emacs + 0: comp.talk.emacs.recovery + Misc + 8: comp.binaries.fractals + 13: comp.sources.unix + @end group + @end example + + So, here we have one top-level topic (@samp{Gnus}), two topics under + that, and one sub-topic under one of the sub-topics. (There is always + just one (1) top-level topic). This topology can be expressed as + follows: + + @lisp + (("Gnus" visible) + (("Emacs -- I wuw it!" visible) + (("Naughty Emacs" visible))) + (("Misc" visible))) + @end lisp + + @vindex gnus-topic-topology + This is in fact how the variable @code{gnus-topic-topology} would look + for the display above. That variable is saved in the @file{.newsrc.eld} + file, and shouldn't be messed with manually---unless you really want + to. Since this variable is read from the @file{.newsrc.eld} file, + setting it in any other startup files will have no effect. + + This topology shows what topics are sub-topics of what topics (right), + and which topics are visible. Two settings are currently + address@hidden and @code{invisible}. + + + @node Topic Parameters + @subsection Topic Parameters + @cindex topic parameters + + All groups in a topic will inherit group parameters from the parent + (and ancestor) topic parameters. All valid group parameters are valid + topic parameters (@pxref{Group Parameters}). When the agent is + enabled, all agent parameters (See Agent Parameters in @ref{Category + Syntax}) are also valid topic parameters. + + In addition, the following parameters are only valid as topic + parameters: + + @table @code + @item subscribe + When subscribing new groups by topic (@pxref{Subscription Methods}), the + @code{subscribe} topic parameter says what groups go in what topic. Its + value should be a regexp to match the groups that should go in that + topic. + + @item subscribe-level + When subscribing new groups by topic (see the @code{subscribe} parameter), + the group will be subscribed with the level specified in the + @code{subscribe-level} instead of @code{gnus-level-default-subscribed}. + + @end table + + Group parameters (of course) override topic parameters, and topic + parameters in sub-topics override topic parameters in super-topics. You + know. Normal inheritance rules. (@dfn{Rules} is here a noun, not a + verb, although you may feel free to disagree with me here.) + + @example + @group + Gnus + Emacs + 3: comp.emacs + 2: alt.religion.emacs + 452: alt.sex.emacs + Relief + 452: alt.sex.emacs + 0: comp.talk.emacs.recovery + Misc + 8: comp.binaries.fractals + 13: comp.sources.unix + 452: alt.sex.emacs + @end group + @end example + + The @samp{Emacs} topic has the topic parameter @code{(score-file + . "emacs.SCORE")}; the @samp{Relief} topic has the topic parameter + @code{(score-file . "relief.SCORE")}; and the @samp{Misc} topic has the + topic parameter @code{(score-file . "emacs.SCORE")}. In addition, + @* @samp{alt.religion.emacs} has the group parameter @code{(score-file + . "religion.SCORE")}. + + Now, when you enter @samp{alt.sex.emacs} in the @samp{Relief} topic, you + will get the @file{relief.SCORE} home score file. If you enter the same + group in the @samp{Emacs} topic, you'll get the @file{emacs.SCORE} home + score file. If you enter the group @samp{alt.religion.emacs}, you'll + get the @file{religion.SCORE} home score file. + + This seems rather simple and self-evident, doesn't it? Well, yes. But + there are some problems, especially with the @code{total-expiry} + parameter. Say you have a mail group in two topics; one with + @code{total-expiry} and one without. What happens when you do @kbd{M-x + gnus-expire-all-expirable-groups}? Gnus has no way of telling which one + of these topics you mean to expire articles from, so anything may + happen. In fact, I hereby declare that it is @dfn{undefined} what + happens. You just have to be careful if you do stuff like that. + + + @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 + + @table @kbd + + @item ^ + @kindex ^ (Group) + @findex gnus-group-enter-server-mode + Enter the server buffer (@code{gnus-group-enter-server-mode}). + @xref{Server Buffer}. + + @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}. + + @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 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}. + + 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 table + + Variables for the group buffer: + + @table @code + + @item gnus-group-mode-hook + @vindex gnus-group-mode-hook + is called after the group buffer has been + created. + + @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. + + @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. + + @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. + + @item gnus-group-name-charset-method-alist + @vindex gnus-group-name-charset-method-alist + An alist of method and the charset for group names. It is used to show + address@hidden group names. + + For example: + @lisp + (setq gnus-group-name-charset-method-alist + '(((nntp "news.com.cn") . cn-gb-2312))) + @end lisp + + @item gnus-group-name-charset-group-alist + @cindex UTF-8 group names + @vindex gnus-group-name-charset-group-alist + An alist of regexp of group name and the charset for group names. It + is used to show address@hidden group names. @code{((".*" + utf-8))} is the default value if UTF-8 is supported, otherwise the + default is @code{nil}. + + For example: + @lisp + (setq gnus-group-name-charset-group-alist + '(("\\.com\\.cn:" . cn-gb-2312))) + @end lisp + + @end table + + @node Scanning New Messages + @subsection Scanning New Messages + @cindex new messages + @cindex scanning new news + + @table @kbd + + @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). + + @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}). + + @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. + + @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 Group Information + @subsection Group Information + @cindex group information + @cindex information on groups + + @table @kbd + + + @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. + + 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. + + @item H c + @kindex H c (Group) + @findex gnus-group-fetch-charter + @vindex gnus-group-charter-alist + @cindex charter + Try to open the charter for the current group in a web browser + (@code{gnus-group-fetch-charter}). Query for a group if given a + prefix argument. + + Gnus will use @code{gnus-group-charter-alist} to find the location of + the charter. If no location is known, Gnus will fetch the control + messages for the group, which in some cases includes the charter. + + @item H C + @kindex H C (Group) + @findex gnus-group-fetch-control + @vindex gnus-group-fetch-control-use-browse-url + @cindex control message + Fetch the control messages for the group from the archive at + @code{ftp.isc.org} (@code{gnus-group-fetch-control}). Query for a + group if given a prefix argument. + + If @code{gnus-group-fetch-control-use-browse-url} is address@hidden, + Gnus will open the control messages in a browser using + @code{browse-url}. Otherwise they are fetched using @code{ange-ftp} + and displayed in an ephemeral group. + + Note that the control messages are compressed. To use this command + you need to turn on @code{auto-compression-mode} (@pxref{Compressed + Files, ,Compressed Files, emacs, The Emacs Manual}). + + @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. + + @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. + + @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}). + + @item ? + @kindex ? (Group) + @findex gnus-group-describe-briefly + Give a very short help message (@code{gnus-group-describe-briefly}). + + @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 Group Timestamp + @subsection Group Timestamp + @cindex timestamps + @cindex group timestamps + + 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}: + + @lisp + (add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) + @end lisp + + After doing this, each time you enter a group, it'll be recorded. + + 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 + + This will result in lines looking like: + + @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: + + @lisp + (setq gnus-group-line-format + "%M\%S\%p\%P\%5y: %(%-40,40g%) %6,6~(cut 2)d\n") + @end lisp + + 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: + + @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 + + + @node File Commands + @subsection File Commands + @cindex file commands + + @table @kbd + + @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 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. + + @c @item Z + @c @kindex Z (Group) + @c @findex gnus-group-clear-dribble + @c Clear the dribble buffer (@code{gnus-group-clear-dribble}). + + @end table + + + @node Sieve Commands + @subsection Sieve Commands + @cindex group sieve commands + + 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. + + @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. + + @vindex gnus-sieve-crosspost + The variable @code{gnus-sieve-crosspost} controls how the Sieve script + is generated. If it is address@hidden (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 address@hidden, it looks the same + except that the line containing the call to @code{stop} is removed.) + + @example + if address "sender" "owner-ding@@hpc.uh.edu" @{ + fileinto "INBOX.ding"; + stop; + @} + @end example + + @xref{Top, Emacs Sieve, Top, sieve, Emacs Sieve}. + + @table @kbd + + @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 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 Summary Buffer + @chapter Summary Buffer + @cindex summary buffer + + 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}). + + You can have as many summary buffers open as you wish. + + @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. + * 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 + + + @node Summary Buffer Format + @section Summary Buffer Format + @cindex summary buffer format + + @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 + + @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 + + @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 + (setq gnus-extract-address-components + 'mail-extract-address-components) + @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 + + @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}). + + 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}. + + The default string is @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n}. + + The following format specification characters and extended format + specification(s) are understood: + + @table @samp + @item N + Article number. + @item S + Subject string. List identifiers stripped, + @code{gnus-list-identifies}. @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: + + @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{> }. + + @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{> }. + + @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{| }. + + @item gnus-sum-thread-tree-indent + @vindex gnus-sum-thread-tree-indent + Used for indenting. The default is @samp{ }. + + @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 gnus-sum-thread-tree-single-leaf + @vindex gnus-sum-thread-tree-single-leaf + Used for a leaf without brothers. The default is @samp{\-> } + + @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 @address@hidden@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 &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 + @address@hidden, 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. + + @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. + + In summary, you'd typically put something like the following in + @file{~/.gnus.el}: + + @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 + + (The values listed above are the default values in Gnus. Alter them + to fit your needs.) + + A note for news server administrators, or for users who wish to try to + convince their news server administrator to provide some additional + support: + + 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): + + @example + Newsgroups:full + @end example + + 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. + + + @node Summary Buffer Mode Line + @subsection Summary Buffer Mode Line + + @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 + 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 + + + @node Summary Highlighting + @subsection Summary Highlighting + + @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 address@hidden value, + @var{face} will be applied to the line. + @end table + + + @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. + + 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 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 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. + + Variables related to summary movement: + + @table @code + + @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 gnus-auto-select-same + @vindex gnus-auto-select-same + If address@hidden, 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. + + This variable is not particularly useful if you use a threaded display. + + @item gnus-summary-check-current + @vindex gnus-summary-check-current + If address@hidden, 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. + + @item gnus-auto-center-summary + @vindex gnus-auto-center-summary + If address@hidden, 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. + + @end table + + + @node Choosing Articles + @section Choosing Articles + @cindex selecting articles + + @menu + * Choosing Commands:: Commands for choosing articles. + * Choosing Variables:: Variables that influence these commands. + @end menu + + + @node Choosing Commands + @subsection Choosing Commands + + None of the following movement commands understand the numeric prefix, + and they all select and display an article. + + If you want to fetch new articles or redisplay the group, see + @ref{Exiting the Summary Buffer}. + + @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}. + + @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}). + + @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 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 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}). + + @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}). + + @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}). + + @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. + + @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}). + + @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 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}). + + @end table + + + @node Choosing Variables + @subsection Choosing Variables + + Some variables relevant for moving and selecting articles: + + @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 address@hidden Gnus will then fetch the article from + the server and display it in the article buffer. + + @item gnus-select-article-hook + @vindex gnus-select-article-hook + This hook is called whenever an article is selected. By default it + exposes any threads hidden under the selected article. 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-unread-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. + + @end table + + + @node Paging the Article + @section Scrolling the Article + @cindex article scrolling + + @table @kbd + + @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}). + + @vindex gnus-article-boring-faces + @vindex gnus-article-skip-boring + If @code{gnus-article-skip-boring} is address@hidden 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}). + + @item RET + @kindex RET (Summary) + @findex gnus-summary-scroll-up + Scroll the current article one line forward + (@code{gnus-summary-scroll-up}). + + @item M-RET + @kindex M-RET (Summary) + @findex gnus-summary-scroll-down + Scroll the current article one line backward + (@code{gnus-summary-scroll-down}). + + @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, fetch the current article, but don't run any of the + article treatment functions. This will give you a raw'' article, just + the way it came from the server. + + 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-summary-show-article-charset-alist + '((1 . cn-gb-2312) + (2 . big5))) + @end lisp + + then you can say @kbd{C-u 1 g} to get the same effect. + + @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}). + + @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}). + + @item h + @kindex h (Summary) + @findex gnus-summary-select-article-buffer + Select the article buffer (@code{gnus-summary-select-article-buffer}). + + @end table + + + @node Reply Followup and Post + @section Reply, Followup and Post + + @menu + * Summary Mail Commands:: Sending mail. + * Summary Post Commands:: Sending news. + * Summary Message Commands:: Other Message-related commands. + * Canceling and Superseding:: + @end menu + + + @node Summary Mail Commands + @subsection Summary Mail Commands + @cindex mail + @cindex composing mail + + Commands for composing a mail message: + + @table @kbd + + @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 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 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 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. + + @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. + + @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. + + @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}. + + @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}). + + @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. + + @item S i + @itemx i + @kindex i (Summary) + @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. + + 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. + + @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 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! + + This command understands the process/prefix convention + (@pxref{Process/Prefix}). + + @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 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. + + @end table + + Also @xref{Header Commands, ,Header Commands, message, The Message + Manual}, for more information. + + + @node Summary Post Commands + @subsection Summary Post Commands + @cindex post + @cindex composing news + + Commands for posting a news article: + + @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. + + @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. + + @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}). + + @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. + + @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 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-mail-forward}). This command uses the + process/prefix convention. + + @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 + + Also @xref{Header Commands, ,Header Commands, message, The Message + Manual}, for more information. + + + @node Summary Message Commands + @subsection Summary Message Commands + + @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 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. + + 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}). + + 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. + + @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. + + 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. + + Just remember, kids: There is no 'c' in 'supersede'. + + @node Delayed Articles + @section Delayed Articles + @cindex delayed sending + @cindex send delayed + + 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: + + @lisp + (gnus-delay-initialize) + @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: + + @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 + 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 + + The action of the @code{gnus-delay-article} command is influenced by a + couple of variables: + + @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 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 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. + + @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-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 address@hidden, + @code{gnus-get-new-news-hook} is not changed. The optional first + argument is ignored. + + 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 + + + @node Marking Articles + @section Marking Articles + @cindex article marking + @cindex article ticking + @cindex marks + + There are several marks you can set on an article. + + 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}. + + In addition, you also have marks that do not affect readedness. + + @menu + * Unread Articles:: Marks for unread articles. + * Read Articles:: Marks for read articles. + * Other Marks:: Marks that do not affect readedness. + @end menu + + @ifinfo + There's a plethora of commands for manipulating these marks: + @end ifinfo + + @menu + * 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 + + + @node Unread Articles + @subsection Unread Articles + + The following marks mark articles as (kinda) unread, in one form or + other. + + @table @samp + @item ! + @vindex gnus-ticked-mark + Marked as ticked (@code{gnus-ticked-mark}). + + @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}). + + @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. + + @item SPACE + @vindex gnus-unread-mark + Marked as unread (@code{gnus-unread-mark}). + + @dfn{Unread articles} are articles that haven't been read at all yet. + @end table + + + @node Read Articles + @subsection Read Articles + @cindex expirable mark + + All the following marks mark articles as read. + + @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}). + + @item R + @vindex gnus-read-mark + Articles that have actually been read (@code{gnus-read-mark}). + + @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}). + + @item X + @vindex gnus-kill-file-mark + Marked as killed by kill files (@code{gnus-kill-file-mark}). + + @item Y + @vindex gnus-low-score-mark + Marked as read by having too low a score (@code{gnus-low-score-mark}). + + @item C + @vindex gnus-catchup-mark + Marked as read by a catchup (@code{gnus-catchup-mark}). + + @item G + @vindex gnus-canceled-mark + Canceled article (@code{gnus-canceled-mark}) + + @item F + @vindex gnus-souped-mark + @sc{soup}ed article (@code{gnus-souped-mark}). @xref{SOUP}. + + @item Q + @vindex gnus-sparse-mark + Sparsely reffed article (@code{gnus-sparse-mark}). @xref{Customizing + Threading}. + + @item M + @vindex gnus-duplicate-mark + Article marked as read by duplicate suppression + (@code{gnus-duplicate-mark}). @xref{Duplicate Suppression}. + + @end table + + All these marks just mean that the article is marked as read, really. + They are interpreted differently when doing adaptive scoring, though. + + One more special mark, though: + + @table @samp + @item E + @vindex gnus-expirable-mark + Marked as expirable (@code{gnus-expirable-mark}). + + 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 + + + @node Other Marks + @subsection Other Marks + @cindex process mark + @cindex bookmarks + + There are some marks that have nothing to do with whether the article is + read or not. + + @itemize @bullet + + @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 + @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 + @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}). + + @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}). + + @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 + @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 + @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.) + + @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.) + + @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. + + @end itemize + + 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? + + 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. + + + @node Setting Marks + @subsection Setting Marks + @cindex setting marks + + All the marking commands understand the numeric prefix. + + @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 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 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}). + + @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}). + + @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}). + + @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}). + + @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}). + + @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}). + + @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}). + + @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 M B + @kindex M B (Summary) + @findex gnus-summary-remove-bookmark + Remove the bookmark from the current article + (@code{gnus-summary-remove-bookmark}). + + @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 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 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 + + @vindex gnus-summary-goto-unread + The @code{gnus-summary-goto-unread} variable controls what action should + be taken after setting a mark. If address@hidden, 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}. + + + @node Generic Marking Commands + @subsection Generic Marking Commands + + 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. + + 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. + + 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. + + 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 + @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 + + @noindent + or + + @lisp + (defun my-alter-summary-map () + (local-set-key "!" "MM!n")) + @end lisp + + + @node Setting Process Marks + @subsection Setting Process Marks + @cindex setting process marks + + 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 + commands into the cache. For more information, + @pxref{Process/Prefix}. + + @table @kbd + + @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 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 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}). + + @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 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}). + + @item M P r + @kindex M P r (Summary) + @findex gnus-uu-mark-region + Mark articles in region (@code{gnus-uu-mark-region}). + + @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}). + + @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}). + + @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}). + + @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}). + + @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}). + + @item M P a + @kindex M P a (Summary) + @findex gnus-uu-mark-all + Mark all articles in series order (@code{gnus-uu-mark-series}). + + @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}). + + @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 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}). + + @end table + + Also see the @kbd{&} command in @ref{Searching for Articles}, for how to + set process marks based on article body contents. + + + @node Limiting + @section Limiting + @cindex limiting + + 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. + + All limiting commands work on subsets of the articles already fetched + from the servers. None of these commands query the server for + additional articles. + + @table @kbd + + @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 / 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 / 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 / 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 / n + @kindex / n (Summary) + @findex gnus-summary-limit-to-articles + Limit the summary buffer to the current article + (@code{gnus-summary-limit-to-articles}). Uses the process/prefix + convention (@pxref{Process/Prefix}). + + @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 / . + @kindex / . (Summary) + @findex gnus-summary-limit-to-unseen + Limit the summary buffer to the unseen articles + (@code{gnus-summary-limit-to-unseen}). + + @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 / 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. + + @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}). + + @item / * + @kindex / * (Summary) + @findex gnus-summary-limit-include-cached + Include all cached articles in the limit + (@code{gnus-summary-limit-include-cached}). + + @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}). + + @item / T + @kindex / T (Summary) + @findex gnus-summary-limit-include-thread + Include all the articles in the current thread in the limit. + + @item / c + @kindex / c (Summary) + @findex gnus-summary-limit-exclude-childless-dormant + Exclude all dormant articles that have no children from the address@hidden + (@code{gnus-summary-limit-exclude-childless-dormant}). + + @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 / N + @kindex / N (Summary) + @findex gnus-summary-insert-new-articles + Insert all new articles in the summary buffer. It scans for new emails + if @address@hidden is address@hidden + + @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. + + @end table + + + @node Threading + @section Threading + @cindex threading + @cindex article threading + + 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. + + 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}. + + First, a quick overview of the concepts: + + @table @dfn + @item root + The top-most article in a thread; the first article in the thread. + + @item thread + A tree-like article structure. + + @item sub-thread + A small(er) section of this tree-like structure. + + @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. + + @item sparse threads + A thread where the missing articles have been guessed'' at, and are + displayed as empty lines in the summary buffer. + + @end table + + + @menu + * Customizing Threading:: Variables you can change to affect the threading. + * Thread Commands:: Thread based commands in the summary buffer. + @end menu + + + @node Customizing Threading + @subsection Customizing Threading + @cindex customizing threading + + @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 address@hidden but you were wrong! + @end menu + + + @node Loose Threads + @subsubsection Loose Threads + @cindex < + @cindex > + @cindex loose threads + + @table @code + @item gnus-summary-make-false-root + @vindex gnus-summary-make-false-root + If address@hidden, 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. + + 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: + + @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 + + @cindex adopting articles + + @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. + + @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 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 none + Don't make any article parent at all. Just gather the threads and + display them after one another. + + @item nil + Don't gather loose threads. + @end table + + @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. + + @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}). + + @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. + + @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: + + @c Written by Michael Ernst <address@hidden> + @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 + + All words that match this regexp will be removed before comparing two + subjects. + + @item gnus-simplify-subject-functions + @vindex gnus-simplify-subject-functions + If address@hidden, 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. + + Useful functions to put in this list include: + + @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. + + @item gnus-simplify-whitespace + @findex gnus-simplify-whitespace + Remove excessive whitespace. + + @item gnus-simplify-all-whitespace + @findex gnus-simplify-all-whitespace + Remove all whitespace. + @end table + + You may also write your own functions, of course. + + + @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 address@hidden + The default is @samp{^ *$\\|^(none)$}. + + @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: + + @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 gnus-gather-threads-by-references + @findex gnus-gather-threads-by-references + This function looks at @code{References} headers exclusively. + @end table + + If you want to test gathering by @code{References}, you could say + something like: + + @lisp + (setq gnus-summary-thread-gathering-function + 'gnus-gather-threads-by-references) + @end lisp + + @end table + + + @node Filling In Threads + @subsubsection Filling In Threads + + @table @code + @item gnus-fetch-old-headers + @vindex gnus-fetch-old-headers + If address@hidden, 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. + + 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 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 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 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, like the @code{nnultimate} groups. + + 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 + + + @node More Threading + @subsubsection More Threading + + @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 address@hidden, 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}. + + Here's an example: + + @lisp + (setq gnus-thread-hide-subtree + '(or gnus-article-unread-p + gnus-article-unseen-p)) + @end lisp + + (It's a pretty nonsensical example, since all unseen articles are also + unread, but you get my drift.) + + + @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 gnus-thread-hide-killed + @vindex gnus-thread-hide-killed + if you kill a thread and this variable is address@hidden, the subtree + will be hidden. + + @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 address@hidden, 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 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 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. + + @end table + + + @node Low-Level Threading + @subsubsection Low-Level Threading + + @table @code + + @item gnus-parse-headers-hook + @vindex gnus-parse-headers-hook + Hook run before parsing any headers. + + @item gnus-alter-header-function + @vindex gnus-alter-header-function + If address@hidden, 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: + + @lisp + (setq gnus-alter-header-function 'my-alter-message-id) + + (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 + + @end table + + + @node Thread Commands + @subsection Thread Commands + @cindex thread commands + + @table @kbd + + @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 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 i + @kindex T i (Summary) + @findex gnus-summary-raise-thread + Increase the score of the current (sub-)thread + (@code{gnus-summary-raise-thread}). + + @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 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 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 address@hidden + (@code{gnus-summary-show-thread}). + + @item T h + @kindex T h (Summary) + @findex gnus-summary-hide-thread + Hide the current (sub-)thread (@code{gnus-summary-hide-thread}). + + @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}). + + @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. + + @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}). + + @end table + + The following commands are thread movement commands. They all + understand the numeric prefix. + + @table @kbd + + @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 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 T d + @kindex T d (Summary) + @findex gnus-summary-down-thread + Descend the thread (@code{gnus-summary-down-thread}). + + @item T u + @kindex T u (Summary) + @findex gnus-summary-up-thread + Ascend the thread (@code{gnus-summary-up-thread}). + + @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 + + @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 address@hidden (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}). + + + @node Sorting the Summary Buffer + @section Sorting 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-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. + + 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-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 address@hidden 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. + + 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: + + @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 + + 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: + + @lisp + (setq gnus-thread-sort-functions + '((lambda (t1 t2) + (not (gnus-thread-sort-by-number t1 t2))) + gnus-thread-sort-by-score)) + @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. + + @findex gnus-article-sort-functions + @findex gnus-article-sort-by-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 + 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}. + + 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 + + + + @node Asynchronous Fetching + @section Asynchronous Article Fetching + @cindex asynchronous article fetching + @cindex article pre-fetch + @cindex pre-fetch + + 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. + + First, some caveats. There are some pitfalls to using asynchronous + article fetching, especially the way Gnus does it. + + 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. + + 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. + + Ok, so now you know that you shouldn't really use this address@hidden unless + you really want to. + + @vindex gnus-asynchronous + Here's how: Set @code{gnus-asynchronous} to @code{t}. The rest should + happen automatically. + + @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-read-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 address@hidden when the article in question is + to be pre-fetched. The default is @code{gnus-async-read-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: + + @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 + + 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. + + @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 read + Remove articles when they are read. + + @item exit + Remove articles when exiting the group. + @end table + + The default value is @code{(read exit)}. + + @c @vindex gnus-use-header-prefetch + @c If @code{gnus-use-header-prefetch} is address@hidden, prefetch articles + @c from the next group. + + + @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. + + Used carefully, though, it could be just an easier way to save articles. + + @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. + + 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. + + When an article is marked as read, is it removed from the cache. + + @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}. + + @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. + + 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. + + @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. + + @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? + + @node Persistent Articles + @section Persistent Articles + @cindex persistent articles + + 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. + + 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: + + @table @kbd + + @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. + + 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: + + @lisp + (setq gnus-use-cache 'passive) + @end lisp + + + @node Article Backlog + @section Article Backlog + @cindex backlog + @cindex article backlog + + 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 address@hidden 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 Saving Articles + @section Saving Articles + @cindex saving articles + + 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}). + + 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 address@hidden, Gnus will not delete + unwanted headers before saving the article. + + @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. + + @table @kbd + + @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 mail format + (@code{gnus-summary-save-article-mail}). + + @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}). + + @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 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}). + + @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 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 O p + @itemx | + @kindex O p (Summary) + @kindex | (Summary) + @findex gnus-summary-pipe-output + 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. + + @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}). + + @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. + + + @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 six ready-made + functions below, or you can create your own. + + @table @code + + @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, @dfn{Babyl}. 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 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}. + + @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}. + + @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}. + + @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 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. + @end table + + @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. + + 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: + + @table @code + + @item gnus-Numeric-save-name + @findex gnus-Numeric-save-name + File names like @file{~/News/Alt.andrea-dworkin/45}. + + @item gnus-numeric-save-name + @findex gnus-numeric-save-name + File names like @file{~/News/alt.andrea-dworkin/45}. + + @item gnus-Plain-save-name + @findex gnus-Plain-save-name + File names like @file{~/News/Alt.andrea-dworkin}. + + @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 + (("^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 + + 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 address@hidden 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. + + 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. + + 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 + (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 + + + @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. + + If you'd like to save articles in a hierarchy that looks something like + a spool, you could + + @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 + + Then just save with @kbd{o}. You'd then read this hierarchy with + ephemeral @code{nneething} address@hidden 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}. + + + @node Decoding Articles + @section Decoding Articles + @cindex decoding articles + + Sometime users post articles (or series of articles) that have been + encoded in some way or other. Gnus can decode them for you. + + @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 + + @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). + + 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.) + + 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]+).*$}.
+
+ 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 Uuencoded Articles
+ @subsection Uuencoded Articles
+ @cindex uudecode
+ @cindex uuencoded 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 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 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}).
+
+ @end table
+
+ 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}).
+
+ 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 Shell Archives
+ @subsection Shell Archives
+ @cindex unshar
+ @cindex shell archives
+ @cindex shared 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:
+
+ @table @kbd
+
+ @item X s
+ @kindex X s (Summary)
+ @findex gnus-uu-decode-unshar
+ Unshars the current series (@code{gnus-uu-decode-unshar}).
+
+ @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}).
+
+ @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 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
+
+
+ @node PostScript Files
+ @subsection PostScript Files
+ @cindex PostScript
+
+ @table @kbd
+
+ @item X p
+ @kindex X p (Summary)
+ @findex gnus-uu-decode-postscript
+ Unpack the current PostScript series (@code{gnus-uu-decode-postscript}).
+
+ @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}).
+
+ @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
+
+
+ @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 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.
+ @end table
+
+
+ @node Decoding Variables
+ @subsection Decoding Variables
+
+
+ * 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.
+
+
+ @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
+       (list '(regexp1 command2)
+             '(regexp2 command2)
+             ...)
+ @end lisp
+
+ @table @code
+
+ @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 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 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 + + + @node Other Decode Variables + @subsubsection Other Decode Variables + + @table @code + @vindex gnus-uu-grabbed-file-functions + + @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: + + @table @code + + @item gnus-uu-grab-view + @findex gnus-uu-grab-view + View the file. + + @item gnus-uu-grab-move + @findex gnus-uu-grab-move + Move the file (if you're using a saving function.) + @end table + + @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 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. + + @item gnus-uu-tmp-dir + @vindex gnus-uu-tmp-dir + Where @code{gnus-uu} does its work. + + @item gnus-uu-do-not-unpack-archives + @vindex gnus-uu-do-not-unpack-archives + address@hidden means that @code{gnus-uu} won't peek inside archives + looking for files to display. + + @item gnus-uu-view-and-save + @vindex gnus-uu-view-and-save + address@hidden means that the user will always be asked to save a file + after viewing it. + + @item gnus-uu-ignore-default-view-rules + @vindex gnus-uu-ignore-default-view-rules + address@hidden means that @code{gnus-uu} will ignore the default viewing + rules. + + @item gnus-uu-ignore-default-archive-rules + @vindex gnus-uu-ignore-default-archive-rules + address@hidden means that @code{gnus-uu} will ignore the default archive + unpacking commands. + + @item gnus-uu-kill-carriage-return + @vindex gnus-uu-kill-carriage-return + address@hidden means that @code{gnus-uu} will strip all carriage returns + from articles. + + @item gnus-uu-unmark-articles-not-decoded + @vindex gnus-uu-unmark-articles-not-decoded + address@hidden means that @code{gnus-uu} will mark unsuccessfully + decoded articles as unread. + + @item gnus-uu-correct-stripped-uucode + @vindex gnus-uu-correct-stripped-uucode + address@hidden 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 + address@hidden 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 gnus-uu-save-in-digest + @vindex gnus-uu-save-in-digest + address@hidden 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. + + @end table + + + @node Uuencoding and Posting + @subsubsection Uuencoding and Posting + + @table @code + + @item gnus-uu-post-include-before-composing + @vindex gnus-uu-post-include-before-composing + address@hidden 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 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 gnus-uu-post-threaded + @vindex gnus-uu-post-threaded + address@hidden 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 address@hidden, but somehow, I don't + think that address@hidden) Default is @code{nil}. + + @item gnus-uu-post-separate-description + @vindex gnus-uu-post-separate-description + address@hidden 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 + + + @node Viewing Files + @subsection Viewing Files + @cindex viewing files + @cindex pseudo-articles + + 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. + + 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. + + @vindex gnus-view-pseudo-asynchronously + If @code{gnus-view-pseudo-asynchronously} is @code{nil}, Emacs will wait + until the viewing is done before proceeding. + + @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. + + @vindex gnus-view-pseudos-separately + If @code{gnus-view-pseudos-separately} is address@hidden, 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. + + @vindex gnus-insert-pseudo-articles + If @code{gnus-insert-pseudo-articles} is address@hidden, insert + pseudo-articles when decoding. It is @code{t} by default. + + 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? + + + @node Article Treatment + @section Article Treatment + + 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. + + @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, Smileys + * Article Signature:: What is a signature? + * Article Miscellanea:: Various other stuff. + @end menu + + + @node Article Highlighting + @subsection Article Highlighting + @cindex highlighting + + Not only do you want your article buffer to look like fruit salad, but + you want it to look like technicolor fruit salad. + + @table @kbd + + @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 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. + + @item W H c + @kindex W H c (Summary) + @findex gnus-article-highlight-citation + Highlight cited text (@code{gnus-article-highlight-citation}). + + Some variables to customize the citation highlights: + + @table @code + @vindex gnus-cite-parse-max-size + + @item gnus-cite-parse-max-size + If the article size if bigger than this variable (which is 25000 by + default), no citation highlighting will be performed. + + @item gnus-cite-max-prefix + @vindex gnus-cite-max-prefix + Maximum possible length for a citation prefix (default 20). + + @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-supercite-regexp + @vindex gnus-supercite-regexp + Regexp matching normal Supercite attribution lines. + + @item gnus-supercite-secondary-regexp + @vindex gnus-supercite-secondary-regexp + Regexp matching mangled Supercite attribution lines. + + @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 gnus-cite-attribution-prefix + @vindex gnus-cite-attribution-prefix + Regexp matching the beginning of an attribution line. + + @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. + + @end table + + + @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 + + @xref{Customizing Articles}, for how to highlight articles automatically. + + + @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-emphasis-alist + '(("_\$$\\w+\$$_" 0 1 gnus-emphasis-underline) + ("\\*\$$\\w+\$$\\*" 0 1 gnus-emphasis-bold))) + @end lisp + + @cindex slash + @cindex asterisk + @cindex underline + @cindex / + @cindex * + + @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}. + + 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: + + @lisp + (copy-face 'red 'gnus-emphasis-italic) + @end lisp + + @vindex gnus-group-highlight-words-alist + + 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. + + @xref{Customizing Articles}, for how to fontize articles automatically. + + + @node Article Hiding + @subsection Article Hiding + @cindex article hiding + + Or rather, hiding certain things in each article. There usually is much + too much cruft in most articles. + + @table @kbd + + @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 W W h + @kindex W W h (Summary) + @findex gnus-article-hide-headers + Hide headers (@code{gnus-article-hide-headers}). @xref{Hiding + Headers}. + + @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 W W s + @kindex W W s (Summary) + @findex gnus-article-hide-signature + Hide signature (@code{gnus-article-hide-signature}). @xref{Article + Signature}. + + @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{\$$..\$$}. + + @table @code + + @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. + + @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}). + + @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. + + 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: + + @lisp + ("@@yoo-hoo\\.co\\.jp\\'" . + "\n_+\nDo You Yoo-hoo!\\?\n.*\n.*\n") + @end lisp + + @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 + + @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: + + @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 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. + + @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: + + @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 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 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}). + + @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. + + Also @pxref{Article Highlighting} for further variables for + citation customization. + + @xref{Customizing Articles}, for how to hide article elements + 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. + + @dfn{Washing} is defined by us as changing something from something to + something else'', but normally results in something looking better. + Cleaner, perhaps. + + @xref{Customizing Articles}, if you want to change how Gnus displays + articles by default. + + @table @kbd + + @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 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 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.) + + 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. + + @item W m + @kindex W m (Summary) + @findex gnus-summary-morse-message + Morse decode the article buffer (@code{gnus-summary-morse-message}). + + @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 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 o + @kindex W o (Summary) + @findex gnus-article-treat-overstrike + Treat overstrike (@code{gnus-article-treat-overstrike}). + + @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. + + 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 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 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 W Y a + @kindex W Y a (Summary) + @findex gnus-article-outlook-repair-attribution + Repair a broken attribution address@hidden + (@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}). + + You can give the command a numerical prefix to specify the width to use + when filling. + + @item W Q + @kindex W Q (Summary) + @findex gnus-article-fill-long-lines + Fill long lines (@code{gnus-article-fill-long-lines}). + + @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 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 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 address@hidden (i.e., 8-bit) articles. It typically + makes strings like @samp{déjà 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 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 + address@hidden (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. + + @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 @address@hidden<:Ky2;address@hidden,NpJ)address@hidden + + @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}. + + If a prefix is given, a charset will be asked for. + + @vindex gnus-article-wash-function + 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}, but this is controlled by the + @code{gnus-article-wash-function} variable. Pre-defined functions you + can use include: + + @table @code + @item w3 + Use Emacs/w3. + + @item w3m + Use @uref{http://emacs-w3m.namazu.org/, emacs-w3m}. + + @item links + Use @uref{http://links.sf.net/, Links}. + + @item lynx + Use @uref{http://lynx.isc.org/, Lynx}. + + @item html2text + Use html2text---a simple @acronym{HTML} converter included with Gnus. + + @end table + + @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 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 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 + address@hidden@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}. + + @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}). + + @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}). + + @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}). + + @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 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 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 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}). + + @end table + + @xref{Customizing Articles}, for how to wash articles automatically. + + + @node Article Header + @subsection Article Header + + These commands perform various transformations of article header. + + @table @kbd + + @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 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 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 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}). + + @end table + + + @node Article Buttons + @subsection Article Buttons + @cindex buttons + + 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. + + @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 gnus-button-alist + @vindex gnus-button-alist + This is an alist where each entry has this form: + + @lisp + (@var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par}) + @end lisp + + @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{<URL:\$$[^\n\r>]*\$$>}. 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}. + + @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. + + @item use-p + This form will be @code{eval}ed, and if the result is address@hidden, + this is considered a match. This is useful if you want extra sifting to + avoid false matches. Often variables named + @address@hidden are used here, @xref{Article Button + Levels}, but any other form may be used too. + + @c @code{use-p} is @code{eval}ed only if @code{regexp} matches. + + @item function + This function will be called when you click on this button. + + @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}. + + @end table + + So the full entry for buttonizing URLs is then + + @lisp + ("<URL:\$$[^\n\r>]*\$$>" 0 t gnus-button-url 1) + @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 + + @var{header} is a regular expression. + @end table + + @subsubsection Related variables and functions + + @table @code + @item address@hidden + @xref{Article Button Levels}. + + @c Stuff related to gnus-button-browse-level + + @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. + + @c Stuff related to gnus-button-man-level + + @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. + + @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 do 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 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 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}. + + @c Stuff related to gnus-button-tex-level + + @item gnus-button-ctan-handler + @findex gnus-button-ctan-handler + The function to use for displaying CTAN links. It must take one + argument, the string naming the URL. + + @item gnus-ctan-url + @vindex gnus-ctan-url + Top directory of a CTAN (Comprehensive TeX Archive Network) archive used + by @code{gnus-button-ctan-handler}. + + @c Misc stuff + + @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 + + @xref{Customizing Articles}, for how to buttonize articles automatically. + + + @node Article Button Levels + @subsection Article button levels + @cindex button levels + The higher the value of the variables @address@hidden, + 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 @address@hidden local to + specific groups (@pxref{Group Parameters}). Here's an example for the + variable @code{gnus-parameters}: + + @lisp + ;; @r{increase @code{gnus-button-*-level} in some groups:} + (setq gnus-parameters + '(("\\<\$$emacs\\|gnus\$$\\>" (gnus-button-emacs-level 10)) + ("\\<unix\\>" (gnus-button-man-level 10)) + ("\\<tex\\>" (gnus-button-tex-level 10)))) + @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}. + + @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}. + + @item gnus-button-tex-level + @vindex gnus-button-tex-level + Controls the display of references to @TeX{} or LaTeX stuff, e.g. for CTAN + URLs. See the variables @code{gnus-ctan-url}, + @code{gnus-button-ctan-handler}, + @code{gnus-button-ctan-directory-regexp}, and + @code{gnus-button-handle-ctan-bogus-regexp}. + + @end table + + + @node Article Date + @subsection Article Date + + 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 @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 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 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 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: + + @example + X-Sent: 6 weeks, 4 days, 1 hour, 3 minutes, 8 seconds ago + @end example + + @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. + + 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. + + @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* + + @end table + + @xref{Customizing Articles}, for how to display the date in your + preferred format automatically. + + + @node Article Display + @subsection Article Display + @cindex picons + @cindex x-face + @cindex smileys + + These commands add various frivolous display gimmicks to the article + buffer in Emacs versions that support them. + + @code{X-Face} headers are small black-and-white images supplied by the + message headers (@pxref{X-Face}). + + @code{Face} headers are small colored images supplied by the message + headers (@pxref{Face}). + + Smileys are those little @samp{:-)} symbols that people like to litter + their messages with (@pxref{Smileys}). + + Picons, on the other hand, reside on your own system, and Gnus will + try to match the headers to what you have (@pxref{Picons}). + + All these functions are toggles---if the elements already exist, + they'll be removed. + + @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 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 D s + @kindex W D s (Summary) + @findex gnus-treat-smiley + Display smileys (@code{gnus-treat-smiley}). + + @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 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 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 D + @kindex W D D (Summary) + @findex gnus-article-remove-images + Remove all images from the article buffer + (@code{gnus-article-remove-images}). + + @end table + + + + @node Article Signature + @subsection Article Signature + @cindex signatures + @cindex article signature + + @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:
+
+ @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
+
+ The more permissive you are, the more likely it is that you'll get false
+ positives.
+
+ @vindex gnus-signature-limit
+ @code{gnus-signature-limit} provides a limit to what is considered a
+ signature when displaying articles.
+
+ @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
+
+ This variable can also be a list where the elements may be of the types
+ listed above.  Here's an example:
+
+ @lisp
+ (setq gnus-signature-limit
+       '(200.0 "^---*Forwarded article"))
+ @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
+
+
+ @node MIME Commands
+ @section MIME Commands
+ @cindex MIME decoding
+ @cindex attachments
+ @cindex viewing attachments
+
+ The following commands all understand the numerical prefix.  For
+ instance, @kbd{3 b} 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.
+
+ @item K o
+ @kindex K o (Summary)
+ Save the @acronym{MIME} part.
+
+ @item K c
+ @kindex K c (Summary)
+ Copy the @acronym{MIME} part.
+
+ @item K e
+ @kindex K e (Summary)
+ View the @acronym{MIME} part externally.
+
+ @item K i
+ @kindex K i (Summary)
+ View the @acronym{MIME} part internally.
+
+ @item K |
+ @kindex K | (Summary)
+ Pipe the @acronym{MIME} part to an external command.
+ @end table
+
+ The rest of these @acronym{MIME} commands do not use the numerical prefix in
+ the same manner:
+
+ @table @kbd
+ @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 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 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 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 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}).
+
+ @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}).
+
+ @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}).
+
+ @end table
+
+ Relevant variables:
+
+ @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}.
+
+ To have all Vcards be ignored, you'd say something like this:
+
+ @lisp
+ (setq gnus-ignored-mime-types
+       '("text/x-vcard"))
+ @end lisp
+
+ @item gnus-article-loose-mime
+ @vindex gnus-article-loose-mime
+ before interpreting the message as a @acronym{MIME} message.  This helps
+ when reading messages from certain broken mail user agents.  The
+ default is @code{nil}.
+
+ @item gnus-article-emulate-mime
+ @vindex gnus-article-emulate-mime
+ There are other, address@hidden encoding methods used.  The most common
+ is @samp{uuencode}, but yEncode is also getting to be popular.  If
+ this variable is address@hidden, 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}.
+
+ @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}.
+
+ @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}.
+
+ 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.
+
+ @item gnus-inhibit-mime-unbuttonizing
+ @vindex gnus-inhibit-mime-unbuttonizing
+ If this is address@hidden, then all @acronym{MIME} parts get buttons.  The
+ default value is @code{nil}.
+
+ @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
+ (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
+
+ @vindex gnus-mime-multipart-functions
+ @item gnus-mime-multipart-functions
+ Alist of @acronym{MIME} multipart types and functions to handle them.
+
+ @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.
+
+ @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
+
+ The standard functions @code{capitalize}, @code{downcase},
+ @code{upcase}, and @code{upcase-initials} may be useful, too.
+
+ 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
+ (setq mm-file-name-rewrite-functions
+       '(mm-file-name-trim-whitespace
+         mm-file-name-collapse-whitespace
+         mm-file-name-replace-whitespace))
+ @end lisp
+
+ @noindent
+
+ @end table
+
+
+ @node Charsets
+ @section Charsets
+ @cindex charsets
+
+ 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-2}.
+
+ @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.
+
+ @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-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
+
+ This variable is an alist of regexps and permitted unencoded charsets
+ for posting.  Each element of the alist has the form @code{(address@hidden
+
+ @table @var
+ @item test
+ is either a regular expression matching the newsgroup header or a
+ variable to query,
+ 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
+
+ @cindex Russian
+ @cindex koi8-r
+ @cindex koi8-u
+ @cindex iso-8859-5
+ @cindex coding system aliases
+ @cindex preferred charset
+
+ Other charset tricks that may be useful, although not Gnus-specific:
+
+ If there are several @acronym{MIME} charsets that encode the same Emacs
+ charset, you can choose what charset to use by saying the following:
+
+ @lisp
+ (put-charset-property 'cyrillic-iso8859-5
+                       'preferred-coding-system 'koi8-r)
+ @end lisp
+
+ This means that Russian will be encoded using @code{koi8-r} instead of
+ the default @code{iso-8859-5} @acronym{MIME} charset.
+
+ If you want to read messages in @code{koi8-u}, you can cheat and say
+
+ @lisp
+ (define-coding-system-alias 'koi8-u 'koi8-r)
+ @end lisp
+
+ This will almost do the right thing.
+
+ And finally, to read charsets like @code{windows-1251}, you can say
+ something like
+
+ @lisp
+ (codepage-setup 1251)
+ (define-coding-system-alias 'windows-1251 'cp1251)
+ @end lisp
+
+
+ @node Article Commands
+ @section Article Commands
+
+ @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}).
+
+ @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.
+
+ @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 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 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 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}).
+
+ @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}).
+
+ @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}).
+
+ @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 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
+
+ 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
+ Commands}).
+
+
+ @node Finding the Parent
+ @section Finding the Parent
+ @cindex parent articles
+ @cindex referring articles
+
+ @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
+
+ 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 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}).
+
+ @item A T (Summary)
+ @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.
+
+ 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 M-^ (Summary)
+ @findex gnus-summary-refer-article
+ @kindex M-^ (Summary)
+ @cindex Message-ID
+ @cindex fetching by Message-ID
+ You can also ask the @acronym{NNTP} server 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. + @end table + + The current select method will be used when fetching by + @code{Message-ID} from non-news select method, but you can override this + by giving this command a prefix. + + @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. + + Here's an example setting that will first try the current method, and + then ask Google if that fails: + + @lisp + (setq gnus-refer-article-method + '(current + (nnweb "google" (nnweb-type google)))) + @end lisp + + 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. (Anything else would be too time consuming.) @code{nnmh} does + not support this at all. + + + @node Alternative Approaches + @section Alternative Approaches + + Different people like to read news using different methods. This being + Gnus, we offer a small selection of minor modes for the summary buffers. + + @menu + * Pick and Read:: First mark articles and then read them. + * Binary Groups:: Auto-decode all articles. + @end menu + + + @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. + + @findex gnus-pick-mode + @kindex M-x gnus-pick-mode + Gnus provides a summary buffer minor mode that allows + address@hidden 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. + + Here are the available keystrokes when using pick mode: + + @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. + + @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 address@hidden, the summary buffer + will still be visible when you are reading. + + @end table + + 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: + + @lisp + (add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) + @end lisp + + @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 address@hidden, mark + all unpicked articles as read. The default is @code{nil}. + + @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 Binary Groups + @subsection Binary Groups + @cindex binary groups + + @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. + + @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}). + + @vindex gnus-binary-mode-hook + @code{gnus-binary-mode-hook} is called in binary minor mode buffers. + + + @node Tree Display + @section Tree Display + @cindex trees + + @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. + + There are a few variables to customize the tree display, of course: + + @table @code + @item gnus-tree-mode-hook + @vindex gnus-tree-mode-hook + A hook called in all tree mode buffers. + + @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-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-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. + + Valid specs are: + + @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 + + @xref{Formatting Variables}. + + Variables related to the display are: + + @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{((?[ . ?]) (?( . ?)) (address@hidden . address@hidden) (?< . ?>))}. + + @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 table + + @item gnus-tree-minimize-window + @vindex gnus-tree-minimize-window + If this variable is address@hidden, 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. + + You may also wish to add the following hook to keep the window minimized + at all times: + + @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 + + Here's an example from a horizontal tree buffer: + + @example + @address@hidden(***)-[odd]-[Gun] + | \[Jan] + | \[odd]-[Eri] + | $$***)-[Eri] + | \[odd]-[Paa] + \[Bjo] + \[Gun] + \[Gun]-[Jor] + @end example + + Here's the same thread displayed in a vertical tree buffer: + + @example + @group + @address@hidden + |--------------------------\-----\-----\ + (***) [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-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 + + @xref{Window Layout}. + + + @node Mail Group Commands + @section Mail Group Commands + @cindex mail group commands + + 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. + + All these commands (except the expiry and edit commands) use the + process/prefix convention (@pxref{Process/Prefix}). + + @table @kbd + + @item B e + @kindex B e (Summary) + @findex gnus-summary-expire-articles + 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 B C-M-e + @kindex B C-M-e (Summary) + @findex gnus-summary-expire-articles-now + 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 B DEL + @kindex B DEL (Summary) + @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 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 address@hidden (which is the default). + + @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 address@hidden (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. + + @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. + + @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. + + @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 address@hidden + (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}). + + @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}). + + @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. + + @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}. + + @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 gnus-move-split-methods + '(("^From:.*Lars Magne" "nnml:junk") + ("^Subject:.*gnus" "nnfolder:important") + (".*" "nnml:misc"))) + @end lisp + + + @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 address@hidden, 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-summary-display-arrow + @item gnus-summary-display-arrow + If address@hidden, display an arrow in the fringe to indicate the + current article. + + @vindex gnus-summary-mode-hook + @item gnus-summary-mode-hook + This hook is called when creating a summary mode buffer. + + @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. + + @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. + + @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. + + @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. + + @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. + + For instance, the following function adds the list of cached articles to + the list in one particular group: + + @lisp + (defun my-add-cached-articles (group articles) + (if (string= group "some.group") + (append gnus-newsgroup-cached articles) + articles)) + @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 values (when the default values are not + @code{nil}), that should be made global while the summary buffer is + active. 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 + + @end table + + + @node Summary Group Information + @subsection Summary Group Information + + @table @kbd + + @item H f + @kindex H f (Summary) + @findex gnus-summary-fetch-faq + @vindex gnus-group-faq-directory + Try to fetch the @acronym{FAQ} (list of frequently asked questions) + for the current group (@code{gnus-summary-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 probably be used for fetching the file. + + @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 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 Searching for Articles + @subsection Searching for Articles + + @table @kbd + + @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 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 & + @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. + + 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 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 + + @item Y g + @kindex Y g (Summary) + @findex gnus-summary-prepare + Regenerate the current summary buffer (@code{gnus-summary-prepare}). + + @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 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}). + + @end table + + + @node Really Various Summary Commands + @subsection Really Various Summary Commands + + @table @kbd + + @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 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}). + + @end table + + + @node Exiting the Summary Buffer + @section Exiting the Summary Buffer + @cindex summary exit + @cindex exiting groups + + Exiting from the summary buffer will normally update all info on the + group and return you to the group buffer. + + @table @kbd + + @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 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 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 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 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 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 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. + + @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}). + + @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}). + + @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 + + @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. + + @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. + + There will never be more than one dead summary buffer at any one time. + + @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}). + + + @node Crosspost Handling + @section Crosspost Handling + + @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. You may want to try NoCeM handling to filter out spam + (@pxref{NoCeM}). + + 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. + + @vindex gnus-nov-is-evil + If you want Gnus to get the @code{Xref}s right all the time, you have to + set @code{gnus-nov-is-evil} to @code{t}, which slows things down + considerably. + + C'est la vie. + + For an alternative approach, @pxref{Duplicate Suppression}. + + + @node Duplicate Suppression + @section Duplicate Suppression + + 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. + + @enumerate + @item + The @acronym{NNTP} server may fail to generate the @code{Xref} header. This + is evil and not very common. + + @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. + + @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 + + I'm sure there are other situations where @code{Xref} handling fails as + well, but these four are the most common situations. + + 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. + + 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-suppress-duplicates + @vindex gnus-suppress-duplicates + If address@hidden, suppress duplicates. + + @item gnus-save-duplicate-list + @vindex gnus-save-duplicate-list + If address@hidden, 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-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-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 + + 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. + + @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: + + @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 Gnus is called PGG (@pxref{Top, ,PGG, pgg, PGG + Manual}), but Mailcrypt and gpg.el are also supported. + + @item + To handle @acronym{S/MIME} message, you need to install OpenSSL. OpenSSL 0.9.6 + or newer is recommended. + + @end enumerate + + More information on how to set things up can be found in the message + manual (@pxref{Security, ,Security, message, Message Manual}). + + @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. + + @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. + + @item mml1991-use + @vindex mml1991-use + Symbol indicating elisp interface to OpenPGP implementation for + @acronym{PGP} messages. The default is @code{pgg}, but + @code{mailcrypt} and @code{gpg} are also supported although + deprecated. + + @item mml2015-use + @vindex mml2015-use + Symbol indicating elisp interface to OpenPGP implementation for + @acronym{PGP/MIME} messages. The default is @code{pgg}, but + @code{mailcrypt} and @code{gpg} are also supported although + deprecated. + + @end table + + @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 + 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}. + + @node Mailing List + @section Mailing List + @cindex mailing list + @cindex RFC 2396 + + @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: + + @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. + + @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. + + @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 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 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 C-c C-n a + @kindex C-c C-n a (Summary) + @findex gnus-mailing-list-owner + Browse the mailing list archive, if List-Archive field exists. + + @end table + + + @node Article Buffer + @chapter Article Buffer + @cindex article buffer + + 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. + + @menu + * Hiding Headers:: Deciding what headers should be displayed. + * Using MIME:: Pushing articles through @acronym{MIME} before reading them. + * Customizing Articles:: Tailoring the look of the articles. + * Article Keymap:: Keystrokes available in the article buffer. + * Misc Article:: Other stuff. + @end menu + + + @node Hiding Headers + @section Hiding Headers + @cindex hiding headers + @cindex deleting headers + + The top section of each article is the @dfn{head}. (The rest is the + @dfn{body}, but you may have guessed that already.) + + @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}. + + Gnus provides you with two variables for sifting headers: + + @table @code + + @item gnus-visible-headers + @vindex gnus-visible-headers + If this variable is address@hidden, 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. + + 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-ignored-headers "^References:\\|^Xref:") + @end lisp + + This variable can also be a list of regexps to match headers to + be removed. + + Note that if @code{gnus-visible-headers} is address@hidden, this + variable will have no effect. + + @end table + + @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. + + 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 + + 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. + + @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. + + 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} header if it is very long. + @item many-to + Remove all @code{To} headers if there are more than one. + @end table + + To include these three elements, you could say something like: + + @lisp + (setq gnus-boring-article-headers + '(empty followup-to reply-to)) + @end lisp + + This is also the default value for this variable. + + + @node Using MIME + @section Using MIME + @cindex @acronym{MIME} + + Mime is a standard for waving your hands through the air, aimlessly, + while people stand around yawning. + + @acronym{MIME}, however, is a standard for encoding your articles, aimlessly, + while all newsreaders die of fear. + + @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. + + 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. + + @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}). + + @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}). + + @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}). + + @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}). + + @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}). 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}). + + @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. + + @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 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}). + + @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}). + + @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}). + + @findex gnus-mime-pipe-part + @item | (Article) + @kindex | (Article) + Output the @acronym{MIME} object to a process (@code{gnus-mime-pipe-part}). + + @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}). + + @end table + + 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. + + 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.) + + Any similarity to real events and people is purely coincidental. Ahem. + + Also @pxref{MIME Commands}. + + + @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. + + 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. + + Note: Some values, while valid, make little sense. Check the list below + for sensible values. + + @enumerate + @item + @code{nil}: Don't do this treatment. + + @item + @code{t}: Do this treatment on all body parts. + + @item + @code{head}: Do the treatment on the headers. + + @item + @code{last}: Do this treatment on the last part. + + @item + An integer: Do this treatment on all body parts that have a length less + than this number. + + @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 + A list where the first element is not a string: + + 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: + + @lisp + (or last + (typep "text/x-vcard")) + @end lisp + + @end enumerate + + 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-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. + + 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. + + @table @code + @item gnus-treat-buttonize (t, integer) + @item gnus-treat-buttonize-head (head) + + @xref{Article Buttons}. + + @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, 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) + + @xref{Article Washing}. + + @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}. + + @item gnus-treat-from-picon (head) + @item gnus-treat-mail-picon (head) + @item gnus-treat-newsgroups-picon (head) + + @xref{Picons}. + + @item gnus-treat-display-smileys (t, integer) + + @item gnus-treat-body-boundary (head) + + @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}. + + @xref{Smileys}. + + @item gnus-treat-display-x-face (head) + + @xref{X-Face}. + + @item gnus-treat-display-face (head) + + @xref{Face}. + + @item gnus-treat-emphasize (t, head, integer) + @item gnus-treat-fill-article (t, integer) + @item gnus-treat-fill-long-lines (t, integer) + @item gnus-treat-hide-boring-headers (head) + @item gnus-treat-hide-citation (t, integer) + @item gnus-treat-hide-citation-maybe (t, integer) + @item gnus-treat-hide-headers (head) + @item gnus-treat-hide-signature (t, last) + @item gnus-treat-strip-banner (t, last) + @item gnus-treat-strip-list-identifiers (head) + + @xref{Article Hiding}. + + @item gnus-treat-highlight-citation (t, integer) + @item gnus-treat-highlight-headers (head) + @item gnus-treat-highlight-signature (t, last, integer) + + @xref{Article Highlighting}. + + @item gnus-treat-play-sounds + @item gnus-treat-translate + @item gnus-treat-x-pgp-sig (head) + + @item gnus-treat-unfold-headers (head) + @item gnus-treat-fold-headers (head) + @item gnus-treat-fold-newsgroups (head) + @item gnus-treat-leading-whitespace (head) + + @xref{Article Header}. + + + @end table + + @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. + + + @node Article Keymap + @section Article Keymap + + 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. + + A few additional keystrokes are available: + + @table @kbd + + @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}. + + @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}). + + @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. + + @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. + + @item M-TAB + @kindex M-TAB (Article) + @findex gnus-article-prev-button + Go to the previous button, if any (@code{gnus-article-prev-button}). + + @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 given a prefix, make a + wide reply. If the region is active, only yank the text in the + region. + + @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 given a prefix, make + a wide reply. If the region is active, only yank the text in the + region. + + + @end table + + + @node Misc Article + @section Misc Article + + @table @code + + @item gnus-single-article-buffer + @vindex gnus-single-article-buffer + If address@hidden, use the same article buffer for all the groups. + (This is the default.) If @code{nil}, each group will have its own + article buffer. + + @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)} + + @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. + + @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}. + + @vindex gnus-article-over-scroll + @item gnus-article-over-scroll + If address@hidden, allow scrolling the article buffer even when there + no more new text to scroll in. The default is @code{nil}. + + @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{Mode Line Formatting}). It + accepts the same format specifications as that variable, with two + extensions: + + @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: + + @table @samp + + @item c + Displayed when cited text may be hidden in the article buffer. + + @item h + Displayed when headers are hidden in the article 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.) + + @item s + Displayed when the signature has been hidden in the Article buffer. + + @item o + Displayed when Gnus has treated overstrike characters in the article buffer. + + @item e + Displayed when Gnus has treated emphasised strings in the article buffer. + + @end table + + @item m + The number of @acronym{MIME} parts in the article. + + @end table + + @vindex gnus-break-pages + + @item gnus-break-pages + Controls whether @dfn{page breaking} is to take place. If this variable + is address@hidden, 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. + + @item gnus-page-delimiter + @vindex gnus-page-delimiter + This is the delimiter mentioned above. By default, it is @samp{^L} + (formfeed). + + @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. This requires + @uref{http://www.gnu.org/software/libidn/, GNU Libidn}, and this + variable is only enabled if you have installed it. + + @end table + + + @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 + + @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}). + + @menu + * Mail:: Mailing and replying. + * Posting Server:: What server should you post and mail via? + * 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 + + Also @pxref{Canceling and Superseding} for information on how to + remove articles you shouldn't have posted. + + + @node Mail + @section Mail + + 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. + + @item gnus-add-to-list + @vindex gnus-add-to-list + If address@hidden, add a @code{to-list} group parameter to mail groups + that have none when you do a @kbd{a}. + + @item gnus-confirm-mail-reply-to-news + @vindex gnus-confirm-mail-reply-to-news + This can also be a function receiving the group name as the only + parameter which should return address@hidden if a confirmation is + needed, or a regular expression matching group names, where + confirmation is should be asked for. + + If you find yourself never wanting to reply to mail, but occasionally + press R anyway, this variable might be for you. + + @item gnus-confirm-treat-mail-like-news + @vindex gnus-confirm-treat-mail-like-news + If address@hidden, 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. + + @end table + + + @node Posting Server + @section Posting 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? + + Thank you for asking. I hate you. + + It can be quite complicated. + + @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: + + @lisp + (setq gnus-post-method '(nnspool "")) + @end lisp + + 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. + + 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. + + 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. + + Finally, if you want to always post using the native select method, + you can set this variable to @code{native}. + + When sending mail, Message invokes @code{message-send-mail-function}. + The default function, @code{message-send-mail-with-sendmail}, pipes + your article to the @code{sendmail} binary for further queuing and + sending. When your local system is not configured for sending mail + using @code{sendmail}, and you have access to a remote @acronym{SMTP} + server, you can set @code{message-send-mail-function} to + @code{smtpmail-send-it} and make sure to setup the @code{smtpmail} + package correctly. An example: + + @lisp + (setq message-send-mail-function 'smtpmail-send-it + smtpmail-default-smtp-server "YOUR SMTP HOST") + @end lisp + + To the thing similar to this, there is + @code{message-smtpmail-send-it}. It is useful if your ISP requires + the @address@hidden authentication. See the + documentation for the function @code{mail-source-touch-pop}. + + Other possible choices for @code{message-send-mail-function} includes + @code{message-send-mail-with-mh}, @code{message-send-mail-with-qmail}, + and @code{feedmail-send-it}. + + @node Mail and Post + @section Mail and Post + + 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 + + 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. + + @item gnus-user-agent + @vindex gnus-user-agent + @cindex User-Agent + + This variable controls which information should be exposed in the + User-Agent header. It can be one of the symbols @code{gnus} (show only + Gnus version), @code{emacs-gnus} (show only Emacs and Gnus versions), + @code{emacs-gnus-config} (same as @code{emacs-gnus} plus system + configuration), @code{emacs-gnus-type} (same as @code{emacs-gnus} plus + system type) or a custom string. If you set it to a string, be sure to + use a valid format, see RFC 2616. + + @end table + + 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 + (add-hook 'message-send-hook 'ispell-message) + @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: + + @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 + + Modify to suit your needs. + + + @node Archived Messages + @section Archived Messages + @cindex archived messages + @cindex sent messages + + 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. + + For archiving interesting messages in a group you read, see the + @kbd{B c} (@code{gnus-summary-copy-article}) command (@pxref{Mail + Group Commands}). + + @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: + + @lisp + (nnfolder "archive" + (nnfolder-directory "~/Mail/archive") + (nnfolder-active-file "~/Mail/archive/active") + (nnfolder-get-new-mail nil) + (nnfolder-inhibit-expiry t)) + @end lisp + + 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: + + @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 + + @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}. + + @item a list of strings + Messages will be saved in all those groups. + + @item an alist of regexps, functions and forms + When a key matches'', the result is used. + + @item @code{nil} + No message archiving will take place. This is the default. + @end table + + Let's illustrate: + + Just saving to a single group called @samp{MisK}: + @lisp + (setq gnus-message-archive-group "MisK") + @end lisp + + Saving to two groups, @samp{MisK} and @samp{safe}: + @lisp + (setq gnus-message-archive-group '("MisK" "safe")) + @end lisp + + 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 + (setq gnus-message-archive-group + '((if (message-news-p) + "misc-news" + "misc-mail"))) + @end lisp + + How about storing all news messages in one file, but storing all mail + messages in one file per month: + + @lisp + (setq gnus-message-archive-group + '((if (message-news-p) + "misc-news" + (concat "mail." (format-time-string "%Y-%m"))))) + @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.) + + 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 + address@hidden, or whatever. New messages will + continue to be stored in the old (now empty) group. + + 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-outgoing-message-group + @vindex gnus-outgoing-message-group + All outgoing messages will be put in this group. If you want to store + all your outgoing mail and articles in the group @samp{nnml:archive}, + you set this variable to that value. This variable can also be a list of + group names. + + If you want to have greater control over what group to put each + message in, you can set this variable to a function that checks the + current newsgroup name and then returns a suitable group name (or list + of names). + + This variable can be used instead of @code{gnus-message-archive-group}, + but the latter is the preferred method. + + @item gnus-gcc-mark-as-read + @vindex gnus-gcc-mark-as-read + If address@hidden, automatically mark @code{Gcc} articles as read. + + @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 + address@hidden, the behavior is the same as @code{all}, but it may be + changed in the future. + + @end table + + + @node Posting Styles + @section Posting Styles + @cindex posting styles + @cindex styles + + All them variables, they make my head swim. + + 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? + + @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 + + 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. + + 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 address@hidden value, then the style is + said to @dfn{match}. + + Each style may contain an arbitrary amount of @dfn{attributes}. Each + attribute consists of a @code{(@var{name} @var{value})} pair. The + attribute name can be one of: + + @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 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. + + The attribute value can be a string (used verbatim), 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. + + @vindex message-reply-headers + + 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. + + @findex message-mail-p + @findex message-news-p + + So here's a new example: + + @lisp + (setq gnus-posting-styles + '((".*" + (signature-file "~/.signature") + (name "User Name") + ("X-Home-Page" (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 (save-excursion + (set-buffer gnus-article-buffer) + (message-fetch-field "to")))) + ("^nn.+:" + (signature-file "~/.mail-signature")))) + @end lisp + + 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. + + + @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.) + + @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. + + 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. + + @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. + + Rejected articles will also be put in this draft group (@pxref{Rejected + Articles}). + + @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. + + @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. + + + @node Rejected Articles + @section Rejected Articles + @cindex rejected articles + + 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. + + 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. + + 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. + + @node Signing and encrypting + @section Signing and encrypting + @cindex using gpg + @cindex using s/mime + @cindex using smime + + 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}). + + @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. + + 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. + + @table @kbd + + @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}. + + @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}. + + @item C-c C-m s p + @kindex C-c C-m s p (Message) + @findex mml-secure-message-sign-pgp + + Digitally sign current message using @acronym{PGP/MIME}. + + @item C-c C-m c s + @kindex C-c C-m c s (Message) + @findex mml-secure-message-encrypt-smime + + Digitally encrypt current message using @acronym{S/MIME}. + + @item C-c C-m c o + @kindex C-c C-m c o (Message) + @findex mml-secure-message-encrypt-pgp + + Digitally encrypt current message using @acronym{PGP}. + + @item C-c C-m c p + @kindex C-c C-m c p (Message) + @findex mml-secure-message-encrypt-pgpmime + + Digitally encrypt current message using @acronym{PGP/MIME}. + + @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. + + @end table + + @xref{Security, ,Security, message, Message Manual}, for more information. + + @node Select Methods + @chapter Select Methods + @cindex foreign groups + @cindex select methods + + 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. + + 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. + + One could say that a select method defines a @dfn{virtual server}---so + we do just that (@pxref{Server Buffer}). + + The @dfn{name} of the group is the name the back end will recognize the + group as. + + 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}. + + The different methods all have their peculiarities, of course. + + @menu + * Server Buffer:: Making and editing virtual servers. + * Getting News:: Reading USENET news with Gnus. + * Getting Mail:: Reading your personal mail with Gnus. + * Browsing the Web:: Getting messages from a plethora of Web sources. + * IMAP:: Using Gnus as a @acronym{IMAP} client. + * Other Sources:: Reading directories, files, SOUP packets. + * Combined Groups:: Combining groups into one group. + * Gnus Unplugged:: Reading news and mail offline. + @end menu + + + @node Server Buffer + @section Server Buffer + + 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. + + 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}. + + 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. + + To enter the server buffer, use the @kbd{^} + (@code{gnus-group-enter-server-mode}) command in the group buffer. + + @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-server-mode-hook + @code{gnus-server-mode-hook} is run when creating the server buffer. + + + @node Server Buffer Format + @subsection Server Buffer Format + @cindex server buffer format + + @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: + + @table @samp + + @item h + How the news is fetched---the back end name. + + @item n + The name of this server. + + @item w + Where the news is to be fetched from---the address. + + @item s + The opened/closed/denied status of the server. + @end table + + @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 @samp + @item S + Server name. + + @item M + Server method. + @end table + + Also @pxref{Formatting Variables}. + + + @node Server Commands + @subsection Server Commands + @cindex server commands + + @table @kbd + + @item a + @kindex a (Server) + @findex gnus-server-add-server + Add a new server (@code{gnus-server-add-server}). + + @item e + @kindex e (Server) + @findex gnus-server-edit-server + Edit a server (@code{gnus-server-edit-server}). + + @item SPACE + @kindex SPACE (Server) + @findex gnus-server-read-server + Browse the current server (@code{gnus-server-read-server}). + + @item q + @kindex q (Server) + @findex gnus-server-exit + Return to the group buffer (@code{gnus-server-exit}). + + @item k + @kindex k (Server) + @findex gnus-server-kill-server + Kill the current server (@code{gnus-server-kill-server}). + + @item y + @kindex y (Server) + @findex gnus-server-yank-server + Yank the previously killed server (@code{gnus-server-yank-server}). + + @item c + @kindex c (Server) + @findex gnus-server-copy-server + Copy the current server (@code{gnus-server-copy-server}). + + @item l + @kindex l (Server) + @findex gnus-server-list-servers + List all servers (@code{gnus-server-list-servers}). + + @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. + + @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. + + @end table + + + @node Example Methods + @subsection Example Methods + + Most select methods are pretty simple and self-explanatory: + + @lisp + (nntp "news.funet.fi") + @end lisp + + Reading directly from the spool is even simpler: + + @lisp + (nnspool "") + @end lisp + + 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. + + After these two elements, there may be an arbitrary number of + @code{(@var{variable} @var{form})} pairs. + + 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: + + @lisp + (nntp "news.funet.fi" (nntp-port-number 15)) + @end lisp + + 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: + + @lisp + (nnmh "private" (nnmh-directory "~/private/mail/")) + @end lisp + + (This server is then called @samp{private}, but you may have guessed + that.) + + Here's the method for a public spool: + + @lisp + (nnmh "public" + (nnmh-directory "/usr/information/spool/") + (nnmh-get-new-mail nil)) + @end lisp + + @cindex proxy + @cindex firewall + + 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 telnet from there to the @acronym{NNTP} server. + Doing this can be rather fiddly, but your virtual server definition + should probably look something like this: + + @lisp + (nntp "firewall" + (nntp-open-connection-function nntp-open-via-rlogin-and-telnet) + (nntp-via-address "the.firewall.machine") + (nntp-address "the.real.nntp.host") + (nntp-end-of-line "\n")) + @end lisp + + 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 + + See also @code{nntp-via-rlogin-command-switches}. + + 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 + telnet connection to the news server as follows: + + @lisp + (nntp "outside" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-via-telnet) + (nntp-address "the.news.server") + (nntp-end-of-line "\n")) + @end lisp + + This means that you have to have set up @code{ssh-agent} correctly to + provide automatic authorization, of course. And to get a compressed + connection, you have to have the @samp{Compression} option in the + @code{ssh} @file{config} file. + + + @node Creating a Virtual Server + @subsection Creating a Virtual Server + + 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. + + 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. + + Type @kbd{a nnml RET cache RET}. + + 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: + + @lisp + (nnml "cache") + @end lisp + + Change that to: + + @lisp + (nnml "cache" + (nnml-directory "~/News/cache/") + (nnml-active-file "~/News/cache/active")) + @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. + + + @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 + (nnml "public" + (nnml-directory "~/my-mail/") + (nnml-active-file "~/my-mail/active") + (nnml-newsgroups-file "~/my-mail/newsgroups")) + @end lisp + + 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}). + + @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}). + + @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}). + + @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 L + @kindex L (Server) + @findex gnus-server-offline-server + Set server status to offline (@code{gnus-server-offline-server}). + + @end table + + + @node Getting News + @section Getting News + @cindex reading news + @cindex news back ends + + 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. + + @menu + * NNTP:: Reading news from an @acronym{NNTP} server. + * News Spool:: Reading news from the local spool. + @end menu + + + @node NNTP + @subsection NNTP + @cindex nntp + + 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. + + 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 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. + + The following variables can be used to create a virtual @code{nntp} + server: + + @table @code + + @item nntp-server-opened-hook + @vindex nntp-server-opened-hook + @cindex @sc{mode reader} + @cindex authinfo + @cindex authentification + @cindex nntp authentification + @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: + + @enumerate + @item + The file contains one or more line, each of which define one server. + + @item + Each line may contain an arbitrary number of token/value pairs. + + 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. + + @end enumerate + + Here's an example file: + + @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. + + 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 + + This will force sending @samp{AUTHINFO} commands to all servers not + previously mentioned. + + Remember to not leave the @file{~/.authinfo} file world-readable. + + @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: + + @lisp + (setq nntp-server-action-alist + '(("innd" (ding)))) + @end lisp + + You probably don't want to do that, though. + + The default value is + + @lisp + '(("nntpd 1\\.5\\.11t" + (remove-hook 'nntp-server-opened-hook + 'nntp-send-mode-reader))) + @end lisp + + 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. + + @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. + + @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. + + @c @item nntp-command-timeout + @c @vindex nntp-command-timeout + @c @cindex PPP connections + @c @cindex dynamic IP addresses + @c If you're running Gnus on a machine that has a dynamically assigned + @c address, Gnus may become confused. If the address of your machine + @c changes after connecting to the @acronym{NNTP} server, Gnus will simply sit + @c waiting forever for replies from the server. To help with this + @c unfortunate problem, you can set this command to a number. Gnus will + @c then, if it sits waiting for a reply from the server longer than that + @c number of seconds, shut down the connection, start a new one, and resend + @c the command. This should hopefully be transparent to the user. A + @c likely number is 30 seconds. + @c + @c @item nntp-retry-on-break + @c @vindex nntp-retry-on-break + @c If this variable is address@hidden, you can also @kbd{C-g} if Gnus + @c hangs. This will have much the same effect as the command timeout + @c described above. + + @item nntp-server-hook + @vindex nntp-server-hook + This hook is run as the last step when connecting to an @acronym{NNTP} + server. + + @item nntp-buggy-select + @vindex nntp-buggy-select + Set this to address@hidden if your select routine is buggy. + + @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")}. + + @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. + + @item nntp-prepare-server-hook + @vindex nntp-prepare-server-hook + A hook run before attempting to connect to an @acronym{NNTP} server. + + @item nntp-warn-about-losing-connection + @vindex nntp-warn-about-losing-connection + If this variable is address@hidden, some noise will be made when a + server closes connection. + + @item nntp-record-commands + @vindex nntp-record-commands + If address@hidden, @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. + Five pre-made functions are supplied. These functions can be grouped in + two categories: direct connection functions (three pre-made), and + indirect ones (two pre-made). + + @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 + + Note that not all servers support the recommended ID. This works for + INN versions 2.3.0 and later, for instance. + + @item nntp-read-timeout + @vindex nntp-read-timeout + How long nntp should wait between checking for the end of output. + Shorter values mean quicker response, but is more CPU intensive. The + default is 0.1 seconds. If you have a slow line to the server (and + don't like to see Emacs eat your available CPU power), you might set + this to, say, 1. + + @end table + + @menu + * Direct Functions:: Connecting directly to the server. + * Indirect Functions:: Connecting indirectly to the server. + * Common Variables:: Understood by several connection functions. + @end menu + + + @node Direct Functions + @subsubsection Direct Functions + @cindex direct connection functions + + 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}). + + @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. + + @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: + + @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 ) + (nntp-address "snews.bar.com")) + @end lisp + + @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: + + @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 + + @findex nntp-open-telnet-stream + @item nntp-open-telnet-stream + Opens a connection to an @acronym{NNTP} server by simply @samp{telnet}'ing + it. 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-telnet-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. + @end table + + + @node Indirect Functions + @subsubsection Indirect Functions + @cindex indirect connection functions + + 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}). + + @table @code + @item nntp-open-via-rlogin-and-telnet + @findex nntp-open-via-rlogin-and-telnet + Does an @samp{rlogin} on a remote system, and then does a @samp{telnet} + to the real @acronym{NNTP} server from there. This is useful for instance if + you need to connect to a firewall machine first. + + @code{nntp-open-via-rlogin-and-telnet}-specific variables: + + @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, otherwise 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. + @end table + + @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. + + @code{nntp-open-via-telnet-and-telnet}-specific variables: + + @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")}. + + @item nntp-via-user-password + @vindex nntp-via-user-password + Password to use when logging in on the intermediate host. + + @item nntp-via-envuser + @vindex nntp-via-envuser + If address@hidden, 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 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?}. + + @end table + + @end table + + + Here are some additional variables that are understood by all the above + functions: + + @table @code + + @item nntp-via-user-name + @vindex nntp-via-user-name + User name to use when connecting to the intermediate host. + + @item nntp-via-address + @vindex nntp-via-address + Address of the intermediate host to connect to. + + @end table + + + @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. + + @table @code + + @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 nntp-address + @vindex nntp-address + The address of the @acronym{NNTP} 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 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 connection function. + + @item nntp-telnet-command + @vindex nntp-telnet-command + Command to use when connecting to the @acronym{NNTP} server through + @samp{telnet}. This is @emph{not} for an intermediate host. This is + just for the real @acronym{NNTP} server. The default is + @samp{telnet}. + + @item nntp-telnet-switches + @vindex nntp-telnet-switches + A list of switches to pass to @code{nntp-telnet-command}. The default + is @samp{("-8")}. + + @end table + + + @node News Spool + @subsection News Spool + @cindex nnspool + @cindex news spool + + 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 address@hidden, for + instance. + + Anyway, you just specify @code{nnspool} as the method and @code{""} (or + anything else) as the address. + + 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. + + @table @code + + @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 nnspool-spool-directory + @vindex nnspool-spool-directory + Where @code{nnspool} looks for the articles. This is normally + @file{/usr/spool/news/}. + + @item nnspool-nov-directory + @vindex nnspool-nov-directory + Where @code{nnspool} will look for @acronym{NOV} files. This is address@hidden + @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. + + @item nnspool-newsgroups-file + @vindex nnspool-newsgroups-file + The name of the group descriptions file. + + @item nnspool-history-file + @vindex nnspool-history-file + The name of the news history file. + + @item nnspool-active-times-file + @vindex nnspool-active-times-file + The name of the active date file. + + @item nnspool-nov-is-evil + @vindex nnspool-nov-is-evil + If address@hidden, @code{nnspool} won't try to use any @acronym{NOV} files + that it finds. + + @item nnspool-sift-nov-with-sed + @vindex nnspool-sift-nov-with-sed + @cindex sed + If address@hidden, 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. + + @end table + + + @node Getting Mail + @section Getting Mail + @cindex reading mail + @cindex mail + + 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 + + + @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. + + 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.) + + In particular, you do not do anything explicitly to delete messages. + + Does this mean that all the messages that have been marked as read are + deleted? How awful! + + 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. + + 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. + + 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. + + 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. + + Gnus provides many options for sorting mail into groups'' which behave + like newsgroups, and for treating each group (whether mail or news) + differently. + + 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. + + 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.) + + + @node Getting Started Reading Mail + @subsection Getting Started Reading Mail + + 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. + + 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: + + @lisp + (setq gnus-secondary-select-methods '((nnml ""))) + @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. + + You will probably want to split the mail into several groups, though: + + @lisp + (setq nnmail-split-methods + '(("junk" "^From:.*Lars Ingebrigtsen") + ("crazy" "^Subject:.*die\\|^Organization:.*flabby") + ("other" ""))) + @end lisp + + 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. + + 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}. + + + @node Splitting Mail + @subsection Splitting Mail + @cindex splitting mail + @cindex mail splitting + @cindex mail filtering (splitting) + + @vindex nnmail-split-methods + The @code{nnmail-split-methods} variable says how the incoming mail is + to be split into groups. + + @lisp + (setq nnmail-split-methods + '(("mail.junk" "^From:.*Lars Ingebrigtsen") + ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") + ("mail.other" ""))) + @end lisp + + 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 + ("list.\\1" "From:.* \\(.*\$$-list@@majordomo.com") + @end lisp + + 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 address@hidden value if it thinks that the + mail belongs in that 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 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. + + 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<SPACE>} line to something else. + + @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. + + @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.) + + @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}). + + @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. + + @vindex nnmail-mail-splitting-charset + @vindex nnmail-mail-splitting-decodes + By default the splitting codes @acronym{MIME} decodes headers so you + can match on address@hidden strings. The + @code{nnmail-mail-splitting-charset} variable specifies the default + charset for decoding. The behaviour can be turned off completely by + binding @code{nnmail-mail-splitting-decodes} to @code{nil}, which is + useful if you want to match articles based on the raw header data. + + @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 address@hidden value to make + splitting happen even in this case. (This variable has no effect on + other kinds of entries.) + + 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. + + + @node Mail Sources + @subsection Mail Sources + + 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. + + @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 + + + @node Mail Source Specifiers + @subsubsection Mail Source Specifiers + @cindex POP + @cindex mail server + @cindex procmail + @cindex mail spool + @cindex mail source + + You tell Gnus how to fetch mail by setting @code{mail-sources} + (@pxref{Fetching Mail}) to a @dfn{mail source specifier}. + + Here's an example: + + @lisp + (pop :server "pop3.mailserver.com" :user "myname") + @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. + + The following mail source types are available: + + @table @code + @item file + Get mail from a single file; typically from the mail spool. + + Keywords: + + @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}). + + @item :prescript + @itemx :postscript + Script run before/after fetching mail. + @end table + + An example file mail source: + + @lisp + (file :path "/usr/spool/mail/user-name") + @end lisp + + Or using the default file name: + + @lisp + (file) + @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. + + @lisp + (setq mail-sources + '((file :prescript "ssh host bin/getmail >%t"))) + @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 find the @samp{movemail} you want to use. + + + @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 address@hidden forces + Gnus to scan the mail source only once. This is particularly useful + if you want to scan mail groups at a specified level. + + @vindex nnmail-resplit-incoming + There is also the variable @code{nnmail-resplit-incoming}, if you set + that to a address@hidden value, then the normal splitting process is + applied to all the files from the directory, @ref{Splitting Mail}. + + Keywords: + + @table @code + @item :path + The name of the directory where the files are. There is no default + 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 address@hidden 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 + + @item pop + Get mail from a @acronym{POP} server. + + Keywords: + + @table @code + @item :server + The name of the @acronym{POP} server. The default is taken from the + @env{MAILHOST} environment variable. + + @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 :user + The user name to give to the @acronym{POP} server. The default is the login + name. + + @item :password + The password to give to the @acronym{POP} server. If not specified, + the user is prompted. + + @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: + + @example + fetchmail %u@@%s -P %p %t + @end example + + The valid format specifier characters are: + + @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 s + The name of the server. + + @item P + The port number of the server. + + @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. + + @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 :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 :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 :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}. + + @end table + + If the @code{:program} and @code{:function} keywords aren't specified, + @code{pop3-movemail} will be used. + + Here are some examples. Fetch from the default @acronym{POP} server, + using the default user name, and default fetcher: + + @lisp + (pop) + @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 + + Use @samp{movemail} to move the mail: + + @lisp + (pop :program "movemail po:%u %t %p") + @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). + + @end table + + Two example maildir mail sources: + + @lisp + (maildir :path "/home/user-name/Maildir/" + :subdirs ("cur" "new")) + @end lisp + + @lisp + (maildir :path "/user@@remotehost.org:~/Maildir/" + :subdirs ("new")) + @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{IMAP}, for more information. + + Note that for the Kerberos, GSSAPI, @acronym{TLS}/@acronym{SSL} and STARTTLS support you + may need external programs and libraries, @xref{IMAP}. + + 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. + + @item :user + The user name to give to the @acronym{IMAP} server. The default is the login + name. + + @item :password + The password to give to the @acronym{IMAP} server. If not specified, the user is + prompted. + + @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 :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 :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: + + @example + ssh %s imapd + @end example + + The valid format specifier characters are: + + @table @samp + @item s + The name of the server. + + @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. + + @item :mailbox + The name of the mailbox to get mail from. The default is @samp{INBOX} + which normally is the mailbox which receive incoming mail. + + @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. + + @item :dontexpunge + If address@hidden, don't remove all articles marked as deleted in the + mailbox after finishing the fetch. + + @end table + + An example @acronym{IMAP} mail source: + + @lisp + (imap :server "mail.mycorp.com" + :stream kerberos4 + :fetchflag "\\Seen") + @end lisp + + @item webmail + Get mail from a webmail server, such as @uref{http://www.hotmail.com/}, + @uref{http://webmail.netscape.com/}, @uref{http://www.netaddress.com/}, + @uref{http://mail.yahoo.com/}. + + NOTE: Webmail largely depends on cookies. A "one-line-cookie" patch is + required for url "4.0pre.46". + + WARNING: Mails may be lost. NO WARRANTY. + + Keywords: + + @table @code + @item :subtype + The type of the webmail server. The default is @code{hotmail}. The + alternatives are @code{netscape}, @code{netaddress}, @code{my-deja}. + + @item :user + The user name to give to the webmail server. The default is the login + name. + + @item :password + The password to give to the webmail server. If not specified, the user is + prompted. + + @item :dontexpunge + If address@hidden, only fetch unread articles and don't move them to + trash folder after finishing the fetch. + + @end table + + An example webmail source: + + @lisp + (webmail :subtype 'hotmail + :user "user-name" + :password "secret") + @end lisp + @end table + + @table @dfn + @item Common Keywords + Common keywords can be used in any type of mail source. + + Keywords: + + @table @code + @item :plugged + If address@hidden, 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. + + @end table + @end table + + @subsubsection Function Interface + + 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: + + @lisp + (setq mail-sources '((pop :user "jrl" + :server "pophost" :function fetchfunc))) + @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). + + See above for a list of keywords for each type of mail source. + + + @node Mail Source Customization + @subsubsection Mail Source Customization + + 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. + + @table @code + @item mail-source-crash-box + @vindex mail-source-crash-box + File where mail will be stored while processing it. The default address@hidden + @file{~/.emacs-mail-crash-box}. + + @item mail-source-delete-incoming + @vindex mail-source-delete-incoming + If address@hidden, 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 + (This 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. + + @item mail-source-delete-old-incoming-confirm + @vindex mail-source-delete-old-incoming-confirm + If address@hidden, ask for 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 address@hidden, ignore errors when reading mail from a mail source. + + @item mail-source-directory + @vindex mail-source-directory + Directory where 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 previous variable is + @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}. + + @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. + + @item mail-source-movemail-program + @vindex mail-source-movemail-program + If address@hidden, name of program for fetching new mail. If + @code{nil}, @code{movemail} in @var{exec-directory}. + + @end table + + + @node Fetching Mail + @subsubsection Fetching Mail + + @vindex mail-sources + @vindex nnmail-spool-file + 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 this variable (and the obsolescent @code{nnmail-spool-file}) is + @code{nil}, the mail back ends will never attempt to fetch mail by + themselves. + + 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: + + @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 + + + 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 Back End Variables + @subsection Mail Back End Variables + + These variables are (for the most part) pertinent to all the various + mail back ends. + + @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. + + @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. + + @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 + address@hidden (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: + + @lisp + (add-hook 'nnmail-pre-get-new-mail-hook + (lambda () (set-default-file-modes 511))) + + (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 address@hidden, 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}. + + @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. + + @item nnmail-cache-accepted-message-ids + @vindex nnmail-cache-accepted-message-ids + If address@hidden, 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}. + + @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. + + This can be useful, for example, when using Fancy Splitting + (@pxref{Fancy Mail Splitting}) together with the function + @code{nnmail-split-fancy-with-parent}. + + @end table + + + @node Fancy Mail Splitting + @subsection Fancy Mail Splitting + @cindex mail splitting + @cindex fancy mail splitting + + @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. + + Let's look at an example value of this variable first: + + @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 address@hidden + (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") + ;; @address@hidden + (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) + ;; @r{Unmatched mail goes to the catch all group.} + "misc.misc") + @end lisp + + 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: + + @table @code + + @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 (@var{field} @var{value} [- @var{restrict} address@hidden ] @var{split}) + If the split is a list, the first element of which is a string, then + store the message as specified by @var{split}, if header @var{field} + (a regexp) contains @var{value} (also a regexp). 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 (| @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 (& @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 junk + If the split is the symbol @code{junk}, then don't save (i.e., delete) + this message. Use with extreme caution. + + @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 + (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 + + The buffer is narrowed to 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 t to do that (@pxref{Splitting in + IMAP}). + + @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. + + @item nil + If the split is @code{nil}, it is ignored. + + @end table + + In these splits, @var{field} must match a complete field name. + @var{value} must match a complete word according to the fundamental mode + syntax table. You can use @code{.*} in the regexps to match partial + field names or words. In other words, all @var{value}'s are wrapped in + @samp{\<} and @samp{\>} pairs. + + @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 + + @vindex nnmail-split-fancy-syntax-table + @code{nnmail-split-fancy-syntax-table} is the syntax table in effect + when all this splitting is performed. + + 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: + + @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}. + + 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. + + @vindex nnmail-split-fancy-match-partial-words + @code{nnmail-split-fancy-match-partial-words} controls whether partial + words are matched during fancy splitting. + + Normally, regular expressions given in @code{nnmail-split-fancy} are + implicitly surrounded by @code{\<...\>} markers, which are word + delimiters. If this variable is true, they are not implicitly + surrounded by anything. + + @example + (any "joe" "joemail") + @end example + + In this example, messages sent from @samp{joedavis@@foo.org} will + normally not be filed in @samp{joemail}. With + @code{nnmail-split-fancy-match-partial-words} set to t, however, the + match will happen. In effect, the requirement of a word boundary is + removed and instead the match becomes more like a grep. + + @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 address@hidden + 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 + + This feature works as follows: when @code{nnmail-treat-duplicates} is + address@hidden, 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 address@hidden, Gnus + also records the message ids of moved articles, so that the followup + messages goes into the new group. + + 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. + + + @node Group Mail Splitting + @subsection Group Mail Splitting + @cindex mail splitting + @cindex group mail splitting + + @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. + + 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}. + + 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. + + 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}. + + @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. + + It's time for an example. Assume the following group parameters have + been defined: + + @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 + + 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 + (| (& (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 + + @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 + (: gnus-group-split-fancy @var{groups} @var{no-crosspost} @var{catch-all}) + @end lisp + + @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. + + @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. + + @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}: + + @lisp + (gnus-group-split-setup @var{auto-update} @var{catch-all}) + @end lisp + + If @var{auto-update} is address@hidden, @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. + + @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. + + @node Incorporating Old Mail + @subsection Incorporating Old Mail + @cindex incorporating old mail + @cindex import old mail + + 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. + + Doing so can be quite easy. + + 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. + + Here's how: + + @enumerate + @item + Go to the group buffer. + + @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 + Type @kbd{SPACE} to enter the newly created group. + + @item + Type @kbd{M P b} to process-mark all articles in this group's buffer + (@pxref{Setting Process Marks}). + + @item + Type @kbd{B r} to respool all the process-marked articles, and answer + @samp{nnml} when prompted (@pxref{Mail Group Commands}). + @end enumerate + + 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. + + 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. + + + @node Expiring Mail + @subsection Expiring Mail + @cindex article expiry + + 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. + + 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. + + 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. + + 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.) + + 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 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. + + 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 + (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 + + 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. + + 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 + (setq gnus-auto-expirable-newsgroups + "mail.nonsense-list\\|mail.nice-list") + @end lisp + + Another way to have auto-expiry happen is to have the element + @code{auto-expire} in the group parameters of the group. + + 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. + + @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. + + 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 + (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 + + The group names this function is fed are unadorned'' group + names---no @samp{nnml:} prefixes and the like. + + 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}. + + You can also use the @code{expiry-wait} group parameter to selectively + change the expiry period (@pxref{Group Parameters}). + + @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}. + + Here's an example for specifying a group name: + @lisp + (setq nnmail-expiry-target "nnml:expired") + @end lisp + + @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: + + @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 + + 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}. + + @vindex nnmail-keep-last-article + If @code{nnmail-keep-last-article} is address@hidden, Gnus will never + expire the final article in a mail newsgroup. This is to make life + easier for procmail users. + + @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! + + Most people make most of their mail groups total-expirable, though. + + @vindex gnus-inhibit-user-auto-expire + If @code{gnus-inhibit-user-auto-expire} is address@hidden, user marking + commands will not mark an article as expirable, even if the group has + auto-expire turned on. + + + @node Washing Mail + @subsection Washing Mail + @cindex mail washing + @cindex list server brain damage + @cindex incoming mail treatment + + 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. + + 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. + + 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. + + @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: + + @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 + + @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 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. + + (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.) + + @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{\$$..\$$}. + + For instance, if you want to remove the @samp{(idm)} and the + @samp{nagnagnag} identifiers: + + @lisp + (setq nnmail-list-identifiers + '("(idm)" "nagnagnag")) + @end lisp + + This can also be done non-destructively with + @code{gnus-list-identifiers}, @xref{Article Hiding}. + + @item nnmail-remove-tabs + @findex nnmail-remove-tabs + Translate all @samp{TAB} characters into @samp{SPACE} characters. + + @item nnmail-fix-eudora-headers + @findex nnmail-fix-eudora-headers + @cindex Eudora + Eudora produces broken @code{References} headers, but OK + @code{In-Reply-To} headers. This function will get rid of the + @code{References} headers. + + @end table + + @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 article-de-quoted-unreadable + @findex article-de-quoted-unreadable + Decode Quoted Readable encoding. + + @end table + @end table + + + @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}. + + You can turn this feature off completely by setting the variable to + @code{nil}. + + 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: + + @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 + + 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! + + + @node Not Reading Mail + @subsection Not Reading 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. + + 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 Rmail + file you have stashed away with @code{nnbabyl}. All back ends have + variables called address@hidden 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}. + + All the mail back ends will call @address@hidden + narrowed to the article to be saved before saving it when reading + incoming mail. + + + @node Choosing a Mail Back End + @subsection Choosing a Mail Back End + + 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}). + + @menu + * Unix Mail Box:: Using the (quite) standard Un*x mbox. + * Rmail Babyl:: Emacs programs use the Rmail Babyl format. + * 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 Unix Mail Box + @subsubsection Unix Mail Box + @cindex nnmbox + @cindex unix mail box + + @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. + + Virtual server settings: + + @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 nnmbox-get-new-mail + @vindex nnmbox-get-new-mail + If address@hidden, @code{nnmbox} will read incoming mail and split it + into groups. Default is @code{t}. + @end table + + + @node Rmail Babyl + @subsubsection Rmail Babyl + @cindex nnbabyl + @cindex Rmail mbox + + @vindex nnbabyl-active-file + @vindex nnbabyl-mbox-file + The @dfn{nnbabyl} back end will use a Babyl mail box (aka. @dfn{Rmail + mbox}) to store mail. @code{nnbabyl} will add extra headers to each + mail article to say which group it belongs in. + + Virtual server settings: + + @table @code + @item nnbabyl-mbox-file + @vindex nnbabyl-mbox-file + The name of the Rmail mbox file. The default is @file{~/RMAIL} + + @item nnbabyl-active-file + @vindex nnbabyl-active-file + The name of the active file for the rmail box. The default is + @file{~/.rmail-active} + + @item nnbabyl-get-new-mail + @vindex nnbabyl-get-new-mail + If address@hidden, @code{nnbabyl} will read incoming mail. Default is + @code{t} + @end table + + + @node Mail Spool + @subsubsection Mail Spool + @cindex nnml + @cindex mail @acronym{NOV} spool + + 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. + + @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. + + @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 is 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). + + 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 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}. + + @item nnml-get-new-mail + @vindex nnml-get-new-mail + If address@hidden, @code{nnml} will read incoming mail. The default is + @code{t}. + + @item nnml-nov-is-evil + @vindex nnml-nov-is-evil + If address@hidden, this back end will ignore any @acronym{NOV} files. The + default is @code{nil}. + + @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. + + @item nnml-marks-is-evil + @vindex nnml-marks-is-evil + If address@hidden, this back end will ignore any @sc{marks} files. The + default is @code{nil}. + + @item nnml-marks-file-name + @vindex nnml-marks-file-name + The name of the @dfn{marks} files. The default is @file{.marks}. + + @item nnml-use-compressed-files + @vindex nnml-use-compressed-files + If address@hidden, @code{nnml} will allow using compressed message + files. + + @end table + + @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 MH Spool + @subsubsection MH Spool + @cindex nnmh + @cindex mh-e mail spool + + @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. + + Virtual server settings: + + @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}) + + @item nnmh-get-new-mail + @vindex nnmh-get-new-mail + If address@hidden, @code{nnmh} will read incoming mail. The default is + @code{t}. + + @item nnmh-be-safe + @vindex nnmh-be-safe + If address@hidden, @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 + + + @node Maildir + @subsubsection Maildir + @cindex nnmaildir + @cindex maildir + + @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. + + 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. + + @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. + + Virtual server settings: + + @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. + + 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. + + @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. + + 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}. + + 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). + + 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 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 get-new-mail + If address@hidden, 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 + + @subsubsection Group parameters + + @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. + + 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.) + + @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 (overrideable by + the @code{expiry-wait}(@code{-function}) group parameters. 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 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{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 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 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 distrust-Lines: + If address@hidden, @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 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 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 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 + + @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. + + @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. + + @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.) + + 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. + + + @node Mail Folders + @subsubsection Mail Folders + @cindex nnfolder + @cindex mbox folders + @cindex mail folders + + @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. + + @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 is 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: + + @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}) + + @item nnfolder-active-file + @vindex nnfolder-active-file + The name of the active file. The default is @file{~/Mail/active}. + + @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} + + @item nnfolder-get-new-mail + @vindex nnfolder-get-new-mail + If address@hidden, @code{nnfolder} will read incoming mail. The + default is @code{t} + + @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: + + @lisp + (defun turn-off-backup () + (set (make-local-variable 'backup-inhibited) t)) + + (add-hook 'nnfolder-save-buffer-hook 'turn-off-backup) + @end lisp + + @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 nnfolder-nov-is-evil + @vindex nnfolder-nov-is-evil + If address@hidden, this back end will ignore any @acronym{NOV} files. The + default is @code{nil}. + + @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 address@hidden, this back end will ignore any @sc{marks} files. The + default is @code{nil}. + + @item nnfolder-marks-file-suffix + @vindex nnfolder-marks-file-suffix + The extension for @sc{marks} files. The default is @file{.mrk}. + + @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. + + @end table + + + @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. + + @node Comparing Mail Back Ends + @subsubsection Comparing Mail Back Ends + + 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. + + 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). + + 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: + + @table @code + @item nnmbox + + 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. + + @item nnbabyl + + 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 by Stallman. + + 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 + + @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. + + @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. + + 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. + + @item nnmh + + 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 address@hidden + is considered to be semantically equivalent to address@hidden 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 nnfolder + + 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. + + 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. + + @item nnmaildir + + For configuring expiry and other things, @code{nnmaildir} uses + incompatible group parameters, slightly different from those of other + mail back ends. + + @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, consider switching to + @uref{http://www.namesys.com/, ReiserFS} or another non-block-structured + file system. + + 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. + + @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}. + + @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. + + 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. + + @code{nnmaildir} does not use @code{nnoo}, so you cannot use @code{nnoo} + to write an @code{nnmaildir}-derived back end. + + @end table + + + @node Browsing the Web + @section Browsing the Web + @cindex web + @cindex browsing the web + @cindex www + @cindex http + + 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? + + Gnus has been getting a bit of a collection of back ends for providing + interfaces to these sources. + + @menu + * Archiving Mail:: + * Web Searches:: Creating groups from articles that match a string. + * Slashdot:: Reading the Slashdot comments. + * Ultimate:: The Ultimate Bulletin Board systems. + * Web Archive:: Reading mailing list archived on web. + * RSS:: Reading RDF site summary. + * Customizing w3:: Doing stuff to Emacs/w3 from Gnus. + @end menu + + All the web sources require Emacs/w3 and the url library 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. + + (Preserving the group level and group parameters as well still + requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity + though.) + + 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. + + 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. + + @node Web Searches + @subsection Web Searches + @cindex nnweb + @cindex Google + @cindex dejanews + @cindex gmane + @cindex Usenet searches + @cindex searching the Usenet + + 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. + + 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. + + @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. + + 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'être} 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. + + You must have the @code{url} and @code{w3} package installed to be able + to use @code{nnweb}. + + Virtual server variables: + + @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}. + + @item nnweb-search + @vindex nnweb-search + The search string to feed to the search engine. + + @item nnweb-max-hits + @vindex nnweb-max-hits + Advisory maximum number of hits per search to display. The default is + 999. + + @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: + + @table @code + @item article + Function to decode the article and provide something that Gnus + understands. + + @item map + Function to create an article number to message header and URL alist. + + @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. + + @item id + Format string URL to fetch an article by @code{Message-ID}. + @end table + + @end table + + + @node Slashdot + @subsection Slashdot + @cindex Slashdot + @cindex nnslashdot + + @uref{http://slashdot.org/, Slashdot} is a popular news site, with + lively discussion following the news articles. @code{nnslashdot} will + let you read this forum in a convenient manner. + + The easiest way to read this source is to put something like the + following in your @file{~/.gnus.el} file: + + @lisp + (setq gnus-secondary-select-methods + '((nnslashdot ""))) + @end lisp + + This will make Gnus query the @code{nnslashdot} back end for new comments + and groups. The @kbd{F} command will subscribe each new news article as + a new Gnus group, and you can read the comments by entering these + groups. (Note that the default subscription method is to subscribe new + groups as zombies. Other methods are available (@pxref{Subscription + Methods}). + + If you want to remove an old @code{nnslashdot} group, the @kbd{G DEL} + command is the most handy tool (@pxref{Foreign Groups}). + + When following up to @code{nnslashdot} comments (or posting new + comments), some light @acronym{HTML}izations will be performed. In + particular, text quoted with @samp{> } will be quoted with + @samp{blockquote} instead, and signatures will have @samp{br} added to + the end of each line. Other than that, you can just write @acronym{HTML} + directly into the message buffer. Note that Slashdot filters out some + @acronym{HTML} forms. + + The following variables can be altered to change its behavior: + + @table @code + @item nnslashdot-threaded + Whether @code{nnslashdot} should display threaded groups or not. The + default is @code{t}. To be able to display threads, @code{nnslashdot} + has to retrieve absolutely all comments in a group upon entry. If a + threaded display is not required, @code{nnslashdot} will only retrieve + the comments that are actually wanted by the user. Threading is nicer, + but much, much slower than unthreaded. + + @item nnslashdot-login-name + @vindex nnslashdot-login-name + The login name to use when posting. + + @item nnslashdot-password + @vindex nnslashdot-password + The password to use when posting. + + @item nnslashdot-directory + @vindex nnslashdot-directory + Where @code{nnslashdot} will store its files. The default is + @file{~/News/slashdot/}. + + @item nnslashdot-active-url + @vindex nnslashdot-active-url + The @acronym{URL} format string that will be used to fetch the + information on news articles and comments. The default address@hidden + @samp{http://slashdot.org/search.pl?section=&min=%d}. + + @item nnslashdot-comments-url + @vindex nnslashdot-comments-url + The @acronym{URL} format string that will be used to fetch comments. + + @item nnslashdot-article-url + @vindex nnslashdot-article-url + The @acronym{URL} format string that will be used to fetch the news + article. The default is + @samp{http://slashdot.org/article.pl?sid=%s&mode=nocomment}. + + @item nnslashdot-threshold + @vindex nnslashdot-threshold + The score threshold. The default is -1. + + @item nnslashdot-group-number + @vindex nnslashdot-group-number + The number of old groups, in addition to the ten latest, to keep + updated. The default is 0. + + @end table + + + + @node Ultimate + @subsection Ultimate + @cindex nnultimate + @cindex Ultimate Bulletin Board + + @uref{http://www.ultimatebb.com/, The Ultimate Bulletin Board} is + probably the most popular Web bulletin board system used. It has a + quite regular and nice interface, and it's possible to get the + information Gnus needs to keep groups updated. + + The easiest way to get started with @code{nnultimate} is to say + something like the following in the group buffer: @kbd{B nnultimate RET + http://www.tcj.com/messboard/ubbcgi/ RET}. (Substitute the @acronym{URL} + (not including @samp{Ultimate.cgi} or the like at the end) for a forum + you're interested in; there's quite a list of them on the Ultimate web + site.) Then subscribe to the groups you're interested in from the + server buffer, and read them from the group buffer. + + The following @code{nnultimate} variables can be altered: + + @table @code + @item nnultimate-directory + @vindex nnultimate-directory + The directory where @code{nnultimate} stores its files. The default address@hidden + @file{~/News/ultimate/}. + @end table + + + @node Web Archive + @subsection Web Archive + @cindex nnwarchive + @cindex Web Archive + + Some mailing lists only have archives on Web servers, such as + @uref{http://www.egroups.com/} and + @uref{http://www.mail-archive.com/}. It has a quite regular and nice + interface, and it's possible to get the information Gnus needs to keep + groups updated. + + @findex gnus-group-make-warchive-group + The easiest way to get started with @code{nnwarchive} is to say + something like the following in the group buffer: @kbd{M-x + gnus-group-make-warchive-group RET @var{an_egroup} RET egroups RET + www.egroups.com RET @var{your@@email.address} RET}. (Substitute the + @var{an_egroup} with the mailing list you subscribed, the + @var{your@@email.address} with your email address.), or to browse the + back end by @kbd{B nnwarchive RET mail-archive RET}. + + The following @code{nnwarchive} variables can be altered: + + @table @code + @item nnwarchive-directory + @vindex nnwarchive-directory + The directory where @code{nnwarchive} stores its files. The default address@hidden + @file{~/News/warchive/}. + + @item nnwarchive-login + @vindex nnwarchive-login + The account name on the web server. + + @item nnwarchive-passwd + @vindex nnwarchive-passwd + The password for your account on the web server. + @end table + + @node RSS + @subsection RSS + @cindex nnrss + @cindex RSS + + 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. + + @kindex G R (Summary) + Use @kbd{G R} from the summary buffer to subscribe to a feed---you + will be prompted for the location of the feed. + + An easy way to get started with @code{nnrss} is to say something like + the following in the group buffer: @kbd{B nnrss RET y}, then + subscribe to groups. + + The following @code{nnrss} variables can be altered: + + @table @code + @item nnrss-directory + @vindex nnrss-directory + The directory where @code{nnrss} stores its files. The default is + @file{~/News/rss/}. + + @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 + + The following code may be helpful, if you want to show the description in + the summary buffer. + + @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)) ""))) + @end lisp + + The following code may be useful to open an nnrss url directly from the + summary buffer. + @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)))) + + (eval-after-load "gnus" + #'(define-key gnus-summary-mode-map + (kbd "<RET>") 'browse-nnrss-url)) + (add-to-list 'nnmail-extra-headers nnrss-url-field) + @end lisp + + @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 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. + + 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: + + @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 + + 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 IMAP + @section IMAP + @cindex nnimap + @cindex @acronym{IMAP} + + @acronym{IMAP} is a network protocol for reading mail (or news, or @dots{}), + think of it as a modernized @acronym{NNTP}. Connecting to a @acronym{IMAP} + server is much similar to connecting to a news server, you just + specify the network address of the server. + + @acronym{IMAP} has two properties. First, @acronym{IMAP} can do + everything that @acronym{POP} can, it can hence be viewed as a + @acronym{POP++}. Secondly, @acronym{IMAP} is a mail storage protocol, + similar to @acronym{NNTP} being a news storage protocol---however, + @acronym{IMAP} offers more features than @acronym{NNTP} because news + is more or less read-only whereas mail is read-write. + + If you want to use @acronym{IMAP} as a @acronym{POP++}, use an imap + entry in @code{mail-sources}. With this, Gnus will fetch mails from + the @acronym{IMAP} server and store them on the local disk. This is + not the usage described in this address@hidden Sources}. + + If you want to use @acronym{IMAP} as a mail storage protocol, use an nnimap + entry in @code{gnus-secondary-select-methods}. With this, Gnus will + manipulate mails stored on the @acronym{IMAP} server. This is the kind of + usage explained in this section. + + A server configuration in @file{~/.gnus.el} with a few @acronym{IMAP} + servers might look something like the following. (Note that for + @acronym{TLS}/@acronym{SSL}, you need external programs and libraries, + see below.) + + @lisp + (setq gnus-secondary-select-methods + '((nnimap "simpleserver") ; @r{no special configuration} + ; @r{perhaps a ssh port forwarded server:} + (nnimap "dolk" + (nnimap-address "localhost") + (nnimap-server-port 1430)) + ; @r{a UW server running on localhost} + (nnimap "barbar" + (nnimap-server-port 143) + (nnimap-address "localhost") + (nnimap-list-pattern ("INBOX" "mail/*"))) + ; @r{anonymous public cyrus server:} + (nnimap "cyrus.andrew.cmu.edu" + (nnimap-authenticator anonymous) + (nnimap-list-pattern "archive.*") + (nnimap-stream network)) + ; @r{a ssl server on a non-standard port:} + (nnimap "vic20" + (nnimap-address "vic20.somewhere.com") + (nnimap-server-port 9930) + (nnimap-stream ssl)))) + @end lisp + + After defining the new server, you can subscribe to groups on the + server using normal Gnus commands such as @kbd{U} in the Group Buffer + (@pxref{Subscription Commands}) or via the Server Buffer + (@pxref{Server Buffer}). + + The following variables can be used to create a virtual @code{nnimap} + server: + + @table @code + + @item nnimap-address + @vindex nnimap-address + + The address of the remote @acronym{IMAP} server. Defaults to the virtual + server name if not specified. + + @item nnimap-server-port + @vindex nnimap-server-port + Port on server to contact. Defaults to port 143, or 993 for @acronym{TLS}/@acronym{SSL}. + + Note that this should be an integer, example server specification: + + @lisp + (nnimap "mail.server.com" + (nnimap-server-port 4711)) + @end lisp + + @item nnimap-list-pattern + @vindex nnimap-list-pattern + String or list of strings of mailboxes to limit available groups to. + This is used when the server has very many mailboxes and you're only + interested in a few---some servers export your home directory via + @acronym{IMAP}, you'll probably want to limit the mailboxes to those in + @file{~/Mail/*} then. + + The string can also be a cons of REFERENCE and the string as above, what + REFERENCE is used for is server specific, but on the University of + Washington server it's a directory that will be concatenated with the + mailbox. + + Example server specification: + + @lisp + (nnimap "mail.server.com" + (nnimap-list-pattern ("INBOX" "Mail/*" "alt.sex.*" + ("~friend/Mail/" . "list/*")))) + @end lisp + + @item nnimap-stream + @vindex nnimap-stream + The type of stream used to connect to your server. By default, nnimap + will detect and automatically use all of the below, with the exception + of @acronym{TLS}/@acronym{SSL}. (@acronym{IMAP} over + @acronym{TLS}/@acronym{SSL} is being replaced by STARTTLS, which can + be automatically detected, but it's not widely deployed yet.) + + Example server specification: + + @lisp + (nnimap "mail.server.com" + (nnimap-stream ssl)) + @end lisp + + Please note that the value of @code{nnimap-stream} is a symbol! + + @itemize @bullet + @item + @dfn{gssapi:} Connect with GSSAPI (usually Kerberos 5). Requires the + @samp{gsasl} or @samp{imtest} program. + @item + @dfn{kerberos4:} Connect with Kerberos 4. Requires the @samp{imtest} program. + @item + @dfn{starttls:} Connect via the STARTTLS extension (similar to + @acronym{TLS}/@acronym{SSL}). Requires the external library @samp{starttls.el} and program + @samp{starttls}. + @item + @dfn{tls:} Connect through @acronym{TLS}. Requires GNUTLS (the program + @samp{gnutls-cli}). + @item + @dfn{ssl:} Connect through @acronym{SSL}. Requires OpenSSL (the program + @samp{openssl}) or SSLeay (@samp{s_client}). + @item + @dfn{shell:} Use a shell command to start @acronym{IMAP} connection. + @item + @dfn{network:} Plain, TCP/IP network connection. + @end itemize + + @vindex imap-kerberos4-program + The @samp{imtest} program is shipped with Cyrus IMAPD. If you're + using @samp{imtest} from Cyrus IMAPD < 2.0.14 (which includes version + 1.5.x and 1.6.x) you need to frob @code{imap-process-connection-type} + to make @code{imap.el} use a pty instead of a pipe when communicating + with @samp{imtest}. You will then suffer from a line length + restrictions on @acronym{IMAP} commands, which might make Gnus seem to hang + indefinitely if you have many articles in a mailbox. The variable + @code{imap-kerberos4-program} contain parameters to pass to the imtest + program. + + For @acronym{TLS} connection, the @code{gnutls-cli} program from GNUTLS is + needed. It is available from + @uref{http://www.gnu.org/software/gnutls/}. + + @vindex imap-gssapi-program + This parameter specifies a list of command lines that invoke a GSSAPI + authenticated @acronym{IMAP} stream in a subshell. They are tried + sequentially until a connection is made, or the list has been + exhausted. By default, @samp{gsasl} from GNU SASL, available from + @uref{http://www.gnu.org/software/gsasl/}, and the @samp{imtest} + program from Cyrus IMAPD (see @code{imap-kerberos4-program}), are + tried. + + @vindex imap-ssl-program + For @acronym{SSL} connections, the OpenSSL program is available from + @uref{http://www.openssl.org/}. OpenSSL was formerly known as SSLeay, + and nnimap support it too---although the most recent versions of + SSLeay, 0.9.x, are known to have serious bugs making it + useless. Earlier versions, especially 0.8.x, of SSLeay are known to + work. The variable @code{imap-ssl-program} contain parameters to pass + to OpenSSL/SSLeay. + + @vindex imap-shell-program + @vindex imap-shell-host + For @acronym{IMAP} connections using the @code{shell} stream, the variable + @code{imap-shell-program} specify what program to call. + + @item nnimap-authenticator + @vindex nnimap-authenticator + + The authenticator used to connect to the server. By default, nnimap + will use the most secure authenticator your server is capable of. + + Example server specification: + + @lisp + (nnimap "mail.server.com" + (nnimap-authenticator anonymous)) + @end lisp + + Please note that the value of @code{nnimap-authenticator} is a symbol! + + @itemize @bullet + @item + @dfn{gssapi:} GSSAPI (usually kerberos 5) authentication. Requires + external program @code{gsasl} or @code{imtest}. + @item + @dfn{kerberos4:} Kerberos 4 authentication. Requires external program + @code{imtest}. + @item + @dfn{digest-md5:} Encrypted username/password via DIGEST-MD5. Requires + external library @code{digest-md5.el}. + @item + @dfn{cram-md5:} Encrypted username/password via CRAM-MD5. + @item + @dfn{login:} Plain-text username/password via LOGIN. + @item + @dfn{anonymous:} Login as anonymous'', supplying your email address as password. + @end itemize + + @item nnimap-expunge-on-close + @cindex expunging + @vindex nnimap-expunge-on-close + Unlike Parmenides the @acronym{IMAP} designers have decided things that + don't exist actually do exist. More specifically, @acronym{IMAP} has + this concept of marking articles @code{Deleted} which doesn't actually + delete them, and this (marking them @code{Deleted}, that is) is what + nnimap does when you delete an article in Gnus (with @kbd{B DEL} or + similar). + + Since the articles aren't really removed when we mark them with the + @code{Deleted} flag we'll need a way to actually delete them. Feel like + running in circles yet? + + Traditionally, nnimap has removed all articles marked as @code{Deleted} + when closing a mailbox but this is now configurable by this server + variable. + + The possible options are: + + @table @code + + @item always + The default behavior, delete all articles marked as Deleted'' when + closing a mailbox. + @item never + Never actually delete articles. Currently there is no way of showing + the articles marked for deletion in nnimap, but other @acronym{IMAP} clients + may allow you to do this. If you ever want to run the EXPUNGE command + manually, @xref{Expunging mailboxes}. + @item ask + When closing mailboxes, nnimap will ask if you wish to expunge deleted + articles or not. + + @end table + + @item nnimap-importantize-dormant + @vindex nnimap-importantize-dormant + + If address@hidden (the default), marks dormant articles as ticked (as + well), for other @acronym{IMAP} clients. Within Gnus, dormant articles will + naturally still (only) be marked as dormant. This is to make dormant + articles stand out, just like ticked articles, in other @acronym{IMAP} + clients. (In other words, Gnus has two Tick'' marks and @acronym{IMAP} + has only one.) + + Probably the only reason for frobing this would be if you're trying + enable per-user persistent dormant flags, using something like: + + @lisp + (setcdr (assq 'dormant nnimap-mark-to-flag-alist) + (format "gnus-dormant-%s" (user-login-name))) + (setcdr (assq 'dormant nnimap-mark-to-predicate-alist) + (format "KEYWORD gnus-dormant-%s" (user-login-name))) + @end lisp + + In this case, you would not want the per-user dormant flag showing up + as ticked for other users. + + @item nnimap-expunge-search-string + @cindex expunging + @vindex nnimap-expunge-search-string + + This variable contain the @acronym{IMAP} search command sent to server when + searching for articles eligible for expiring. The default is + @code{"UID %s NOT SINCE %s"}, where the first @code{%s} is replaced by + UID set and the second @code{%s} is replaced by a date. + + Probably the only useful value to change this to is + @code{"UID %s NOT SENTSINCE %s"}, which makes nnimap use the Date: in + messages instead of the internal article date. See section 6.4.4 of + RFC 2060 for more information on valid strings. + + @item nnimap-authinfo-file + @vindex nnimap-authinfo-file + + A file containing credentials used to log in on servers. The format is + (almost) the same as the @code{ftp} @file{~/.netrc} file. See the + variable @code{nntp-authinfo-file} for exact syntax; also see + @ref{NNTP}. + + @item nnimap-need-unselect-to-notice-new-mail + @vindex nnimap-need-unselect-to-notice-new-mail + + Unselect mailboxes before looking for new mail in them. Some servers + seem to need this under some circumstances; it was reported that + Courier 1.7.1 did. + + @end table + + @menu + * Splitting in IMAP:: Splitting mail with nnimap. + * Expiring in IMAP:: Expiring mail with nnimap. + * Editing IMAP ACLs:: Limiting/enabling other users access to a mailbox. + * Expunging mailboxes:: Equivalent of a compress mailbox'' button. + * A note on namespaces:: How to (not) use @acronym{IMAP} namespace in Gnus. + * Debugging IMAP:: What to do when things don't work. + @end menu + + + + @node Splitting in IMAP + @subsection Splitting in IMAP + @cindex splitting imap mail + + Splitting is something Gnus users have loved and used for years, and now + the rest of the world is catching up. Yeah, dream on, not many + @acronym{IMAP} servers have server side splitting and those that have + splitting seem to use some non-standard protocol. This means that + @acronym{IMAP} support for Gnus has to do its own splitting. + + And it does. + + (Incidentally, people seem to have been dreaming on, and Sieve has + gaining a market share and is supported by several IMAP servers. + Fortunately, Gnus support it too, @xref{Sieve Commands}.) + + Here are the variables of interest: + + @table @code + + @item nnimap-split-crosspost + @cindex splitting, crosspost + @cindex crosspost + @vindex nnimap-split-crosspost + + If address@hidden, do crossposting if several split methods match the + mail. If @code{nil}, the first match in @code{nnimap-split-rule} + found will be used. + + Nnmail equivalent: @code{nnmail-crosspost}. + + @item nnimap-split-inbox + @cindex splitting, inbox + @cindex inbox + @vindex nnimap-split-inbox + + A string or a list of strings that gives the name(s) of @acronym{IMAP} + mailboxes to split from. Defaults to @code{nil}, which means that + splitting is disabled! + + @lisp + (setq nnimap-split-inbox + '("INBOX" ("~/friend/Mail" . "lists/*") "lists.imap")) + @end lisp + + No nnmail equivalent. + + @item nnimap-split-rule + @cindex splitting, rules + @vindex nnimap-split-rule + + New mail found in @code{nnimap-split-inbox} will be split according to + this variable. + + This variable contains a list of lists, where the first element in the + sublist gives the name of the @acronym{IMAP} mailbox to move articles + matching the regexp in the second element in the sublist. Got that? + Neither did I, we need examples. + + @lisp + (setq nnimap-split-rule + '(("INBOX.nnimap" + "^Sender: owner-nnimap@@vic20.globalcom.se") + ("INBOX.junk" "^Subject:.*MAKE MONEY") + ("INBOX.private" ""))) + @end lisp + + This will put all articles from the nnimap mailing list into mailbox + INBOX.nnimap, all articles containing MAKE MONEY in the Subject: line + into INBOX.junk and everything else in INBOX.private. + + The first string may contain @samp{\\1} forms, like the ones used by + replace-match to insert sub-expressions from the matched text. For + instance: + + @lisp + ("INBOX.lists.\\1" "^Sender: owner-\$$[a-z-]+\$$@@") + @end lisp + + The first element can also be the symbol @code{junk} to indicate that + matching messages should simply be deleted. Use with care. + + The second element can also be a function. In that case, it will be + called with the first element of the rule as the argument, in a buffer + containing the headers of the article. It should return a + address@hidden value if it thinks that the mail belongs in that group. + + Nnmail users might recollect that the last regexp had to be empty to + match all articles (like in the example above). This is not required in + nnimap. Articles not matching any of the regexps will not be moved out + of your inbox. (This might affect performance if you keep lots of + unread articles in your inbox, since the splitting code would go over + them every time you fetch new mail.) + + 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''. + + This variable can also have a function as its value, the function will + be called with the headers narrowed and should return a group where it + thinks the article should be split to. See @code{nnimap-split-fancy}. + + The splitting code tries to create mailboxes if it needs to. + + To allow for different split rules on different virtual servers, and + even different split rules in different inboxes on the same server, + the syntax of this variable have been extended along the lines of: + + @lisp + (setq nnimap-split-rule + '(("my1server" (".*" (("ding" "ding@@gnus.org") + ("junk" "From:.*Simon")))) + ("my2server" ("INBOX" nnimap-split-fancy)) + ("my[34]server" (".*" (("private" "To:.*Simon") + ("junk" my-junk-func)))))) + @end lisp + + The virtual server name is in fact a regexp, so that the same rules + may apply to several servers. In the example, the servers + @code{my3server} and @code{my4server} both use the same rules. + Similarly, the inbox string is also a regexp. The actual splitting + rules are as before, either a function, or a list with group/regexp or + group/function elements. + + Nnmail equivalent: @code{nnmail-split-methods}. + + @item nnimap-split-predicate + @cindex splitting + @vindex nnimap-split-predicate + + Mail matching this predicate in @code{nnimap-split-inbox} will be + split, it is a string and the default is @samp{UNSEEN UNDELETED}. + + This might be useful if you use another @acronym{IMAP} client to read mail in + your inbox but would like Gnus to split all articles in the inbox + regardless of readedness. Then you might change this to + @samp{UNDELETED}. + + @item nnimap-split-fancy + @cindex splitting, fancy + @findex nnimap-split-fancy + @vindex nnimap-split-fancy + + It's possible to set @code{nnimap-split-rule} to + @code{nnmail-split-fancy} if you want to use fancy + splitting. @xref{Fancy Mail Splitting}. + + However, to be able to have different fancy split rules for nnmail and + nnimap back ends you can set @code{nnimap-split-rule} to + @code{nnimap-split-fancy} and define the nnimap specific fancy split + rule in @code{nnimap-split-fancy}. + + Example: + + @lisp + (setq nnimap-split-rule 'nnimap-split-fancy + nnimap-split-fancy ...) + @end lisp + + Nnmail equivalent: @code{nnmail-split-fancy}. + + @item nnimap-split-download-body + @findex nnimap-split-download-body + @vindex nnimap-split-download-body + + Set to address@hidden to download entire articles during splitting. + This is generally not required, and will slow things down + considerably. You may need it if you want to use an advanced + splitting function that analyses the body to split the article. + + @end table + + @node Expiring in IMAP + @subsection Expiring in IMAP + @cindex expiring imap mail + + Even though @code{nnimap} is not a proper @code{nnmail} derived back + end, it supports most features in regular expiring (@pxref{Expiring + Mail}). Unlike splitting in @acronym{IMAP} (@pxref{Splitting in + IMAP}) it does not clone the @code{nnmail} variables (i.e., creating + @var{nnimap-expiry-wait}) but reuse the @code{nnmail} variables. What + follows below are the variables used by the @code{nnimap} expiry + process. + + A note on how the expire mark is stored on the @acronym{IMAP} server is + appropriate here as well. The expire mark is translated into a + @code{imap} client specific mark, @code{gnus-expire}, and stored on the + message. This means that likely only Gnus will understand and treat + the @code{gnus-expire} mark properly, although other clients may allow + you to view client specific flags on the message. It also means that + your server must support permanent storage of client specific flags on + messages. Most do, fortunately. + + @table @code + + @item nnmail-expiry-wait + @item nnmail-expiry-wait-function + + These variables are fully supported. The expire value can be a + number, the symbol @code{immediate} or @code{never}. + + @item nnmail-expiry-target + + This variable is supported, and internally implemented by calling the + @code{nnmail} functions that handle this. It contains an optimization + that if the destination is a @acronym{IMAP} group on the same server, the + article is copied instead of appended (that is, uploaded again). + + @end table + + @node Editing IMAP ACLs + @subsection Editing IMAP ACLs + @cindex editing imap acls + @cindex Access Control Lists + @cindex Editing @acronym{IMAP} ACLs + @kindex G l (Group) + @findex gnus-group-nnimap-edit-acl + + ACL stands for Access Control List. ACLs are used in @acronym{IMAP} for + limiting (or enabling) other users access to your mail boxes. Not all + @acronym{IMAP} servers support this, this function will give an error if it + doesn't. + + To edit an ACL for a mailbox, type @kbd{G l} + (@code{gnus-group-edit-nnimap-acl}) and you'll be presented with an ACL + editing window with detailed instructions. + + Some possible uses: + + @itemize @bullet + @item + Giving anyone'' the lrs'' rights (lookup, read, keep seen/unseen flags) + on your mailing list mailboxes enables other users on the same server to + follow the list without subscribing to it. + @item + At least with the Cyrus server, you are required to give the user + anyone'' posting ("p") capabilities to have plussing'' work (that is, + mail sent to user+mailbox@@domain ending up in the @acronym{IMAP} mailbox + INBOX.mailbox). + @end itemize + + @node Expunging mailboxes + @subsection Expunging mailboxes + @cindex expunging + + @cindex expunge + @cindex manual expunging + @kindex G x (Group) + @findex gnus-group-nnimap-expunge + + If you're using the @code{never} setting of @code{nnimap-expunge-on-close}, + you may want the option of expunging all deleted articles in a mailbox + manually. This is exactly what @kbd{G x} does. + + Currently there is no way of showing deleted articles, you can just + delete them. + + @node A note on namespaces + @subsection A note on namespaces + @cindex IMAP namespace + @cindex namespaces + + The @acronym{IMAP} protocol has a concept called namespaces, described + by the following text in the RFC: + + @display + 5.1.2. Mailbox Namespace Naming Convention + + By convention, the first hierarchical element of any mailbox name + which begins with "#" identifies the "namespace" of the remainder of + the name. This makes it possible to disambiguate between different + types of mailbox stores, each of which have their own namespaces. + + For example, implementations which offer access to USENET + newsgroups MAY use the "#news" namespace to partition the USENET + newsgroup namespace from that of other mailboxes. Thus, the + comp.mail.misc newsgroup would have an mailbox name of + "#news.comp.mail.misc", and the name "comp.mail.misc" could refer + to a different object (e.g. a user's private mailbox). + @end display + + While there is nothing in this text that warrants concern for the + @acronym{IMAP} implementation in Gnus, some servers use namespace + prefixes in a way that does not work with how Gnus uses mailbox names. + + Specifically, University of Washington's @acronym{IMAP} server uses + mailbox names like @code{#driver.mbx/read-mail} which are valid only + in the @sc{create} and @sc{append} commands. After the mailbox is + created (or a messages is appended to a mailbox), it must be accessed + without the namespace prefix, i.e. @code{read-mail}. Since Gnus do + not make it possible for the user to guarantee that user entered + mailbox names will only be used with the CREATE and APPEND commands, + you should simply not use the namespace prefixed mailbox names in + Gnus. + + See the UoW IMAPD documentation for the @code{#driver.*/} prefix + for more information on how to use the prefixes. They are a power + tool and should be used only if you are sure what the effects are. + + @node Debugging IMAP + @subsection Debugging IMAP + @cindex IMAP debugging + @cindex protocol dump (IMAP) + + @acronym{IMAP} is a complex protocol, more so than @acronym{NNTP} or + @acronym{POP3}. Implementation bugs are not unlikely, and we do our + best to fix them right away. If you encounter odd behaviour, chances + are that either the server or Gnus is buggy. + + If you are familiar with network protocols in general, you will + probably be able to extract some clues from the protocol dump of the + exchanges between Gnus and the server. Even if you are not familiar + with network protocols, when you include the protocol dump in + @acronym{IMAP}-related bug reports you are helping us with data + critical to solving the problem. Therefore, we strongly encourage you + to include the protocol dump when reporting IMAP bugs in Gnus. + + + @vindex imap-log + Because the protocol dump, when enabled, generates lots of data, it is + disabled by default. You can enable it by setting @code{imap-log} as + follows: + + @lisp + (setq imap-log t) + @end lisp + + This instructs the @code{imap.el} package to log any exchanges with + the server. The log is stored in the buffer @samp{*imap-log*}. Look + for error messages, which sometimes are tagged with the keyword + @code{BAD} - but when submitting a bug, make sure to include all the + data. + + @node Other Sources + @section Other Sources + + 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. + * SOUP:: Reading @sc{soup} packets offline''. + * Mail-To-News Gateways:: Posting articles via mail-to-news gateways. + @end menu + + + @node Directory Groups + @subsection Directory Groups + @cindex nndir + @cindex directory groups + + 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. + + 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. + + @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! + + @code{nndir} will use @acronym{NOV} files if they are present. + + @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}. + + + @node Anything Groups + @subsection Anything Groups + @cindex nneething + + 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. + + 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. + + 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. + + 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. + + 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. + + 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/}. + + @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. + + @item nneething-include-files + @vindex nneething-include-files + Regexp saying what files to include in the group. If this variable is + address@hidden, only files matching this regexp will be included. + + @item nneething-map-file + @vindex nneething-map-file + Name of the map files. + @end table + + + @node Document Groups + @subsection Document Groups + @cindex nndoc + @cindex documentation group + @cindex help group + + @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 + @cindex Babyl + @cindex Rmail mbox + + @item babyl + The Babyl (Rmail) mail box. + @cindex mbox + @cindex Unix mbox + + @item mbox + The standard Unix mbox file. + + @cindex MMDF mail box + @item mmdf + The MMDF mail box format. + + @item news + Several news articles appended into a file. + + @item rnews + @cindex rnews batch files + The rnews batch transport format. + @cindex forwarded messages + + @item forward + Forwarded articles. + + @item nsmail + Netscape mail boxes. + + @item mime-parts + @acronym{MIME} multipart messages. + + @item standard-digest + The standard (RFC 1153) digest format. + + @item mime-digest + A @acronym{MIME} digest of messages. + + @item lanl-gov-announce + Announcement messages from LANL Gov Announce. + + @item rfc822-forward + A message forwarded according to RFC822. + + @item outlook + The Outlook mail box. + + @item oe-dbx + The Outlook Express dbx mail box. + + @item exim-bounce + A bounce message from the Exim MTA. + + @item forward + A message forwarded according to informal rules. + + @item rfc934 + An RFC934-forwarded message. + + @item mailman + A mailman digest. + + @item clari-briefs + A digest of Clarinet brief news items. + + @item slack-digest + Non-standard digest format---matches most things, but does it badly. + + @item mail-in-mail + The last resort. + @end table + + 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. + + @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. + + 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! + + 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}. + + @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 Document Server Internals + @subsubsection Document Server Internals + + 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}. + + First, here's an example document type definition: + + @example + (mmdf + (article-begin . "^\^A\^A\^A\^A\n") + (body-end . "^\^A\^A\^A\^A\n")) + @end example + + 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: + + @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 article-begin + This setting has to be present in all document type definitions. It + says what the beginning of each article looks like. + + @item head-begin-function + If present, this should be a function that moves point to the head of + the article. + + @item nndoc-head-begin + If present, this should be a regexp that matches the head of the + article. + + @item nndoc-head-end + This should match the end of the head of the article. It defaults to + @samp{^$}---the empty line.
+
+ @item body-begin-function
+ If present, this function should move point to the beginning of the body
+ of the article.
+
+ @item body-begin
+ This should match the beginning of the body of the article.  It defaults
+ to @samp{^\n}.
+
+ @item body-end-function
+ If present, this function should move point to the end of the body of
+ the article.
+
+ @item body-end
+ If present, this should match the end of the body of the article.
+
+ @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.
+
+ @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.
+
+ 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.
+
+ @end table
+
+ Let's look at the most complicated example I can come up with---standard
+ digests:
+
+ @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
+
+ 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.
+
+ 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
+ @address@hidden 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.
+
+
+ @node SOUP
+ @subsection SOUP
+ @cindex SOUP
+ @cindex offline
+
+ In the PC world people often talk about offline'' newsreaders.  These
+ are thingies that are combined reader/news transport monstrosities.
+ With built-in modem programs.  Yecchh!
+
+ Of course, us Unix Weenie types of human beans use things like
+ @code{uucp} and, like, @code{nntpd} and set up proper news and mail
+ transport things like Ghod intended.  And then we just use normal
+
+ However, it can sometimes be convenient to do something that's a bit
+ easier on the brain if you have a very slow modem, and you're not really
+ that interested in doing things properly.
+
+ A file format called @sc{soup} has been developed for transporting news
+ and mail from servers to home machines and back again.  It can be a bit
+ fiddly.
+
+ First some terminology:
+
+ @table @dfn
+
+ @item server
+ This is the machine that is connected to the outside world and where you
+ get news and/or mail from.
+
+ @item home machine
+ This is the machine that you want to do the actual reading and responding
+ on.  It is typically not connected to the rest of the world in any way.
+
+ @item packet
+ Something that contains messages and/or commands.  There are two kinds
+ of packets:
+
+ @table @dfn
+ @item message packets
+ These are packets made at the server, and typically contain lots of
+ messages for you to read.  These are called @file{SoupoutX.tgz} by
+ default, where @var{x} is a number.
+
+ @item response packets
+ These are packets made at the home machine, and typically contains
+ replies that you've written.  These are called @file{SoupinX.tgz} by
+ default, where @var{x} is a number.
+
+ @end table
+
+ @end table
+
+
+ @enumerate
+
+ @item
+ You log in on the server and create a @sc{soup} packet.  You can either
+ use a dedicated @sc{soup} thingie (like the @code{awk} program), or you
+ can use Gnus to create the packet with its @sc{soup} commands (@kbd{O
+ s} and/or @kbd{G s b}; and then @kbd{G s p}) (@pxref{SOUP Commands}).
+
+ @item
+ You transfer the packet home.  Rail, boat, car or modem will do fine.
+
+ @item
+ You put the packet in your home directory.
+
+ @item
+ You fire up Gnus on your home machine using the @code{nnsoup} back end as
+ the native or secondary server.
+
+ @item
+ You read articles and mail and answer and followup to the things you
+ want (@pxref{SOUP Replies}).
+
+ @item
+ You do the @kbd{G s r} command to pack these replies into a @sc{soup}
+ packet.
+
+ @item
+ You transfer this packet to the server.
+
+ @item
+ You use Gnus to mail this packet out with the @kbd{G s s} command.
+
+ @item
+ You then repeat until you die.
+
+ @end enumerate
+
+ So you basically have a bipartite system---you use @code{nnsoup} for
+ reading and Gnus for packing/sending these @sc{soup} packets.
+
+ * SOUP Commands::               Commands for creating and sending @sc{soup}
packets
+ * SOUP Groups::                 A back end for reading @sc{soup} packets.
+ * SOUP Replies::                How to enable @code{nnsoup} to take over mail
and news.
+
+
+ @node SOUP Commands
+ @subsubsection SOUP Commands
+
+ These are commands for creating and manipulating @sc{soup} packets.
+
+ @table @kbd
+ @item G s b
+ @kindex G s b (Group)
+ @findex gnus-group-brew-soup
+ Pack all unread articles in the current group
+ (@code{gnus-group-brew-soup}).  This command understands the
+ process/prefix convention.
+
+ @item G s w
+ @kindex G s w (Group)
+ @findex gnus-soup-save-areas
+ Save all @sc{soup} data files (@code{gnus-soup-save-areas}).
+
+ @item G s s
+ @kindex G s s (Group)
+ @findex gnus-soup-send-replies
+ Send all replies from the replies packet
+ (@code{gnus-soup-send-replies}).
+
+ @item G s p
+ @kindex G s p (Group)
+ @findex gnus-soup-pack-packet
+ Pack all files into a @sc{soup} packet (@code{gnus-soup-pack-packet}).
+
+ @item G s r
+ @kindex G s r (Group)
+ @findex nnsoup-pack-replies
+ Pack all replies into a replies packet (@code{nnsoup-pack-replies}).
+
+ @item O s
+ @kindex O s (Summary)
+ This summary-mode command adds the current article to a @sc{soup} packet
+ (@code{gnus-soup-add-article}).  It understands the process/prefix
+ convention (@pxref{Process/Prefix}).
+
+ @end table
+
+
+ There are a few variables to customize where Gnus will put all these
+ thingies:
+
+ @table @code
+
+ @item gnus-soup-directory
+ @vindex gnus-soup-directory
+ Directory where Gnus will save intermediate files while composing
+ @sc{soup} packets.  The default is @file{~/SoupBrew/}.
+
+ @item gnus-soup-replies-directory
+ @vindex gnus-soup-replies-directory
+ This is what Gnus will use as a temporary directory while sending our
+ reply packets.  @file{~/SoupBrew/SoupReplies/} is the default.
+
+ @item gnus-soup-prefix-file
+ @vindex gnus-soup-prefix-file
+ Name of the file where Gnus stores the last used prefix.  The default is
+ @samp{gnus-prefix}.
+
+ @item gnus-soup-packer
+ @vindex gnus-soup-packer
+ A format string command for packing a @sc{soup} packet.  The default is
+ @samp{tar cf - %s | gzip > $HOME/Soupout%d.tgz}. + + @item gnus-soup-unpacker + @vindex gnus-soup-unpacker + Format string command for unpacking a @sc{soup} packet. The default is + @samp{gunzip -c %s | tar xvf -}. + + @item gnus-soup-packet-directory + @vindex gnus-soup-packet-directory + Where Gnus will look for reply packets. The default is @file{~/}. + + @item gnus-soup-packet-regexp + @vindex gnus-soup-packet-regexp + Regular expression matching @sc{soup} reply packets in + @code{gnus-soup-packet-directory}. + + @end table + + + @node SOUP Groups + @subsubsection SOUP Groups + @cindex nnsoup + + @code{nnsoup} is the back end for reading @sc{soup} packets. It will + read incoming packets, unpack them, and put them in a directory where + you can read them at leisure. + + These are the variables you can use to customize its behavior: + + @table @code + + @item nnsoup-tmp-directory + @vindex nnsoup-tmp-directory + When @code{nnsoup} unpacks a @sc{soup} packet, it does it in this + directory. (@file{/tmp/} by default.) + + @item nnsoup-directory + @vindex nnsoup-directory + @code{nnsoup} then moves each message and index file to this directory. + The default is @file{~/SOUP/}. + + @item nnsoup-replies-directory + @vindex nnsoup-replies-directory + All replies will be stored in this directory before being packed into a + reply packet. The default is @file{~/SOUP/replies/}. + + @item nnsoup-replies-format-type + @vindex nnsoup-replies-format-type + The @sc{soup} format of the replies packets. The default is @samp{?n} + (rnews), and I don't think you should touch that variable. I probably + shouldn't even have documented it. Drats! Too late! + + @item nnsoup-replies-index-type + @vindex nnsoup-replies-index-type + The index type of the replies packet. The default is @samp{?n}, which + means none''. Don't fiddle with this one either! + + @item nnsoup-active-file + @vindex nnsoup-active-file + Where @code{nnsoup} stores lots of information. This is not an active + file'' in the @code{nntp} sense; it's an Emacs Lisp file. If you lose + this file or mess it up in any way, you're dead. The default is + @file{~/SOUP/active}. + + @item nnsoup-packer + @vindex nnsoup-packer + Format string command for packing a reply @sc{soup} packet. The default + is @samp{tar cf - %s | gzip >$HOME/Soupin%d.tgz}.
+
+ @item nnsoup-unpacker
+ @vindex nnsoup-unpacker
+ Format string command for unpacking incoming @sc{soup} packets.  The
+ default is @samp{gunzip -c %s | tar xvf -}.
+
+ @item nnsoup-packet-directory
+ @vindex nnsoup-packet-directory
+ Where @code{nnsoup} will look for incoming packets.  The default is
+ @file{~/}.
+
+ @item nnsoup-packet-regexp
+ @vindex nnsoup-packet-regexp
+ Regular expression matching incoming @sc{soup} packets.  The default is
+ @samp{Soupout}.
+
+ @item nnsoup-always-save
+ @vindex nnsoup-always-save
+ If address@hidden, save the replies buffer after each posted message.
+
+ @end table
+
+
+ @node SOUP Replies
+ @subsubsection SOUP Replies
+
+ Just using @code{nnsoup} won't mean that your postings and mailings end
+ up in @sc{soup} reply packets automagically.  You have to work a bit
+ more for that to happen.
+
+ @findex nnsoup-set-variables
+ The @code{nnsoup-set-variables} command will set the appropriate
+ variables to ensure that all your followups and replies end up in the
+ @sc{soup} system.
+
+ In specific, this is what it does:
+
+ @lisp
+ (setq message-send-news-function 'nnsoup-request-post)
+ (setq message-send-mail-function 'nnsoup-request-mail)
+ @end lisp
+
+ And that's it, really.  If you only want news to go into the @sc{soup}
+ system you just use the first line.  If you only want mail to be
+ @sc{soup}ed you use the second.
+
+
+ @node Mail-To-News Gateways
+ @subsection Mail-To-News Gateways
+ @cindex mail-to-news gateways
+ @cindex gateways
+
+ 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.
+
+ Note that you can't read anything from this back end---it can only be
+ used to post with.
+
+ Server variables:
+
+ @table @code
+ This is the address of the mail-to-news gateway.
+
+ 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
+
+ This default function just inserts a new @code{To} header based on the
+ For instance, an article with this @code{Newsgroups} header:
+
+ @example
+ Newsgroups: alt.religion.emacs
+ @end example
+
+ will get this @code{To} header inserted:
+
+ @example
+ To: alt-religion-emacs@@GATEWAY
+ @end example
+
+ The following pre-defined functions exist:
+
+ @table @code
+
+ Creates a @code{To} header that looks like
+
+
+ Creates a @code{To} header that looks like
+ @end table
+
+ @end table
+
+ Here's an example:
+
+ @lisp
+ (setq gnus-post-method
+       '(nngateway
+         "mail2news@@replay.com"
+ @end lisp
+
+ So, to use this, simply say something like:
+
+ @lisp
+ @end lisp
+
+
+
+ @node Combined Groups
+ @section Combined Groups
+
+ Gnus allows combining a mixture of all the other group types into bigger
+ groups.
+
+ * Virtual Groups::              Combining articles from many groups.
+ * Kibozed Groups::              Looking through parts of the newsfeed for
articles.
+
+
+ @node Virtual Groups
+ @subsection Virtual Groups
+ @cindex nnvirtual
+ @cindex virtual groups
+ @cindex merging groups
+
+ An @dfn{nnvirtual group} is really nothing more than a collection of
+ other groups.
+
+ 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!
+
+ You specify @code{nnvirtual} as the method.  The address should be a
+ regexp to match component groups.
+
+ 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})
+
+ Here's an example @code{nnvirtual} method that collects all Andrea Dworkin
+ newsgroups into one, big, happy newsgroup:
+
+ @lisp
+ (nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*") + @end lisp + + The component groups can be native or foreign; everything should work + smoothly, but if your computer explodes, it was probably my fault. + + 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: + + @example + "^nntp\\+server\\.jp:soc\\.motss$\\|^nntp\\+server\\.no:soc\\.motss$" + @end example + + (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.) + + 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}). + + 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. + + @vindex nnvirtual-always-rescan + If the @code{nnvirtual-always-rescan} is address@hidden, + @code{nnvirtual} will always scan groups for unread articles when + entering a virtual group. If this variable is @code{nil} (which is the + default) 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. + + @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.) + + @kbd{C-c C-n} in the message buffer will insert the @code{Newsgroups} + line from the article you respond to in these cases. + + @code{nnvirtual} groups do not inherit anything but articles and marks + from component groups---group parameters, for instance, are not + inherited. + + + @node Kibozed Groups + @subsection Kibozed Groups + @cindex nnkiboze + @cindex kibozing + + @dfn{Kibozing} is defined by the @acronym{OED} as grepping through + (parts of) the news feed''. @code{nnkiboze} is a back end that will + do this for you. Oh joy! Now you can grind any @acronym{NNTP} server + down to a halt with useless requests! Oh happiness! + + @kindex G k (Group) + To create a kibozed group, use the @kbd{G k} command in the group + buffer. + + The address field of the @code{nnkiboze} method is, as with + @code{nnvirtual}, a regexp to match groups to be included'' in the + @code{nnkiboze} group. That's where most similarities between + @code{nnkiboze} and @code{nnvirtual} end. + + In addition to this regexp detailing component groups, an + @code{nnkiboze} group must have a score file to say what articles are + to be included in the group (@pxref{Scoring}). + + @kindex M-x nnkiboze-generate-groups + @findex nnkiboze-generate-groups + You must run @kbd{M-x nnkiboze-generate-groups} after creating the + @code{nnkiboze} groups you want to have. This command will take time. + Lots of time. Oodles and oodles of time. Gnus has to fetch the + headers from all the articles in all the component groups and run them + through the scoring process to determine if there are any articles in + the groups that are to be part of the @code{nnkiboze} groups. + + Please limit the number of component groups by using restrictive + regexps. Otherwise your sysadmin may become annoyed with you, and the + @acronym{NNTP} site may throw you off and never let you back in again. + Stranger things have happened. + + @code{nnkiboze} component groups do not have to be alive---they can be dead, + and they can be foreign. No restrictions. + + @vindex nnkiboze-directory + The generation of an @code{nnkiboze} group means writing two files in + @code{nnkiboze-directory}, which is @file{~/News/kiboze/} by default. + One contains the @acronym{NOV} header lines for all the articles in + the group, and the other is an additional @file{.newsrc} file to store + information on what groups have been searched through to find + component articles. + + Articles marked as read in the @code{nnkiboze} group will have + their @acronym{NOV} lines removed from the @acronym{NOV} file. + + + @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. + + 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. + + 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. + + Setting up Gnus as an offline'' newsreader is quite simple. In + fact, you don't even have to configure anything. + + Of course, to use it as such, you have to learn a few new commands. + + @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 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 Basics + @subsection Agent Basics + + First, let's get some terminology out of the way. + + 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 @dfn{local} machine is the one you're running on, and which isn't + connected to the net continuously. + + @dfn{Downloading} means fetching things from the net to your local + machine. @dfn{Uploading} is doing the opposite. + + 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! + + 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). + + 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. + + 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. + + Let's take a typical Gnus session using the Agent. + + @itemize @bullet + + @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 + 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 + 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 + 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 + And then you go to step 2. + @end itemize + + Here are some things you should do the first time (or so) that you use + the Agent. + + @itemize @bullet + + @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. + + @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}. + + 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. + + @item + address@hidden that's it. + @end itemize + + + @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. + + 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. + + 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. + + 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. + + @menu + * Category Syntax:: What a category looks like. + * Category Buffer:: A buffer for maintaining categories. + * Category Variables:: Customize'r'Us. + @end menu + + + @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 gnus-agent-cat-name + The name of the category. + + @item gnus-agent-cat-groups + The list of groups that are in this category. + + @item gnus-agent-cat-predicate + A predicate which (generally) gives a rough outline of which articles + are eligible for downloading; and + + @item gnus-agent-cat-score-file + 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-cat-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-cat-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-cat-low-score + an integer that overrides the value of @code{gnus-agent-low-score}. + + @item gnus-agent-cat-high-score + an integer that overrides the value of @code{gnus-agent-high-score}. + + @item gnus-agent-cat-length-when-short + an integer that overrides the value of + @code{gnus-agent-short-article}. + + @item gnus-agent-cat-length-when-long + an integer that overrides the value of @code{gnus-agent-long-article}. + + @c @item gnus-agent-cat-disable-undownloaded-faces + @c a symbol indicating whether the summary buffer should @emph{not} display + @c undownloaded articles using the gnus-summary-*-undownloaded-face + @c faces. The symbol nil will enable the use of undownloaded faces while + @c all other symbols disable them. + + @item gnus-agent-cat-enable-undownloaded-faces + a symbol indicating whether the summary buffer should display + undownloaded articles using the gnus-summary-*-undownloaded-face + faces. The symbol nil will disable the use of undownloaded faces while + all other symbols enable them. + @end table + + The name of a category can not be changed once the category has been + created. + + 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. + + 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. + + 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. + + 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. + + Perhaps some examples are in order. + + Here's a simple predicate. (It's the default predicate, in fact, used + for all groups that don't belong to any other category.) + + @lisp + short + @end lisp + + Quite simple, eh? This predicate is true if and only if the article is + short (for some value of short''). + + Here's a more complex predicate: + + @lisp + (or high + (and + (not low) + (not long))) + @end lisp + + 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. + + 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.) + + 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 iff the article is shorter than @code{gnus-agent-short-article} + lines; default 100. + + @item long + True iff the article is longer than @code{gnus-agent-long-article} + lines; default 200. + + @item low + True iff the article has a download score less than + @code{gnus-agent-low-score}; default 0. + + @item high + True iff the article has a download score greater than + @code{gnus-agent-high-score}; default 0. + + @item spam + True iff 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. + + @item true + Always true. + + @item false + Always false. + @end table + + 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. + + 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 + + with the predicate then defined as: + + @lisp + (not my-article-old-p) + @end lisp + + or you could append your predicate to the predefined + @code{gnus-category-predicate-alist} in your @file{~/.gnus.el} or + wherever. + + @lisp + (require 'gnus-agent) + (setq gnus-category-predicate-alist + (append gnus-category-predicate-alist + '((old . my-article-old-p)))) + @end lisp + + and simply specify your predicate as: + + @lisp + (not old) + @end lisp + + 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. + + 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 + + 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 + (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. + + + 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}. + + 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: + + @enumerate + @item + Score rule + + This has the same syntax as a normal Gnus score file except only a + subset of scoring keywords are available as mentioned above. + + example: + + @itemize @bullet + @item + Category specification + + @lisp + (("from" + ("Lars Ingebrigtsen" 1000000 nil s)) + ("lines" + (500 -100 nil <))) + @end lisp + + @item + Group/Topic Parameter specification + + @lisp + (agent-score ("from" + ("Lars Ingebrigtsen" 1000000 nil s)) + ("lines" + (500 -100 nil <))) + @end lisp + + Again, note the omission of the outermost parenthesis here. + @end itemize + + @item + Agent score file + + These score files must @emph{only} contain the permitted scoring + keywords stated above. + + example: + + @itemize @bullet + @item + Category specification + + @lisp + ("~/News/agent.SCORE") + @end lisp + + or perhaps + + @lisp + ("~/News/agent.SCORE" "~/News/agent.group.SCORE") + @end lisp + + @item + Group Parameter specification + + @lisp + (agent-score "~/News/agent.SCORE") + @end lisp + + Additional score files can be specified as above. Need I say anything + about parenthesis? + @end itemize + + @item + Use @code{normal} score files + + 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. + + 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 + Category Specification + + @lisp + file + @end lisp + + @item + 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: + + @table @kbd + @item q + @kindex q (Category) + @findex gnus-category-exit + Return to the group buffer (@code{gnus-category-exit}). + + @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}). + + @item c + @kindex c (Category) + @findex gnus-category-copy + Copy the current category (@code{gnus-category-copy}). + + @item a + @kindex a (Category) + @findex gnus-category-add + Add a new category (@code{gnus-category-add}). + + @item p + @kindex p (Category) + @findex gnus-category-edit-predicate + Edit the predicate of the current category + (@code{gnus-category-edit-predicate}). + + @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}). + + @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 l + @kindex l (Category) + @findex gnus-category-list + List all the categories (@code{gnus-category-list}). + @end table + + + @node Category Variables + @subsubsection Category Variables + + @table @code + @item gnus-category-mode-hook + @vindex gnus-category-mode-hook + Hook run in category buffers. + + @item gnus-category-line-format + @vindex gnus-category-line-format + Format of the lines in the category buffer (@pxref{Formatting + Variables}). Valid elements are: + + @table @samp + @item c + The name of the category. + + @item g + The number of groups in the category. + @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 gnus-agent-short-article + @vindex gnus-agent-short-article + Articles that have fewer lines than this are short. Default 100. + + @item gnus-agent-long-article + @vindex gnus-agent-long-article + Articles that have more lines than this are long. Default 200. + + @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 gnus-agent-high-score + @vindex gnus-agent-high-score + Articles that have a score higher than this have a high score. Default + 0. + + @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 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. + + @end table + + + @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. + + + @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 + + + + + @node Group Agent Commands + @subsubsection Group Agent Commands + + @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}). + + @item J c + @kindex J c (Agent Group) + @findex gnus-enter-category-buffer + Enter the Agent category buffer (@code{gnus-enter-category-buffer}). + + @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}. + + @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}). + + @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}). + + @item J Y + @kindex J Y (Agent Group) + @findex gnus-agent-synchronize-flags + Synchronize flags changed while unplugged with remote server, if any. + + + @end table + + + @node Summary Agent Commands + @subsubsection Summary Agent Commands + + @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}). + + @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. + + @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 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 J s + @kindex J s (Agent Summary) + @findex gnus-agent-fetch-series + Download all processable articles in this group. + (@code{gnus-agent-fetch-series}). + + @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}). + + @end table + + + @node Server Agent Commands + @subsubsection Server Agent Commands + + @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 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}). + + @end table + + + @node Agent Visuals + @subsection Agent Visuals + + 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}). + + 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. + + 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 occasional Agent users, the undownloaded faces may appear to be an + absolutely horrible idea. The issue being that, since most of their + articles have not been fetched into the Agent, most of the normal + faces will be obscured by the undownloaded faces. If this is your + situation, you have two choices available. First, you can completely + disable the undownload faces by customizing + @code{gnus-summary-highlight} to delete the three cons-cells that + refer to the @code{gnus-summary-*-undownloaded-face} faces. Second, if + you prefer to take a more fine-grained approach, you may set the + @code{agent-disable-undownloaded-faces} group parameter to 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}). + + @node Agent as Cache + @subsection Agent as Cache + + 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. + + 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. + + @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 + + 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. + + 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 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 address@hidden, 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. + + 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. + + @node Agent Regeneration + @subsection Agent Regeneration + + @cindex agent regeneration + @cindex Gnus agent regeneration + @cindex regeneration + + 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. + + 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. + + @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. + + @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. + + @node Agent and IMAP + @subsection Agent and IMAP + + 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. + + The first thing to keep in mind is that all flags (read, ticked, etc) + are kept on the @acronym{IMAP} server, rather than in @file{.newsrc} as is the + case for nntp. Thus Gnus need to remember flag changes when + disconnected, and synchronize these flags when you plug back in. + + Gnus keeps track of flag changes when reading nnimap groups under the + Agent. When you plug back in, Gnus will check if you have any changed + any flags and ask if you wish to synchronize these with the server. + The behavior is customizable by @code{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. + + 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. + + Some things are currently not implemented in the Agent that you'd might + expect from a disconnected @acronym{IMAP} client, including: + + @itemize @bullet + + @item + Copying/moving articles into nnimap groups when unplugged. + + @item + Creating/deleting nnimap groups when unplugged. + + @end itemize + + Technical note: the synchronization algorithm does not work by pushing'' + all local flags to the server, but rather incrementally update 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 and + 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. + + + @node Outgoing Messages + @subsection Outgoing Messages + + 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. + + When Gnus is plugged again, 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. + + + + @node Agent Variables + @subsection Agent Variables + + @table @code + @item gnus-agent-directory + @vindex gnus-agent-directory + Where the Gnus Agent will store its files. The default is + @file{~/News/agent/}. + + @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 gnus-agent-plugged-hook + @vindex gnus-agent-plugged-hook + Hook run when connecting to the network. + + @item gnus-agent-unplugged-hook + @vindex gnus-agent-unplugged-hook + Hook run when disconnecting from the network. + + @item gnus-agent-fetched-hook + @vindex gnus-agent-fetched-hook + Hook run when finished fetching articles. + + @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 address@hidden, which means to use the Agent as a cache. + + @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 gnus-agent-mark-unread-after-downloaded + @vindex gnus-agent-mark-unread-after-downloaded + If @code{gnus-agent-mark-unread-after-downloaded} is address@hidden, + 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 t. + + @item gnus-agent-consider-all-articles + @vindex gnus-agent-consider-all-articles + If @code{gnus-agent-consider-all-articles} is address@hidden, 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 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 loosing the connection will be + available while unplugged). The default is 10M so it is unusual to + see any cycling. + + @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 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. + + The legal 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-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 backends should be auto-agentized. It is typically only useful + to agentize remote backends. 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)}. + + @end table + + + @node Example Setup + @subsection Example Setup + + 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 + ;;; @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")) + + ;;; @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"))) + + ;;; @r{Say how Gnus is to store the mail. We use nnml groups.} + (setq gnus-secondary-select-methods '((nnml ""))) + + ;;; @r{Make Gnus into an offline newsreader.} + ;;; (gnus-agentize) ; @r{The obsolete setting.} + ;;; (setq gnus-agent t) ; @r{Now the default.} + @end lisp + + 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. + + 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.) + + 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. + + + @node Batching Agents + @subsection Batching Agents + @findex gnus-agent-batch + + 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: + + You can run a complete batch command from the command line with the + following incantation: + + @example + #!/bin/sh + emacs -batch -l ~/.emacs -f -l ~/.gnus.el gnus-agent-batch >/dev/null 2>&1 + @end example + + + @node Agent Caveats + @subsection Agent Caveats + + The Gnus Agent doesn't seem to work like most other offline + newsreaders. Here are some common questions that some imaginary people + may ask: + + @table @dfn + @item If I read an article while plugged, do they get entered into the Agent? + + @strong{No}. If you want this behaviour, add + @code{gnus-agent-fetch-selected-article} to + @code{gnus-select-article-hook}. + + @item If I read an article while plugged, and the article already exists in + the Agent, will it get downloaded once more? + + @strong{No}, unless @code{gnus-agent-cache} is @code{nil}. + + @end table + + 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. + + + @node Scoring + @chapter Scoring + @cindex scoring + + 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! + + @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. + + Gnus will read any @dfn{score files} that apply to the current group + before generating the summary buffer. + + 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. + + @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. + * GroupLens:: Getting predictions on what you like to read. + * Advanced Scoring:: Using logical expressions to build score rules. + * Score Decays:: It can be useful to let scores wither away. + @end menu + + + @node Summary Score Commands + @section Summary Score Commands + @cindex score commands + + 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. + + General score commands that don't actually change the score file: + + @table @kbd + + @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 V S + @kindex V S (Summary) + @findex gnus-summary-current-score + Display the score of the current article + (@code{gnus-summary-current-score}). + + @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 V w + @kindex V w (Summary) + @findex gnus-score-find-favourite-words + List words used in scoring (@code{gnus-score-find-favourite-words}). + + @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. + + @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 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 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}). + + @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. + + @item V C + @kindex V C (Summary) + @findex gnus-score-customize + Customize a score file in a visually pleasing manner + (@code{gnus-score-customize}). + + @end table + + The rest of these commands modify the local score file. + + @table @kbd + + @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 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 + + 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.) + + @findex gnus-summary-increase-score + @findex gnus-summary-lower-score + + @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 + + @item a + Score on the author name. + + @item s + Score on the subject line. + + @item x + Score on the @code{Xref} line---i.e., the cross-posting line. + + @item r + Score on the @code{References} line. + + @item d + Score on the date. + + @item l + Score on the number of lines. + + @item i + Score on the @code{Message-ID} header. + + @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 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 b + Score on the body. + + @item h + Score on the head. + + @item t + Score on thread. (Using this key leads to the creation of @file{ADAPT} + files.) + + @end table + + @item + The third key is the match type. Which match types are valid depends on + what headers you are scoring on. + + @table @code + + @item strings + + @table @kbd + + @item e + Exact matching. + + @item s + Substring matching. + + @item f + Fuzzy matching (@pxref{Fuzzy Matching}). + + @item r + Regexp matching + @end table + + @item date + @table @kbd + + @item b + Before date. + + @item a + After date. + + @item n + This date. + @end table + + @item number + @table @kbd + + @item < + Less than number. + + @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 + + @item t + Temporary score entry. + + @item p + Permanent score entry. + + @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. + + 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}. + + 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. + + @vindex gnus-score-mimic-keymap + The @code{gnus-score-mimic-keymap} says whether these commands will + pretend they are keymaps or not. + + + @node Group Score Commands + @section Group Score Commands + @cindex group score commands + + There aren't many of these as yet, I'm afraid. + + @table @kbd + + @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: + + @findex gnus-batch-score + @cindex batch scoring + @example +$ emacs -batch -l ~/.emacs -l ~/.gnus.el -f gnus-batch-score
+ @end example
+
+
+ @node Score Variables
+ @section Score Variables
+ @cindex score variables
+
+ @table @code
+
+ @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 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 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 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, if 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
+ 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. + + 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. + + @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 gnus-summary-default-score + @vindex gnus-summary-default-score + Default score of an article, which is 0 by default. + + @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{+}. + + @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{-}. + + @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. + + Predefined functions available are: + @table @code + + @item gnus-score-find-single + @findex gnus-score-find-single + Only apply the group's own score file. + + @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. + + 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. + + 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. + + @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. + + @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 + + @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. + + @item gnus-update-score-entry-dates + @vindex gnus-update-score-entry-dates + If this variable is address@hidden, 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. + + @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-score-thread-simplify + @vindex gnus-score-thread-simplify + If this variable is address@hidden, 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. + + @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. + + Anyway, if you'd like to dig into it yourself, here's an example: + + @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 + + This example demonstrates most score file elements. @xref{Advanced + Scoring}, for a different approach. + + 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: + + @table @code + + @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. + + @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. + + @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. + + @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 + + @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. + + @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: + + @lisp + ("111.222.333.444" -1000 nil s + "NNTP-Posting-Host") + @end lisp + + @item Lines, Chars + These two headers use different match types: @code{<}, @code{>}, + @code{=}, @code{>=} and @code{<=}. + + These predicates are true if + + @example + (PREDICATE HEADER MATCH) + @end example + + evaluates to address@hidden For instance, the advanced match + @code{("lines" 4 <)} (@pxref{Advanced Scoring}) will result in the + following form: + + @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.) + + 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. + + @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.) + + @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 address@hidden@address@hidden 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?) + + @item Head, Body, All + These three match keys use the same match types as the @code{From} (etc) + header uses. + + @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.) + + @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 + + @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. + + @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 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 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 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 eval + The value of this entry will be @code{eval}el. This element will be + ignored when handling global score files. + + @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 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. + + You can do this with the following two score file entries: + + @example + (orphan -500) + (mark-and-expunge -100) + @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. + + 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 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 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 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 File Editing + @section Score File Editing + + 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. + + It's simply a slightly customized @code{emacs-lisp} mode, with these + additional commands: + + @table @kbd + + @item C-c C-c + @kindex C-c C-c (Score) + @findex gnus-score-edit-done + Save the changes you have made and return to the summary buffer + (@code{gnus-score-edit-done}). + + @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 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. + + @end table + + Type @kbd{M-x gnus-score-mode} to use this mode. + + @vindex gnus-score-mode-hook + @code{gnus-score-menu-hook} is run in score mode buffers. + + In the summary buffer you can use commands like @kbd{V f}, @kbd{V e} and + @kbd{V t} to begin editing score files. + + + @node Adaptive Scoring + @section Adaptive Scoring + @cindex adaptive scoring + + 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. + + @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: + + @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 + + 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. + + Each article can have only one mark, so just a single of these rules + will be applied to each article. + + 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. + + 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. + + 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. + + 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. + + 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. + + @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}. + + @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. + + @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 + + 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-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. + + @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}. + + @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. + + @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}. + + @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. + + 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 Home Score File + @section Home 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}. + + 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. + + @vindex gnus-home-score-file + The variable that controls this is @code{gnus-home-score-file}. It can + be: + + @enumerate + @item + A string. Then this file will be used as the home score file for all + groups. + + @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 + A list. The elements in this list can be: + + @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 + A function. If the function returns address@hidden, the result will + be used as the home score file. + + @item + A string. Use the string as the home score file. + @end enumerate + + The list will be traversed from the beginning towards the end looking + for matches. + + @end enumerate + + So, if you want to use just a single score file, you could say: + + @lisp + (setq gnus-home-score-file + "my-total-score-file.SCORE") + @end lisp + + 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: + + @findex gnus-hierarchial-home-score-file + @lisp + (setq gnus-home-score-file + 'gnus-hierarchial-home-score-file) + @end lisp + + This is a ready-made function provided for your convenience. + Other functions include + + @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. + + @end table + + 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: + + @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 + + @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. + + 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. + + + @node Followups To Yourself + @section Followups To Yourself + + 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. + + @table @code + + @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 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 + + @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 + + + 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: + + @example + <x6u3u47icf.fsf@@eyesore.no> + <x6sp9o7ibw.fsf@@eyesore.no> + @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: + + @lisp + ("references" + ("<x6[0-9a-z]+\\.fsf\$$_-_\$$?@@.*eyesore\\.no>" + 1000 nil r)) + @end lisp + + Whether it's the first two or first three characters that are yours'' + is system-dependent. + + + @node Scoring On Other Headers + @section Scoring On Other Headers + @cindex scoring on other headers + + Gnus is quite fast when scoring the traditional'' + address@hidden, @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. + + Now, there's not much you can do about this 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. + + Put the following in your @file{~/.gnus.el} file. + + @lisp + (setq gnus-extra-headers '(To Cc Newsgroups Keywords) + nnmail-extra-headers gnus-extra-headers) + @end lisp + + 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. + + Now you can score on @samp{To} and @samp{Cc} as extra headers'' like + so: @kbd{I e s p To RET <your name> RET}. + + See? Simple. + + + @node Scoring Tips + @section Scoring Tips + @cindex scoring tips + + @table @dfn + + @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 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 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 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 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 + + + @node Reverse Scoring + @section Reverse Scoring + @cindex reverse scoring + + 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: + + @lisp + (("subject" + ("Sex with Emacs" 2)) + (mark 1) + (expunge 1)) + @end lisp + + So, you raise all articles that match @samp{Sex with Emacs} and mark the + rest as read, and expunge them to boot. + + + @node Global Score Files + @section Global Score Files + @cindex global score files + + 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! + + 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! + + @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. + + 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: + + @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 + + @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. + + 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! + + Here are some tips for the would-be retro-moderator, off the top of my + head: + + @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. + + @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 + + 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. + + 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. + + 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. + + Normal kill files look like this: + + @lisp + (gnus-kill "From" "Lars Ingebrigtsen") + (gnus-kill "Subject" "ding") + (gnus-expunge "X") + @end lisp + + This will mark every article written by me as read, and remove the + marked articles from the summary buffer. Very useful, you'll agree. + + 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. + + Two summary functions for editing a @sc{gnus} kill file: + + @table @kbd + + @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 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 + + Two group mode functions for editing the kill files: + + @table @kbd + + @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 + + Kill file variables: + + @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}. + + @vindex gnus-kill-save-kill-file + @item gnus-kill-save-kill-file + If this variable is address@hidden, Gnus will save the + kill file after processing, which is necessary if you use expiring + kills. + + @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-kill-file-mode-hook + @vindex gnus-kill-file-mode-hook + A hook called in kill-file mode buffers. + + @end table + + + @node Converting Kill Files + @section Converting Kill Files + @cindex kill files + @cindex converting kill files + + 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. + + The kill to score conversion package isn't included in Gnus by default. + You can fetch it from + @uref{http://www.stud.ifi.uio.no/~larsi/ding-various/gnus-kill-to-score.el}. + + If your old kill files are very complex---if they contain more + address@hidden 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. + + + @node GroupLens + @section GroupLens + @cindex GroupLens + + @sc{Note:} Unfortunately the GroupLens system seems to have shut down, + so this section is mostly of historical interest. + + @uref{http://www.cs.umn.edu/Research/GroupLens/, GroupLens} is a + collaborative filtering system that helps you work together with other + people to find the quality news articles out of the huge volume of + news articles generated every day. + + To accomplish this the GroupLens system combines your opinions about + articles you have already read with the opinions of others who have done + likewise and gives you a personalized prediction for each unread news + article. Think of GroupLens as a matchmaker. GroupLens watches how you + rate articles, and finds other people that rate articles the same way. + Once it has found some people you agree with it tells you, in the form + of a prediction, what they thought of the article. You can use this + prediction to help you decide whether or not you want to read the + article. + + @menu + * Using GroupLens:: How to make Gnus use GroupLens. + * Rating Articles:: Letting GroupLens know how you rate articles. + * Displaying Predictions:: Displaying predictions given by GroupLens. + * GroupLens Variables:: Customizing GroupLens. + @end menu + + + @node Using GroupLens + @subsection Using GroupLens + + To use GroupLens you must register a pseudonym with your local + @uref{http://www.cs.umn.edu/Research/GroupLens/bbb.html, Better Bit + Bureau (BBB)} is the only better bit in town at the moment. + + Once you have registered you'll need to set a couple of variables. + + @table @code + + @item gnus-use-grouplens + @vindex gnus-use-grouplens + Setting this variable to a address@hidden value will make Gnus hook into + all the relevant GroupLens functions. + + @item grouplens-pseudonym + @vindex grouplens-pseudonym + This variable should be set to the pseudonym you got when registering + with the Better Bit Bureau. + + @item grouplens-newsgroups + @vindex grouplens-newsgroups + A list of groups that you want to get GroupLens predictions for. + + @end table + + That's the minimum of what you need to get up and running with GroupLens. + Once you've registered, GroupLens will start giving you scores for + articles based on the average of what other people think. But, to get + the real benefit of GroupLens you need to start rating articles + yourself. Then the scores GroupLens gives you will be personalized for + you, based on how the people you usually agree with have already rated. + + + @node Rating Articles + @subsection Rating Articles + + In GroupLens, an article is rated on a scale from 1 to 5, inclusive. + Where 1 means something like this article is a waste of bandwidth and 5 + means that the article was really good. The basic question to ask + yourself is, on a scale from 1 to 5 would I like to see more articles + like this one?'' + + There are four ways to enter a rating for an article in GroupLens. + + @table @kbd + + @item r + @kindex r (GroupLens) + @findex bbb-summary-rate-article + This function will prompt you for a rating on a scale of one to five. + + @item k + @kindex k (GroupLens) + @findex grouplens-score-thread + This function will prompt you for a rating, and rate all the articles in + the thread. This is really useful for some of those long running giant + threads in rec.humor. + + @end table + + The next two commands, @kbd{n} and @kbd{,} take a numerical prefix to be + the score of the article you're reading. + + @table @kbd + + @item 1-5 n + @kindex n (GroupLens) + @findex grouplens-next-unread-article + Rate the article and go to the next unread article. + + @item 1-5 , + @kindex , (GroupLens) + @findex grouplens-best-unread-article + Rate the article and go to the next unread article with the highest score. + + @end table + + If you want to give the current article a score of 4 and then go to the + next article, just type @kbd{4 n}. + + + @node Displaying Predictions + @subsection Displaying Predictions + + GroupLens makes a prediction for you about how much you will like a + news article. The predictions from GroupLens are on a scale from 1 to + 5, where 1 is the worst and 5 is the best. You can use the predictions + from GroupLens in one of three ways controlled by the variable + @code{gnus-grouplens-override-scoring}. + + @vindex gnus-grouplens-override-scoring + There are three ways to display predictions in grouplens. You may + choose to have the GroupLens scores contribute to, or override the + regular Gnus scoring mechanism. override is the default; however, some + people prefer to see the Gnus scores plus the grouplens scores. To get + the separate scoring behavior you need to set + @code{gnus-grouplens-override-scoring} to @code{'separate}. To have the + GroupLens predictions combined with the grouplens scores set it to + @code{'override} and to combine the scores set + @code{gnus-grouplens-override-scoring} to @code{'combine}. When you use + the combine option you will also want to set the values for + @code{grouplens-prediction-offset} and + @code{grouplens-score-scale-factor}. + + @vindex grouplens-prediction-display + In either case, GroupLens gives you a few choices for how you would like + to see your predictions displayed. The display of predictions is + controlled by the @code{grouplens-prediction-display} variable. + + The following are valid values for that variable. + + @table @code + @item prediction-spot + The higher the prediction, the further to the right an @samp{*} is + displayed. + + @item confidence-interval + A numeric confidence interval. + + @item prediction-bar + The higher the prediction, the longer the bar. + + @item confidence-bar + Numerical confidence. + + @item confidence-spot + The spot gets bigger with more confidence. + + @item prediction-num + Plain-old numeric value. + + @item confidence-plus-minus + Prediction +/- confidence. + + @end table + + + @node GroupLens Variables + @subsection GroupLens Variables + + @table @code + + @item gnus-summary-grouplens-line-format + The summary line format used in GroupLens-enhanced summary buffers. It + accepts the same specs as the normal summary line format (@pxref{Summary + Buffer Lines}). The default is @samp{%U%R%z%l%I%(%[%4L: %-23,23n%]%) + %s\n}. + + @item grouplens-bbb-host + Host running the bbbd server. @samp{grouplens.cs.umn.edu} is the + default. + + @item grouplens-bbb-port + Port of the host running the bbbd server. The default is 9000. + + @item grouplens-score-offset + Offset the prediction by this value. In other words, subtract the + prediction value by this number to arrive at the effective score. The + default is 0. + + @item grouplens-score-scale-factor + This variable allows the user to magnify the effect of GroupLens scores. + The scale factor is applied after the offset. The default is 1. + + @end table + + + @node Advanced Scoring + @section Advanced Scoring + + 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? + + By using advanced scoring rules you may create arbitrarily complex + scoring patterns. + + @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 Advanced Scoring Syntax + @subsection Advanced Scoring Syntax + + 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 + address@hidden value. + + These lists may consist of three logical operators, one redirection + operator, and various match operators. + + Logical operators: + + @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}. + + @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 ! + @itemx not + @itemx ¬ + This logical operator only takes a single argument. It returns the + logical negation of the value of its argument. + + @end table + + 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. + + 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. + + + @node Advanced Scoring Examples + @subsection Advanced Scoring Examples + + 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. + + Let's say you want to increase the score of articles written by Lars + when he's talking about Gnus: + + @example + @group + ((& + ("from" "Lars Ingebrigtsen") + ("subject" "Gnus")) + 1000) + @end group + @end example + + Quite simple, huh? + + When he writes long articles, he sometimes has something nice to say: + + @example + ((& + ("from" "Lars Ingebrigtsen") + (| + ("subject" "Gnus") + ("lines" 100 >))) + 1000) + @end example + + However, when he responds to things written by Reig Eigil Logge, you + really don't want to read what he's written: + + @example + ((& + ("from" "Lars Ingebrigtsen") + (1- ("from" "Reig Eigir Logge"))) + -100000) + @end example + + 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: + + @example + ((& + (1- + (& + ("from" "redmondo@@.*no" r) + ("body" "disappearing.*socks" t))) + (! ("from" "Lars Ingebrigtsen")) + ("body" "white.*socks")) + 1000) + @end example + + The possibilities are endless. + + + @node Advanced Scoring Tips + @subsection Advanced Scoring Tips + + 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. + + 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 + ... + (1- + (1- + ("from" "lars"))) + ... + @end example + + 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: + + @example + (1- + (& + ("from" "Lars") + ("subject" "Gnus"))) + @end example + + than it is to say: + + @example + (& + (1- ("from" "Lars")) + (1- ("subject" "Gnus"))) + @end example + + + @node Score Decays + @section Score Decays + @cindex score decays + @cindex decays + + 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. + + @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 + address@hidden, Gnus will run the score files through the decaying + mechanism thereby lowering the scores of all non-permanent score rules. + 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: + + @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 + + @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: + + @enumerate + @item + Scores between -3 and 3 will be set to 0 when this function is called. + + @item + Scores with magnitudes between 3 and 60 will be shrunk by 3. + + @item + Scores with magnitudes greater than 60 will be shrunk by 5% of the + score. + @end enumerate + + 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. + + 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. + + @iftex + @iflatex + @chapter Message + @include message.texi + @chapter Emacs MIME + @include emacs-mime.texi + @chapter Sieve + @include sieve.texi + @chapter PGG + @include pgg.texi + @end iflatex + @end iftex + + @node Various + @chapter Various + + @menu + * Process/Prefix:: A convention used by many treatment commands. + * Interactive:: Making Gnus ask you many questions. + * Symbolic Prefixes:: How to supply some Gnus functions with options. + * Formatting Variables:: You can specify what buffers should look like. + * Window Layout:: Configuring the Gnus buffer windows. + * Faces and Fonts:: How to change how faces look. + * Compilation:: How to speed Gnus up. + * Mode Lines:: Displaying information in the mode lines. + * Highlighting and Menus:: Making buffers look all nice and cozy. + * Buttons:: Get tendinitis in ten easy steps! + * Daemons:: Gnus can do things behind your back. + * NoCeM:: How to avoid spam and other fatty foods. + * Undo:: Some actions can be undone. + * Predicate Specifiers:: Specifying predicates. + * Moderation:: What to do if you're a moderator. + * Image Enhancements:: Modern versions of Emacs/XEmacs can display images. + * Fuzzy Matching:: What's the big fuzz? + * Thwarting Email Spam:: A how-to on avoiding unsolicited commercial email. + * Other modes:: Interaction with other modes. + * Various Various:: Things that are really various. + @end menu + + + @node Process/Prefix + @section Process/Prefix + @cindex process/prefix convention + + Many functions, among them functions for moving, decoding and saving + articles, use what is known as the @dfn{Process/Prefix convention}. + + This is a method for figuring out what articles the user wants the + command to be performed on. + + It goes like this: + + If the numeric prefix is N, perform the operation on the next N + articles, starting with the current one. If the numeric prefix is + negative, perform the operation on the previous N articles, starting + with the current one. + + @vindex transient-mark-mode + If @code{transient-mark-mode} in address@hidden and the region is + active, all articles in the region will be worked upon. + + If there is no numeric prefix, but some articles are marked with the + process mark, perform the operation on the articles marked with + the process mark. + + If there is neither a numeric prefix nor any articles marked with the + process mark, just perform the operation on the current article. + + Quite simple, really, but it needs to be made clear so that surprises + are avoided. + + Commands that react to the process mark will push the current list of + process marked articles onto a stack and will then clear all process + marked articles. You can restore the previous configuration with the + @kbd{M P y} command (@pxref{Setting Process Marks}). + + @vindex gnus-summary-goto-unread + One thing that seems to shock & horrify lots of people is that, for + instance, @kbd{3 d} does exactly the same as @kbd{d} @kbd{d} @kbd{d}. + Since each @kbd{d} (which marks the current article as read) by default + goes to the next unread article after marking, this means that @kbd{3 d} + will mark the next three unread articles as read, no matter what the + summary buffer looks like. Set @code{gnus-summary-goto-unread} to + @code{nil} for a more straightforward action. + + Many commands do not use the process/prefix convention. All commands + that do explicitly say so in this manual. To apply the process/prefix + convention to commands that do not use it, you can use the @kbd{M-&} + command. For instance, to mark all the articles in the group as + expirable, you could say @kbd{M P b M-& E}. + + + @node Interactive + @section Interactive + @cindex interaction + + @table @code + + @item gnus-novice-user + @vindex gnus-novice-user + If this variable is address@hidden, you are either a newcomer to the + World of Usenet, or you are very cautious, which is a nice thing to be, + really. You will be given questions of the type Are you sure you want + to do this?'' before doing anything dangerous. This is @code{t} by + default. + + @item gnus-expert-user + @vindex gnus-expert-user + If this variable is address@hidden, you will seldom be asked any + questions by Gnus. It will simply assume you know what you're doing, no + matter how strange. + + @item gnus-interactive-catchup + @vindex gnus-interactive-catchup + Require confirmation before catching up a group if address@hidden It + is @code{t} by default. + + @item gnus-interactive-exit + @vindex gnus-interactive-exit + Require confirmation before exiting Gnus. This variable is @code{t} by + default. + @end table + + + @node Symbolic Prefixes + @section Symbolic Prefixes + @cindex symbolic prefixes + + Quite a lot of Emacs commands react to the (numeric) prefix. For + instance, @kbd{C-u 4 C-f} moves point four characters forward, and + @kbd{C-u 9 0 0 I s s p} adds a permanent @code{Subject} substring score + rule of 900 to the current article. + + This is all nice and well, but what if you want to give a command some + additional information? Well, what most commands do is interpret the + raw'' prefix in some special way. @kbd{C-u 0 C-x C-s} means that one + doesn't want a backup file to be created when saving the current buffer, + for instance. But what if you want to save without making a backup + file, and you want Emacs to flash lights and play a nice tune at the + same time? You can't, and you're probably perfectly happy that way. + + @kindex M-i (Summary) + @findex gnus-symbolic-argument + I'm not, so I've added a second prefix---the @dfn{symbolic prefix}. The + prefix key is @kbd{M-i} (@code{gnus-symbolic-argument}), and the next + character typed in is the value. You can stack as many @kbd{M-i} + prefixes as you want. @kbd{M-i a C-M-u} means feed the @kbd{C-M-u} + command the symbolic prefix @code{a}''. @kbd{M-i a M-i b C-M-u} means + feed the @kbd{C-M-u} command the symbolic prefixes @code{a} and + @code{b}''. You get the drift. + + Typing in symbolic prefixes to commands that don't accept them doesn't + hurt, but it doesn't do any good either. Currently not many Gnus + functions make use of the symbolic prefix. + + If you're interested in how Gnus implements this, @pxref{Extended + Interactive}. + + + @node Formatting Variables + @section Formatting Variables + @cindex formatting variables + + Throughout this manual you've probably noticed lots of variables called + things like @code{gnus-group-line-format} and + @code{gnus-summary-mode-line-format}. These control how Gnus is to + output lines in the various buffers. There's quite a lot of them. + Fortunately, they all use the same syntax, so there's not that much to + be annoyed by. + + Here's an example format spec (from the group buffer): @samp{%M%S%5y: + %(%g%)\n}. We see that it is indeed extremely ugly, and that there are + lots of percentages everywhere. + + @menu + * Formatting Basics:: A formatting variable is basically a format string. + * Mode Line Formatting:: Some rules about mode line formatting variables. + * Advanced Formatting:: Modifying output in various ways. + * User-Defined Specs:: Having Gnus call your own functions. + * Formatting Fonts:: Making the formatting look colorful and nice. + * Positioning Point:: Moving point to a position after an operation. + * Tabulation:: Tabulating your output. + * Wide Characters:: Dealing with wide characters. + @end menu + + Currently Gnus uses the following formatting variables: + @code{gnus-group-line-format}, @code{gnus-summary-line-format}, + @code{gnus-server-line-format}, @code{gnus-topic-line-format}, + @code{gnus-group-mode-line-format}, + @code{gnus-summary-mode-line-format}, + @code{gnus-article-mode-line-format}, + @code{gnus-server-mode-line-format}, and + @code{gnus-summary-pick-line-format}. + + All these format variables can also be arbitrary elisp forms. In that + case, they will be @code{eval}ed to insert the required lines. + + @kindex M-x gnus-update-format + @findex gnus-update-format + Gnus includes a command to help you while creating your own format + specs. @kbd{M-x gnus-update-format} will @code{eval} the current form, + update the spec in question and pop you to a buffer where you can + examine the resulting Lisp code to be run to generate the line. + + + + @node Formatting Basics + @subsection Formatting Basics + + Each @samp{%} element will be replaced by some string or other when the + buffer in question is generated. @samp{%5y} means insert the @samp{y} + spec, and pad with spaces to get a 5-character field''. + + As with normal C and Emacs Lisp formatting strings, the numerical + modifier between the @samp{%} and the formatting type character will + @dfn{pad} the output so that it is always at least that long. + @samp{%5y} will make the field always (at least) five characters wide by + padding with spaces to the left. If you say @samp{%-5y}, it will pad to + the right instead. + + You may also wish to limit the length of the field to protect against + particularly wide values. For that you can say @samp{%4,6y}, which + means that the field will never be more than 6 characters wide and never + less than 4 characters wide. + + Also Gnus supports some extended format specifications, such as + @samp{%&user-date;}. + + + @node Mode Line Formatting + @subsection Mode Line Formatting + + Mode line formatting variables (e.g., + @code{gnus-summary-mode-line-format}) follow the same rules as other, + buffer line oriented formatting variables (@pxref{Formatting Basics}) + with the following two differences: + + @enumerate + + @item + There must be no newline (@samp{\n}) at the end. + + @item + The special @samp{%%b} spec can be used to display the buffer name. + Well, it's no spec at all, address@hidden is just a way to quote + @samp{%} to allow it to pass through the formatting machinery unmangled, + so that Emacs receives @samp{%b}, which is something the Emacs mode line + display interprets to mean show the buffer name''. For a full list of + mode line specs Emacs understands, see the documentation of the + @code{mode-line-format} variable. + + @end enumerate + + + @node Advanced Formatting + @subsection Advanced Formatting + + It is frequently useful to post-process the fields in some way. + Padding, limiting, cutting off parts and suppressing certain values can + be achieved by using @dfn{tilde modifiers}. A typical tilde spec might + look like @samp{%~(cut 3)~(ignore "0")y}. + + These are the valid modifiers: + + @table @code + @item pad + @itemx pad-left + Pad the field to the left with spaces until it reaches the required + length. + + @item pad-right + Pad the field to the right with spaces until it reaches the required + length. + + @item max + @itemx max-left + Cut off characters from the left until it reaches the specified length. + + @item max-right + Cut off characters from the right until it reaches the specified + length. + + @item cut + @itemx cut-left + Cut off the specified number of characters from the left. + + @item cut-right + Cut off the specified number of characters from the right. + + @item ignore + Return an empty string if the field is equal to the specified value. + + @item form + Use the specified form as the field value when the @samp{@@} spec is + used. + + Here's an example: + + @lisp + "~(form (current-time-string))@@" + @end lisp + + @end table + + Let's take an example. The @samp{%o} spec in the summary mode lines + will return a date in compact ISO8601 address@hidden + This is quite a mouthful, so we want to shave off the century number and + the time, leaving us with a six-character date. That would be + @samp{%~(cut-left 2)~(max-right 6)~(pad 6)o}. (Cutting is done before + maxing, and we need the padding to ensure that the date is never less + than 6 characters to make it look nice in columns.) + + Ignoring is done first; then cutting; then maxing; and then as the very + last operation, padding. + + If you use lots of these advanced thingies, you'll find that Gnus gets + quite slow. This can be helped enormously by running @kbd{M-x + gnus-compile} when you are satisfied with the look of your lines. + @xref{Compilation}. + + + @node User-Defined Specs + @subsection User-Defined Specs + + All the specs allow for inserting user defined address@hidden + The next character in the format string should be a letter. Gnus + will call the function @address@hidden, where + @samp{X} is the letter following @samp{%u}. The function will be passed + a single parameter---what the parameter means depends on what buffer + it's being called from. The function should return a string, which will + be inserted into the buffer just like information from any other + specifier. This function may also be called with dummy values, so it + should protect against that. + + Also Gnus supports extended user-defined specs, such as @samp{%u&foo;}. + Gnus will call the function @address@hidden + + You can also use tilde modifiers (@pxref{Advanced Formatting} to achieve + much the same without defining new functions. Here's an example: + @samp{%~(form (count-lines (point-min) (point)))@@}. The form + given here will be evaluated to yield the current line number, and then + inserted. + + + @node Formatting Fonts + @subsection Formatting Fonts + + There are specs for highlighting, and these are shared by all the format + variables. Text inside the @samp{%(} and @samp{%)} specifiers will get + the special @code{mouse-face} property set, which means that it will be + highlighted (with @code{gnus-mouse-face}) when you put the mouse pointer + over it. + + Text inside the @address@hidden and @address@hidden specifiers will have their + normal faces set using @code{gnus-face-0}, which is @code{bold} by + default. If you say @address@hidden, you'll get @code{gnus-face-1} instead, + and so on. Create as many faces as you wish. The same goes for the + @code{mouse-face} specs---you can say @samp{%3(hello%)} to have + @samp{hello} mouse-highlighted with @code{gnus-mouse-face-3}. + + Text inside the @samp{%<<} and @samp{%>>} specifiers will get the + special @code{balloon-help} property set to + @code{gnus-balloon-face-0}. If you say @samp{%1<<}, you'll get + @code{gnus-balloon-face-1} and so on. The @code{gnus-balloon-face-*} + variables should be either strings or symbols naming functions that + return a string. When the mouse passes over text with this property + set, a balloon window will appear and display the string. Please + refer to @ref{Tooltips, ,Tooltips, emacs, The Emacs Manual}, + (in GNU Emacs) or the doc string of @code{balloon-help-mode} (in + XEmacs) for more information on this. (For technical reasons, the + guillemets have been approximated as @samp{<<} and @samp{>>} in this + paragraph.) + + Here's an alternative recipe for the group buffer: + + @lisp + ;; @r{Create three face types.} + (setq gnus-face-1 'bold) + (setq gnus-face-3 'italic) + + ;; @r{We want the article count to be in} + ;; @r{a bold and green face. So we create} + ;; @r{a new face called @code{my-green-bold}.} + (copy-face 'bold 'my-green-bold) + ;; @r{Set the color.} + (set-face-foreground 'my-green-bold "ForestGreen") + (setq gnus-face-2 'my-green-bold) + + ;; @r{Set the new & fancy format.} + (setq gnus-group-line-format + "address@hidden@}%2[:%] %(address@hidden@}%)\n") + @end lisp + + I'm sure you'll be able to use this scheme to create totally unreadable + and extremely vulgar displays. Have fun! + + Note that the @samp{%(} specs (and friends) do not make any sense on the + mode-line variables. + + @node Positioning Point + @subsection Positioning Point + + Gnus usually moves point to a pre-defined place on each line in most + buffers. By default, point move to the first colon character on the + line. You can customize this behaviour in three different ways. + + You can move the colon character to somewhere else on the line. + + @findex gnus-goto-colon + You can redefine the function that moves the point to the colon. The + function is called @code{gnus-goto-colon}. + + But perhaps the most convenient way to deal with this, if you don't want + to have a colon in your line, is to use the @samp{%*} specifier. If you + put a @samp{%*} somewhere in your format line definition, Gnus will + place point there. + + + @node Tabulation + @subsection Tabulation + + You can usually line up your displays by padding and cutting your + strings. However, when combining various strings of different size, it + can often be more convenient to just output the strings, and then worry + about lining up the following text afterwards. + + To do that, Gnus supplies tabulator address@hidden There are two + different address@hidden tabulators} and @dfn{soft tabulators}. + + @samp{%50=} will insert space characters to pad the line up to column + 50. If the text is already past column 50, nothing will be inserted. + This is the soft tabulator. + + @samp{%-50=} will insert space characters to pad the line up to column + 50. If the text is already past column 50, the excess text past column + 50 will be removed. This is the hard tabulator. + + + @node Wide Characters + @subsection Wide Characters + + Fixed width fonts in most countries have characters of the same width. + Some countries, however, use Latin characters mixed with wider + characters---most notable East Asian countries. + + The problem is that when formatting, Gnus assumes that if a string is 10 + characters wide, it'll be 10 Latin characters wide on the screen. In + these countries, that's not true. + + @vindex gnus-use-correct-string-widths + To help fix this, you can set @code{gnus-use-correct-string-widths} to + @code{t}. This makes buffer generation slower, but the results will be + prettier. The default value under XEmacs is @code{t} but @code{nil} + for Emacs. + + + @node Window Layout + @section Window Layout + @cindex window layout + + No, there's nothing here about X, so be quiet. + + @vindex gnus-use-full-window + If @code{gnus-use-full-window} address@hidden, Gnus will delete all + other windows and occupy the entire Emacs screen by itself. It is + @code{t} by default. + + Setting this variable to @code{nil} kinda works, but there are + glitches. Use at your own peril. + + @vindex gnus-buffer-configuration + @code{gnus-buffer-configuration} describes how much space each Gnus + buffer should be given. Here's an excerpt of this variable: + + @lisp + ((group (vertical 1.0 (group 1.0 point) + (if gnus-carpal (group-carpal 4)))) + (article (vertical 1.0 (summary 0.25 point) + (article 1.0)))) + @end lisp + + This is an alist. The @dfn{key} is a symbol that names some action or + other. For instance, when displaying the group buffer, the window + configuration function will use @code{group} as the key. A full list of + possible names is listed below. + + The @dfn{value} (i.e., the @dfn{split}) says how much space each buffer + should occupy. To take the @code{article} split as an example - + + @lisp + (article (vertical 1.0 (summary 0.25 point) + (article 1.0))) + @end lisp + + This @dfn{split} says that the summary buffer should occupy 25% of upper + half of the screen, and that it is placed over the article buffer. As + you may have noticed, 100% + 25% is actually 125% (yup, I saw y'all + reaching for that calculator there). However, the special number + @code{1.0} is used to signal that this buffer should soak up all the + rest of the space available after the rest of the buffers have taken + whatever they need. There should be only one buffer with the @code{1.0} + size spec per split. + + Point will be put in the buffer that has the optional third element + @code{point}. In a @code{frame} split, the last subsplit having a leaf + split where the tag @code{frame-focus} is a member (i.e. is the third or + fourth element in the list, depending on whether the @code{point} tag is + present) gets focus. + + Here's a more complicated example: + + @lisp + (article (vertical 1.0 (group 4) + (summary 0.25 point) + (if gnus-carpal (summary-carpal 4)) + (article 1.0))) + @end lisp + + If the size spec is an integer instead of a floating point number, + then that number will be used to say how many lines a buffer should + occupy, not a percentage. + + If the @dfn{split} looks like something that can be @code{eval}ed (to be + precise---if the @code{car} of the split is a function or a subr), this + split will be @code{eval}ed. If the result is address@hidden, it will + be used as a split. This means that there will be three buffers if + @code{gnus-carpal} is @code{nil}, and four buffers if @code{gnus-carpal} + is address@hidden + + Not complicated enough for you? Well, try this on for size: + + @lisp + (article (horizontal 1.0 + (vertical 0.5 + (group 1.0) + (gnus-carpal 4)) + (vertical 1.0 + (summary 0.25 point) + (summary-carpal 4) + (article 1.0)))) + @end lisp + + Whoops. Two buffers with the mystery 100% tag. And what's that + @code{horizontal} thingie? + + If the first element in one of the split is @code{horizontal}, Gnus will + split the window horizontally, giving you two windows side-by-side. + Inside each of these strips you may carry on all you like in the normal + fashion. The number following @code{horizontal} says what percentage of + the screen is to be given to this strip. + + For each split, there @emph{must} be one element that has the 100% tag. + The splitting is never accurate, and this buffer will eat any leftover + lines from the splits. + + To be slightly more formal, here's a definition of what a valid split + may look like: + + @example + @group + split = frame | horizontal | vertical | buffer | form + frame = "(frame " size *split ")" + horizontal = "(horizontal " size *split ")" + vertical = "(vertical " size *split ")" + buffer = "(" buf-name " " size *[ "point" ] *[ "frame-focus"] ")" + size = number | frame-params + buf-name = group | article | summary ... + @end group + @end example + + The limitations are that the @code{frame} split can only appear as the + top-level split. @var{form} should be an Emacs Lisp form that should + return a valid split. We see that each split is fully recursive, and + may contain any number of @code{vertical} and @code{horizontal} splits. + + @vindex gnus-window-min-width + @vindex gnus-window-min-height + @cindex window height + @cindex window width + Finding the right sizes can be a bit complicated. No window may be less + than @code{gnus-window-min-height} (default 1) characters high, and all + windows must be at least @code{gnus-window-min-width} (default 1) + characters wide. Gnus will try to enforce this before applying the + splits. If you want to use the normal Emacs window width/height limit, + you can just set these two variables to @code{nil}. + + If you're not familiar with Emacs terminology, @code{horizontal} and + @code{vertical} splits may work the opposite way of what you'd expect. + Windows inside a @code{horizontal} split are shown side-by-side, and + windows within a @code{vertical} split are shown above each other. + + @findex gnus-configure-frame + If you want to experiment with window placement, a good tip is to call + @code{gnus-configure-frame} directly with a split. This is the function + that does all the real work when splitting buffers. Below is a pretty + nonsensical configuration with 5 windows; two for the group buffer and + three for the article buffer. (I said it was nonsensical.) If you + @code{eval} the statement below, you can get an idea of how that would + look straight away, without going through the normal Gnus channels. + Play with it until you're satisfied, and then use + @code{gnus-add-configuration} to add your new creation to the buffer + configuration list. + + @lisp + (gnus-configure-frame + '(horizontal 1.0 + (vertical 10 + (group 1.0) + (article 0.3 point)) + (vertical 1.0 + (article 1.0) + (horizontal 4 + (group 1.0) + (article 10))))) + @end lisp + + You might want to have several frames as well. No prob---just use the + @code{frame} split: + + @lisp + (gnus-configure-frame + '(frame 1.0 + (vertical 1.0 + (summary 0.25 point frame-focus) + (article 1.0)) + (vertical ((height . 5) (width . 15) + (user-position . t) + (left . -1) (top . 1)) + (picon 1.0)))) + + @end lisp + + This split will result in the familiar summary/article window + configuration in the first (or main'') frame, while a small additional + frame will be created where picons will be shown. As you can see, + instead of the normal @code{1.0} top-level spec, each additional split + should have a frame parameter alist as the size spec. + @xref{Frame Parameters, , Frame Parameters, elisp, The GNU Emacs Lisp + Reference Manual}. Under XEmacs, a frame property list will be + accepted, too---for instance, @code{(height 5 width 15 left -1 top 1)} + is such a plist. + The list of all possible keys for @code{gnus-buffer-configuration} can + be found in its default value. + + Note that the @code{message} key is used for both + @code{gnus-group-mail} and @code{gnus-summary-mail-other-window}. If + it is desirable to distinguish between the two, something like this + might be used: + + @lisp + (message (horizontal 1.0 + (vertical 1.0 (message 1.0 point)) + (vertical 0.24 + (if (buffer-live-p gnus-summary-buffer) + '(summary 0.5)) + (group 1.0)))) + @end lisp + + One common desire for a multiple frame split is to have a separate frame + for composing mail and news while leaving the original frame intact. To + accomplish that, something like the following can be done: + + @lisp + (message + (frame 1.0 + (if (not (buffer-live-p gnus-summary-buffer)) + (car (cdr (assoc 'group gnus-buffer-configuration))) + (car (cdr (assoc 'summary gnus-buffer-configuration)))) + (vertical ((user-position . t) (top . 1) (left . 1) + (name . "Message")) + (message 1.0 point)))) + @end lisp + + @findex gnus-add-configuration + Since the @code{gnus-buffer-configuration} variable is so long and + complicated, there's a function you can use to ease changing the config + of a single setting: @code{gnus-add-configuration}. If, for instance, + you want to change the @code{article} setting, you could say: + + @lisp + (gnus-add-configuration + '(article (vertical 1.0 + (group 4) + (summary .25 point) + (article 1.0)))) + @end lisp + + You'd typically stick these @code{gnus-add-configuration} calls in your + @file{~/.gnus.el} file or in some startup hook---they should be run after + Gnus has been loaded. + + @vindex gnus-always-force-window-configuration + If all windows mentioned in the configuration are already visible, Gnus + won't change the window configuration. If you always want to force the + right'' window configuration, you can set + @code{gnus-always-force-window-configuration} to address@hidden + + If you're using tree displays (@pxref{Tree Display}), and the tree + window is displayed vertically next to another window, you may also want + to fiddle with @code{gnus-tree-minimize-window} to avoid having the + windows resized. + + @subsection Example Window Configurations + + @itemize @bullet + @item + Narrow left hand side occupied by group buffer. Right hand side split + between summary buffer (top one-sixth) and article buffer (bottom). + + @ifinfo + @example + +---+---------+ + | G | Summary | + | r +---------+ + | o | | + | u | Article | + | p | | + +---+---------+ + @end example + @end ifinfo + + @lisp + (gnus-add-configuration + '(article + (horizontal 1.0 + (vertical 25 (group 1.0)) + (vertical 1.0 + (summary 0.16 point) + (article 1.0))))) + + (gnus-add-configuration + '(summary + (horizontal 1.0 + (vertical 25 (group 1.0)) + (vertical 1.0 (summary 1.0 point))))) + @end lisp + + @end itemize + + + @node Faces and Fonts + @section Faces and Fonts + @cindex faces + @cindex fonts + @cindex colors + + Fiddling with fonts and faces used to be very difficult, but these days + it is very simple. You simply say @kbd{M-x customize-face}, pick out + the face you want to alter, and alter it via the standard Customize + interface. + + + @node Compilation + @section Compilation + @cindex compilation + @cindex byte-compilation + + @findex gnus-compile + + Remember all those line format specification variables? + @code{gnus-summary-line-format}, @code{gnus-group-line-format}, and so + on. Now, Gnus will of course heed whatever these variables are, but, + unfortunately, changing them will mean a quite significant slow-down. + (The default values of these variables have byte-compiled functions + associated with them, while the user-generated versions do not, of + course.) + + To help with this, you can run @kbd{M-x gnus-compile} after you've + fiddled around with the variables and feel that you're (kind of) + satisfied. This will result in the new specs being byte-compiled, and + you'll get top speed again. Gnus will save these compiled specs in the + @file{.newsrc.eld} file. (User-defined functions aren't compiled by + this function, though---you should compile them yourself by sticking + them into the @file{~/.gnus.el} file and byte-compiling that file.) + + + @node Mode Lines + @section Mode Lines + @cindex mode lines + + @vindex gnus-updated-mode-lines + @code{gnus-updated-mode-lines} says what buffers should keep their mode + lines updated. It is a list of symbols. Supported symbols include + @code{group}, @code{article}, @code{summary}, @code{server}, + @code{browse}, and @code{tree}. If the corresponding symbol is present, + Gnus will keep that mode line updated with information that may be + pertinent. If this variable is @code{nil}, screen refresh may be + quicker. + + @cindex display-time + + @vindex gnus-mode-non-string-length + By default, Gnus displays information on the current article in the mode + lines of the summary and article buffers. The information Gnus wishes + to display (e.g. the subject of the article) is often longer than the + mode lines, and therefore have to be cut off at some point. The + @code{gnus-mode-non-string-length} variable says how long the other + elements on the line is (i.e., the non-info part). If you put + additional elements on the mode line (e.g. a clock), you should modify + this variable: + + @c Hook written by Francesco Potorti <address@hidden> + @lisp + (add-hook 'display-time-hook + (lambda () (setq gnus-mode-non-string-length + (+ 21 + (if line-number-mode 5 0) + (if column-number-mode 4 0) + (length display-time-string))))) + @end lisp + + If this variable is @code{nil} (which is the default), the mode line + strings won't be chopped off, and they won't be padded either. Note + that the default is unlikely to be desirable, as even the percentage + complete in the buffer may be crowded off the mode line; the user should + configure this variable appropriately for her configuration. + + + @node Highlighting and Menus + @section Highlighting and Menus + @cindex visual + @cindex highlighting + @cindex menus + + @vindex gnus-visual + The @code{gnus-visual} variable controls most of the Gnus-prettifying + aspects. If @code{nil}, Gnus won't attempt to create menus or use fancy + colors or fonts. This will also inhibit loading the @file{gnus-vis.el} + file. + + This variable can be a list of visual properties that are enabled. The + following elements are valid, and are all included by default: + + @table @code + @item group-highlight + Do highlights in the group buffer. + @item summary-highlight + Do highlights in the summary buffer. + @item article-highlight + Do highlights in the article buffer. + @item highlight + Turn on highlighting in all buffers. + @item group-menu + Create menus in the group buffer. + @item summary-menu + Create menus in the summary buffers. + @item article-menu + Create menus in the article buffer. + @item browse-menu + Create menus in the browse buffer. + @item server-menu + Create menus in the server buffer. + @item score-menu + Create menus in the score buffers. + @item menu + Create menus in all buffers. + @end table + + So if you only want highlighting in the article buffer and menus in all + buffers, you could say something like: + + @lisp + (setq gnus-visual '(article-highlight menu)) + @end lisp + + If you want highlighting only and no menus whatsoever, you'd say: + + @lisp + (setq gnus-visual '(highlight)) + @end lisp + + If @code{gnus-visual} is @code{t}, highlighting and menus will be used + in all Gnus buffers. + + Other general variables that influence the look of all buffers include: + + @table @code + @item gnus-mouse-face + @vindex gnus-mouse-face + This is the face (i.e., font) used for mouse highlighting in Gnus. No + mouse highlights will be done if @code{gnus-visual} is @code{nil}. + + @end table + + There are hooks associated with the creation of all the different menus: + + @table @code + + @item gnus-article-menu-hook + @vindex gnus-article-menu-hook + Hook called after creating the article mode menu. + + @item gnus-group-menu-hook + @vindex gnus-group-menu-hook + Hook called after creating the group mode menu. + + @item gnus-summary-menu-hook + @vindex gnus-summary-menu-hook + Hook called after creating the summary mode menu. + + @item gnus-server-menu-hook + @vindex gnus-server-menu-hook + Hook called after creating the server mode menu. + + @item gnus-browse-menu-hook + @vindex gnus-browse-menu-hook + Hook called after creating the browse mode menu. + + @item gnus-score-menu-hook + @vindex gnus-score-menu-hook + Hook called after creating the score mode menu. + + @end table + + + @node Buttons + @section Buttons + @cindex buttons + @cindex mouse + @cindex click + + Those new-fangled @dfn{mouse} contraptions is very popular with the + young, hep kids who don't want to learn the proper way to do things + these days. Why, I remember way back in the summer of '89, when I was + using Emacs on a Tops 20 system. Three hundred users on one single + machine, and every user was running Simula compilers. Bah! + + Right. + + @vindex gnus-carpal + Well, you can make Gnus display bufferfuls of buttons you can click to + do anything by setting @code{gnus-carpal} to @code{t}. Pretty simple, + really. Tell the chiropractor I sent you. + + + @table @code + + @item gnus-carpal-mode-hook + @vindex gnus-carpal-mode-hook + Hook run in all carpal mode buffers. + + @item gnus-carpal-button-face + @vindex gnus-carpal-button-face + Face used on buttons. + + @item gnus-carpal-header-face + @vindex gnus-carpal-header-face + Face used on carpal buffer headers. + + @item gnus-carpal-group-buffer-buttons + @vindex gnus-carpal-group-buffer-buttons + Buttons in the group buffer. + + @item gnus-carpal-summary-buffer-buttons + @vindex gnus-carpal-summary-buffer-buttons + Buttons in the summary buffer. + + @item gnus-carpal-server-buffer-buttons + @vindex gnus-carpal-server-buffer-buttons + Buttons in the server buffer. + + @item gnus-carpal-browse-buffer-buttons + @vindex gnus-carpal-browse-buffer-buttons + Buttons in the browse buffer. + @end table + + All the @code{buttons} variables are lists. The elements in these list + are either cons cells where the @code{car} contains a text to be displayed and + the @code{cdr} contains a function symbol, or a simple string. + + + @node Daemons + @section Daemons + @cindex demons + @cindex daemons + + Gnus, being larger than any program ever written (allegedly), does lots + of strange stuff that you may wish to have done while you're not + present. For instance, you may want it to check for new mail once in a + while. Or you may want it to close down all connections to all servers + when you leave Emacs idle. And stuff like that. + + Gnus will let you do stuff like that by defining various + @dfn{handlers}. Each handler consists of three elements: A + @var{function}, a @var{time}, and an @var{idle} parameter. + + Here's an example of a handler that closes connections when Emacs has + been idle for thirty minutes: + + @lisp + (gnus-demon-close-connections nil 30) + @end lisp + + Here's a handler that scans for @acronym{PGP} headers every hour when + Emacs is idle: + + @lisp + (gnus-demon-scan-pgp 60 t) + @end lisp + + This @var{time} parameter and that @var{idle} parameter work together + in a strange, but wonderful fashion. Basically, if @var{idle} is + @code{nil}, then the function will be called every @var{time} minutes. + + If @var{idle} is @code{t}, then the function will be called after + @var{time} minutes only if Emacs is idle. So if Emacs is never idle, + the function will never be called. But once Emacs goes idle, the + function will be called every @var{time} minutes. + + If @var{idle} is a number and @var{time} is a number, the function will + be called every @var{time} minutes only when Emacs has been idle for + @var{idle} minutes. + + If @var{idle} is a number and @var{time} is @code{nil}, the function + will be called once every time Emacs has been idle for @var{idle} + minutes. + + And if @var{time} is a string, it should look like @samp{07:31}, and + the function will then be called once every day somewhere near that + time. Modified by the @var{idle} parameter, of course. + + @vindex gnus-demon-timestep + (When I say minute'' here, I really mean @code{gnus-demon-timestep} + seconds. This is 60 by default. If you change that variable, + all the timings in the handlers will be affected.) + + So, if you want to add a handler, you could put something like this in + your @file{~/.gnus.el} file: + + @findex gnus-demon-add-handler + @lisp + (gnus-demon-add-handler 'gnus-demon-close-connections 30 t) + @end lisp + + @findex gnus-demon-add-nocem + @findex gnus-demon-add-scanmail + @findex gnus-demon-add-rescan + @findex gnus-demon-add-scan-timestamps + @findex gnus-demon-add-disconnection + Some ready-made functions to do this have been created: + @code{gnus-demon-add-nocem}, @code{gnus-demon-add-disconnection}, + @code{gnus-demon-add-nntp-close-connection}, + @code{gnus-demon-add-scan-timestamps}, @code{gnus-demon-add-rescan}, and + @code{gnus-demon-add-scanmail}. Just put those functions in your + @file{~/.gnus.el} if you want those abilities. + + @findex gnus-demon-init + @findex gnus-demon-cancel + @vindex gnus-demon-handlers + If you add handlers to @code{gnus-demon-handlers} directly, you should + run @code{gnus-demon-init} to make the changes take hold. To cancel all + daemons, you can use the @code{gnus-demon-cancel} function. + + Note that adding daemons can be pretty naughty if you over do it. Adding + functions that scan all news and mail from all servers every two seconds + is a sure-fire way of getting booted off any respectable system. So + behave. + + + @node NoCeM + @section NoCeM + @cindex nocem + @cindex spam + + @dfn{Spamming} is posting the same article lots and lots of times. + Spamming is bad. Spamming is evil. + + Spamming is usually canceled within a day or so by various anti-spamming + agencies. These agencies usually also send out @dfn{NoCeM} messages. + NoCeM is pronounced no see-'em'', and means what the name + implies---these are messages that make the offending articles, like, go + away. + + What use are these NoCeM messages if the articles are canceled anyway? + Some sites do not honor cancel messages and some sites just honor cancels + from a select few people. Then you may wish to make use of the NoCeM + messages, which are distributed in the @samp{alt.nocem.misc} newsgroup. + + Gnus can read and parse the messages in this group automatically, and + this will make spam disappear. + + There are some variables to customize, of course: + + @table @code + @item gnus-use-nocem + @vindex gnus-use-nocem + Set this variable to @code{t} to set the ball rolling. It is @code{nil} + by default. + + @item gnus-nocem-groups + @vindex gnus-nocem-groups + Gnus will look for NoCeM messages in the groups in this list. The + default is + @lisp + ("news.lists.filters" "news.admin.net-abuse.bulletins" + "alt.nocem.misc" "news.admin.net-abuse.announce") + @end lisp + + @item gnus-nocem-issuers + @vindex gnus-nocem-issuers + There are many people issuing NoCeM messages. This list says what + people you want to listen to. The default is + @lisp + ("Automoose-1" "clewis@@ferret.ocunix.on.ca" + "cosmo.roadkill" "SpamHippo" "hweede@@snafu.de") + @end lisp + fine, upstanding citizens all of them. + + Known despammers that you can put in this list are listed address@hidden + @uref{http://www.xs4all.nl/~rosalind/nocemreg/nocemreg.html}. + + You do not have to heed NoCeM messages from all these people---just the + ones you want to listen to. You also don't have to accept all NoCeM + messages from the people you like. Each NoCeM message has a @dfn{type} + header that gives the message a (more or less, usually less) rigorous + definition. Common types are @samp{spam}, @samp{spew}, @samp{mmf}, + @samp{binary}, and @samp{troll}. To specify this, you have to use + @code{(@var{issuer} @var{conditions} @dots{})} elements in the list. + Each condition is either a string (which is a regexp that matches types + you want to use) or a list on the form @code{(not @var{string})}, where + @var{string} is a regexp that matches types you don't want to use. + + For instance, if you want all NoCeM messages from Chris Lewis except his + @samp{troll} messages, you'd say: + + @lisp + ("clewis@@ferret.ocunix.on.ca" ".*" (not "troll")) + @end lisp + + On the other hand, if you just want nothing but his @samp{spam} and + @samp{spew} messages, you'd say: + + @lisp + ("clewis@@ferret.ocunix.on.ca" (not ".*") "spew" "spam") + @end lisp + + The specs are applied left-to-right. + + + @item gnus-nocem-verifyer + @vindex gnus-nocem-verifyer + @findex mc-verify + This should be a function for verifying that the NoCeM issuer is who she + says she is. The default is @code{mc-verify}, which is a Mailcrypt + function. If this is too slow and you don't care for verification + (which may be dangerous), you can set this variable to @code{nil}. + + If you want signed NoCeM messages to be verified and unsigned messages + not to be verified (but used anyway), you could do something like: + + @lisp + (setq gnus-nocem-verifyer 'my-gnus-mc-verify) + + (defun my-gnus-mc-verify () + (not (eq 'forged + (ignore-errors + (if (mc-verify) + t + 'forged))))) + @end lisp + + This might be dangerous, though. + + @item gnus-nocem-directory + @vindex gnus-nocem-directory + This is where Gnus will store its NoCeM cache files. The default address@hidden + @file{~/News/NoCeM/}. + + @item gnus-nocem-expiry-wait + @vindex gnus-nocem-expiry-wait + The number of days before removing old NoCeM entries from the cache. + The default is 15. If you make it shorter Gnus will be faster, but you + might then see old spam. + + @item gnus-nocem-check-from + @vindex gnus-nocem-check-from + address@hidden means check for valid issuers in message bodies. + Otherwise don't bother fetching articles unless their author matches a + valid issuer; that is much faster if you are selective about the + issuers. + + @item gnus-nocem-check-article-limit + @vindex gnus-nocem-check-article-limit + If address@hidden, the maximum number of articles to check in any NoCeM + group. NoCeM groups can be huge and very slow to process. + + @end table + + Using NoCeM could potentially be a memory hog. If you have many living + (i. e., subscribed or unsubscribed groups), your Emacs process will grow + big. If this is a problem, you should kill off all (or most) of your + unsubscribed groups (@pxref{Subscription Commands}). + + + @node Undo + @section Undo + @cindex undo + + It is very useful to be able to undo actions one has done. In normal + Emacs buffers, it's easy enough---you just push the @code{undo} button. + In Gnus buffers, however, it isn't that simple. + + The things Gnus displays in its buffer is of no value whatsoever to + Gnus---it's all just data designed to look nice to the user. + Killing a group in the group buffer with @kbd{C-k} makes the line + disappear, but that's just a side-effect of the real action---the + removal of the group in question from the internal Gnus structures. + Undoing something like that can't be done by the normal Emacs + @code{undo} function. + + Gnus tries to remedy this somewhat by keeping track of what the user + does and coming up with actions that would reverse the actions the user + takes. When the user then presses the @code{undo} key, Gnus will run + the code to reverse the previous action, or the previous actions. + However, not all actions are easily reversible, so Gnus currently offers + a few key functions to be undoable. These include killing groups, + yanking groups, and changing the list of read articles of groups. + That's it, really. More functions may be added in the future, but each + added function means an increase in data to be stored, so Gnus will + never be totally undoable. + + @findex gnus-undo-mode + @vindex gnus-use-undo + @findex gnus-undo + The undoability is provided by the @code{gnus-undo-mode} minor mode. It + is used if @code{gnus-use-undo} is address@hidden, which is the + default. The @kbd{C-M-_} key performs the @code{gnus-undo} + command, which should feel kinda like the normal Emacs @code{undo} + command. + + + @node Predicate Specifiers + @section Predicate Specifiers + @cindex predicate specifiers + + Some Gnus variables are @dfn{predicate specifiers}. This is a special + form that allows flexible specification of predicates without having + to type all that much. + + These specifiers are lists consisting of functions, symbols and lists. + + Here's an example: + + @lisp + (or gnus-article-unseen-p + gnus-article-unread-p) + @end lisp + + The available symbols are @code{or}, @code{and} and @code{not}. The + functions all take one parameter. + + @findex gnus-make-predicate + Internally, Gnus calls @code{gnus-make-predicate} on these specifiers + to create a function that can be called. This input parameter to this + function will be passed along to all the functions in the predicate + specifier. + + + @node Moderation + @section Moderation + @cindex moderation + + If you are a moderator, you can use the @file{gnus-mdrtn.el} package. + It is not included in the standard Gnus package. Write a mail to + @samp{larsi@@gnus.org} and state what group you moderate, and you'll + get a copy. + + The moderation package is implemented as a minor mode for summary + buffers. Put + + @lisp + (add-hook 'gnus-summary-mode-hook 'gnus-moderate) + @end lisp + + in your @file{~/.gnus.el} file. + + If you are the moderator of @samp{rec.zoofle}, this is how it's + supposed to work: + + @enumerate + @item + You split your incoming mail by matching on + @samp{Newsgroups:.*rec.zoofle}, which will put all the to-be-posted + articles in some mail group---for instance, @samp{nnml:rec.zoofle}. + + @item + You enter that group once in a while and post articles using the @kbd{e} + (edit-and-post) or @kbd{s} (just send unedited) commands. + + @item + If, while reading the @samp{rec.zoofle} newsgroup, you happen upon some + articles that weren't approved by you, you can cancel them with the + @kbd{c} command. + @end enumerate + + To use moderation mode in these two groups, say: + + @lisp + (setq gnus-moderated-list + "^nnml:rec.zoofle$\\|^rec.zoofle$") + @end lisp + + + @node Image Enhancements + @section Image Enhancements + + XEmacs, as well as Emacs address@hidden 21 on MS Windows doesn't + support images yet.}, is able to display pictures and stuff, so Gnus has + taken advantage of that. + + @menu + * X-Face:: Display a funky, teensy black-and-white image. + * Face:: Display a funkier, teensier colored image. + * Smileys:: Show all those happy faces the way they were meant to be shown. + * Picons:: How to display pictures of what you're reading. + * XVarious:: Other XEmacsy Gnusey variables. + @end menu + + + @node X-Face + @subsection X-Face + @cindex x-face + + @code{X-Face} headers describe a 48x48 pixel black-and-white (1 bit + depth) image that's supposed to represent the author of the message. + It seems to be supported by an ever-growing number of mail and news + readers. + + @cindex x-face + @findex gnus-article-display-x-face + @vindex gnus-article-x-face-command + @vindex gnus-article-x-face-too-ugly + @iftex + @iflatex + \include{xface} + @end iflatex + @end iftex + @c @anchor{X-Face} + + Decoding an @code{X-Face} header either requires an Emacs that has + @samp{compface} support (which most XEmacs versions has), or that you + have @samp{compface} installed on your system. If either is true, + Gnus will default to displaying @code{X-Face} headers. + + The variable that controls this is the + @code{gnus-article-x-face-command} variable. If this variable is a + string, this string will be executed in a sub-shell. If it is a + function, this function will be called with the face as the argument. + If the @code{gnus-article-x-face-too-ugly} (which is a regexp) matches + the @code{From} header, the face will not be shown. + + The default action under Emacs 20 is to fork off the @code{display} + address@hidden@code{display} is from the ImageMagick package. For + the @code{uncompface} and @code{icontopbm} programs look for a package + like @code{compface} or @code{faces-xface} on a GNU/Linux system.} to + view the face. + + Under XEmacs or Emacs 21+ with suitable image support, the default + action is to display the face before the @code{From} header. (It's + nicer if XEmacs has been compiled with @code{X-Face} support---that + will make display somewhat faster. If there's no native @code{X-Face} + support, Gnus will try to convert the @code{X-Face} header using + external programs from the @code{pbmplus} package and + address@hidden a GNU/Linux system look for packages with names + like @code{netpbm}, @code{libgr-progs} and @code{compface}.}) + + (Note: @code{x-face} is used in the variable/function names, not + @code{xface}). + + Gnus provides a few convenience functions and variables to allow + easier insertion of X-Face headers in outgoing messages. + + @findex gnus-random-x-face + @vindex gnus-convert-pbm-to-x-face-command + @vindex gnus-x-face-directory + @code{gnus-random-x-face} goes through all the @samp{pbm} files in + @code{gnus-x-face-directory} and picks one at random, and then + converts it to the X-Face format by using the + @code{gnus-convert-pbm-to-x-face-command} shell command. The + @samp{pbm} files should be 48x48 pixels big. It returns the X-Face + header data as a string. + + @findex gnus-insert-random-x-face-header + @code{gnus-insert-random-x-face-header} calls + @code{gnus-random-x-face} and inserts a @samp{X-Face} header with the + randomly generated data. + + @findex gnus-x-face-from-file + @vindex gnus-convert-image-to-x-face-command + @code{gnus-x-face-from-file} takes a GIF file as the parameter, and then + converts the file to X-Face format by using the + @code{gnus-convert-image-to-x-face-command} shell command. + + Here's how you would typically use the first function. Put something + like the following in your @file{~/.gnus.el} file: + + @lisp + (setq message-required-news-headers + (nconc message-required-news-headers + (list '(X-Face . gnus-random-x-face)))) + @end lisp + + Using the last function would be something like this: + + @lisp + (setq message-required-news-headers + (nconc message-required-news-headers + (list '(X-Face . (lambda () + (gnus-x-face-from-file + "~/My-face.gif")))))) + @end lisp + + + @node Face + @subsection Face + @cindex face + + @c #### FIXME: faces and x-faces'implementations should really be harmonized. + + @code{Face} headers are essentially a funkier version of @code{X-Face} + ones. They describe a 48x48 pixel colored image that's supposed to + represent the author of the message. + + @cindex face + @findex gnus-article-display-face + The contents of a @code{Face} header must be a base64 encoded PNG image. + See @uref{http://quimby.gnus.org/circus/face/} for the precise + specifications. + + Gnus provides a few convenience functions and variables to allow + easier insertion of Face headers in outgoing messages. + + @findex gnus-convert-png-to-face + @code{gnus-convert-png-to-face} takes a 48x48 PNG image, no longer than + 726 bytes long, and converts it to a face. + + @findex gnus-face-from-file + @vindex gnus-convert-image-to-face-command + @code{gnus-face-from-file} takes a JPEG file as the parameter, and then + converts the file to Face format by using the + @code{gnus-convert-image-to-face-command} shell command. + + Here's how you would typically use this function. Put something like the + following in your @file{~/.gnus.el} file: + + @lisp + (setq message-required-news-headers + (nconc message-required-news-headers + (list '(Face . (lambda () + (gnus-face-from-file "~/face.jpg")))))) + @end lisp + + + @node Smileys + @subsection Smileys + @cindex smileys + + @iftex + @iflatex + \gnusfig{-3cm}{0.5cm}{\epsfig{figure=ps/BigFace,height=20cm}} + \input{smiley} + @end iflatex + @end iftex + + @dfn{Smiley} is a package separate from Gnus, but since Gnus is + currently the only package that uses Smiley, it is documented here. + + In short---to use Smiley in Gnus, put the following in your + @file{~/.gnus.el} file: + + @lisp + (setq gnus-treat-display-smileys t) + @end lisp + + Smiley maps text smiley address@hidden:-)}, @samp{8-)}, @samp{:-(} and + the like---to pictures and displays those instead of the text smiley + faces. The conversion is controlled by a list of regexps that matches + text and maps that to file names. + + @vindex smiley-regexp-alist + The alist used is specified by the @code{smiley-regexp-alist} + variable. The first item in each element is the regexp to be matched; + the second element is the regexp match group that is to be replaced by + the picture; and the third element is the name of the file to be + displayed. + + The following variables customize where Smiley will look for these + files: + + @table @code + + @item smiley-data-directory + @vindex smiley-data-directory + Where Smiley will look for smiley faces files. + + @item gnus-smiley-file-types + @vindex gnus-smiley-file-types + List of suffixes on smiley file names to try. + + @end table + + + @node Picons + @subsection Picons + + @iftex + @iflatex + \include{picons} + @end iflatex + @end iftex + + address@hidden You want to slow down your news reader even more! This is a + good way to do so. It's also a great way to impress people staring + over your shoulder as you read news. + + What are Picons? To quote directly from the Picons Web site: + + @iftex + @iflatex + \margindex{} + @end iflatex + @end iftex + + @quotation + @dfn{Picons} is short for personal icons''. They're small, + constrained images used to represent users and domains on the net, + organized into databases so that the appropriate image for a given + e-mail address can be found. Besides users and domains, there are picon + databases for Usenet newsgroups and weather forecasts. The picons are + in either monochrome @code{XBM} format or color @code{XPM} and + @code{GIF} formats. + @end quotation + + @vindex gnus-picon-databases + For instructions on obtaining and installing the picons databases, + point your Web browser at + @uref{http://www.cs.indiana.edu/picons/ftp/index.html}. + + If you are using Debian GNU/Linux, saying @samp{apt-get install + picons.*} will install the picons where Gnus can find them. + + To enable displaying picons, simply make sure that + @code{gnus-picon-databases} points to the directory containing the + Picons databases. + + The following variables offer control over where things are located. + + @table @code + + @item gnus-picon-databases + @vindex gnus-picon-databases + The location of the picons database. This is a list of directories + containing the @file{news}, @file{domains}, @file{users} (and so on) + subdirectories. Defaults to @code{("/usr/lib/picon" + "/usr/local/faces")}. + + @item gnus-picon-news-directories + @vindex gnus-picon-news-directories + List of subdirectories to search in @code{gnus-picon-databases} for + newsgroups faces. @code{("news")} is the default. + + @item gnus-picon-user-directories + @vindex gnus-picon-user-directories + List of subdirectories to search in @code{gnus-picon-databases} for user + faces. @code{("users" "usenix" "local" "misc")} is the default. + + @item gnus-picon-domain-directories + @vindex gnus-picon-domain-directories + List of subdirectories to search in @code{gnus-picon-databases} for + domain name faces. Defaults to @code{("domains")}. Some people may + want to add @samp{"unknown"} to this list. + + @item gnus-picon-file-types + @vindex gnus-picon-file-types + Ordered list of suffixes on picon file names to try. Defaults to + @code{("xpm" "gif" "xbm")} minus those not built-in your Emacs. + + @end table + + + @node XVarious + @subsection Various XEmacs Variables + + @table @code + @item gnus-xmas-glyph-directory + @vindex gnus-xmas-glyph-directory + This is where Gnus will look for pictures. Gnus will normally + auto-detect this directory, but you may set it manually if you have an + unusual directory structure. + + @item gnus-xmas-logo-color-alist + @vindex gnus-xmas-logo-color-alist + This is an alist where the key is a type symbol and the values are the + foreground and background color of the splash page glyph. + + @item gnus-xmas-logo-color-style + @vindex gnus-xmas-logo-color-style + This is the key used to look up the color in the alist described above. + Valid values include @code{flame}, @code{pine}, @code{moss}, + @code{irish}, @code{sky}, @code{tin}, @code{velvet}, @code{grape}, + @code{labia}, @code{berry}, @code{neutral}, and @code{september}. + + @item gnus-xmas-modeline-glyph + @vindex gnus-xmas-modeline-glyph + A glyph displayed in all Gnus mode lines. It is a tiny gnu head by + default. + + @end table + + @subsubsection Toolbar + + @table @code + + @item gnus-use-toolbar + @vindex gnus-use-toolbar + If @code{nil}, don't display toolbars. If address@hidden, it should be + one of @code{default-toolbar}, @code{top-toolbar}, @code{bottom-toolbar}, + @code{right-toolbar}, or @code{left-toolbar}. + + @item gnus-group-toolbar + @vindex gnus-group-toolbar + The toolbar in the group buffer. + + @item gnus-summary-toolbar + @vindex gnus-summary-toolbar + The toolbar in the summary buffer. + + @item gnus-summary-mail-toolbar + @vindex gnus-summary-mail-toolbar + The toolbar in the summary buffer of mail groups. + + @end table + + @iftex + @iflatex + \margindex{} + @end iflatex + @end iftex + + + @node Fuzzy Matching + @section Fuzzy Matching + @cindex fuzzy matching + + Gnus provides @dfn{fuzzy matching} of @code{Subject} lines when doing + things like scoring, thread gathering and thread comparison. + + As opposed to regular expression matching, fuzzy matching is very fuzzy. + It's so fuzzy that there's not even a definition of what @dfn{fuzziness} + means, and the implementation has changed over time. + + Basically, it tries to remove all noise from lines before comparing. + @samp{Re: }, parenthetical remarks, white space, and so on, are filtered + out of the strings before comparing the results. This often leads to + adequate results---even when faced with strings generated by text + manglers masquerading as newsreaders. + + + @node Thwarting Email Spam + @section Thwarting Email Spam + @cindex email spam + @cindex spam + @cindex UCE + @cindex unsolicited commercial email + + In these last days of the Usenet, commercial vultures are hanging about + and grepping through news like crazy to find email addresses they can + foist off their scams and products to. As a reaction to this, many + people have started putting nonsense addresses into their @code{From} + lines. I think this is counterproductive---it makes it difficult for + people to send you legitimate mail in response to things you write, as + well as making it difficult to see who wrote what. This rewriting may + perhaps be a bigger menace than the unsolicited commercial email itself + in the end. + + The biggest problem I have with email spam is that it comes in under + false pretenses. I press @kbd{g} and Gnus merrily informs me that I + have 10 new emails. I say Golly gee! Happy is me!'' and select the + mail group, only to find two pyramid schemes, seven advertisements + (New! Miracle tonic for growing full, lustrous hair on your toes!'') + and one mail asking me to repent and find some god. + + This is annoying. Here's what you can do about it. + + @menu + * The problem of spam:: Some background, and some solutions + * Anti-Spam Basics:: Simple steps to reduce the amount of spam. + * SpamAssassin:: How to use external anti-spam tools. + * Hashcash:: Reduce spam by burning CPU time. + * Filtering Spam Using The Spam ELisp Package:: + * Filtering Spam Using Statistics with spam-stat:: + @end menu + + @node The problem of spam + @subsection The problem of spam + @cindex email spam + @cindex spam filtering approaches + @cindex filtering approaches, spam + @cindex UCE + @cindex unsolicited commercial email + + First, some background on spam. + + If you have access to e-mail, you are familiar with spam (technically + termed @acronym{UCE}, Unsolicited Commercial E-mail). Simply put, it + exists because e-mail delivery is very cheap compared to paper mail, + so only a very small percentage of people need to respond to an UCE to + make it worthwhile to the advertiser. Ironically, one of the most + common spams is the one offering a database of e-mail addresses for + further spamming. Senders of spam are usually called @emph{spammers}, + but terms like @emph{vermin}, @emph{scum}, @emph{sociopaths}, and + @emph{morons} are in common use as well. + + Spam comes from a wide variety of sources. It is simply impossible to + dispose of all spam without discarding useful messages. A good + example is the TMDA system, which requires senders + unknown to you to confirm themselves as legitimate senders before + their e-mail can reach you. Without getting into the technical side + of TMDA, a downside is clearly that e-mail from legitimate sources may + be discarded if those sources can't or won't confirm themselves + through the TMDA system. Another problem with TMDA is that it + requires its users to have a basic understanding of e-mail delivery + and processing. + + The simplest approach to filtering spam is filtering, at the mail + server or when you sort through incoming mail. If you get 200 spam + messages per day from @samp{random-address@@vmadmin.com}, you block + @samp{vmadmin.com}. If you get 200 messages about @samp{VIAGRA}, you + discard all messages with @samp{VIAGRA} in the message. If you get + lots of spam from China, for example, you try to filter all mail from + Chinese IPs. + + This, unfortunately, is a great way to discard legitimate e-mail. For + instance, the very informative and useful RISKS digest has been + blocked by overzealous mail filters because it @strong{contained} + words that were common in spam messages. The risks of blocking a + whole country from contacting you should also be obvious, so don't do + it if you have the choice. Nevertheless, in isolated cases, with + great care, direct filtering of mail can be useful. + + Another approach to filtering e-mail is the distributed spam + processing, for instance DCC implements such a system. In essence, + @var{N} systems around the world agree that a machine @var{X} in + Ghana, Estonia, or California is sending out spam e-mail, and these + @var{N} systems enter @var{X} or the spam e-mail from @var{X} into a + database. The criteria for spam detection vary---it may be the number + of messages sent, the content of the messages, and so on. When a user + of the distributed processing system wants to find out if a message is + spam, he consults one of those @var{N} systems. + + Distributed spam processing works very well against spammers that send + a large number of messages at once, but it requires the user to set up + fairly complicated checks. There are commercial and free distributed + spam processing systems. Distributed spam processing has its risks as + well. For instance legitimate e-mail senders have been accused of + sending spam, and their web sites and mailing lists have been shut + down for some time because of the incident. + + The statistical approach to spam filtering is also popular. It is + based on a statistical analysis of previous spam messages. Usually + the analysis is a simple word frequency count, with perhaps pairs of + words or 3-word combinations thrown into the mix. Statistical + analysis of spam works very well in most of the cases, but it can + classify legitimate e-mail as spam in some cases. It takes time to + run the analysis, the full message must be analyzed, and the user has + to store the database of spam analyses. Statistical analysis on the + server is gaining popularity. This has the advantage of letting the + user Just Read Mail, but has the disadvantage that it's harder to tell + the server that it has misclassified mail. + + Fighting spam is not easy, no matter what anyone says. There is no + magic switch that will distinguish Viagra ads from Mom's e-mails. + Even people are having a hard time telling spam apart from non-spam, + because spammers are actively looking to fool us into thinking they + are Mom, essentially. Spamming is irritating, irresponsible, and + idiotic behavior from a bunch of people who think the world owes them + a favor. We hope the following sections will help you in fighting the + spam plague. + + @node Anti-Spam Basics + @subsection Anti-Spam Basics + @cindex email spam + @cindex spam + @cindex UCE + @cindex unsolicited commercial email + + One way of dealing with spam is having Gnus split out all spam into a + @samp{spam} mail group (@pxref{Splitting Mail}). + + First, pick one (1) valid mail address that you can be reached at, and + put it in your @code{From} header of all your news articles. (I've + chosen @samp{larsi@@trym.ifi.uio.no}, but for many addresses on the form + @samp{larsi+usenet@@ifi.uio.no} will be a better choice. Ask your + sysadmin whether your sendmail installation accepts keywords in the local + part of the mail address.) + + @lisp + (setq message-default-news-headers + "From: Lars Magne Ingebrigtsen <larsi@@trym.ifi.uio.no>\n") + @end lisp + + Then put the following split rule in @code{nnmail-split-fancy} + (@pxref{Fancy Mail Splitting}): + + @lisp + (... + (to "larsi@@trym.ifi.uio.no" + (| ("subject" "re:.*" "misc") + ("references" ".*@@.*" "misc") + "spam")) + ...) + @end lisp + + This says that all mail to this address is suspect, but if it has a + @code{Subject} that starts with a @samp{Re:} or has a @code{References} + header, it's probably ok. All the rest goes to the @samp{spam} group. + (This idea probably comes from Tim Pierce.) + + In addition, many mail spammers talk directly to your @acronym{SMTP} server + and do not include your email address explicitly in the @code{To} + header. Why they do this is unknown---perhaps it's to thwart this + thwarting scheme? In any case, this is trivial to deal with---you just + put anything not addressed to you in the @samp{spam} group by ending + your fancy split rule in this way: + + @lisp + ( + ... + (to "larsi" "misc") + "spam") + @end lisp + + In my experience, this will sort virtually everything into the right + group. You still have to check the @samp{spam} group from time to time to + check for legitimate mail, though. If you feel like being a good net + citizen, you can even send off complaints to the proper authorities on + each unsolicited commercial email---at your leisure. + + This works for me. It allows people an easy way to contact me (they can + just press @kbd{r} in the usual way), and I'm not bothered at all with + spam. It's a win-win situation. Forging @code{From} headers to point + to non-existent domains is yucky, in my opinion. + + Be careful with this approach. Spammers are wise to it. + + + @node SpamAssassin + @subsection SpamAssassin, Vipul's Razor, DCC, etc + @cindex SpamAssassin + @cindex Vipul's Razor + @cindex DCC + + The days where the hints in the previous section were sufficient in + avoiding spam are coming to an end. There are many tools out there + that claim to reduce the amount of spam you get. This section could + easily become outdated fast, as new products replace old, but + fortunately most of these tools seem to have similar interfaces. Even + though this section will use SpamAssassin as an example, it should be + easy to adapt it to most other tools. + + Note that this section does not involve the @code{spam.el} package, + which is discussed in the next section. If you don't care for all + the features of @code{spam.el}, you can make do with these simple + recipes. + + If the tool you are using is not installed on the mail server, you + need to invoke it yourself. Ideas on how to use the + @code{:postscript} mail source parameter (@pxref{Mail Source + Specifiers}) follow. + + @lisp + (setq mail-sources + '((file :prescript "formail -bs spamassassin < /var/mail/%u") + (pop :user "jrl" + :server "pophost" + :postscript + "mv %t /tmp/foo; formail -bs spamc < /tmp/foo > %t"))) + @end lisp + + Once you manage to process your incoming spool somehow, thus making + the mail contain e.g.@: a header indicating it is spam, you are ready to + filter it out. Using normal split methods (@pxref{Splitting Mail}): + + @lisp + (setq nnmail-split-methods '(("spam" "^X-Spam-Flag: YES") + ...)) + @end lisp + + Or using fancy split methods (@pxref{Fancy Mail Splitting}): + + @lisp + (setq nnmail-split-methods 'nnmail-split-fancy + nnmail-split-fancy '(| ("X-Spam-Flag" "YES" "spam") + ...)) + @end lisp + + Some people might not like the idea of piping the mail through various + programs using a @code{:prescript} (if some program is buggy, you + might lose all mail). If you are one of them, another solution is to + call the external tools during splitting. Example fancy split method: + + @lisp + (setq nnmail-split-fancy '(| (: kevin-spamassassin) + ...)) + (defun kevin-spamassassin () + (save-excursion + (save-restriction + (widen) + (if (eq 1 (call-process-region (point-min) (point-max) + "spamc" nil nil nil "-c")) + "spam")))) + @end lisp + + Note that with the nnimap backend, message bodies will not be + downloaded by default. You need to set + @code{nnimap-split-download-body} to t to do that (@pxref{Splitting in + IMAP}). + + That is about it. As some spam is likely to get through anyway, you + might want to have a nifty function to call when you happen to read + spam. And here is the nifty function: + + @lisp + (defun my-gnus-raze-spam () + "Submit SPAM to Vipul's Razor, then mark it as expirable." + (interactive) + (gnus-summary-show-raw-article) + (gnus-summary-save-in-pipe "razor-report -f -d") + (gnus-summary-mark-as-expirable 1)) + @end lisp + + @node Hashcash + @subsection Hashcash + @cindex hashcash + + A novel technique to fight spam is to require senders to do something + costly for each message they send. This has the obvious drawback that + you cannot rely on everyone in the world using this technique, + since it is not part of the Internet standards, but it may be useful + in smaller communities. + + While the tools in the previous section work well in practice, they + work only because the tools are constantly maintained and updated as + new form of spam appears. This means that a small percentage of spam + will always get through. It also means that somewhere, someone needs + to read lots of spam to update these tools. Hashcash avoids that, but + instead prefers that everyone you contact through e-mail supports the + scheme. You can view the two approaches as pragmatic vs dogmatic. + The approaches have their own advantages and disadvantages, but as + often in the real world, a combination of them is stronger than either + one of them separately. + + @cindex X-Hashcash + The something costly'' is to burn CPU time, more specifically to + compute a hash collision up to a certain number of bits. The + resulting hashcash cookie is inserted in a @samp{X-Hashcash:} + header. For more details, and for the external application + @code{hashcash} you need to install to use this feature, see + @uref{http://www.cypherspace.org/~adam/hashcash/}. Even more + information can be found at @uref{http://www.camram.org/}. + + If you wish to call hashcash for each message you send, say something + like: + + @lisp + (require 'hashcash) + (add-hook 'message-send-hook 'mail-add-payment) + @end lisp + + The @file{hashcash.el} library can be found in the Gnus development + contrib directory or at + @uref{http://users.actrix.gen.nz/mycroft/hashcash.el}. + + You will need to set up some additional variables as well: + + @table @code + + @item hashcash-default-payment + @vindex hashcash-default-payment + This variable indicates the default number of bits the hash collision + should consist of. By default this is 0, meaning nothing will be + done. Suggested useful values include 17 to 29. + + @item hashcash-payment-alist + @vindex hashcash-payment-alist + Some receivers may require you to spend burn more CPU time than the + default. This variable contains a list of @samp{(@var{addr} + @var{amount})} cells, where @var{addr} is the receiver (email address + or newsgroup) and @var{amount} is the number of bits in the collision + that is needed. It can also contain @samp{(@var{addr} @var{string} + @var{amount})} cells, where the @var{string} is the string to use + (normally the email address or newsgroup name is used). + + @item hashcash + @vindex hashcash + Where the @code{hashcash} binary is installed. + + @end table + + Currently there is no built in functionality in Gnus to verify + hashcash cookies, it is expected that this is performed by your hand + customized mail filtering scripts. Improvements in this area would be + a useful contribution, however. + + @node Filtering Spam Using The Spam ELisp Package + @subsection Filtering Spam Using The Spam ELisp Package + @cindex spam filtering + @cindex spam + + The idea behind @file{spam.el} is to have a control center for spam detection + and filtering in Gnus. To that end, @file{spam.el} does two things: it + filters new mail, and it analyzes mail known to be spam or ham. + @dfn{Ham} is the name used throughout @file{spam.el} to indicate + non-spam messages. + + First of all, you @strong{must} run the function + @code{spam-initialize} to autoload @code{spam.el} and to install the + @code{spam.el} hooks. There is one exception: if you use the + @code{spam-use-stat} (@pxref{spam-stat spam filtering}) setting, you + should turn it on before @code{spam-initialize}: + + @example + (setq spam-use-stat t) ;; if needed + (spam-initialize) + @end example + + So, what happens when you load @file{spam.el}? + + First, some hooks will get installed by @code{spam-initialize}. There + are some hooks for @code{spam-stat} so it can save its databases, and + there are hooks so interesting things will happen when you enter and + leave a group. More on the sequence of events later (@pxref{Spam + ELisp Package Sequence of Events}). + + You get the following keyboard commands: + + @table @kbd + + @item M-d + @itemx M s x + @itemx S x + @kindex M-d + @kindex S x + @kindex M s x + @findex gnus-summary-mark-as-spam + @code{gnus-summary-mark-as-spam}. + + Mark current article as spam, showing it with the @samp{$} mark.
+ Whenever you see a spam article, make sure to mark its summary line
+ with @kbd{M-d} before leaving the group.  This is done automatically
+ for unread articles in @emph{spam} groups.
+
+ @item M s t
+ @itemx S t
+ @kindex M s t
+ @kindex S t
+ @findex spam-bogofilter-score
+ @code{spam-bogofilter-score}.
+
+ You must have Bogofilter installed for that command to work properly.
+
+ @xref{Bogofilter}.
+
+ @end table
+
+ Also, when you load @file{spam.el}, you will be able to customize its
+ variables.  Try @code{customize-group} on the @samp{spam} variable
+ group.
+
+ * Spam ELisp Package Sequence of Events::
+ * Spam ELisp Package Filtering of Incoming Mail::
+ * Spam ELisp Package Global Variables::
+ * Spam ELisp Package Configuration Examples::
+ * Blacklists and Whitelists::
+ * BBDB Whitelists::
+ * Gmane Spam Reporting::
+ * Anti-spam Hashcash Payments::
+ * Blackholes::
+ * Regular Expressions Header Matching::
+ * Bogofilter::
+ * ifile spam filtering::
+ * spam-stat spam filtering::
+ * SpamOracle::
+ * Extending the Spam ELisp package::
+
+ @node Spam ELisp Package Sequence of Events
+ @subsubsection Spam ELisp Package Sequence of Events
+ @cindex spam filtering
+ @cindex spam filtering sequence of events
+ @cindex spam
+
+ You must read this section to understand how @code{spam.el} works.
+ Do not skip, speed-read, or glance through this section.
+
+ There are two @emph{contact points}, if you will, between
+ @code{spam.el} and the rest of Gnus: checking new mail for spam, and
+ leaving a group.
+
+ Getting new mail is done in one of two ways.  You can either split
+ your incoming mail or you can classify new articles as ham or spam
+ when you enter the group.
+
+ Splitting incoming mail is better suited to mail backends such as
+ @code{nnml} or @code{nnimap} where new mail appears in a single file
+ called a @dfn{Spool File}.  See @xref{Spam ELisp Package Filtering of
+ Incoming Mail}.
+
+ For backends such as @code{nntp} there is no incoming mail spool, so
+ an alternate mechanism must be used.  This may also happen for
+ backends where the server is in charge of splitting incoming mail, and
+ Gnus does not do further splitting.  The @code{spam-autodetect} and
+ @code{spam-autodetect-methods} group parameters (accessible with
+ @kbd{G c} and @kbd{G p} as usual), and the corresponding variables
+ @code{gnus-spam-autodetect-methods} and
+ @code{gnus-spam-autodetect-methods} (accessible with @kbd{M-x
+ customize-variable} as usual).
+
+ When @code{spam-autodetect} is used, it hooks into the process of
+ entering a group.  Thus, entering a group with unseen or unread
+ articles becomes the substitute for checking incoming mail.  Whether
+ only unseen articles or all unread articles will be processed is
+ determined by the @code{spam-autodetect-recheck-messages}.  When set
+ to t, unread messages will be rechecked.
+
+ @code{spam-autodetect} grants the user at once more and less control
+ of spam filtering.  The user will have more control over each group's
+ spam methods, so for instance the @samp{ding} group may have
+ @code{spam-use-BBDB} as the autodetection method, while the
+ @samp{suspect} group may have the @code{spam-use-blacklist} and
+ @code{spam-use-bogofilter} methods enabled.  Every article detected to
+ be spam will be marked with the spam mark @samp{$} and processed on + exit from the group as normal spam. The user has less control over + the @emph{sequence} of checks, as he might with @code{spam-split}. + + When the newly split mail goes into groups, or messages are + autodetected to be ham or spam, those groups must be exited (after + entering, if needed) for further spam processing to happen. It + matters whether the group is considered a ham group, a spam group, or + is unclassified, based on its @code{spam-content} parameter + (@pxref{Spam ELisp Package Global Variables}). Spam groups have the + additional characteristic that, when entered, any unseen or unread + articles (depending on the @code{spam-mark-only-unseen-as-spam} + variable) will be marked as spam. Thus, mail split into a spam group + gets automatically marked as spam when you enter the group. + + So, when you exit a group, the @code{spam-processors} are applied, if + any are set, and the processed mail is moved to the + @code{ham-process-destination} or the @code{spam-process-destination} + depending on the article's classification. If the + @code{ham-process-destination} or the @code{spam-process-destination}, + whichever is appropriate, are nil, the article is left in the current + group. + + If a spam is found in any group (this can be changed to only non-spam + groups with @code{spam-move-spam-nonspam-groups-only}), it is + processed by the active @code{spam-processors} (@pxref{Spam ELisp + Package Global Variables}) when the group is exited. Furthermore, the + spam is moved to the @code{spam-process-destination} (@pxref{Spam + ELisp Package Global Variables}) for further training or deletion. + You have to load the @code{gnus-registry.el} package and enable the + @code{spam-log-to-registry} variable if you want spam to be processed + no more than once. Thus, spam is detected and processed everywhere, + which is what most people want. If the + @code{spam-process-destination} is nil, the spam is marked as + expired, which is usually the right thing to do. + + If spam can not be moved - because of a read-only backend such as NNTP, + for example, it will be copied. + + If a ham mail is found in a ham group, as determined by the + @code{ham-marks} parameter, it is processed as ham by the active ham + @code{spam-processor} when the group is exited. With the variables + @code{spam-process-ham-in-spam-groups} and + @code{spam-process-ham-in-nonham-groups} the behavior can be further + altered so ham found anywhere can be processed. You have to load the + @code{gnus-registry.el} package and enable the + @code{spam-log-to-registry} variable if you want ham to be processed + no more than once. Thus, ham is detected and processed only when + necessary, which is what most people want. More on this in + @xref{Spam ELisp Package Configuration Examples}. + + If ham can not be moved - because of a read-only backend such as NNTP, + for example, it will be copied. + + If all this seems confusing, don't worry. Soon it will be as natural + as typing Lisp one-liners on a neural interface... err, sorry, that's + 50 years in the future yet. Just trust us, it's not so bad. + + @node Spam ELisp Package Filtering of Incoming Mail + @subsubsection Spam ELisp Package Filtering of Incoming Mail + @cindex spam filtering + @cindex spam filtering incoming mail + @cindex spam + + To use the @file{spam.el} facilities for incoming mail filtering, you + must add the following to your fancy split list + @code{nnmail-split-fancy} or @code{nnimap-split-fancy}: + + @example + (: spam-split) + @end example + + Note that the fancy split may be called @code{nnmail-split-fancy} or + @code{nnimap-split-fancy}, depending on whether you use the nnmail or + nnimap back ends to retrieve your mail. + + The @code{spam-split} function will process incoming mail and send the + mail considered to be spam into the group name given by the variable + @code{spam-split-group}. By default that group name is @samp{spam}, + but you can customize @code{spam-split-group}. Make sure the contents + of @code{spam-split-group} are an @emph{unqualified} group name, for + instance in an @code{nnimap} server @samp{your-server} the value + @samp{spam} will turn out to be @samp{nnimap+your-server:spam}. The + value @samp{nnimap+server:spam}, therefore, is wrong and will + actually give you the group + @samp{nnimap+your-server:nnimap+server:spam} which may or may not + work depending on your server's tolerance for strange group names. + + You can also give @code{spam-split} a parameter, + e.g. @samp{'spam-use-regex-headers} or @samp{"maybe-spam"}. Why is + this useful? + + Take these split rules (with @code{spam-use-regex-headers} and + @code{spam-use-blackholes} set): + + @example + nnimap-split-fancy '(| + (any "ding" "ding") + (: spam-split) + ;; default mailbox + "mail") + @end example + + Now, the problem is that you want all ding messages to make it to the + ding folder. But that will let obvious spam (for example, spam + detected by SpamAssassin, and @code{spam-use-regex-headers}) through, + when it's sent to the ding list. On the other hand, some messages to + the ding list are from a mail server in the blackhole list, so the + invocation of @code{spam-split} can't be before the ding rule. + + You can let SpamAssassin headers supersede ding rules, but all other + @code{spam-split} rules (including a second invocation of the + regex-headers check) will be after the ding rule: + + @example + nnimap-split-fancy '(| + ;;; all spam detected by spam-use-regex-headers goes to "regex-spam" + (: spam-split "regex-spam" 'spam-use-regex-headers) + (any "ding" "ding") + ;;; all other spam detected by spam-split goes to spam-split-group + (: spam-split) + ;; default mailbox + "mail") + @end example + + This lets you invoke specific @code{spam-split} checks depending on + your particular needs, and to target the results of those checks to a + particular spam group. You don't have to throw all mail into all the + spam tests. Another reason why this is nice is that messages to + mailing lists you have rules for don't have to have resource-intensive + blackhole checks performed on them. You could also specify different + spam checks for your nnmail split vs. your nnimap split. Go crazy. + + You should still have specific checks such as + @code{spam-use-regex-headers} set to @code{t}, even if you + specifically invoke @code{spam-split} with the check. The reason is + that when loading @file{spam.el}, some conditional loading is done + depending on what @code{spam-use-xyz} variables you have set. This + is usually not critical, though. + + @emph{Note for IMAP users} + + The boolean variable @code{nnimap-split-download-body} needs to be + set, if you want to split based on the whole message instead of just + the headers. By default, the nnimap back end will only retrieve the + message headers. If you use @code{spam-check-bogofilter}, + @code{spam-check-ifile}, or @code{spam-check-stat} (the splitters that + can benefit from the full message body), you should set this variable. + It is not set by default because it will slow @acronym{IMAP} down, and + that is not an appropriate decision to make on behalf of the user. + + @xref{Splitting in IMAP}. + + @emph{TODO: spam.el needs to provide a uniform way of training all the + statistical databases. Some have that functionality built-in, others + don't.} + + @node Spam ELisp Package Global Variables + @subsubsection Spam ELisp Package Global Variables + @cindex spam filtering + @cindex spam filtering variables + @cindex spam variables + @cindex spam + + @vindex gnus-spam-process-newsgroups + The concepts of ham processors and spam processors are very important. + Ham processors and spam processors for a group can be set with the + @code{spam-process} group parameter, or the + @code{gnus-spam-process-newsgroups} variable. Ham processors take + mail known to be non-spam (@emph{ham}) and process it in some way so + that later similar mail will also be considered non-spam. Spam + processors take mail known to be spam and process it so similar spam + will be detected later. + + The format of the spam or ham processor entry used to be a symbol, + but now it is a cons cell. See the individual spam processor entries + for more information. + + @vindex gnus-spam-newsgroup-contents + Gnus learns from the spam you get. You have to collect your spam in + one or more spam groups, and set or customize the variable + @code{spam-junk-mailgroups} as appropriate. You can also declare + groups to contain spam by setting their group parameter + @code{spam-contents} to @code{gnus-group-spam-classification-spam}, or + by customizing the corresponding variable + @code{gnus-spam-newsgroup-contents}. The @code{spam-contents} group + parameter and the @code{gnus-spam-newsgroup-contents} variable can + also be used to declare groups as @emph{ham} groups if you set their + classification to @code{gnus-group-spam-classification-ham}. If + groups are not classified by means of @code{spam-junk-mailgroups}, + @code{spam-contents}, or @code{gnus-spam-newsgroup-contents}, they are + considered @emph{unclassified}. All groups are unclassified by + default. + + @vindex gnus-spam-mark + @cindex$
+ In spam groups, all messages are considered to be spam by default:
+ they get the @samp{$} mark (@code{gnus-spam-mark}) when you enter the + group. If you have seen a message, had it marked as spam, then + unmarked it, it won't be marked as spam when you enter the group + thereafter. You can disable that behavior, so all unread messages + will get the @samp{$} mark, if you set the
+ @code{spam-mark-only-unseen-as-spam} parameter to @code{nil}.  You
+ should remove the @samp{$} mark when you are in the group summary + buffer for every message that is not spam after all. To remove the + @samp{$} mark, you can use @kbd{M-u} to unread'' the article, or
+ @kbd{d} for declaring it read the non-spam way.  When you leave a
+ group, all spam-marked (@samp{$}) articles are sent to a spam + processor which will study them as spam samples. + + Messages may also be deleted in various other ways, and unless + @code{ham-marks} group parameter gets overridden below, marks @samp{R} + and @samp{r} for default read or explicit delete, marks @samp{X} and + @samp{K} for automatic or explicit kills, as well as mark @samp{Y} for + low scores, are all considered to be associated with articles which + are not spam. This assumption might be false, in particular if you + use kill files or score files as means for detecting genuine spam, you + should then adjust the @code{ham-marks} group parameter. + + @defvar ham-marks + You can customize this group or topic parameter to be the list of + marks you want to consider ham. By default, the list contains the + deleted, read, killed, kill-filed, and low-score marks (the idea is + that these articles have been read, but are not spam). It can be + useful to also include the tick mark in the ham marks. It is not + recommended to make the unread mark a ham mark, because it normally + indicates a lack of classification. But you can do it, and we'll be + happy for you. + @end defvar + + @defvar spam-marks + You can customize this group or topic parameter to be the list of + marks you want to consider spam. By default, the list contains only + the spam mark. It is not recommended to change that, but you can if + you really want to. + @end defvar + + When you leave @emph{any} group, regardless of its + @code{spam-contents} classification, all spam-marked articles are sent + to a spam processor, which will study these as spam samples. If you + explicit kill a lot, you might sometimes end up with articles marked + @samp{K} which you never saw, and which might accidentally contain + spam. Best is to make sure that real spam is marked with @samp{$},
+ and nothing else.
+
+ @vindex gnus-ham-process-destinations
+ When you leave a @emph{spam} group, all spam-marked articles are
+ marked as expired after processing with the spam processor.  This is
+ not done for @emph{unclassified} or @emph{ham} groups.  Also, any
+ @strong{ham} articles in a spam group will be moved to a location
+ determined by either the @code{ham-process-destination} group
+ parameter or a match in the @code{gnus-ham-process-destinations}
+ variable, which is a list of regular expressions matched with group
+ names (it's easiest to customize this variable with
+ @code{customize-variable gnus-ham-process-destinations}).  Each
+ newsgroup specification has the format (REGEXP PROCESSOR) in a
+ standard Lisp list, if you prefer to customize the variable manually.
+ The ultimate location is a group name or names.  If the
+ @code{ham-process-destination} parameter is not set, ham articles are
+ left in place.  If the
+ set, the ham articles are marked as unread before being moved.
+
+ If ham can not be moved - because of a read-only backend such as NNTP,
+ for example, it will be copied.
+
+ Note that you can use multiples destinations per group or regular
+ expression!  This enables you to send your ham to a regular mail
+ group and to a @emph{ham training} group.
+
+ When you leave a @emph{ham} group, all ham-marked articles are sent to
+ a ham processor, which will study these as non-spam samples.
+
+ @vindex spam-process-ham-in-spam-groups
+ By default the variable @code{spam-process-ham-in-spam-groups} is
+ @code{nil}.  Set it to @code{t} if you want ham found in spam groups
+ to be processed.  Normally this is not done, you are expected instead
+ to send your ham to a ham group and process it there.
+
+ @vindex spam-process-ham-in-nonham-groups
+ By default the variable @code{spam-process-ham-in-nonham-groups} is
+ @code{nil}.  Set it to @code{t} if you want ham found in non-ham (spam
+ or unclassified) groups to be processed.  Normally this is not done,
+ you are expected instead to send your ham to a ham group and process
+ it there.
+
+ @vindex gnus-spam-process-destinations
+ When you leave a @emph{ham} or @emph{unclassified} group, all
+ @strong{spam} articles are moved to a location determined by either
+ the @code{spam-process-destination} group parameter or a match in the
+ @code{gnus-spam-process-destinations} variable, which is a list of
+ regular expressions matched with group names (it's easiest to
+ customize this variable with @code{customize-variable
+ gnus-spam-process-destinations}).  Each newsgroup specification has
+ the repeated format (REGEXP GROUP) and they are all in a standard Lisp
+ list, if you prefer to customize the variable manually.  The ultimate
+ location is a group name or names.  If the
+ @code{spam-process-destination} parameter is not set, the spam
+ articles are only expired.  The group name is fully qualified, meaning
+ that if you see @samp{nntp:servername} before the group name in the
+ group buffer then you need it here as well.
+
+ If spam can not be moved - because of a read-only backend such as NNTP,
+ for example, it will be copied.
+
+ Note that you can use multiples destinations per group or regular
+ expression!  This enables you to send your spam to multiple @emph{spam
+ training} groups.
+
+ @vindex spam-log-to-registry
+ The problem with processing ham and spam is that Gnus doesn't track
+ this processing by default.  Enable the @code{spam-log-to-registry}
+ variable so @code{spam.el} will use @code{gnus-registry.el} to track
+ what articles have been processed, and avoid processing articles
+ multiple times.  Keep in mind that if you limit the number of registry
+ entries, this won't work as well as it does without a limit.
+
+ @vindex spam-mark-only-unseen-as-spam
+ Set this variable if you want only unseen articles in spam groups to
+ be marked as spam.  By default, it is set.  If you set it to nil,
+ unread articles will also be marked as spam.
+
+ Set this variable if you want ham to be unmarked before it is moved
+ out of the spam group.  This is very useful when you use something
+ like the tick mark @samp{!} to mark ham - the article will be placed
+ in your ham-process-destination, unmarked as if it came fresh from
+ the mail server.
+
+ @vindex spam-autodetect-recheck-messages
+ When autodetecting spam, this variable tells @code{spam.el} whether
+ only unseen articles or all unread articles should be checked for
+ spam.  It is recommended that you leave it off.
+
+ @node Spam ELisp Package Configuration Examples
+ @subsubsection Spam ELisp Package Configuration Examples
+ @cindex spam filtering
+ @cindex spam filtering configuration examples
+ @cindex spam configuration examples
+ @cindex spam
+
+
+ From Ted Zlatanov <tzz@@lifelogs.com>.
+ @example
+
+ ;; for gnus-registry-split-fancy-with-parent and spam autodetection
+ (gnus-registry-initialize)
+ (spam-initialize)
+
+ ;; I like control-S for marking spam
+ (define-key gnus-summary-mode-map "\C-s" 'gnus-summary-mark-as-spam)
+
+ (setq
+  spam-log-to-registry t ;; for spam autodetection
+  spam-use-BBDB t
+  spam-use-regex-headers t               ; catch X-Spam-Flag (SpamAssassin)
+  ;; all groups with "spam" in the name contain spam
+  gnus-spam-newsgroup-contents '(("spam" gnus-group-spam-classification-spam))
+  ;; see documentation for these
+  spam-move-spam-nonspam-groups-only nil
+  spam-mark-only-unseen-as-spam t
+  nnimap-split-rule 'nnimap-split-fancy
+  ;; understand what this does before you copy it to your own setup!
+  nnimap-split-fancy '(|
+                       ;; trace references to parents and put in their group
+                       (: gnus-registry-split-fancy-with-parent)
+                       ;; this will catch server-side SpamAssassin tags
+                       (any "ding" "ding")
+                       ;; note that spam by default will go to "spam"
+                       (: spam-split)
+                       ;; default mailbox
+                       "mail"))
+
+ ;; my parameters, set with G p'
+
+ ;; all nnml groups, and all nnimap groups except
+ ;; "nnimap+mail.lifelogs.com:train" and
+ ;; "nnimap+mail.lifelogs.com:spam": any spam goes to nnimap training,
+ ;; because it must have been detected manually
+
+ ((spam-process-destination . "nnimap+mail.lifelogs.com:train"))
+
+ ;; all NNTP groups
+ ;; autodetect spam with the blacklist and ham with the BBDB
+ ((spam-autodetect-methods spam-use-blacklist spam-use-BBDB)
+ ;; send all spam to the training group
+  (spam-process-destination . "nnimap+mail.lifelogs.com:train"))
+
+ ;; only some NNTP groups, where I want to autodetect spam
+ ((spam-autodetect . t))
+
+ ;; my nnimap "nnimap+mail.lifelogs.com:spam" group
+
+ ;; this is a spam group
+ ((spam-contents gnus-group-spam-classification-spam)
+
+  ;; any spam (which happens when I enter for all unseen messages,
+  ;; because of the gnus-spam-newsgroup-contents setting above), goes to
+  ;; "nnimap+mail.lifelogs.com:train" unless I mark it as ham
+
+  (spam-process-destination "nnimap+mail.lifelogs.com:train")
+
+  ;; any ham goes to my "nnimap+mail.lifelogs.com:mail" folder, but
+  ;; also to my "nnimap+mail.lifelogs.com:trainham" folder for training
+
+  (ham-process-destination "nnimap+mail.lifelogs.com:mail"
+                           "nnimap+mail.lifelogs.com:trainham")
+  ;; in this group, only '!' marks are ham
+  (ham-marks
+   (gnus-ticked-mark))
+  ;; remembers senders in the blacklist on the way out - this is
+  ;; definitely not needed, it just makes me feel better
+  (spam-process (gnus-group-spam-exit-processor-blacklist)))
+
+ ;; Later, on the IMAP server I use the "train" group for training
+ ;; SpamAssassin to recognize spam, and the "trainham" group for
+ ;; recognizing ham - but Gnus has nothing to do with it.
+
+ @end example
+
+ @subsubheading Using @file{spam.el} on an IMAP server with a statistical
filter on the server
+
+ From Reiner Steib <reiner.steib@@gmx.de>.
+
+ My provider has set up bogofilter (in combination with @acronym{DCC}) on
+ the mail server (@acronym{IMAP}).  Recognized spam goes to
+ @samp{spam.detected}, the rest goes through the normal filter rules,
+ i.e. to @samp{some.folder} or to @samp{INBOX}.  Training on false
+ positives or negatives is done by copying or moving the article to
+ @samp{training.ham} or @samp{training.spam} respectively.  A cron job on
+ the server feeds those to bogofilter with the suitable ham or spam
+ options and deletes them from the @samp{training.ham} and
+ @samp{training.spam} folders.
+
+ With the following entries in @code{gnus-parameters}, @code{spam.el}
+ does most of the job for me:
+
+ @lisp
+    ("nnimap:spam\\.detected"
+     (gnus-article-sort-functions '(gnus-article-sort-by-chars))
+     (ham-process-destination "nnimap:INBOX" "nnimap:training.ham")
+     (spam-contents gnus-group-spam-classification-spam))
+    ("nnimap:\$$INBOX\\|other-folders\$$"
+     (spam-process-destination . "nnimap:training.spam")
+     (spam-contents gnus-group-spam-classification-ham))
+ @end lisp
+
+ @itemize
+
+ @item @b{The Spam folder:}
+
+ In the folder @samp{spam.detected}, I have to check for false positives
+ (i.e. legitimate mails, that were wrongly judged as spam by
+ bogofilter or DCC).
+
+ Because of the @code{gnus-group-spam-classification-spam} entry, all
+ messages are marked as spam (with @code{$}). When I find a false + positive, I mark the message with some other ham mark (@code{ham-marks}, + @ref{Spam ELisp Package Global Variables}). On group exit, those + messages are copied to both groups, @samp{INBOX} (were I want to have + the article) and @samp{training.ham} (for training bogofilter) and + deleted from the @samp{spam.detected} folder. + + The @code{gnus-article-sort-by-chars} entry simplifies detection of + false positives for me. I receive lots of worms (sweN, @dots{}), that all + have a similar size. Grouping them by size (i.e. chars) makes finding + other false positives easier. (Of course worms aren't @i{spam} + (@acronym{UCE}, @acronym{UBE}) strictly speaking. Anyhow, bogofilter is + an excellent tool for filtering those unwanted mails for me.) + + @item @b{Ham folders:} + + In my ham folders, I just hit @kbd{S x} + (@code{gnus-summary-mark-as-spam}) whenever I see an unrecognized spam + mail (false negative). On group exit, those messages are moved to + @samp{training.ham}. + @end itemize + + @subsubheading Reporting spam articles in Gmane groups with @code{spam-report.el} + + From Reiner Steib <reiner.steib@@gmx.de>. + + With following entry in @code{gnus-parameters}, @kbd{S x} + (@code{gnus-summary-mark-as-spam}) marks articles in @code{gmane.*} + groups as spam and reports the to Gmane at group exit: + + @lisp + ("^gmane\\." + (spam-process (gnus-group-spam-exit-processor-report-gmane))) + @end lisp + + Additionally, I use (setq spam-report-gmane-use-article-number nil)' + because I don't read the groups directly from news.gmane.org, but + through my local news server (leafnode). I.e. the article numbers are + not the same as on news.gmane.org, thus @code{spam-report.el} has to check + the @code{X-Report-Spam} header to find the correct number. + + @node Blacklists and Whitelists + @subsubsection Blacklists and Whitelists + @cindex spam filtering + @cindex whitelists, spam filtering + @cindex blacklists, spam filtering + @cindex spam + + @defvar spam-use-blacklist + + Set this variable to @code{t} if you want to use blacklists when + splitting incoming mail. Messages whose senders are in the blacklist + will be sent to the @code{spam-split-group}. This is an explicit + filter, meaning that it acts only on mail senders @emph{declared} to + be spammers. + + @end defvar + + @defvar spam-use-whitelist + + Set this variable to @code{t} if you want to use whitelists when + splitting incoming mail. Messages whose senders are not in the + whitelist will be sent to the next spam-split rule. This is an + explicit filter, meaning that unless someone is in the whitelist, their + messages are not assumed to be spam or ham. + + @end defvar + + @defvar spam-use-whitelist-exclusive + + Set this variable to @code{t} if you want to use whitelists as an + implicit filter, meaning that every message will be considered spam + unless the sender is in the whitelist. Use with care. + + @end defvar + + @defvar gnus-group-spam-exit-processor-blacklist + + Add this symbol to a group's @code{spam-process} parameter by + customizing the group parameters or the + @code{gnus-spam-process-newsgroups} variable. When this symbol is + added to a group's @code{spam-process} parameter, the senders of + spam-marked articles will be added to the blacklist. + + @emph{WARNING} + + Instead of the obsolete + @code{gnus-group-spam-exit-processor-blacklist}, it is recommended + that you use @code{'(spam spam-use-blacklist)}. Everything will work + the same way, we promise. + + @end defvar + + @defvar gnus-group-ham-exit-processor-whitelist + + Add this symbol to a group's @code{spam-process} parameter by + customizing the group parameters or the + @code{gnus-spam-process-newsgroups} variable. When this symbol is + added to a group's @code{spam-process} parameter, the senders of + ham-marked articles in @emph{ham} groups will be added to the + whitelist. Note that this ham processor has no effect in @emph{spam} + or @emph{unclassified} groups. + + @emph{WARNING} + + Instead of the obsolete + @code{gnus-group-ham-exit-processor-whitelist}, it is recommended + that you use @code{'(ham spam-use-whitelist)}. Everything will work + the same way, we promise. + + @end defvar + + Blacklists are lists of regular expressions matching addresses you + consider to be spam senders. For instance, to block mail from any + sender at @samp{vmadmin.com}, you can put @samp{vmadmin.com} in your + blacklist. You start out with an empty blacklist. Blacklist entries + use the Emacs regular expression syntax. + + Conversely, whitelists tell Gnus what addresses are considered + legitimate. All messages from whitelisted addresses are considered + non-spam. Also see @ref{BBDB Whitelists}. Whitelist entries use the + Emacs regular expression syntax. + + The blacklist and whitelist file locations can be customized with the + @code{spam-directory} variable (@file{~/News/spam} by default), or + the @code{spam-whitelist} and @code{spam-blacklist} variables + directly. The whitelist and blacklist files will by default be in the + @code{spam-directory} directory, named @file{whitelist} and + @file{blacklist} respectively. + + @node BBDB Whitelists + @subsubsection BBDB Whitelists + @cindex spam filtering + @cindex BBDB whitelists, spam filtering + @cindex BBDB, spam filtering + @cindex spam + + @defvar spam-use-BBDB + + Analogous to @code{spam-use-whitelist} (@pxref{Blacklists and + Whitelists}), but uses the BBDB as the source of whitelisted + addresses, without regular expressions. You must have the BBDB loaded + for @code{spam-use-BBDB} to work properly. Messages whose senders are + not in the BBDB will be sent to the next spam-split rule. This is an + explicit filter, meaning that unless someone is in the BBDB, their + messages are not assumed to be spam or ham. + + @end defvar + + @defvar spam-use-BBDB-exclusive + + Set this variable to @code{t} if you want to use the BBDB as an + implicit filter, meaning that every message will be considered spam + unless the sender is in the BBDB. Use with care. Only sender + addresses in the BBDB will be allowed through; all others will be + classified as spammers. + + @end defvar + + @defvar gnus-group-ham-exit-processor-BBDB + + Add this symbol to a group's @code{spam-process} parameter by + customizing the group parameters or the + @code{gnus-spam-process-newsgroups} variable. When this symbol is + added to a group's @code{spam-process} parameter, the senders of + ham-marked articles in @emph{ham} groups will be added to the + BBDB. Note that this ham processor has no effect in @emph{spam} + or @emph{unclassified} groups. + + @emph{WARNING} + + Instead of the obsolete + @code{gnus-group-ham-exit-processor-BBDB}, it is recommended + that you use @code{'(ham spam-use-BBDB)}. Everything will work + the same way, we promise. + + @end defvar + + @node Gmane Spam Reporting + @subsubsection Gmane Spam Reporting + @cindex spam reporting + @cindex Gmane, spam reporting + @cindex Gmane, spam reporting + @cindex spam + + @defvar gnus-group-spam-exit-processor-report-gmane + + Add this symbol to a group's @code{spam-process} parameter by + customizing the group parameters or the + @code{gnus-spam-process-newsgroups} variable. When this symbol is + added to a group's @code{spam-process} parameter, the spam-marked + articles groups will be reported to the Gmane administrators via a + HTTP request. + + Gmane can be found at @uref{http://gmane.org}. + + @emph{WARNING} + + Instead of the obsolete + @code{gnus-group-spam-exit-processor-report-gmane}, it is recommended + that you use @code{'(spam spam-use-gmane)}. Everything will work the + same way, we promise. + + @end defvar + + @defvar spam-report-gmane-use-article-number + + This variable is @code{t} by default. Set it to @code{nil} if you are + running your own news server, for instance, and the local article + numbers don't correspond to the Gmane article numbers. When + @code{spam-report-gmane-use-article-number} is @code{nil}, + @code{spam-report.el} will use the @code{X-Report-Spam} header that + Gmane provides. + + @end defvar + + @node Anti-spam Hashcash Payments + @subsubsection Anti-spam Hashcash Payments + @cindex spam filtering + @cindex hashcash, spam filtering + @cindex spam + + @defvar spam-use-hashcash + + Similar to @code{spam-use-whitelist} (@pxref{Blacklists and + Whitelists}), but uses hashcash tokens for whitelisting messages + instead of the sender address. You must have the @code{hashcash.el} + package loaded for @code{spam-use-hashcash} to work properly. + Messages without a hashcash payment token will be sent to the next + spam-split rule. This is an explicit filter, meaning that unless a + hashcash token is found, the messages are not assumed to be spam or + ham. + + @end defvar + + @node Blackholes + @subsubsection Blackholes + @cindex spam filtering + @cindex blackholes, spam filtering + @cindex spam + + @defvar spam-use-blackholes + + This option is disabled by default. You can let Gnus consult the + blackhole-type distributed spam processing systems (DCC, for instance) + when you set this option. The variable @code{spam-blackhole-servers} + holds the list of blackhole servers Gnus will consult. The current + list is fairly comprehensive, but make sure to let us know if it + contains outdated servers. + + The blackhole check uses the @code{dig.el} package, but you can tell + @file{spam.el} to use @code{dns.el} instead for better performance if + you set @code{spam-use-dig} to @code{nil}. It is not recommended at + this time to set @code{spam-use-dig} to @code{nil} despite the + possible performance improvements, because some users may be unable to + use it, but you can try it and see if it works for you. + + @end defvar + + @defvar spam-blackhole-servers + + The list of servers to consult for blackhole checks. + + @end defvar + + @defvar spam-blackhole-good-server-regex + + A regular expression for IPs that should not be checked against the + blackhole server list. When set to @code{nil}, it has no effect. + + @end defvar + + @defvar spam-use-dig + + Use the @code{dig.el} package instead of the @code{dns.el} package. + The default setting of @code{t} is recommended. + + @end defvar + + Blackhole checks are done only on incoming mail. There is no spam or + ham processor for blackholes. + + @node Regular Expressions Header Matching + @subsubsection Regular Expressions Header Matching + @cindex spam filtering + @cindex regular expressions header matching, spam filtering + @cindex spam + + @defvar spam-use-regex-headers + + This option is disabled by default. You can let Gnus check the + message headers against lists of regular expressions when you set this + option. The variables @code{spam-regex-headers-spam} and + @code{spam-regex-headers-ham} hold the list of regular expressions. + Gnus will check against the message headers to determine if the + message is spam or ham, respectively. + + @end defvar + + @defvar spam-regex-headers-spam + + The list of regular expressions that, when matched in the headers of + the message, positively identify it as spam. + + @end defvar + + @defvar spam-regex-headers-ham + + The list of regular expressions that, when matched in the headers of + the message, positively identify it as ham. + + @end defvar + + Regular expression header checks are done only on incoming mail. + There is no specific spam or ham processor for regular expressions. + + @node Bogofilter + @subsubsection Bogofilter + @cindex spam filtering + @cindex bogofilter, spam filtering + @cindex spam + + @defvar spam-use-bogofilter + + Set this variable if you want @code{spam-split} to use Eric Raymond's + speedy Bogofilter. + + With a minimum of care for associating the @samp{$} mark for spam
+ articles only, Bogofilter training all gets fairly automatic.  You
+ should do this until you get a few hundreds of articles in each
+ category, spam or not.  The command @kbd{S t} in summary mode, either
+ for debugging or for curiosity, shows the @emph{spamicity} score of
+ the current article (between 0.0 and 1.0).
+
+ Bogofilter determines if a message is spam based on a specific
+ threshold.  That threshold can be customized, consult the Bogofilter
+ documentation.
+
+ If the @code{bogofilter} executable is not in your path, Bogofilter
+ processing will be turned off.
+
+ You should not enable this if you use @code{spam-use-bogofilter-headers}.
+
+ @end defvar
+
+
+ Set this variable if you want @code{spam-split} to use Eric Raymond's
+ speedy Bogofilter, looking only at the message headers.  It works
+ similarly to @code{spam-use-bogofilter}, but the @code{X-Bogosity} header
+ must be in the message already.  Normally you would do this with a
+ procmail recipe or something similar; consult the Bogofilter
+ installation documents for details.
+
+ You should not enable this if you use @code{spam-use-bogofilter}.
+
+ @end defvar
+
+ @defvar gnus-group-spam-exit-processor-bogofilter
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameters or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is
+ added to a group's @code{spam-process} parameter, spam-marked articles
+ will be added to the Bogofilter spam database.
+
+ @emph{WARNING}
+
+ @code{gnus-group-spam-exit-processor-bogofilter}, it is recommended
+ that you use @code{'(spam spam-use-bogofilter)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ @defvar gnus-group-ham-exit-processor-bogofilter
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameters or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is
+ added to a group's @code{spam-process} parameter, the ham-marked
+ articles in @emph{ham} groups will be added to the Bogofilter database
+ of non-spam messages.  Note that this ham processor has no effect in
+ @emph{spam} or @emph{unclassified} groups.
+
+ @emph{WARNING}
+
+ @code{gnus-group-ham-exit-processor-bogofilter}, it is recommended
+ that you use @code{'(ham spam-use-bogofilter)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ @defvar spam-bogofilter-database-directory
+
+ This is the directory where Bogofilter will store its databases.  It
+ is not specified by default, so Bogofilter will use its own default
+ database directory.
+
+ @end defvar
+
+ The Bogofilter mail classifier is similar to @command{ifile} in intent and
+ purpose.  A ham and a spam processor are provided, plus the
+ variables to indicate to spam-split that Bogofilter should either be
+ used, or has already been used on the article.  The 0.9.2.1 version of
+ Bogofilter was used to test this functionality.
+
+ @node ifile spam filtering
+ @subsubsection ifile spam filtering
+ @cindex spam filtering
+ @cindex ifile, spam filtering
+ @cindex spam
+
+ @defvar spam-use-ifile
+
+ Enable this variable if you want @code{spam-split} to use @command{ifile}, a
+ statistical analyzer similar to Bogofilter.
+
+ @end defvar
+
+ @defvar spam-ifile-all-categories
+
+ Enable this variable if you want @code{spam-use-ifile} to give you all
+ the ifile categories, not just spam/non-spam.  If you use this, make
+ sure you train ifile as described in its documentation.
+
+ @end defvar
+
+ @defvar spam-ifile-spam-category
+
+ This is the category of spam messages as far as ifile is concerned.
+ The actual string used is irrelevant, but you probably want to leave
+ the default value of @samp{spam}.
+ @end defvar
+
+ @defvar spam-ifile-database-path
+
+ This is the filename for the ifile database.  It is not specified by
+ default, so ifile will use its own default database name.
+
+ @end defvar
+
+ The ifile mail classifier is similar to Bogofilter in intent and
+ purpose.  A ham and a spam processor are provided, plus the
+ @code{spam-use-ifile} variable to indicate to spam-split that ifile
+ should be used.  The 1.2.1 version of ifile was used to test this
+ functionality.
+
+ @node spam-stat spam filtering
+ @subsubsection spam-stat spam filtering
+ @cindex spam filtering
+ @cindex spam-stat, spam filtering
+ @cindex spam-stat
+ @cindex spam
+
+ @xref{Filtering Spam Using Statistics with spam-stat}.
+
+ @defvar spam-use-stat
+
+ Enable this variable if you want @code{spam-split} to use
+ spam-stat.el, an Emacs Lisp statistical analyzer.
+
+ @end defvar
+
+ @defvar gnus-group-spam-exit-processor-stat
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameters or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is
+ added to a group's @code{spam-process} parameter, the spam-marked
+ articles will be added to the spam-stat database of spam messages.
+
+ @emph{WARNING}
+
+ @code{gnus-group-spam-exit-processor-stat}, it is recommended
+ that you use @code{'(spam spam-use-stat)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ @defvar gnus-group-ham-exit-processor-stat
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameters or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is
+ added to a group's @code{spam-process} parameter, the ham-marked
+ articles in @emph{ham} groups will be added to the spam-stat database
+ of non-spam messages.  Note that this ham processor has no effect in
+ @emph{spam} or @emph{unclassified} groups.
+
+ @emph{WARNING}
+
+ @code{gnus-group-ham-exit-processor-stat}, it is recommended
+ that you use @code{'(ham spam-use-stat)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ This enables @file{spam.el} to cooperate with @file{spam-stat.el}.
+ @file{spam-stat.el} provides an internal (Lisp-only) spam database,
+ which unlike ifile or Bogofilter does not require external programs.
+ A spam and a ham processor, and the @code{spam-use-stat} variable for
+ @code{spam-split} are provided.
+
+ @node SpamOracle
+ @subsubsection Using SpamOracle with Gnus
+ @cindex spam filtering
+ @cindex SpamOracle
+ @cindex spam
+
+ An easy way to filter out spam is to use SpamOracle.  SpamOracle is an
+ statistical mail filtering tool written by Xavier Leroy and needs to be
+ installed separately.
+
+ There are several ways to use SpamOracle with Gnus.  In all cases, your
+ mail is piped through SpamOracle in its @emph{mark} mode.  SpamOracle will
+ then enter an @samp{X-Spam} header indicating whether it regards the
+ mail as a spam mail or not.
+
+ One possibility is to run SpamOracle as a @code{:prescript} from the
+ @xref{Mail Source Specifiers}, (@pxref{SpamAssassin}).  This method has
+
+ The easiest method is to make @file{spam.el} (@pxref{Filtering Spam
+ Using The Spam ELisp Package}) call SpamOracle.
+
+ @vindex spam-use-spamoracle
+ To enable SpamOracle usage by @file{spam.el}, set the variable
+ @code{spam-use-spamoracle} to @code{t} and configure the
+ @code{nnmail-split-fancy} or @code{nnimap-split-fancy} as described in
+ the section @xref{Filtering Spam Using The Spam ELisp Package}.  In
+ this example the @samp{INBOX} of an nnimap server is filtered using
+ SpamOracle.  Mails recognized as spam mails will be moved to
+ @code{spam-split-group}, @samp{Junk} in this case.  Ham messages stay
+ in @samp{INBOX}:
+
+ @example
+ (setq spam-use-spamoracle t
+       spam-split-group "Junk"
+       nnimap-split-inbox '("INBOX")
+       nnimap-split-rule 'nnimap-split-fancy
+       nnimap-split-fancy '(| (: spam-split) "INBOX"))
+ @end example
+
+ @defvar spam-use-spamoracle
+ Set to @code{t} if you want Gnus to enable spam filtering using
+ SpamOracle.
+ @end defvar
+
+ @defvar spam-spamoracle-binary
+ Gnus uses the SpamOracle binary called @file{spamoracle} found in the
+ user's PATH.  Using the variable @code{spam-spamoracle-binary}, this
+ can be customized.
+ @end defvar
+
+ @defvar spam-spamoracle-database
+ By default, SpamOracle uses the file @file{~/.spamoracle.db} as a database to
+ store its analyses.  This is controlled by the variable
+ @code{spam-spamoracle-database} which defaults to @code{nil}.  That means
+ the default SpamOracle database will be used.  In case you want your
+ database to live somewhere special, set
+ @code{spam-spamoracle-database} to this path.
+ @end defvar
+
+ SpamOracle employs a statistical algorithm to determine whether a
+ message is spam or ham.  In order to get good results, meaning few
+ false hits or misses, SpamOracle needs training.  SpamOracle learns the
+ (training mode) one has to feed good (ham) and spam mails to
+ SpamOracle.  This can be done by pressing @kbd{|} in the Summary buffer
+ and pipe the mail to a SpamOracle process or using @file{spam.el}'s
+ spam- and ham-processors, which is much more convenient.  For a
+ detailed description of spam- and ham-processors, @xref{Filtering Spam
+ Using The Spam ELisp Package}.
+
+ @defvar gnus-group-spam-exit-processor-spamoracle
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameter or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is added
+ to a group's @code{spam-process} parameter, spam-marked articles will be
+ sent to SpamOracle as spam samples.
+
+ @emph{WARNING}
+
+ @code{gnus-group-spam-exit-processor-spamoracle}, it is recommended
+ that you use @code{'(spam spam-use-spamoracle)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ @defvar gnus-group-ham-exit-processor-spamoracle
+ Add this symbol to a group's @code{spam-process} parameter by
+ customizing the group parameter or the
+ @code{gnus-spam-process-newsgroups} variable.  When this symbol is added
+ to a grup's @code{spam-process} parameter, the ham-marked articles in
+ @emph{ham} groups will be sent to the SpamOracle as samples of ham
+ messages.  Note that this ham processor has no effect in @emph{spam} or
+ @emph{unclassified} groups.
+
+ @emph{WARNING}
+
+ @code{gnus-group-ham-exit-processor-spamoracle}, it is recommended
+ that you use @code{'(ham spam-use-spamoracle)}.  Everything will work
+ the same way, we promise.
+ @end defvar
+
+ @emph{Example:} These are the Group Parameters of a group that has been
+ classified as a ham group, meaning that it should only contain ham
+ messages.
+ @example
+  ((spam-contents gnus-group-spam-classification-ham)
+   (spam-process ((ham spam-use-spamoracle)
+                  (spam spam-use-spamoracle))))
+ @end example
+ For this group the @code{spam-use-spamoracle} is installed for both
+ ham and spam processing.  If the group contains spam message
+ (e.g. because SpamOracle has not had enough sample messages yet) and
+ the user marks some messages as spam messages, these messages will be
+ processed by SpamOracle.  The processor sends the messages to
+ SpamOracle as new samples for spam.
+
+ @node Extending the Spam ELisp package
+ @subsubsection Extending the Spam ELisp package
+ @cindex spam filtering
+ @cindex spam elisp package, extending
+ @cindex extending the spam elisp package
+
+ Say you want to add a new back end called blackbox.  For filtering
+ incoming mail, provide the following:
+
+ @enumerate
+
+ @item
+ code
+
+ @lisp
+ (defvar spam-use-blackbox nil
+   "True if blackbox should be used.")
+ @end lisp
+
+ @example
+     (spam-use-blackbox   . spam-check-blackbox)
+ @end example
+ to @code{spam-list-of-checks}.
+
+ @example
+     (gnus-group-ham-exit-processor-blackbox     ham spam-use-blackbox)
+     (gnus-group-spam-exit-processor-blackbox    spam spam-use-blackbox)
+ @end example
+ to @code{spam-list-of-processors}.
+
+ @example
+     (spam-use-blackbox  spam-blackbox-register-routine
+                  nil
+                  spam-blackbox-unregister-routine
+                  nil)
+ @end example
+ to @code{spam-registration-functions}.  Write the register/unregister
+ routines using the bogofilter register/unregister routines as a
+ start, or other restister/unregister routines more appropriate to
+ Blackbox.
+
+ @item
+ functionality
+
+ Write the @code{spam-check-blackbox} function.  It should return
+ @samp{nil} or @code{spam-split-group}, observing the other
+ conventions.  See the existing @code{spam-check-*} functions for
+ examples of what you can do, and stick to the template unless you
+ fully understand the reasons why you aren't.
+
+ Make sure to add @code{spam-use-blackbox} to
+ @code{spam-list-of-statistical-checks} if Blackbox is a statistical
+ mail analyzer that needs the full message body to operate.
+
+ @end enumerate
+
+ For processing spam and ham messages, provide the following:
+
+ @enumerate
+
+ @item
+ code
+
+ Note you don't have to provide a spam or a ham processor.  Only
+ provide them if Blackbox supports spam or ham processing.
+
+ Also, ham and spam processors are being phased out as single
+ variables.  Instead the form @code{'(spam spam-use-blackbox)} or
+ @code{'(ham spam-use-blackbox)} is favored.  For now, spam/ham
+ processor variables are still around but they won't be for long.
+
+ @lisp
+ (defvar gnus-group-spam-exit-processor-blackbox "blackbox-spam"
+   "The Blackbox summary exit spam processor.
+ Only applicable to spam groups.")
+
+ (defvar gnus-group-ham-exit-processor-blackbox "blackbox-ham"
+   "The whitelist summary exit ham processor.
+ Only applicable to non-spam (unclassified and ham) groups.")
+
+ @end lisp
+
+ @item
+ Gnus parameters
+
+ @example
+                    (const :tag "Spam: Blackbox"   (spam spam-use-blackbox))
+                    (const :tag "Ham: Blackbox"    (ham spam-use-blackbox))
+ @end example
+ to the @code{spam-process} group parameter in @code{gnus.el}.  Make
+ sure you do it twice, once for the parameter and once for the
+ variable customization.
+
+ @example
+           (variable-item spam-use-blackbox)
+ @end example
+ to the @code{spam-autodetect-methods} group parameter in
+ @code{gnus.el}.
+
+ @end enumerate
+
+
+ @node Filtering Spam Using Statistics with spam-stat
+ @subsection Filtering Spam Using Statistics with spam-stat
+ @cindex Paul Graham
+ @cindex Graham, Paul
+ @cindex naive Bayesian spam filtering
+ @cindex Bayesian spam filtering, naive
+ @cindex spam filtering, naive Bayesian
+
+ Paul Graham has written an excellent essay about spam filtering using
+ statistics: @uref{http://www.paulgraham.com/spam.html,A Plan for
+ Spam}.  In it he describes the inherent deficiency of rule-based
+ filtering as used by SpamAssassin, for example: Somebody has to write
+ the rules, and everybody else has to install these rules.  You are
+ always late.  It would be much better, he argues, to filter mail based
+ on whether it somehow resembles spam or non-spam.  One way to measure
+ this is word distribution.  He then goes on to describe a solution
+ that checks whether a new mail resembles any of your other spam mails
+ or not.
+
+ The basic idea is this:  Create a two collections of your mail, one
+ with spam, one with non-spam.  Count how often each word appears in
+ either collection, weight this by the total number of mails in the
+ collections, and store this information in a dictionary.  For every
+ word in a new mail, determine its probability to belong to a spam or a
+ non-spam mail.  Use the 15 most conspicuous words, compute the total
+ probability of the mail being spam.  If this probability is higher
+ than a certain threshold, the mail is considered to be spam.
+
+ Gnus supports this kind of filtering.  But it needs some setting up.
+ First, you need two collections of your mail, one with spam, one with
+ non-spam.  Then you need to create a dictionary using these two
+ collections, and save it.  And last but not least, you need to use
+ this dictionary in your fancy mail splitting rules.
+
+ * Creating a spam-stat dictionary::
+ * Splitting mail using spam-stat::
+ * Low-level interface to the spam-stat dictionary::
+
+ @node Creating a spam-stat dictionary
+ @subsubsection Creating a spam-stat dictionary
+
+ Before you can begin to filter spam based on statistics, you must
+ create these statistics based on two mail collections, one with spam,
+ one with non-spam.  These statistics are then stored in a dictionary
+ for later use.  In order for these statistics to be meaningful, you
+ need several hundred emails in both collections.
+
+ Gnus currently supports only the nnml back end for automated dictionary
+ creation.  The nnml back end stores all mails in a directory, one file
+ per mail.  Use the following:
+
+ @defun spam-stat-process-spam-directory
+ Create spam statistics for every file in this directory.  Every file
+ is treated as one spam mail.
+ @end defun
+
+ @defun spam-stat-process-non-spam-directory
+ Create non-spam statistics for every file in this directory.  Every
+ file is treated as one non-spam mail.
+ @end defun
+
+ Usually you would call @code{spam-stat-process-spam-directory} on a
+ directory such as @file{~/Mail/mail/spam} (this usually corresponds
+ the the group @samp{nnml:mail.spam}), and you would call
+ @code{spam-stat-process-non-spam-directory} on a directory such as
+ @file{~/Mail/mail/misc} (this usually corresponds the the group
+ @samp{nnml:mail.misc}).
+
+ When you are using @acronym{IMAP}, you won't have the mails available
+ locally, so that will not work.  One solution is to use the Gnus Agent
+ to cache the articles.  Then you can use directories such as
+ @file{"~/News/agent/nnimap/mail.yourisp.com/personal_spam"} for
+ @code{spam-stat-process-spam-directory}.  @xref{Agent as Cache}.
+
+ @defvar spam-stat
+ This variable holds the hash-table with all the statistics---the
+ dictionary we have been talking about.  For every word in either
+ collection, this hash-table stores a vector describing how often the
+ word appeared in spam and often it appeared in non-spam mails.
+ @end defvar
+
+ If you want to regenerate the statistics from scratch, you need to
+ reset the dictionary.
+
+ @defun spam-stat-reset
+ Reset the @code{spam-stat} hash-table, deleting all the statistics.
+ @end defun
+
+ When you are done, you must save the dictionary.  The dictionary may
+ be rather large.  If you will not update the dictionary incrementally
+ (instead, you will recreate it once a month, for example), then you
+ can reduce the size of the dictionary by deleting all words that did
+ not appear often enough or that do not clearly belong to only spam or
+ only non-spam mails.
+
+ @defun spam-stat-reduce-size
+ Reduce the size of the dictionary.  Use this only if you do not want
+ to update the dictionary incrementally.
+ @end defun
+
+ @defun spam-stat-save
+ Save the dictionary.
+ @end defun
+
+ @defvar spam-stat-file
+ The filename used to store the dictionary.  This defaults to
+ @file{~/.spam-stat.el}.
+ @end defvar
+
+ @node Splitting mail using spam-stat
+ @subsubsection Splitting mail using spam-stat
+
+ In order to use @code{spam-stat} to split your mail, you need to add the
+ following to your @file{~/.gnus.el} file:
+
+ @lisp
+ (require 'spam-stat)
+ @end lisp
+
+ This will load the necessary Gnus code, and the dictionary you
+ created.
+
+ Next, you need to adapt your fancy splitting rules:  You need to
+ determine how to use @code{spam-stat}.  The following examples are for
+ the nnml back end.  Using the nnimap back end works just as well.  Just
+ use @code{nnimap-split-fancy} instead of @code{nnmail-split-fancy}.
+
+ In the simplest case, you only have two groups, @samp{mail.misc} and
+ @samp{mail.spam}.  The following expression says that mail is either
+ spam or it should go into @samp{mail.misc}.  If it is spam, then
+ @code{spam-stat-split-fancy} will return @samp{mail.spam}.
+
+ @lisp
+ (setq nnmail-split-fancy
+       (| (: spam-stat-split-fancy)
+           "mail.misc"))
+ @end lisp
+
+ @defvar spam-stat-split-fancy-spam-group
+ The group to use for spam.  Default is @samp{mail.spam}.
+ @end defvar
+
+ If you also filter mail with specific subjects into other groups, use
+ the following expression.  Only mails not matching the regular
+ expression are considered potential spam.
+
+ @lisp
+ (setq nnmail-split-fancy
+       (| ("Subject" "\\bspam-stat\\b" "mail.emacs")
+           (: spam-stat-split-fancy)
+           "mail.misc"))
+ @end lisp
+
+ If you want to filter for spam first, then you must be careful when
+ creating the dictionary.  Note that @code{spam-stat-split-fancy} must
+ consider both mails in @samp{mail.emacs} and in @samp{mail.misc} as
+ non-spam, therefore both should be in your collection of non-spam
+ mails, when creating the dictionary!
+
+ @lisp
+ (setq nnmail-split-fancy
+       (| (: spam-stat-split-fancy)
+           ("Subject" "\\bspam-stat\\b" "mail.emacs")
+           "mail.misc"))
+ @end lisp
+
+ You can combine this with traditional filtering.  Here, we move all
+ HTML-only mails into the @samp{mail.spam.filtered} group.  Note that since
+ @code{spam-stat-split-fancy} will never see them, the mails in
+ @samp{mail.spam.filtered} should be neither in your collection of spam mails,
+ nor in your collection of non-spam mails, when creating the
+ dictionary!
+
+ @lisp
+ (setq nnmail-split-fancy
+       (| ("Content-Type" "text/html" "mail.spam.filtered")
+           (: spam-stat-split-fancy)
+           ("Subject" "\\bspam-stat\\b" "mail.emacs")
+           "mail.misc"))
+ @end lisp
+
+
+ @node Low-level interface to the spam-stat dictionary
+ @subsubsection Low-level interface to the spam-stat dictionary
+
+ The main interface to using @code{spam-stat}, are the following functions:
+
+ @defun spam-stat-buffer-is-spam
+ Called in a buffer, that buffer is considered to be a new spam mail.
+ Use this for new mail that has not been processed before.
+ @end defun
+
+ @defun spam-stat-buffer-is-no-spam
+ Called in a buffer, that buffer is considered to be a new non-spam
+ mail.  Use this for new mail that has not been processed before.
+ @end defun
+
+ @defun spam-stat-buffer-change-to-spam
+ Called in a buffer, that buffer is no longer considered to be normal
+ mail but spam.  Use this to change the status of a mail that has
+ already been processed as non-spam.
+ @end defun
+
+ @defun spam-stat-buffer-change-to-non-spam
+ Called in a buffer, that buffer is no longer considered to be spam but
+ normal mail.  Use this to change the status of a mail that has already
+ been processed as spam.
+ @end defun
+
+ @defun spam-stat-save
+ Save the hash table to the file.  The filename used is stored in the
+ variable @code{spam-stat-file}.
+ @end defun
+
+ Load the hash table from a file.  The filename used is stored in the
+ variable @code{spam-stat-file}.
+ @end defun
+
+ @defun spam-stat-score-word
+ Return the spam score for a word.
+ @end defun
+
+ @defun spam-stat-score-buffer
+ Return the spam score for a buffer.
+ @end defun
+
+ @defun spam-stat-split-fancy
+ Use this function for fancy mail splitting.  Add the rule @samp{(:
+ spam-stat-split-fancy)} to @code{nnmail-split-fancy}
+ @end defun
+
+ Make sure you load the dictionary before using it.  This requires the
+ following in your @file{~/.gnus.el} file:
+
+ @lisp
+ (require 'spam-stat)
+ @end lisp
+
+ Typical test will involve calls to the following functions:
+
+ @smallexample
+ Reset: (setq spam-stat (make-hash-table :test 'equal))
+ Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
+ Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
+ Save table: (spam-stat-save)
+ File size: (nth 7 (file-attributes spam-stat-file))
+ Number of words: (hash-table-count spam-stat)
+ Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
+ Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
+ Reduce table size: (spam-stat-reduce-size)
+ Save table: (spam-stat-save)
+ File size: (nth 7 (file-attributes spam-stat-file))
+ Number of words: (hash-table-count spam-stat)
+ Test spam: (spam-stat-test-directory "~/Mail/mail/spam")
+ Test non-spam: (spam-stat-test-directory "~/Mail/mail/misc")
+ @end smallexample
+
+ Here is how you would create your dictionary:
+
+ @smallexample
+ Reset: (setq spam-stat (make-hash-table :test 'equal))
+ Learn spam: (spam-stat-process-spam-directory "~/Mail/mail/spam")
+ Learn non-spam: (spam-stat-process-non-spam-directory "~/Mail/mail/misc")
+ Repeat for any other non-spam group you need...
+ Reduce table size: (spam-stat-reduce-size)
+ Save table: (spam-stat-save)
+ @end smallexample
+
+ @node Other modes
+ @section Interaction with other modes
+
+ @subsection Dired
+ @cindex dired
+
+ @code{gnus-dired-minor-mode} provided some useful functions for dired
+ buffers.  It is enabled with
+ @lisp
+ @end lisp
+
+ @table @kbd
+ @item C-c C-m C-a
+ @findex gnus-dired-attach
+ Send dired's marked files as an attachment (@code{gnus-dired-attach}).
+ You will be prompted for a message buffer.
+
+ @item C-c C-m C-l
+ @findex gnus-dired-find-file-mailcap
+ Visit a file according to the appropriate mailcap entry
+ (@code{gnus-dired-find-file-mailcap}).  With prefix, open file in a new
+ buffer.
+
+ @item C-c C-m C-p
+ @findex gnus-dired-print
+ Print file according to the mailcap entry (@code{gnus-dired-print}).  If
+ there is no print command, print in a PostScript image.
+ @end table
+
+ @node Various Various
+ @section Various Various
+ @cindex mode lines
+ @cindex highlights
+
+ @table @code
+
+ @item gnus-home-directory
+ @vindex gnus-home-directory
+ All Gnus file and directory variables will be initialized from this
+ variable, which defaults to @file{~/}.
+
+ @item gnus-directory
+ @vindex gnus-directory
+ Most Gnus storage file and directory variables will be initialized from
+ this variable, which defaults to the @env{SAVEDIR} environment
+ variable, or @file{~/News/} if that variable isn't set.
+
+ Note that Gnus is mostly loaded when the @file{~/.gnus.el} file is read.
+ This means that other directory variables that are initialized from this
+ variable won't be set properly if you set this variable in
+ @file{~/.gnus.el}.  Set this variable in @file{.emacs} instead.
+
+ @item gnus-default-directory
+ @vindex gnus-default-directory
+ Not related to the above variable at all---this variable says what the
+ default directory of all Gnus buffers should be.  If you issue commands
+ like @kbd{C-x C-f}, the prompt you'll get starts in the current buffer's
+ default directory.  If this variable is @code{nil} (which is the
+ default), the default directory will be the default directory of the
+ buffer you were in when you started Gnus.
+
+ @item gnus-verbose
+ @vindex gnus-verbose
+ This variable is an integer between zero and ten.  The higher the value,
+ the more messages will be displayed.  If this variable is zero, Gnus
+ will never flash any messages, if it is seven (which is the default),
+ most important messages will be shown, and if it is ten, Gnus won't ever
+ shut up, but will flash so many messages it will make your head swim.
+
+ @item gnus-verbose-backends
+ @vindex gnus-verbose-backends
+ This variable works the same way as @code{gnus-verbose}, but it applies
+ to the Gnus back ends instead of Gnus proper.
+
+ as little as possible.  This variable (default 4096) specifies
+ the absolute max length the back ends will try to read before giving up
+ on finding a separator line between the head and the body.  If this
+ variable is @code{nil}, there is no upper read bound.  If it is
+ @code{t}, the back ends won't try to read the articles piece by piece,
+ but read the entire articles.  This makes sense with some versions of
+ @code{ange-ftp} or @code{efs}.
+
+ This variable (default 2048) says how big a piece of each article to
+ read when doing the operation described above.
+
+ @cindex file names
+ @cindex invalid characters in file names
+ @cindex characters in file names
+ This is an alist that says how to translate characters in file names.
+ For instance, if @samp{:} is invalid as a file character in file names
+ on your system (you OS/2 user you), you could say something like:
+
+ @lisp
+ @group
+       '((?: . ?_)))
+ @end group
+ @end lisp
+
+ In fact, this is the default value for this variable on OS/2 and MS
+ Windows (phooey) systems.
+
+ @item gnus-hidden-properties
+ @vindex gnus-hidden-properties
+ This is a list of properties to use to hide invisible'' text.  It is
+ @code{(invisible t intangible t)} by default on most systems, which
+ makes invisible text invisible and intangible.
+
+ A hook called before parsing headers.  It can be used, for instance, to
+ gather statistics on the headers fetched, or perhaps you'd like to prune
+ some headers.  I don't see why you'd want that, though.
+
+ @item gnus-shell-command-separator
+ @vindex gnus-shell-command-separator
+ String used to separate two shell commands.  The default is @samp{;}.
+
+ @item gnus-invalid-group-regexp
+ @vindex gnus-invalid-group-regexp
+
+ Regexp to match invalid'' group names when querying user for a group
+ name.  The default value catches some @strong{really} invalid group
+ names who could possibly mess up Gnus internally (like allowing
+ @samp{:} in a group name, which is normally used to delimit method and
+ group).
+
+ @acronym{IMAP} users might want to allow @samp{/} in group names though.
+
+
+ @end table
+
+ @node The End
+ @chapter The End
+
+ Well, that's the manual---you can get on with your life now.  Keep in
+ touch.  Say hello to your cats from me.
+
+ My @strong{ghod}---I just can't stand goodbyes.  Sniffle.
+
+ Ol' Charles Reznikoff said it pretty well, so I leave the floor to him:
+
+ @quotation
+ @strong{Te Deum}
+
+ @sp 1
+ Not because of victories @*
+ I sing,@*
+ having none,@*
+ but for the common sunshine,@*
+ the breeze,@*
+ the largess of the spring.
+
+ @sp 1
+ but for the day's work address@hidden
+ as well as I was able;@*
+ not for a seat upon the address@hidden
+ but at the common address@hidden
+ @end quotation
+
+
+ @node Appendices
+ @chapter Appendices
+
+ * XEmacs::                      Requirements for installing under XEmacs.
+ * History::                     How Gnus got where it is today.
+ * On Writing Manuals::          Why this is not a beginner's guide.
+ * Terminology::                 We use really difficult, like, words here.
+ * Customization::               Tailoring Gnus to your needs.
+ * Troubleshooting::             What you might try if things do not work.
+ * Gnus Reference Guide::        Rilly, rilly technical stuff.
+ * Emacs for Heathens::          A short introduction to Emacsian terms.
+ * Frequently Asked Questions::  The Gnus FAQ
+
+
+ @node XEmacs
+ @section XEmacs
+ @cindex XEmacs
+ @cindex installing under XEmacs
+
+ XEmacs is distributed as a collection of packages.  You should install
+ whatever packages the Gnus XEmacs package requires.  The current
+ requirements are @samp{gnus}, @samp{mail-lib}, @samp{xemacs-base},
+ @samp{eterm}, @samp{sh-script}, @samp{net-utils}, @samp{os-utils},
+ @samp{dired}, @samp{mh-e}, @samp{sieve}, @samp{ps-print}, @samp{w3},
+ @samp{pgg}, @samp{mailcrypt}, @samp{ecrypto}, and @samp{sasl}.
+
+
+ @node History
+ @section History
+
+ @cindex history
+ @sc{gnus} was written by Masanobu @sc{Umeda}.  When autumn crept up in
+ '94, Lars Magne Ingebrigtsen grew bored and decided to rewrite Gnus.
+
+ If you want to investigate the person responsible for this outrage,
+ you can point your (feh!) web browser to
+ @uref{http://quimby.gnus.org/}.  This is also the primary
+ distribution point for the new and spiffy versions of Gnus, and is
+ known as The Site That Destroys Newsrcs And Drives People Mad.
+
+ During the first extended alpha period of development, the new Gnus was
+ called (ding) Gnus''.  @dfn{(ding)} is, of course, short for
+ @dfn{ding is not Gnus}, which is a total and utter lie, but who cares?
+ (Besides, the Gnus'' in this abbreviation should probably be
+ pronounced news'' as @sc{Umeda} intended, which makes it a more
+ appropriate name, don't you think?)
+
+ In any case, after spending all that energy on coming up with a new and
+ spunky name, we decided that the name was @emph{too} spunky, so we
+ renamed it back again to Gnus''.  But in mixed case.  Gnus'' vs.
+
+ * Gnus Versions::               What Gnus versions have been released.
+ * Other Gnus Versions::         Other Gnus versions that also have been
released.
+ * Why?::                        What's the point of Gnus?
+ * Compatibility::               Just how compatible is Gnus with @sc{gnus}?
+ * Conformity::                  Gnus tries to conform to all standards.
+ * Emacsen::                     Gnus can be run on a few modern Emacsen.
+ * Gnus Development::            How Gnus is developed.
+ * Contributors::                Oodles of people.
+ * New Features::                Pointers to some of the new stuff in Gnus.
+
+
+ @node Gnus Versions
+ @subsection Gnus Versions
+ @cindex ding Gnus
+ @cindex September Gnus
+ @cindex Red Gnus
+ @cindex Quassia Gnus
+ @cindex Pterodactyl Gnus
+ @cindex Oort Gnus
+ @cindex No Gnus
+ @cindex Gnus versions
+
+ The first proper'' release of Gnus 5 was done in November 1995 when it
+ was included in the Emacs 19.30 distribution (132 (ding) Gnus releases
+ plus 15 Gnus 5.0 releases).
+
+ In May 1996 the next Gnus generation (aka. September Gnus'' (after 99
+ releases)) was released under the name Gnus 5.2'' (40 releases).
+
+ On July 28th 1996 work on Red Gnus was begun, and it was released on
+ January 25th 1997 (after 84 releases) as Gnus 5.4'' (67 releases).
+
+ On September 13th 1997, Quassia Gnus was started and lasted 37 releases.
+ If was released as Gnus 5.6'' on March 8th 1998 (46 releases).
+
+ Gnus 5.6 begat Pterodactyl Gnus on August 29th 1998 and was released as
+ Gnus 5.8'' (after 99 releases and a CVS repository) on December 3rd
+ 1999.
+
+ On the 26th of October 2000, Oort Gnus was begun.
+
+ If you happen upon a version of Gnus that has a prefixed name --
+ (ding) Gnus'', September Gnus'', Red Gnus'', Quassia Gnus'',
+ Pterodactyl Gnus'', Oort Gnus'' -- don't panic.  Don't let it know
+ that you're frightened.  Back away.  Slowly.  Whatever you do, don't
+ run.  Walk away, calmly, until you're out of its reach.  Find a proper
+ released version of Gnus and snuggle up to that instead.
+
+
+ @node Other Gnus Versions
+ @subsection Other Gnus Versions
+ @cindex Semi-gnus
+
+ In addition to the versions of Gnus which have had their releases
+ coordinated by Lars, one major development has been Semi-gnus from
+ Japan.  It's based on a library called @acronym{SEMI}, which provides
+ @acronym{MIME} capabilities.
+
+ These Gnusae are based mainly on Gnus 5.6 and Pterodactyl Gnus.
+ Collectively, they are called Semi-gnus'', and different strains are
+ called T-gnus, ET-gnus, Nana-gnus and Chaos.  These provide powerful
+ @acronym{MIME} and multilingualization things, especially important for
+ Japanese users.
+
+
+ @node Why?
+ @subsection Why?
+
+ What's the point of Gnus?
+
+ I want to provide a rad'', happening'', way cool'' and hep''
+ newsreader, that lets you do anything you can think of.  That was my
+ original motivation, but while working on Gnus, it has become clear to
+ me that this generation of newsreaders really belong in the stone age.
+ Newsreaders haven't developed much since the infancy of the net.  If the
+ volume continues to rise with the current rate of increase, all current
+ newsreaders will be pretty much useless.  How do you deal with
+ newsgroups that have thousands of new articles each day?  How do you
+ keep track of millions of people who post?
+
+ Gnus offers no real solutions to these questions, but I would very much
+ like to see Gnus being used as a testing ground for new methods of
+ reading and fetching news.  Expanding on @sc{Umeda}-san's wise decision
+ to separate the newsreader from the back ends, Gnus now offers a simple
+ interface for anybody who wants to write new back ends for fetching mail
+ and news from different sources.  I have added hooks for customizations
+ everywhere I could imagine it being useful.  By doing so, I'm inviting
+ every one of you to explore and invent.
+
+ May Gnus never be complete.  @kbd{C-u 100 M-x all-hail-emacs} and
+ @kbd{C-u 100 M-x all-hail-xemacs}.
+
+
+ @node Compatibility
+ @subsection Compatibility
+
+ @cindex compatibility
+ Gnus was designed to be fully compatible with @sc{gnus}.  Almost all key
+ bindings have been kept.  More key bindings have been added, of course,
+ but only in one or two obscure cases have old bindings been changed.
+
+ Our motto is:
+ @quotation
+ @cartouche
+ @center In a cloud bones of steel.
+ @end cartouche
+ @end quotation
+
+ All commands have kept their names.  Some internal functions have changed
+ their names.
+
+ The @code{gnus-uu} package has changed drastically.  @xref{Decoding
+ Articles}.
+
+ One major compatibility question is the presence of several summary
+ buffers.  All variables relevant while reading a group are
+ buffer-local to the summary buffer they belong in.  Although many
+ important variables have their values copied into their global
+ counterparts whenever a command is executed in the summary buffer, this
+ change might lead to incorrect values being used unless you are careful.
+
+ All code that relies on knowledge of @sc{gnus} internals will probably
+ fail.  To take two examples: Sorting @code{gnus-newsrc-alist} (or
+ changing it in any way, as a matter of fact) is strictly verboten.  Gnus
+ maintains a hash table that points to the entries in this alist (which
+ speeds up many functions), and changing the alist directly will lead to
+ peculiar results.
+
+ @cindex hilit19
+ @cindex highlighting
+ Old hilit19 code does not work at all.  In fact, you should probably
+ remove all hilit code from all Gnus hooks
+ (@code{gnus-group-prepare-hook} and @code{gnus-summary-prepare-hook}).
+ Gnus provides various integrated functions for highlighting.  These are
+ faster and more accurate.  To make life easier for everybody, Gnus will
+ by default remove all hilit calls from all hilit hooks.  Uncleanliness!
+ Away!
+
+ Packages like @code{expire-kill} will no longer work.  As a matter of
+ fact, you should probably remove all old @sc{gnus} packages (and other
+ code) when you start using Gnus.  More likely than not, Gnus already
+ does what you have written code to make @sc{gnus} do.  (Snicker.)
+
+ Even though old methods of doing things are still supported, only the
+ new methods are documented in this manual.  If you detect a new method of
+ doing something while reading this manual, that does not mean you have
+ to stop doing it the old way.
+
+ Gnus understands all @sc{gnus} startup files.
+
+ @kindex M-x gnus-bug
+ @findex gnus-bug
+ @cindex reporting bugs
+ @cindex bugs
+ Overall, a casual user who hasn't written much code that depends on
+ @sc{gnus} internals should suffer no problems.  If problems occur,
+ please let me know by issuing that magic command @kbd{M-x gnus-bug}.
+
+ @vindex gnus-bug-create-help-buffer
+ If you are in the habit of sending bug reports @emph{very} often, you
+ may find the helpful help buffer annoying after a while.  If so, set
+ @code{gnus-bug-create-help-buffer} to @code{nil} to avoid having it pop
+ up at you.
+
+
+ @node Conformity
+ @subsection Conformity
+
+ No rebels without a clue here, ma'am.  We conform to all standards known
+ to (wo)man.  Except for those standards and/or conventions we disagree
+ with, of course.
+
+ @table @strong
+
+ @item RFC (2)822
+ @cindex RFC 822
+ @cindex RFC 2822
+ There are no known breaches of this standard.
+
+ @item RFC 1036
+ @cindex RFC 1036
+ There are no known breaches of this standard, either.
+
+ @item Son-of-RFC 1036
+ @cindex Son-of-RFC 1036
+ We do have some breaches to this one.
+
+ @table @emph
+
+ @itemx User-Agent
+ These are considered to be vanity headers'', while I consider them
+ to be consumer information.  After seeing so many badly formatted
+ articles coming from @code{tin} and @code{Netscape} I know not to use
+ either of those for posting articles.  I would not have known that if
+ @end table
+
+ @item USEFOR
+ @cindex USEFOR
+ USEFOR is an IETF working group writing a successor to RFC 1036, based
+ on Son-of-RFC 1036.  They have produced a number of drafts proposing
+ various changes to the format of news articles.  The Gnus towers will
+ look into implementing the changes when the draft is accepted as an RFC.
+
+ @item MIME - RFC 2045-2049 etc
+ @cindex @acronym{MIME}
+ All the various @acronym{MIME} RFCs are supported.
+
+ @item Disposition Notifications - RFC 2298
+
+ @item PGP - RFC 1991 and RFC 2440
+ @cindex RFC 1991
+ @cindex RFC 2440
+ RFC 1991 is the original @acronym{PGP} message specification,
+ published as an informational RFC.  RFC 2440 was the follow-up, now
+ called Open PGP, and put on the Standards Track.  Both document a
+ address@hidden aware @acronym{PGP} format.  Gnus supports both
+ encoding (signing and encryption) and decoding (verification and
+ decryption).
+
+ @item PGP/MIME - RFC 2015/3156
+ RFC 2015 (superseded by 3156 which references RFC 2440 instead of RFC
+ 1991) describes the @acronym{MIME}-wrapping around the RF 1991/2440 format.
+ Gnus supports both encoding and decoding.
+
+ @item S/MIME - RFC 2633
+ RFC 2633 describes the @acronym{S/MIME} format.
+
+ @item IMAP - RFC 1730/2060, RFC 2195, RFC 2086, RFC 2359, RFC 2595, RFC 1731
+ RFC 1730 is @acronym{IMAP} version 4, updated somewhat by RFC 2060
+ (@acronym{IMAP} 4 revision 1).  RFC 2195 describes CRAM-MD5
+ authentication for @acronym{IMAP}.  RFC 2086 describes access control
+ lists (ACLs) for @acronym{IMAP}.  RFC 2359 describes a @acronym{IMAP}
+ protocol enhancement.  RFC 2595 describes the proper @acronym{TLS}
+ integration (STARTTLS) with @acronym{IMAP}.  RFC 1731 describes the
+ GSSAPI/Kerberos4 mechanisms for @acronym{IMAP}.
+
+ @end table
+
+ If you ever notice Gnus acting non-compliant with regards to the texts
+ mentioned above, don't hesitate to drop a note to Gnus Towers and let us
+ know.
+
+
+ @node Emacsen
+ @subsection Emacsen
+ @cindex Emacsen
+ @cindex XEmacs
+ @cindex Mule
+ @cindex Emacs
+
+ Gnus should work on:
+
+ @itemize @bullet
+
+ @item
+ Emacs 20.7 and up.
+
+ @item
+ XEmacs 21.1 and up.
+
+ @end itemize
+
+ This Gnus version will absolutely not work on any Emacsen older than
+ that.  Not reliably, at least.  Older versions of Gnus may work on older
+ Emacs versions.
+
+ There are some vague differences between Gnus on the various
+ platforms---XEmacs features more graphics (a logo and a toolbar)---but
+ other than that, things should look pretty much the same under all
+ Emacsen.
+
+
+ @node Gnus Development
+ @subsection Gnus Development
+
+ Gnus is developed in a two-phased cycle.  The first phase involves much
+ discussion on the @samp{ding@@gnus.org} mailing list, where people
+ propose changes and new features, post patches and new back ends.  This
+ phase is called the @dfn{alpha} phase, since the Gnusae released in this
+ phase are @dfn{alpha releases}, or (perhaps more commonly in other
+ circles) @dfn{snapshots}.  During this phase, Gnus is assumed to be
+ unstable and should not be used by casual users.  Gnus alpha releases
+ have names like Red Gnus'' and Quassia Gnus''.
+
+ After futzing around for 50-100 alpha releases, Gnus is declared
+ @dfn{frozen}, and only bug fixes are applied.  Gnus loses the prefix,
+ and is called things like Gnus 5.6.32'' instead.  Normal people are
+ supposed to be able to use these, and these are mostly discussed on the
+ @samp{gnu.emacs.gnus} newsgroup.
+
+ @cindex Incoming*
+ @vindex mail-source-delete-incoming
+ Some variable defaults differ between alpha Gnusae and released Gnusae.
+ In particular, @code{mail-source-delete-incoming} defaults to @code{nil} in
+ alpha Gnusae and @code{t} in released Gnusae.  This is to prevent
+ lossage of mail if an alpha release hiccups while handling the mail.
+
+ The division of discussion between the ding mailing list and the Gnus
+ newsgroup is not purely based on publicity concerns.  It's true that
+ having people write about the horrible things that an alpha Gnus release
+ can do (sometimes) in a public forum may scare people off, but more
+ importantly, talking about new experimental features that have been
+ introduced may confuse casual users.  New features are frequently
+ introduced, fiddled with, and judged to be found wanting, and then
+ usually keep up with these rapid changes, while people on the newsgroup
+ can't be assumed to do so.
+
+
+
+ @node Contributors
+ @subsection Contributors
+ @cindex contributors
+
+ The new Gnus version couldn't have been done without the help of all the
+ people on the (ding) mailing list.  Every day for over a year I have
+ gotten billions of nice bug reports from them, filling me with joy,
+ every single one of them.  Smooches.  The people on the list have been
+ tried beyond endurance, what with my oh, that's a neat idea <type
+ type>, yup, I'll release it right away <ship off> no wait, that doesn't
+ work at all <type type>, yup, I'll ship that one off right away <ship
+ off> no, wait, that absolutely does not work'' policy for releases.
+ Micro$oft---bah. Amateurs. I'm @emph{much} worse. (Or is that + worser''? much worser''? worsest''?) + + I would like to take this opportunity to thank the Academy address@hidden oops, + wrong show. + + @itemize @bullet + + @item + Masanobu @sc{Umeda}---the writer of the original @sc{gnus}. + + @item + Shenghuo Zhu---uudecode.el, mm-uu.el, rfc1843.el, webmail.el, + nnwarchive and many, many other things connected with @acronym{MIME} and + other types of en/decoding, as well as general bug fixing, new + functionality and stuff. + + @item + Per Abrahamsen---custom, scoring, highlighting and @sc{soup} code (as + well as numerous other things). + + @item + Luis Fernandes---design and graphics. + + @item + Joe Reiss---creator of the smiley faces. + + @item + Justin Sheehy---the @acronym{FAQ} maintainer. + + @item + Erik Naggum---help, ideas, support, code and stuff. + + @item + Wes address@hidden and the manual section on + @dfn{picons} (@pxref{Picons}). + + @item + Kim-Minh Kaplan---further work on the picon code. + + @item + Brad address@hidden and the GroupLens manual section + (@pxref{GroupLens}). + + @item + Sudish Joseph---innumerable bug fixes. + + @item + Ilja address@hidden + + @item + Steven L. Baur---lots and lots and lots of bugs detections and fixes. + + @item + Vladimir Alexiev---the refcard and reference booklets. + + @item + Felix Lee & Jamie Zawinski---I stole some pieces from the XGnus + distribution by Felix Lee and JWZ. + + @item + Scott address@hidden enhancements & rewrite. + + @item + Peter Mutsaers---orphan article scoring code. + + @item + Ken Raeburn---POP mail support. + + @item + Hallvard B Furuseth---various bits and pieces, especially dealing with + .newsrc files. + + @item + Brian address@hidden + + @item + David Moore---rewrite of @file{nnvirtual.el} and many other things. + + @item + Kevin Davidson---came up with the name @dfn{ding}, so blame him. + + @item + François Pinard---many, many interesting and thorough bug reports, as + well as autoconf support. + + @end itemize + + This manual was proof-read by Adrian Aichner, with Ricardo Nassif, Mark + Borges, and Jost Krieger proof-reading parts of the manual. + + The following people have contributed many patches and suggestions: + + Christopher Davis, + Andrew Eskilsson, + Kai Grossjohann, + Kevin Greiner, + Jesper Harder, + Paul Jarc, + Simon Josefsson, + David Kågedal, + Richard Pieri, + Fabrice Popineau, + Daniel Quinlan, + Michael Shields, + Reiner Steib, + Jason L. Tibbitts, III, + Jack Vinson, + Katsumi Yamaoka, @c Yamaoka + and + Teodor Zlatanov. + + Also thanks to the following for patches and stuff: + + Jari Aalto, + Adrian Aichner, + Vladimir Alexiev, + Russ Allbery, + Peter Arius, + Matt Armstrong, + Marc Auslander, + Miles Bader, + Alexei V. Barantsev, + Frank Bennett, + Robert Bihlmeyer, + Chris Bone, + Mark Borges, + Mark Boyns, + Lance A. Brown, + Rob Browning, + Kees de Bruin, + Martin Buchholz, + Joe Buehler, + Kevin Buhr, + Alastair Burt, + Joao Cachopo, + Zlatko Calusic, + Massimo Campostrini, + Castor, + David Charlap, + Dan Christensen, + Kevin Christian, + Jae-you Chung, @c ? + James H. Cloos, Jr., + Laura Conrad, + Michael R. Cook, + Glenn Coombs, + Andrew J. Cosgriff, + Neil Crellin, + Frank D. Cringle, + Geoffrey T. Dairiki, + Andre Deparade, + Ulrik Dickow, + Dave Disser, + Rui-Tao Dong, @c ? + Joev Dubach, + Michael Welsh Duggan, + Dave Edmondson, + Paul Eggert, + Mark W. Eichin, + Karl Eichwalder, + Enami Tsugutomo, @c Enami + Michael Ernst, + Luc Van Eycken, + Sam Falkner, + Nelson Jose dos Santos Ferreira, + Sigbjorn Finne, + Sven Fischer, + Paul Fisher, + Decklin Foster, + Gary D. Foster, + Paul Franklin, + Guy Geens, + Arne Georg Gleditsch, + David S. Goldberg, + Michelangelo Grigni, + Dale Hagglund, + D. Hall, + Magnus Hammerin, + Kenichi Handa, @c Handa + Raja R. Harinath, + Yoshiki Hayashi, @c Hayashi + P. E. Jareth Hein, + Hisashige Kenji, @c Hisashige + Scott Hofmann, + Marc Horowitz, + Gunnar Horrigmo, + Richard Hoskins, + Brad Howes, + Miguel de Icaza, + François Felix Ingrand, + Tatsuya Ichikawa, @c Ichikawa + Ishikawa Ichiro, @c Ishikawa + Lee Iverson, + Iwamuro Motonori, @c Iwamuro + Rajappa Iyer, + Andreas Jaeger, + Adam P. Jenkins, + Randell Jesup, + Fred Johansen, + Gareth Jones, + Greg Klanderman, + Karl Kleinpaste, + Michael Klingbeil, + Peter Skov Knudsen, + Shuhei Kobayashi, @c Kobayashi + Petr Konecny, + Koseki Yoshinori, @c Koseki + Thor Kristoffersen, + Jens Lautenbacher, + Martin Larose, + Seokchan Lee, @c Lee + Joerg Lenneis, + Carsten Leonhardt, + James LewisMoss, + Christian Limpach, + Markus Linnala, + Dave Love, + Mike McEwan, + Tonny Madsen, + Shlomo Mahlab, + Nat Makarevitch, + Istvan Marko, + David Martin, + Jason R. Mastaler, + Gordon Matzigkeit, + Timo Metzemakers, + Richard Mlynarik, + Lantz Moore, + Morioka Tomohiko, @c Morioka + Erik Toubro Nielsen, + Hrvoje Niksic, + Andy Norman, + Fred Oberhauser, + C. R. Oldham, + Alexandre Oliva, + Ken Olstad, + Masaharu Onishi, @c Onishi + Hideki Ono, @c Ono + Ettore Perazzoli, + William Perry, + Stephen Peters, + Jens-Ulrik Holger Petersen, + Ulrich Pfeifer, + Matt Pharr, + Andy Piper, + John McClary Prevost, + Bill Pringlemeir, + Mike Pullen, + Jim Radford, + Colin Rafferty, + Lasse Rasinen, + Lars Balker Rasmussen, + Joe Reiss, + Renaud Rioboo, + Roland B. Roberts, + Bart Robinson, + Christian von Roques, + Markus Rost, + Jason Rumney, + Wolfgang Rupprecht, + Jay Sachs, + Dewey M. Sasser, + Conrad Sauerwald, + Loren Schall, + Dan Schmidt, + Ralph Schleicher, + Philippe Schnoebelen, + Andreas Schwab, + Randal L. Schwartz, + Danny Siu, + Matt Simmons, + Paul D. Smith, + Jeff Sparkes, + Toby Speight, + Michael Sperber, + Darren Stalder, + Richard Stallman, + Greg Stark, + Sam Steingold, + Paul Stevenson, + Jonas Steverud, + Paul Stodghill, + Kiyokazu Suto, @c Suto + Kurt Swanson, + Samuel Tardieu, + Teddy, + Chuck Thompson, + Tozawa Akihiko, @c Tozawa + Philippe Troin, + James Troup, + Trung Tran-Duc, + Jack Twilley, + Aaron M. Ucko, + Aki Vehtari, + Didier Verna, + Vladimir Volovich, + Jan Vroonhof, + Stefan Waldherr, + Pete Ware, + Barry A. Warsaw, + Christoph Wedler, + Joe Wells, + Lee Willis, + and + Lloyd Zusman. + + + For a full overview of what each person has done, the ChangeLogs + included in the Gnus alpha distributions should give ample reading + (550kB and counting). + + Apologies to everybody that I've forgotten, of which there are many, I'm + sure. + + Gee, that's quite a list of people. I guess that must mean that there + actually are people who are using Gnus. Who'd'a thunk it! + + + @node New Features + @subsection New Features + @cindex new features + + @menu + * ding Gnus:: New things in Gnus 5.0/5.1, the first new Gnus. + * September Gnus:: The Thing Formally Known As Gnus 5.2/5.3. + * Red Gnus:: Third time best---Gnus 5.4/5.5. + * Quassia Gnus:: Two times two is four, or Gnus 5.6/5.7. + * Pterodactyl Gnus:: Pentad also starts with P, AKA Gnus 5.8/5.9. + * Oort Gnus:: It's big. It's far out. Gnus 5.10. + @end menu + + These lists are, of course, just @emph{short} overviews of the + @emph{most} important new features. No, really. There are tons more. + Yes, we have feeping creaturism in full effect. + + @node ding Gnus + @subsubsection (ding) Gnus + + New features in Gnus 5.0/5.1: + + @itemize @bullet + + @item + The look of all buffers can be changed by setting format-like variables + (@pxref{Group Buffer Format} and @pxref{Summary Buffer Format}). + + @item + Local spool and several @acronym{NNTP} servers can be used at once + (@pxref{Select Methods}). + + @item + You can combine groups into virtual groups (@pxref{Virtual Groups}). + + @item + You can read a number of different mail formats (@pxref{Getting Mail}). + All the mail back ends implement a convenient mail expiry scheme + (@pxref{Expiring Mail}). + + @item + Gnus can use various strategies for gathering threads that have lost + their roots (thereby gathering loose sub-threads into one thread) or it + can go back and retrieve enough headers to build a complete thread + (@pxref{Customizing Threading}). + + @item + Killed groups can be displayed in the group buffer, and you can read + them as well (@pxref{Listing Groups}). + + @item + Gnus can do partial group updates---you do not have to retrieve the + entire active file just to check for new articles in a few groups + (@pxref{The Active File}). + + @item + Gnus implements a sliding scale of subscribedness to groups + (@pxref{Group Levels}). + + @item + You can score articles according to any number of criteria + (@pxref{Scoring}). You can even get Gnus to find out how to score + articles for you (@pxref{Adaptive Scoring}). + + @item + Gnus maintains a dribble buffer that is auto-saved the normal Emacs + manner, so it should be difficult to lose much data on what you have + read if your machine should go down (@pxref{Auto Save}). + + @item + Gnus now has its own startup file (@file{~/.gnus.el}) to avoid + cluttering up the @file{.emacs} file. + + @item + You can set the process mark on both groups and articles and perform + operations on all the marked items (@pxref{Process/Prefix}). + + @item + You can grep through a subset of groups and create a group from the + results (@pxref{Kibozed Groups}). + + @item + You can list subsets of groups according to, well, anything + (@pxref{Listing Groups}). + + @item + You can browse foreign servers and subscribe to groups from those + servers (@pxref{Browse Foreign Server}). + + @item + Gnus can fetch articles, asynchronously, on a second connection to the + server (@pxref{Asynchronous Fetching}). + + @item + You can cache articles locally (@pxref{Article Caching}). + + @item + The uudecode functions have been expanded and generalized + (@pxref{Decoding Articles}). + + @item + You can still post uuencoded articles, which was a little-known feature + of @sc{gnus}' past (@pxref{Uuencoding and Posting}). + + @item + Fetching parents (and other articles) now actually works without + glitches (@pxref{Finding the Parent}). + + @item + Gnus can fetch @acronym{FAQ}s and group descriptions (@pxref{Group Information}). + + @item + Digests (and other files) can be used as the basis for groups + (@pxref{Document Groups}). + + @item + Articles can be highlighted and customized (@pxref{Customizing + Articles}). + + @item + URLs and other external references can be buttonized (@pxref{Article + Buttons}). + + @item + You can do lots of strange stuff with the Gnus window & frame + configuration (@pxref{Window Layout}). + + @item + You can click on buttons instead of using the keyboard + (@pxref{Buttons}). + + @end itemize + + + @node September Gnus + @subsubsection September Gnus + + @iftex + @iflatex + \gnusfig{-28cm}{0cm}{\epsfig{figure=ps/september,height=20cm}} + @end iflatex + @end iftex + + New features in Gnus 5.2/5.3: + + @itemize @bullet + + @item + A new message composition mode is used. All old customization variables + for @code{mail-mode}, @code{rnews-reply-mode} and @code{gnus-msg} are + now obsolete. + + @item + Gnus is now able to generate @dfn{sparse} threads---threads where + missing articles are represented by empty nodes (@pxref{Customizing + Threading}). + + @lisp + (setq gnus-build-sparse-threads 'some) + @end lisp + + @item + Outgoing articles are stored on a special archive server + (@pxref{Archived Messages}). + + @item + Partial thread regeneration now happens when articles are + referred. + + @item + Gnus can make use of GroupLens predictions (@pxref{GroupLens}). + + @item + Picons (personal icons) can be displayed under XEmacs (@pxref{Picons}). + + @item + A @code{trn}-like tree buffer can be displayed (@pxref{Tree Display}). + + @lisp + (setq gnus-use-trees t) + @end lisp + + @item + An @code{nn}-like pick-and-read minor mode is available for the summary + buffers (@pxref{Pick and Read}). + + @lisp + (add-hook 'gnus-summary-mode-hook 'gnus-pick-mode) + @end lisp + + @item + In binary groups you can use a special binary minor mode (@pxref{Binary + Groups}). + + @item + Groups can be grouped in a folding topic hierarchy (@pxref{Group + Topics}). + + @lisp + (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) + @end lisp + + @item + Gnus can re-send and bounce mail (@pxref{Summary Mail Commands}). + + @item + Groups can now have a score, and bubbling based on entry frequency + is possible (@pxref{Group Score}). + + @lisp + (add-hook 'gnus-summary-exit-hook 'gnus-summary-bubble-group) + @end lisp + + @item + Groups can be process-marked, and commands can be performed on + groups of groups (@pxref{Marking Groups}). + + @item + Caching is possible in virtual groups. + + @item + @code{nndoc} now understands all kinds of digests, mail boxes, rnews + news batches, ClariNet briefs collections, and just about everything + else (@pxref{Document Groups}). + + @item + Gnus has a new back end (@code{nnsoup}) to create/read SOUP packets + (@pxref{SOUP}). + + @item + The Gnus cache is much faster. + + @item + Groups can be sorted according to many criteria (@pxref{Sorting + Groups}). + + @item + New group parameters have been introduced to set list-addresses and + expiry times (@pxref{Group Parameters}). + + @item + All formatting specs allow specifying faces to be used + (@pxref{Formatting Fonts}). + + @item + There are several more commands for setting/removing/acting on process + marked articles on the @kbd{M P} submap (@pxref{Setting Process Marks}). + + @item + The summary buffer can be limited to show parts of the available + articles based on a wide range of criteria. These commands have been + bound to keys on the @kbd{/} submap (@pxref{Limiting}). + + @item + Articles can be made persistent with the @kbd{*} command + (@pxref{Persistent Articles}). + + @item + All functions for hiding article elements are now toggles. + + @item + Article headers can be buttonized (@pxref{Article Washing}). + + @item + All mail back ends support fetching articles by @code{Message-ID}. + + @item + Duplicate mail can now be treated properly (@pxref{Duplicates}). + + @item + All summary mode commands are available directly from the article + buffer (@pxref{Article Keymap}). + + @item + Frames can be part of @code{gnus-buffer-configuration} (@pxref{Window + Layout}). + + @item + Mail can be re-scanned by a daemonic process (@pxref{Daemons}). + @iftex + @iflatex + \marginpar[\mbox{}\hfill\epsfig{figure=ps/fseptember,height=5cm}]{\epsfig{figure=ps/fseptember,height=5cm}} + @end iflatex + @end iftex + + @item + Gnus can make use of NoCeM files to weed out spam (@pxref{NoCeM}). + + @lisp + (setq gnus-use-nocem t) + @end lisp + + @item + Groups can be made permanently visible (@pxref{Listing Groups}). + + @lisp + (setq gnus-permanently-visible-groups "^nnml:") + @end lisp + + @item + Many new hooks have been introduced to make customizing easier. + + @item + Gnus respects the @code{Mail-Copies-To} header. + + @item + Threads can be gathered by looking at the @code{References} header + (@pxref{Customizing Threading}). + + @lisp + (setq gnus-summary-thread-gathering-function + 'gnus-gather-threads-by-references) + @end lisp + + @item + Read articles can be stored in a special backlog buffer to avoid + refetching (@pxref{Article Backlog}). + + @lisp + (setq gnus-keep-backlog 50) + @end lisp + + @item + A clean copy of the current article is always stored in a separate + buffer to allow easier treatment. + + @item + Gnus can suggest where to save articles (@pxref{Saving Articles}). + + @item + Gnus doesn't have to do as much prompting when saving (@pxref{Saving + Articles}). + + @lisp + (setq gnus-prompt-before-saving t) + @end lisp + + @item + @code{gnus-uu} can view decoded files asynchronously while fetching + articles (@pxref{Other Decode Variables}). + + @lisp + (setq gnus-uu-grabbed-file-functions 'gnus-uu-grab-view) + @end lisp + + @item + Filling in the article buffer now works properly on cited text + (@pxref{Article Washing}). + + @item + Hiding cited text adds buttons to toggle hiding, and how much + cited text to hide is now customizable (@pxref{Article Hiding}). + + @lisp + (setq gnus-cited-lines-visible 2) + @end lisp + + @item + Boring headers can be hidden (@pxref{Article Hiding}). + + @item + Default scoring values can now be set from the menu bar. + + @item + Further syntax checking of outgoing articles have been added. + + @end itemize + + + @node Red Gnus + @subsubsection Red Gnus + + New features in Gnus 5.4/5.5: + + @iftex + @iflatex + \gnusfig{-5.5cm}{-4cm}{\epsfig{figure=ps/red,height=20cm}} + @end iflatex + @end iftex + + @itemize @bullet + + @item + @file{nntp.el} has been totally rewritten in an asynchronous fashion. + + @item + Article prefetching functionality has been moved up into + Gnus (@pxref{Asynchronous Fetching}). + + @item + Scoring can now be performed with logical operators like @code{and}, + @code{or}, @code{not}, and parent redirection (@pxref{Advanced + Scoring}). + + @item + Article washing status can be displayed in the + article mode line (@pxref{Misc Article}). + + @item + @file{gnus.el} has been split into many smaller files. + + @item + Suppression of duplicate articles based on Message-ID can be done + (@pxref{Duplicate Suppression}). + + @lisp + (setq gnus-suppress-duplicates t) + @end lisp + + @item + New variables for specifying what score and adapt files are to be + considered home score and adapt files (@pxref{Home Score File}) have + been added. + + @item + @code{nndoc} was rewritten to be easily extendable (@pxref{Document + Server Internals}). + + @item + Groups can inherit group parameters from parent topics (@pxref{Topic + Parameters}). + + @item + Article editing has been revamped and is now actually usable. + + @item + Signatures can be recognized in more intelligent fashions + (@pxref{Article Signature}). + + @item + Summary pick mode has been made to look more @code{nn}-like. Line + numbers are displayed and the @kbd{.} command can be used to pick + articles (@code{Pick and Read}). + + @item + Commands for moving the @file{.newsrc.eld} from one server to + another have been added (@pxref{Changing Servers}). + + @item + There's a way now to specify that uninteresting'' fields be suppressed + when generating lines in buffers (@pxref{Advanced Formatting}). + + @item + Several commands in the group buffer can be undone with @kbd{C-M-_} + (@pxref{Undo}). + + @item + Scoring can be done on words using the new score type @code{w} + (@pxref{Score File Format}). + + @item + Adaptive scoring can be done on a Subject word-by-word basis + (@pxref{Adaptive Scoring}). + + @lisp + (setq gnus-use-adaptive-scoring '(word)) + @end lisp + + @item + Scores can be decayed (@pxref{Score Decays}). + + @lisp + (setq gnus-decay-scores t) + @end lisp + + @item + Scoring can be performed using a regexp on the Date header. The Date is + normalized to compact ISO 8601 format first (@pxref{Score File Format}). + + @item + A new command has been added to remove all data on articles from + the native server (@pxref{Changing Servers}). + + @item + A new command for reading collections of documents + (@code{nndoc} with @code{nnvirtual} on top) has been address@hidden + (@pxref{Really Various Summary Commands}). + + @item + Process mark sets can be pushed and popped (@pxref{Setting Process + Marks}). + + @item + A new mail-to-news back end makes it possible to post even when the @acronym{NNTP} + server doesn't allow posting (@pxref{Mail-To-News Gateways}). + + @item + A new back end for reading searches from Web search engines + (@dfn{DejaNews}, @dfn{Alta Vista}, @dfn{InReference}) has been added + (@pxref{Web Searches}). + + @item + Groups inside topics can now be sorted using the standard sorting + functions, and each topic can be sorted independently (@pxref{Topic + Sorting}). + + @item + Subsets of the groups can be sorted independently (@code{Sorting + Groups}). + + @item + Cached articles can be pulled into the groups (@pxref{Summary Generation + Commands}). + @iftex + @iflatex + \marginpar[\mbox{}\hfill\epsfig{figure=ps/fred,width=3cm}]{\epsfig{figure=ps/fred,width=3cm}} + @end iflatex + @end iftex + + @item + Score files are now applied in a more reliable order (@pxref{Score + Variables}). + + @item + Reports on where mail messages end up can be generated (@pxref{Splitting + Mail}). + + @item + More hooks and functions have been added to remove junk from incoming + mail before saving the mail (@pxref{Washing Mail}). + + @item + Emphasized text can be properly fontisized: + + @end itemize + + + @node Quassia Gnus + @subsubsection Quassia Gnus + + New features in Gnus 5.6: + + @itemize @bullet + + @item + New functionality for using Gnus as an offline newsreader has been + added. A plethora of new commands and modes have been added. + @xref{Gnus Unplugged}, for the full story. + + @item + The @code{nndraft} back end has returned, but works differently than + before. All Message buffers are now also articles in the @code{nndraft} + group, which is created automatically. + + @item + @code{gnus-alter-header-function} can now be used to alter header + values. + + @item + @code{gnus-summary-goto-article} now accept Message-ID's. + + @item + A new Message command for deleting text in the body of a message + outside the region: @kbd{C-c C-v}. + + @item + You can now post to component group in @code{nnvirtual} groups with + @kbd{C-u C-c C-c}. + + @item + @code{nntp-rlogin-program}---new variable to ease customization. + + @item + @code{C-u C-c C-c} in @code{gnus-article-edit-mode} will now inhibit + re-highlighting of the article buffer. + + @item + New element in @address@hidden + + @item + @kbd{M-i} symbolic prefix command. @xref{Symbolic Prefixes}, for + details. + + @item + @kbd{L} and @kbd{I} in the summary buffer now take the symbolic prefix + @kbd{a} to add the score rule to the @file{all.SCORE} file. + + @item + @code{gnus-simplify-subject-functions} variable to allow greater + control over simplification. + + @item + @kbd{A T}---new command for fetching the current thread. + + @item + @kbd{/ T}---new command for including the current thread in the + limit. + + @item + @kbd{M-RET} is a new Message command for breaking cited text. + + @item + @samp{\\1}-expressions are now valid in @code{nnmail-split-methods}. + + @item + The @code{custom-face-lookup} function has been removed. + If you used this function in your initialization files, you must + rewrite them to use @code{face-spec-set} instead. + + @item + Canceling now uses the current select method. Symbolic prefix + @kbd{a} forces normal posting method. + + @item + New command to translate M******** sm*rtq**t*s into proper + address@hidden d}. + + @item + For easier debugging of @code{nntp}, you can set + @code{nntp-record-commands} to a address@hidden value. + + @item + @code{nntp} now uses @file{~/.authinfo}, a @file{.netrc}-like file, for + controlling where and how to send @sc{authinfo} to @acronym{NNTP} servers. + + @item + A command for editing group parameters from the summary buffer + has been added. + + @item + A history of where mails have been split is available. + + @item + A new article date command has been address@hidden + + @item + Subjects can be simplified when threading by setting + @code{gnus-score-thread-simplify}. + + @item + A new function for citing in Message has been + address@hidden + + @item + @code{article-strip-all-blank-lines}---new article command. + + @item + A new Message command to kill to the end of the article has + been added. + + @item + A minimum adaptive score can be specified by using the + @code{gnus-adaptive-word-minimum} variable. + + @item + The lapsed date'' article header can be kept continually + updated by the @code{gnus-start-date-timer} command. + + @item + Web listserv archives can be read with the @code{nnlistserv} back end. + + @item + Old dejanews archives can now be read by @code{nnweb}. + + @end itemize + + @node Pterodactyl Gnus + @subsubsection Pterodactyl Gnus + + New features in Gnus 5.8: + + @itemize @bullet + + @item + The mail-fetching functions have changed. See the manual for the + many details. In particular, all procmail fetching variables are gone. + + If you used procmail like in + + @lisp + (setq nnmail-use-procmail t) + (setq nnmail-spool-file 'procmail) + (setq nnmail-procmail-directory "~/mail/incoming/") + (setq nnmail-procmail-suffix "\\.in") + @end lisp + + this now has changed to + + @lisp + (setq mail-sources + '((directory :path "~/mail/incoming/" + :suffix ".in"))) + @end lisp + + @xref{Mail Source Specifiers}. + + @item + Gnus is now a @acronym{MIME}-capable reader. This affects many parts of + Gnus, and adds a slew of new commands. See the manual for details. + + @item + Gnus has also been multilingualized. This also affects too + many parts of Gnus to summarize here, and adds many new variables. + + @item + @code{gnus-auto-select-first} can now be a function to be + called to position point. + + @item + The user can now decide which extra headers should be included in + summary buffers and @acronym{NOV} files. + + @item + @code{gnus-article-display-hook} has been removed. Instead, a number + of variables starting with @code{gnus-treat-} have been added. + + @item + The Gnus posting styles have been redone again and now works in a + subtly different manner. + + @item + New web-based back ends have been added: @code{nnslashdot}, + @code{nnwarchive} and @code{nnultimate}. nnweb has been revamped, + again, to keep up with ever-changing layouts. + + @item + Gnus can now read @acronym{IMAP} mail via @code{nnimap}. + + @end itemize + + @node Oort Gnus + @subsubsection Oort Gnus + @cindex Oort Gnus + + New features in Gnus 5.10: + + @itemize @bullet + + @item + @kbd{F} (@code{gnus-article-followup-with-original}) and @kbd{R} + (@code{gnus-article-reply-with-original}) only yank the text in the + region if the region is active. + + @item + @code{gnus-group-read-ephemeral-group} can be called interactively, + using @kbd{G M}. + + @item + In draft groups, @kbd{e} is now bound to @code{gnus-draft-edit-message}. + Use @kbd{B w} for @code{gnus-summary-edit-article} instead. + + @item + The revised Gnus @acronym{FAQ} is included in the manual, + @xref{Frequently Asked Questions}. + + @item + Upgrading from previous (stable) version if you have used Oort. + + If you have tried Oort (the unstable Gnus branch leading to this + release) but went back to a stable version, be careful when upgrading to + this version. In particular, you will probably want to remove all + @file{.marks} (nnml) and @file{.mrk} (nnfolder) files, so that flags are + read from your @file{.newsrc.eld} instead of from the + @file{.marks}/@file{.mrk} file where this release store flags. See a + later entry for more information about marks. Note that downgrading + isn't save in general. + + @item + Article Buttons + + More buttons for URLs, mail addresses, Message-IDs, Info links, man + pages and Emacs or Gnus related references. @xref{Article Buttons}. The + variables @address@hidden can be used to control the + appearance of all article buttons. @xref{Article Button Levels}. + + @item + Dired integration + + @code{gnus-dired-minor-mode} (see @ref{Other modes}) installs key + bindings in dired buffers to send a file as an attachment, open a file + using the appropriate mailcap entry, and print a file using the mailcap + entry. + + @item + Gnus can display RSS newsfeeds as a newsgroup. @xref{RSS}. + + @item + Single-part yenc encoded attachments can be decoded. + + @item + Picons + + The picons code has been reimplemented to work in GNU Emacs---some of + the previous options have been removed or renamed. + + Picons are small personal icons'' representing users, domain and + newsgroups, which can be displayed in the Article buffer. + @xref{Picons}. + + @item + If the new option @code{gnus-treat-body-boundary} is address@hidden, a + boundary line is drawn at the end of the headers. + + @item + Retrieval of charters and control messages + + There are new commands for fetching newsgroup charters (@kbd{H c}) and + control messages (@kbd{H C}). + + @item + Delayed articles + + You can delay the sending of a message with @kbd{C-c C-j} in the Message + buffer. The messages are delivered at specified time. This is useful + for sending yourself reminders. @xref{Delayed Articles}. + + @item + If @code{auto-compression-mode} is enabled, attachments are automatically + decompressed when activated. + + @item + If the new option @code{nnml-use-compressed-files} is address@hidden, + the nnml back end allows compressed message files. + + @item + Signed article headers (X-PGP-Sig) can be verified with @kbd{W p}. + + @item + The Summary Buffer uses an arrow in the fringe to indicate the current + article. Use @code{(setq gnus-summary-display-arrow nil)} to disable it. + + @item + Warn about email replies to news + + Do you often find yourself replying to news by email by mistake? Then + the new option @code{gnus-confirm-mail-reply-to-news} is just the thing for + you. + + @item + If the new option @code{gnus-summary-display-while-building} is + address@hidden, the summary buffer is shown and updated as it's being + built. + + @item + The new @code{recent} mark @samp{.} indicates newly arrived messages (as + opposed to old but unread messages). + + @item + The new option @code{gnus-gcc-mark-as-read} automatically marks + Gcc articles as read. + + @item + The nndoc back end now supports mailman digests and exim bounces. + + @item + Gnus supports RFC 2369 mailing list headers, and adds a number of + related commands in mailing list groups. @xref{Mailing List}. + + @item + The Date header can be displayed in a format that can be read aloud + in English. @xref{Article Date}. + + @item + The envelope sender address can be customized when using Sendmail. + @xref{Mail Variables, Mail Variables,, message, Message Manual}. + + @item + diffs are automatically highlighted in groups matching + @code{mm-uu-diff-groups-regexp} + + @item + @acronym{TLS} wrapper shipped with Gnus + + @acronym{TLS}/@acronym{SSL} is now supported in @acronym{IMAP} and + @acronym{NNTP} via @file{tls.el} and GNUTLS. The old + @acronym{TLS}/@acronym{SSL} support via (external third party) + @file{ssl.el} and OpenSSL still works. + + @item + New @file{make.bat} for compiling and installing Gnus under MS Windows + + Use @file{make.bat} if you want to install Gnus under MS Windows, the + first argument to the batch-program should be the directory where + @file{xemacs.exe} respectively @file{emacs.exe} is located, iff you want + to install Gnus after compiling it, give @file{make.bat} @code{/copy} as + the second parameter. + + @file{make.bat} has been rewritten from scratch, it now features + automatic recognition of XEmacs and GNU Emacs, generates + @file{gnus-load.el}, checks if errors occur while compilation and + generation of info files and reports them at the end of the build + process. It now uses @code{makeinfo} if it is available and falls + back to @file{infohack.el} otherwise. @file{make.bat} should now + install all files which are necessary to run Gnus and be generally a + complete replacement for the @code{configure; make; make install} + cycle used under Unix systems. + + The new @file{make.bat} makes @file{make-x.bat} superfluous, so it has + been removed. + + @item + Support for address@hidden domain names + + Message supports address@hidden domain names in From:, To: and + Cc: and will query you whether to perform encoding when you try to + send a message. The variable @code{message-use-idna} controls this. + Gnus will also decode address@hidden domain names in From:, To: + and Cc: when you view a message. The variable @code{gnus-use-idna} + controls this. + + @item + Better handling of Microsoft citation styles + + Gnus now tries to recognize the mangled header block that some Microsoft + mailers use to indicate that the rest of the message is a citation, even + though it is not quoted in any way. The variable + @code{gnus-cite-unsightly-citation-regexp} matches the start of these + citations. + + @item + @code{gnus-article-skip-boring} + + If you set @code{gnus-article-skip-boring} to @code{t}, then Gnus will + not scroll down to show you a page that contains only boring text, + which by default means cited text and signature. You can customize + what is skippable using @code{gnus-article-boring-faces}. + + This feature is especially useful if you read many articles that + consist of a little new content at the top with a long, untrimmed + message cited below. + + @item + The format spec @code{%C} for positioning point has changed to @code{%*}. + + @item + The new variable @code{gnus-parameters} can be used to set group parameters. + + Earlier this was done only via @kbd{G p} (or @kbd{G c}), which stored + the parameters in @file{~/.newsrc.eld}, but via this variable you can + enjoy the powers of customize, and simplified backups since you set the + variable in @file{~/.emacs} instead of @file{~/.newsrc.eld}. The + variable maps regular expressions matching group names to group + parameters, a'la: + @lisp + (setq gnus-parameters + '(("mail\\..*" + (gnus-show-threads nil) + (gnus-use-scoring nil)) + ("^nnimap:\$$foo.bar\$$$"
+          (to-group . "\\1"))))
+ @end lisp
+
+ @item
+ Smileys (@samp{:-)}, @samp{;-)} etc) are now iconized for Emacs too.
+
+ Put @code{(setq gnus-treat-display-smileys nil)} in @file{~/.emacs} to
+ disable it.
+
+ @item
+ Gnus no longer generate the Sender: header automatically.
+
+ Earlier it was generated iff the user configurable email address was
+ different from the Gnus guessed default user address.  As the guessing
+ algorithm is rarely correct these days, and (more controversially) the
+ only use of the Sender: header was to check if you are entitled to
+ cancel/supersede news (which is now solved by Cancel Locks instead,
+ see another entry), generation of the header has been disabled by
+ default.  See the variables @code{message-required-headers},
+
+ @item
+ Features from third party @file{message-utils.el} added to @file{message.el}.
+
+ Message now asks if you wish to remove @samp{(was: <old subject>)} from
+ subject lines (see @code{message-subject-trailing-was-query}).  @kbd{C-c
+ M-m} and @kbd{C-c M-f} inserts markers indicating included text.
+ @kbd{C-c C-f a} adds a X-No-Archive: header.  @kbd{C-c C-f x} inserts
+ appropriate headers and a note in the body for cross-postings and
+ followups (see the variables @address@hidden).
+
+ @item
+ References and X-Draft-Headers are no longer generated when you start
+ composing messages and @code{message-generate-headers-first} is
+ @code{nil}.
+
+ @item
+ Improved anti-spam features.
+
+ Gnus is now able to take out spam from your mail and news streams
+ using a wide variety of programs and filter rules.  Among the supported
+ methods are RBL blocklists, bogofilter and white/blacklists.  Hooks
+ for easy use of external packages such as SpamAssassin and Hashcash
+ are also new.  @xref{Thwarting Email Spam}.
+
+ @item
+ Easy inclusion of X-Faces headers.
+
+ @item
+
+ @item
+ In the summary buffer, the new command @kbd{/ N} inserts new messages
+ and @kbd{/ o} inserts old messages.
+
+ @item
+ Gnus decodes morse encoded messages if you press @kbd{W m}.
+
+ @item
+ Unread count correct in nnimap groups.
+
+ The estimated number of unread articles in the group buffer should now
+ be correct for nnimap groups.  This is achieved by calling
+ @code{gnus-setup-news-hook} (called on startup) and
+ @code{gnus-after-getting-new-news-hook}. (called after getting new
+ mail).  If you have modified those variables from the default, you may
+ you were happy with the estimate and want to save some (minimal) time
+ when getting new mail, remove the function.
+
+ @item
+ Group Carbon Copy (GCC) quoting
+
+ To support groups that contains SPC and other weird characters, groups
+ are quoted before they are placed in the Gcc: header.  This means
+ variables such as @code{gnus-message-archive-group} should no longer
+ contain quote characters to make groups containing SPC work.  Also, if
+ you are using the string @samp{nnml:foo, nnml:bar} (indicating Gcc
+ into two groups) you must change it to return the list
+ @code{("nnml:foo" "nnml:bar")}, otherwise the Gcc: line will be quoted
+ incorrectly.  Note that returning the string @samp{nnml:foo, nnml:bar}
+ was incorrect earlier, it just didn't generate any problems since it
+ was inserted directly.
+
+ @item
+ @file{~/News/overview/} not used.
+
+ As a result of the following change, the @file{~/News/overview/}
+ directory is not used any more.  You can safely delete the entire
+ hierarchy.
+
+ @item
+ @code{gnus-agent}
+
+ The Gnus Agent has seen a major updated and is now enabled by default,
+ and all nntp and nnimap servers from @code{gnus-select-method} and
+ @code{gnus-secondary-select-method} are agentized by default.  Earlier
+ only the server in @code{gnus-select-method} was agentized by the
+ default, and the agent was disabled by default.  When the agent is
+ of the back ends when possible.  Earlier this only happened in the
+ unplugged state.  You can enroll or remove servers with @kbd{J a} and
+ @kbd{J r} in the server buffer.  Gnus will not download articles into
+ the Agent cache, unless you instruct it to do so, though, by using
+ @kbd{J u} or @kbd{J s} from the Group buffer.  You revert to the old
+ behaviour of having the Agent disabled with @code{(setq gnus-agent
+ nil)}.  Note that putting @code{(gnus-agentize)} in @file{~/.gnus.el}
+ is not needed any more.
+
+ @item
+ @code{gnus-summary-line-format}
+
+ The default value changed to @samp{%U%R%z%I%(%[%4L: %-23,23f%]%)
+ changed their default so that the users name will be replaced by the
+ recipient's name or the group name posting to for @acronym{NNTP}
+ groups.
+
+ @item
+ @file{deuglify.el} (@code{gnus-article-outlook-deuglify-article})
+
+ A new file from Raymond Scholz @email{rscholz@@zonix.de} for deuglifying
+ broken Outlook (Express) articles.
+
+ @item
+
+ If you use a stand-alone Gnus distribution, you'd better add
+
+ some of which may not be included in distributions of Emacsen.
+
+ @item
+ @code{gnus-slave-unplugged}
+
+ A new command which starts Gnus offline in slave mode.
+
+ @item
+ @code{message-insinuate-rmail}
+
+ mail-user-agent 'gnus-user-agent)} in @file{.emacs} convinces Rmail to
+ compose, reply and forward messages in message-mode, where you can
+ enjoy the power of @acronym{MML}.
+
+ @item
+ @code{message-minibuffer-local-map}
+
+ The line below enables BBDB in resending a message:
+ @lisp
+ (define-key message-minibuffer-local-map [(tab)]
+   'bbdb-complete-name)
+ @end lisp
+
+ @item
+ Externalizing and deleting of attachments.
+
+ If @code{gnus-gcc-externalize-attachments} or
+ local files as external parts.
+
+ The command @code{gnus-mime-save-part-and-strip} (bound to @kbd{C-o}
+ on @acronym{MIME} buttons) saves a part and replaces the part with an
+ external one.  @code{gnus-mime-delete-part} (bound to @kbd{d} on
+ @acronym{MIME} buttons) removes a part.  It works only on back ends
+ that support editing.
+
+ @item
+ @code{gnus-default-charset}
+
+ The default value is determined from the
+ @code{iso-8859-1}.  Also the @samp{.*} item in
+ @code{gnus-group-charset-alist} is removed.
+
+ @item
+ @code{gnus-posting-styles}
+
+ Add a new format of match like
+ @lisp
+  (Organization "Somewhere, Inc."))
+ @end lisp
+ The old format like the lines below is obsolete, but still accepted.
+ @lisp
+         (Organization "Somewhere, Inc."))
+ @end lisp
+
+ @item
+
+ @samp{X-Draft-From} and @samp{X-Gnus-Agent-Meta-Information} have been
+ added into these two variables.  If you customized those, perhaps you
+
+ @item
+ Gnus reads the @acronym{NOV} and articles in the Agent if plugged.
+
+ If one reads an article while plugged, and the article already exists
+ gnus-agent-cache nil)} reverts to the old behavior.
+
+ @item
+ Gnus supports the format=flowed'' (RFC 2646) parameter.  On
+ composing messages, it is enabled by @code{use-hard-newlines}.
+ Decoding format=flowed was present but not documented in earlier
+ versions.
+
+ @item
+ Gnus supports the generation of RFC 2298 Disposition Notification requests.
+
+ This is invoked with the @kbd{C-c M-n} key binding from message mode.
+
+ @item
+ Gnus supports Maildir groups.
+
+ Gnus includes a new back end @file{nnmaildir.el}.  @xref{Maildir}.
+
+ @item
+ Printing capabilities are enhanced.
+
+ Gnus supports Muttprint natively with @kbd{O P} from the Summary and
+ Article buffers.  Also, each individual @acronym{MIME} part can be
+ printed using @kbd{p} on the @acronym{MIME} button.
+
+ @item
+ Message supports the Importance: (RFC 2156) header.
+
+ In the message buffer, @kbd{C-c C-f C-i} or @kbd{C-c C-u} cycles through
+ the valid values.
+
+ @item
+ Gnus supports Cancel Locks in News.
+
+ This means a header @samp{Cancel-Lock} is inserted in news posting.  It is
+ used to determine if you wrote an article or not (for canceling and
+ superseding).  Gnus generates a random password string the first time
+ you post a message, and saves it in your @file{~/.emacs} using the Custom
+ system.  While the variable is called @code{canlock-password}, it is not
+ security sensitive data.  Publishing your canlock string on the web
+ will not allow anyone to be able to anything she could not already do.
+ The behaviour can be changed by customizing @code{message-insert-canlock}.
+
+ @item
+ Gnus supports server-side mail filtering using Sieve.
+
+ Sieve rules can be added as Group Parameters for groups, and the
+ complete Sieve script is generated using @kbd{D g} from the Group
+ buffer, and then uploaded to the server using @kbd{C-c C-l} in the
+ generated Sieve buffer.  @xref{Sieve Commands}, and the new Sieve
+ manual @ref{Top, , Top, sieve, Emacs Sieve}.
+
+ @item
+ Extended format specs.
+
+ Format spec @samp{%&user-date;} is added into
+ @code{gnus-summary-line-format-alist}.  Also, user defined extended
+ format specs are supported.  The extended format specs look like
+ @samp{%u&foo;}, which invokes function
+ @address@hidden  Because @samp{&} is used as the
+ escape character, old user defined format @samp{%u&} is no longer supported.
+
+ @item
+ @kbd{/ *} (@code{gnus-summary-limit-include-cached}) is rewritten.
+
+ It was aliased to @kbd{Y c}
+ (@code{gnus-summary-insert-cached-articles}).  The new function filters
+ out other articles.
+
+ @item Some limiting commands accept a @kbd{C-u} prefix to negate the match.
+
+ If @kbd{C-u} is used on subject, author or extra headers, i.e., @kbd{/
+ s}, @kbd{/ a}, and @kbd{/ x}
+ result will be to display all articles that do not match the expression.
+
+ @item
+ Group names are treated as UTF-8 by default.
+
+ This is supposedly what USEFOR wanted to migrate to.  See
+ @code{gnus-group-name-charset-group-alist} and
+ @code{gnus-group-name-charset-method-alist} for customization.
+
+ @item
+ The nnml and nnfolder back ends store marks for each groups.
+
+ This makes it possible to take backup of nnml/nnfolder servers/groups
+ separately of @file{~/.newsrc.eld}, while preserving marks.  It also
+ makes it possible to share articles and marks between users (without
+ sharing the @file{~/.newsrc.eld} file) within e.g. a department.  It
+ works by storing the marks stored in @file{~/.newsrc.eld} in a per-group
+ file @file{.marks} (for nnml) and @address@hidden (for
+ nnfolder, named @var{groupname}).  If the nnml/nnfolder is moved to
+ another machine, Gnus will automatically use the @file{.marks} or
+ @file{.mrk} file instead of the information in @file{~/.newsrc.eld}.
+ The new server variables @code{nnml-marks-is-evil} and
+ @code{nnfolder-marks-is-evil} can be used to disable this feature.
+
+ @item
+ The menu bar item (in Group and Summary buffer) named Misc'' has
+ been renamed to Gnus''.
+
+ @item
+ The menu bar item (in Message mode) named address@hidden'' has been
+ renamed to Attachments''.  Note that this menu also contains security
+ related stuff, like signing and encryption (@pxref{Security, Security,,
+ message, Message Manual}).
+
+ @item
+ @code{gnus-group-charset-alist} and
+ @code{gnus-group-ignored-charsets-alist}.
+
+ The regexps in these variables are compared with full group names
+ instead of real group names in 5.8.  Users who customize these
+ variables should change those regexps accordingly.  For example:
+ @lisp
+ ("^han\\>" euc-kr) -> ("\$$^\\|:\$$han\\>" euc-kr)
+ @end lisp
+
+ @item
+ Gnus supports @acronym{PGP} (RFC 1991/2440), @acronym{PGP/MIME} (RFC
+ 2015/3156) and @acronym{S/MIME} (RFC 2630-2633).
+
+ It needs an external @acronym{S/MIME} and OpenPGP implementation, but no
+ Attachments menu, and @kbd{C-c RET} key bindings, when composing
+ messages.  This also obsoletes @code{gnus-article-hide-pgp-hook}.
+
+ @item
+ Gnus inlines external parts (message/external).
+
+ @item
+ @acronym{MML} (Mime compose) prefix changed from @kbd{M-m} to @kbd{C-c
+ C-m}.
+
+ This change was made to avoid conflict with the standard binding of
+ @code{back-to-indentation}, which is also useful in message mode.
+
+ @item
+ The default for @code{message-forward-show-mml} changed to symbol @code{best}.
+
+ The behaviour for the @code{best} value is to show @acronym{MML} (i.e.,
+ convert to @acronym{MIME}) when appropriate.  @acronym{MML} will not be
+ used when forwarding signed or encrypted messages, as the conversion
+ invalidate the digital signature.
+ @end itemize
+
+ @iftex
+
+ @page
+ @node The Manual
+ @section The Manual
+ @cindex colophon
+ @cindex manual
+
+ This manual was generated from a TeXinfo file and then run through
+ either @code{texi2dvi}
+ @iflatex
+ or my own home-brewed TeXinfo to \LaTeX\ transformer,
+ and then run through @code{latex} and @code{dvips}
+ @end iflatex
+ to get what you hold in your hands now.
+
+ The following conventions have been used:
+
+ @enumerate
+
+ @item
+ This is a @samp{string}
+
+ @item
+ This is a @kbd{keystroke}
+
+ @item
+ This is a @file{file}
+
+ @item
+ This is a @code{symbol}
+
+ @end enumerate
+
+ So if I were to say set @code{flargnoze} to @samp{yes}'', that would
+ mean:
+
+ @lisp
+ (setq flargnoze "yes")
+ @end lisp
+
+ If I say set @code{flumphel} to @code{yes}'', that would mean:
+
+ @lisp
+ (setq flumphel 'yes)
+ @end lisp
+
+ @samp{yes} and @code{yes} are two @emph{very} different things---don't
+ ever get them confused.
+
+ @iflatex
+ Of course, everything in this manual is of vital interest, so you should
+ read it all.  Several times.  However, if you feel like skimming the
+ manual, look for that gnu head you should see in the margin over
+ there---it means that what's being discussed is of more importance than
+ the rest of the stuff.  (On the other hand, if everything is infinitely
+ important, how can anything be more important than that?  Just one more
+ of the mysteries of this world, I guess.)
+ @end iflatex
+
+ @end iftex
+
+
+ @node On Writing Manuals
+ @section On Writing Manuals
+
+ I guess most manuals are written after-the-fact; documenting a program
+ that's already there.  This is not how this manual is written.  When
+ implementing something, I write the manual entry for that something
+ straight away.  I then see that it's difficult to explain the
+ functionality, so I write how it's supposed to be, and then I change the
+ implementation.  Writing the documentation and writing the code goes
+ hand in hand.
+
+ This, of course, means that this manual has no, or little, flow.  It
+ documents absolutely everything in Gnus, but often not where you're
+ looking for it.  It is a reference manual, and not a guide to how to get
+ started with Gnus.
+
+ That would be a totally different book, that should be written using the
+ reference manual as source material.  It would look quite differently.
+
+
+ @page
+ @node Terminology
+ @section Terminology
+
+ @cindex terminology
+ @table @dfn
+
+ @item news
+ @cindex news
+ This is what you are supposed to use this thing for---reading news.
+ News is generally fetched from a nearby @acronym{NNTP} server, and is
+ generally publicly available to everybody.  If you post news, the entire
+ world is likely to read just what you have written, and they'll all
+ snigger mischievously.  Behind your back.
+
+ @item mail
+ @cindex mail
+ Everything that's delivered to you personally is mail.  Some news/mail
+ readers (like Gnus) blur the distinction between mail and news, but
+ there is a difference.  Mail is private.  News is public.  Mailing is
+ not posting, and replying is not following up.
+
+ Send a mail to the person who has written what you are reading.
+
+ Post an article to the current newsgroup responding to the article you
+
+ @item back end
+ @cindex back end
+ Gnus considers mail and news to be mostly the same, really.  The only
+ difference is how to access the actual articles.  News articles are
+ commonly fetched via the protocol @acronym{NNTP}, whereas mail
+ messages could be read from a file on the local disk.  The internal
+ architecture of Gnus thus comprises a front end'' and a number of
+ back ends''.  Internally, when you enter a group (by hitting
+ @key{RET}, say), you thereby invoke a function in the front end in
+ Gnus.  The front end then talks'' to a back end and says things like
+ Give me the list of articles in the foo group'' or Show me article
+ number 4711''.
+
+ So a back end mainly defines either a protocol (the @code{nntp} back
+ end accesses news via @acronym{NNTP}, the @code{nnimap} back end
+ accesses mail via @acronym{IMAP}) or a file format and directory
+ layout (the @code{nnspool} back end accesses news via the common
+ spool directory'' format, the @code{nnml} back end access mail via a
+ file format and directory layout that's quite similar).
+
+ Gnus does not handle the underlying media, so to speak---this is all
+ done by the back ends.  A back end is a collection of functions to
+ access the articles.
+
+ However, sometimes the term back end'' is also used where server''
+ would have been more appropriate.  And then there is the term select
+ method'' which can mean either.  The Gnus terminology can be quite
+ confusing.
+
+ @item native
+ @cindex native
+ Gnus will always use one method (and back end) as the @dfn{native}, or
+ default, way of getting news.
+
+ @item foreign
+ @cindex foreign
+ You can also have any number of foreign groups active at the same time.
+ These are groups that use non-native non-secondary back ends for getting
+ news.
+
+ @item secondary
+ @cindex secondary
+ Secondary back ends are somewhere half-way between being native and being
+ foreign, but they mostly act like they are native.
+
+ @item article
+ @cindex article
+ A message that has been posted as news.
+
+ @item mail message
+ @cindex mail message
+ A message that has been mailed.
+
+ @item message
+ @cindex message
+ A mail message or news article
+
+ The top part of a message, where administrative information (etc.) is
+ put.
+
+ @item body
+ @cindex body
+ The rest of an article.  Everything not in the head is in the
+ body.
+
+ A line from the head of an article.
+
+ A collection of such lines, or a collection of heads.  Or even a
+ collection of @acronym{NOV} lines.
+
+ @item @acronym{NOV}
+ @cindex @acronym{NOV}
+ When Gnus enters a group, it asks the back end for the headers of all
+ unread articles in the group.  Most servers support the News OverView
+ format, which is more compact and much faster to read and parse than the
+
+ @item level
+ @cindex levels
+ Each group is subscribed at some @dfn{level} or other (1-9).  The ones
+ that have a lower level are more'' subscribed than the groups with a
+ higher level.  In fact, groups on levels 1-5 are considered
+ @dfn{subscribed}; 6-7 are @dfn{unsubscribed}; 8 are @dfn{zombies}; and 9
+ are @dfn{killed}.  Commands for listing groups and scanning for new
+ articles will all use the numeric prefix as @dfn{working level}.
+
+ @item killed groups
+ @cindex killed groups
+ No information on killed groups is stored or updated, which makes killed
+ groups much easier to handle than subscribed groups.
+
+ @item zombie groups
+ @cindex zombie groups
+ Just like killed groups, only slightly less dead.
+
+ @item active file
+ @cindex active file
+ The news server has to keep track of what articles it carries, and what
+ groups exist.  All this information in stored in the active file, which
+ is rather large, as you might surmise.
+
+ @item bogus groups
+ @cindex bogus groups
+ A group that exists in the @file{.newsrc} file, but isn't known to the
+ server (i.e.,  it isn't in the active file), is a @emph{bogus group}.
+ This means that the group probably doesn't exist (any more).
+
+ @item activating
+ @cindex activating groups
+ The act of asking the server for info on a group and computing the
+ number of unread articles is called @dfn{activating the group}.
+ Un-activated groups are listed with @samp{*} in the group buffer.
+
+ @item server
+ @cindex server
+ A machine one can connect to and get news (or mail) from.
+
+ @item select method
+ @cindex select method
+ A structure that specifies the back end, the server and the virtual
+ server settings.
+
+ @item virtual server
+ @cindex virtual server
+ A named select method.  Since a select method defines all there is to
+ know about connecting to a (physical) server, taking the thing as a
+ whole is a virtual server.
+
+ @item washing
+ @cindex washing
+ Taking a buffer and running it through a filter of some sort.  The
+ result will (more often than not) be cleaner and more pleasing than the
+ original.
+
+ @item ephemeral groups
+ @cindex ephemeral groups
+ @cindex temporary groups
+ Most groups store data on what articles you have read.  @dfn{Ephemeral}
+ groups are groups that will have no data stored---when you exit the
+ group, it'll disappear into the aether.
+
+ @item solid groups
+ @cindex solid groups
+ This is the opposite of ephemeral groups.  All groups listed in the
+ group buffer are solid groups.
+
+ @item sparse articles
+ @cindex sparse articles
+ These are article placeholders shown in the summary buffer when
+ @code{gnus-build-sparse-threads} has been switched on.
+
+ To put responses to articles directly after the articles they respond
+ to---in a hierarchical fashion.
+
+ @item root
+ @cindex root
+ The first article in a thread is the root.  It is the ancestor of all
+
+ @item parent
+ @cindex parent
+ An article that has responses.
+
+ @item child
+ @cindex child
+ An article that responds to a different article---its parent.
+
+ @item digest
+ @cindex digest
+ A collection of messages in one file.  The most common digest format is
+ specified by RFC 1153.
+
+ @item splitting
+ @cindex splitting, terminolgy
+ @cindex mail sorting
+ @cindex mail filtering (splitting)
+ The action of sorting your emails according to certain rules. Sometimes
+ incorrectly called mail filtering.
+
+ @end table
+
+
+ @page
+ @node Customization
+ @section Customization
+ @cindex general customization
+
+ All variables are properly documented elsewhere in this manual.  This
+ section is designed to give general pointers on how to customize Gnus
+ for some quite common situations.
+
+ * Slow/Expensive Connection::   You run a local Emacs and get the news
elsewhere.
+ * Slow Terminal Connection::    You run a remote Emacs.
+ * Little Disk Space::           You feel that having large setup files is
icky.
+ * Slow Machine::                You feel like buying a faster machine.
+
+
+ @node Slow/Expensive Connection
+ @subsection Slow/Expensive NNTP Connection
+
+ If you run Emacs on a machine locally, and get your news from a machine
+ over some very thin strings, you want to cut down on the amount of data
+ Gnus has to get from the @acronym{NNTP} server.
+
+ @table @code
+
+ Set this to @code{nil}, which will inhibit Gnus from requesting the
+ entire active file from the server.  This file is often v.  large.  You
+ also have to set @code{gnus-check-new-newsgroups} and
+ @code{gnus-check-bogus-newsgroups} to @code{nil} to make sure that Gnus
+ doesn't suddenly decide to fetch the active file anyway.
+
+ @item gnus-nov-is-evil
+ This one has to be @code{nil}.  If not, grabbing article headers from
+ the @acronym{NNTP} server will not be very fast.  Not all @acronym{NNTP}
servers
+ support @sc{xover}; Gnus will detect this by itself.
+ @end table
+
+
+ @node Slow Terminal Connection
+ @subsection Slow Terminal Connection
+
+ Let's say you use your home computer for dialing up the system that runs
+ Emacs and Gnus.  If your modem is slow, you want to reduce (as much as
+ possible) the amount of data sent over the wires.
+
+ @table @code
+
+ @item gnus-auto-center-summary
+ Set this to @code{nil} to inhibit Gnus from re-centering the summary
+ buffer all the time.  If it is @code{vertical}, do only vertical
+ re-centering.  If it is neither @code{nil} nor @code{vertical}, do both
+ horizontal and vertical recentering.
+
+ Cut down on the headers included in the articles to the
+ minimum.  You can, in fact, make do without them altogether---most of the
+ useful data is in the summary buffer, anyway.  Set this variable to
+ @samp{^NEVVVVER} or @samp{From:}, or whatever you feel you need.
+
+ Set this hook to all the available hiding commands:
+ @lisp
+       gnus-treat-hide-signature t
+       gnus-treat-hide-citation t)
+ @end lisp
+
+ @item gnus-use-full-window
+ By setting this to @code{nil}, you can make all the windows smaller.
+ While this doesn't really cut down much generally, it means that you
+ have to see smaller portions of articles before deciding that you didn't
+ want to read them anyway.
+
+ If this is address@hidden, all threads in the summary buffer will be
+ hidden initially.
+
+
+ @item gnus-updated-mode-lines
+ If this is @code{nil}, Gnus will not put information in the buffer mode
+ lines, which might save some time.
+ @end table
+
+
+ @node Little Disk Space
+ @subsection Little Disk Space
+ @cindex disk space
+
+ The startup files can get rather large, so you may want to cut their
+ sizes a bit if you are running out of space.
+
+ @table @code
+
+ @item gnus-save-newsrc-file
+ If this is @code{nil}, Gnus will never save @file{.newsrc}---it will
+ only save @file{.newsrc.eld}.  This means that you will not be able to
+ use any other newsreaders than Gnus.  This variable is @code{t} by
+ default.
+
+ If this is @code{nil}, Gnus will never read @file{.newsrc}---it will
+ only read @file{.newsrc.eld}.  This means that you will not be able to
+ use any other newsreaders than Gnus.  This variable is @code{t} by
+ default.
+
+ @item gnus-save-killed-list
+ If this is @code{nil}, Gnus will not save the list of dead groups.  You
+ should also set @code{gnus-check-new-newsgroups} to @code{ask-server}
+ and @code{gnus-check-bogus-newsgroups} to @code{nil} if you set this
+ variable to @code{nil}.  This variable is @code{t} by default.
+
+ @end table
+
+
+ @node Slow Machine
+ @subsection Slow Machine
+ @cindex slow machine
+
+ If you have a slow machine, or are just really impatient, there are a
+ few things you can do to make Gnus run faster.
+
+ Set @code{gnus-check-new-newsgroups} and
+ @code{gnus-check-bogus-newsgroups} to @code{nil} to make startup faster.
+
+ @code{gnus-nov-is-evil} to @code{nil} to make entering and exiting the
+ summary buffer faster.
+
+
+ @page
+ @node Troubleshooting
+ @section Troubleshooting
+ @cindex troubleshooting
+
+ Gnus works @emph{so} well straight out of the box---I can't imagine any
+ problems, really.
+
+ Ahem.
+
+ @enumerate
+
+ @item
+ Make sure your computer is switched on.
+
+ @item
+ Make sure that you really load the current Gnus version.  If you have
+ been running @sc{gnus}, you need to exit Emacs and start it up again before
+ Gnus will work.
+
+ @item
+ Try doing an @kbd{M-x gnus-version}.  If you get something that looks
+ like @samp{Gnus v5.10.6} you have the right files loaded.  Otherwise
+ you have some old @file{.el} files lying around.  Delete these.
+
+ @item
+ Read the help group (@kbd{G h} in the group buffer) for a
+ @acronym{FAQ} and a how-to.
+
+ @item
+ @vindex max-lisp-eval-depth
+ Gnus works on many recursive structures, and in some extreme (and very
+ rare) cases Gnus may recurse down too deeply'' and Emacs will beep at
+ you.  If this happens to you, set @code{max-lisp-eval-depth} to 500 or
+ something like that.
+ @end enumerate
+
+ If all else fails, report the problem as a bug.
+
+ @cindex bugs
+ @cindex reporting bugs
+
+ @kindex M-x gnus-bug
+ @findex gnus-bug
+ If you find a bug in Gnus, you can report it with the @kbd{M-x gnus-bug}
+ command.  @kbd{M-x set-variable RET debug-on-error RET t RET}, and send
+ me the backtrace.  I will fix bugs, but I can only fix them if you send
+ me a precise description as to how to reproduce the bug.
+
+ You really can never be too detailed in a bug report.  Always use the
+ @kbd{M-x gnus-bug} command when you make bug reports, even if it creates
+ a 10Kb mail each time you use it, and even if you have sent me your
+ environment 500 times before.  I don't care.  I want the full info each
+ time.
+
+ It is also important to remember that I have no memory whatsoever.  If
+ you send a bug report, and I send you a reply, and then you just send
+ back No, it's not! Moron!'', I will have no idea what you are
+ insulting me about.  Always over-explain everything.  It's much easier
+ for all of us---if I don't have all the information I need, I will just
+
+ If the problem you're seeing is very visual, and you can't quite explain
+ it, copy the Emacs window to a file (with @code{xwd}, for instance), put
+ it somewhere it can be reached, and include the URL of the picture in
+ the bug report.
+
+ @cindex patches
+ If you would like to contribute a patch to fix bugs or make
+ improvements, please produce the patch using @samp{diff -u}.
+
+ @cindex edebug
+ If you want to debug your problem further before reporting, possibly
+ in order to solve the problem yourself and send a patch, you can use
+ edebug.  Debugging Lisp code is documented in the Elisp manual
+ (@pxref{Debugging, , Debugging Lisp Programs, elisp, The GNU Emacs
+ Lisp Reference Manual}).  To get you started with edebug, consider if
+ you discover some weird behaviour when pressing @kbd{c}, the first
+ step is to do @kbd{C-h k c} and click on the hyperlink (Emacs only) in
+ the documentation buffer that leads you to the function definition,
+ then press @kbd{M-x edebug-defun RET} with point inside that function,
+ return to Gnus and press @kbd{c} to invoke the code.  You will be
+ placed in the lisp buffer and can single step using @kbd{SPC} and
+ evaluate expressions using @kbd{M-:} or inspect variables using
+ @kbd{C-h v}, abort execution with @kbd{q}, and resume execution with
+ @kbd{c} or @kbd{g}.
+
+ @cindex elp
+ @cindex profile
+ @cindex slow
+ Sometimes, a problem do not directly generate an elisp error but
+ manifests itself by causing Gnus to be very slow.  In these cases, you
+ can use @kbd{M-x toggle-debug-on-quit} and press @kbd{C-g} when things are
+ slow, and then try to analyze the backtrace (repeating the procedure
+ helps isolating the real problem areas).
+
+ A fancier approach is to use the elisp profiler, ELP.  The profiler is
+ (or should be) fully documented elsewhere, but to get you started
+ there are a few steps that need to be followed.  First, instrument the
+ part of Gnus you are interested in for profiling, e.g. @kbd{M-x
+ elp-instrument-package RET gnus} or @kbd{M-x elp-instrument-package
+ RET message}.  Then perform the operation that is slow and press
+ @kbd{M-x elp-results}.  You will then see which operations that takes
+ time, and can debug them further.  If the entire operation takes much
+ longer than the time spent in the slowest function in the profiler
+ output, you probably profiled the wrong part of Gnus.  To reset
+ profiling statistics, use @kbd{M-x elp-reset-all}.  @kbd{M-x
+ elp-restore-all} is supposed to remove profiling, but given the
+ complexities and dynamic code generation in Gnus, it might not always
+ work perfectly.
+
+ @cindex gnu.emacs.gnus
+ @cindex ding mailing list
+ If you just need help, you are better off asking on
+ @email{ding@@gnus.org, the ding mailing list}.  Write to
+ @email{ding-request@@gnus.org} to subscribe.
+
+
+ @page
+ @node Gnus Reference Guide
+ @section Gnus Reference Guide
+
+ It is my hope that other people will figure out smart stuff that Gnus
+ can do, and that other people will write those smart things as well.  To
+ facilitate that I thought it would be a good idea to describe the inner
+ workings of Gnus.  And some of the not-so-inner workings, while I'm at
+ it.
+
+ You can never expect the internals of a program not to change, but I
+ will be defining (in some details) the interface between Gnus and its
+ back ends (this is written in stone), the format of the score files
+ (ditto), data structures (some are less likely to change than others)
+ and general methods of operation.
+
+ * Gnus Utility Functions::      Common functions and variable to use.
+ * Back End Interface::          How Gnus communicates with the servers.
+ * Score File Syntax::           A BNF definition of the score file standard.
+ * Ranges::                      A handy format for storing mucho numbers.
+ * Group Info::                  The group info format.
+ * Extended Interactive::        Symbolic prefixes and stuff.
+ * Emacs/XEmacs Code::           Gnus can be run under all modern Emacsen.
+ * Various File Formats::        Formats of files that Gnus use.
+
+
+ @node Gnus Utility Functions
+ @subsection Gnus Utility Functions
+ @cindex Gnus utility functions
+ @cindex utility functions
+ @cindex functions
+ @cindex internal variables
+
+ When writing small functions to be run from hooks (and stuff), it's
+ vital to have access to the Gnus internal functions and variables.
+ Below is a list of the most common ones.
+
+ @table @code
+
+ @item gnus-newsgroup-name
+ @vindex gnus-newsgroup-name
+ This variable holds the name of the current newsgroup.
+
+ @item gnus-find-method-for-group
+ @findex gnus-find-method-for-group
+ A function that returns the select method for @var{group}.
+
+ @item gnus-group-real-name
+ @findex gnus-group-real-name
+ Takes a full (prefixed) Gnus group name, and returns the unprefixed
+ name.
+
+ @item gnus-group-prefixed-name
+ @findex gnus-group-prefixed-name
+ Takes an unprefixed group name and a select method, and returns the full
+ (prefixed) Gnus group name.
+
+ @item gnus-get-info
+ @findex gnus-get-info
+ Returns the group info list for @var{group}.
+
+ The number of unread articles in @var{group}, or @code{t} if that is
+ unknown.
+
+ @item gnus-active
+ @findex gnus-active
+ The active entry for @var{group}.
+
+ @item gnus-set-active
+ @findex gnus-set-active
+ Set the active entry for @var{group}.
+
+ Adds the current buffer to the list of buffers to be killed on Gnus
+ exit.
+
+ @item gnus-continuum-version
+ @findex gnus-continuum-version
+ Takes a Gnus version string as a parameter and returns a floating point
+ number.  Earlier versions will always get a lower number than later
+ versions.
+
+ Says whether @var{group} is read-only or not.
+
+ @item gnus-news-group-p
+ @findex gnus-news-group-p
+ Says whether @var{group} came from a news back end.
+
+ @item gnus-ephemeral-group-p
+ @findex gnus-ephemeral-group-p
+ Says whether @var{group} is ephemeral or not.
+
+ @item gnus-server-to-method
+ @findex gnus-server-to-method
+ Returns the select method corresponding to @var{server}.
+
+ @item gnus-server-equal
+ @findex gnus-server-equal
+ Says whether two virtual servers are equal.
+
+ @item gnus-group-native-p
+ @findex gnus-group-native-p
+ Says whether @var{group} is native or not.
+
+ @item gnus-group-secondary-p
+ @findex gnus-group-secondary-p
+ Says whether @var{group} is secondary or not.
+
+ @item gnus-group-foreign-p
+ @findex gnus-group-foreign-p
+ Says whether @var{group} is foreign or not.
+
+ @item gnus-group-find-parameter
+ @findex gnus-group-find-parameter
+ Returns the parameter list of @var{group}.  If given a second parameter,
+ returns the value of that parameter for @var{group}.
+
+ @item gnus-group-set-parameter
+ @findex gnus-group-set-parameter
+ Takes three parameters; @var{group}, @var{parameter} and @var{value}.
+
+ @item gnus-narrow-to-body
+ @findex gnus-narrow-to-body
+ Narrows the current buffer to the body of the article.
+
+ @item gnus-check-backend-function
+ @findex gnus-check-backend-function
+ Takes two parameters, @var{function} and @var{group}.  If the back end
+ @var{group} comes from supports @var{function}, return address@hidden
+
+ @lisp
+ (gnus-check-backend-function "request-scan" "nnml:misc")
+ @result{} t
+ @end lisp
+
+ Prompts the user for a select method.
+
+ @end table
+
+
+ @node Back End Interface
+ @subsection Back End Interface
+
+ Gnus doesn't know anything about @acronym{NNTP}, spools, mail or virtual
+ groups.  It only knows how to talk to @dfn{virtual servers}.  A virtual
+ server is a @dfn{back end} and some @dfn{back end variables}.  As examples
+ of the first, we have @code{nntp}, @code{nnspool} and @code{nnmbox}.  As
+ examples of the latter we have @code{nntp-port-number} and
+ @code{nnmbox-directory}.
+
+ When Gnus asks for information from a back end---say @code{nntp}---on
+ something, it will normally include a virtual server name in the
+ function parameters.  (If not, the back end should use the current''
+ virtual server.)  For instance, @code{nntp-request-list} takes a virtual
+ server as its only (optional) parameter.  If this virtual server hasn't
+ been opened, the function should fail.
+
+ Note that a virtual server name has no relation to some physical server
+ name.  Take this example:
+
+ @lisp
+ (nntp "odd-one"
+       (nntp-port-number 4324))
+ @end lisp
+
+ Here the virtual server name is @samp{odd-one} while the name of
+ the physical server is @samp{ifi.uio.no}.
+
+ The back ends should be able to switch between several virtual servers.
+ The standard back ends implement this by keeping an alist of virtual
+ server environments that they pull down/push up when needed.
+
+ There are two groups of interface functions: @dfn{required functions},
+ which must be present, and @dfn{optional functions}, which Gnus will
+ always check for presence before attempting to call 'em.
+
+ All these functions are expected to return data in the buffer
+ @code{nntp-server-buffer} (@samp{ *nntpd*}), which is somewhat
+ unfortunately named, but we'll have to live with it.  When I talk about
+ @dfn{resulting data}, I always refer to the data in that buffer.  When I
+ talk about @dfn{return value}, I talk about the function value returned by
+ the function call.  Functions that fail should return @code{nil} as the
+ return value.
+
+ Some back ends could be said to be @dfn{server-forming} back ends, and
+ some might be said not to be.  The latter are back ends that generally
+ only operate on one group at a time, and have no concept of server''
+ ---they have a group, and they deliver info on that group and nothing
+ more.
+
+ Gnus identifies each message by way of group name and article number.  A
+ few remarks about these article numbers might be useful.  First of all,
+ the numbers are positive integers.  Secondly, it is normally not
+ possible for later articles to re-use'' older article numbers without
+ confusing Gnus.  That is, if a group has ever contained a message
+ numbered 42, then no other message may get that number, or Gnus will get
+ @code{nnchoke-request-update-info}, @ref{Optional Back End Functions}.}
+ Third, article numbers must be assigned in order of arrival in the
+ group; this is not necessarily the same as the date of the message.
+
+ The previous paragraph already mentions all the hard'' restrictions that
+ article numbers must fulfill.  But it seems that it might be useful to
+ assign @emph{consecutive} article numbers, for Gnus gets quite confused
+ if there are holes in the article numbering sequence.  However, due to
+ the no-reuse'' restriction, holes cannot be avoided altogether.  It's
+ also useful for the article numbers to start at 1 to avoid running out
+ of numbers as long as possible.
+
+ Note that by convention, back ends are named @code{nnsomething}, but
+ Gnus also comes with some @code{nnnotbackends}, such as
+
+ In the examples and definitions I will refer to the imaginary back end
+ @code{nnchoke}.
+
+ @cindex @code{nnchoke}
+
+ * Required Back End Functions::  Functions that must be implemented.
+ * Optional Back End Functions::  Functions that need not be implemented.
+ * Writing New Back Ends::       Extending old back ends.
+ * Hooking New Back Ends Into Gnus::  What has to be done on the Gnus end.
+ * Mail-like Back Ends::         Some tips on mail back ends.
+
+
+ @node Required Back End Functions
+ @subsubsection Required Back End Functions
+
+ @table @code
+
+ @item (nnchoke-retrieve-headers ARTICLES &optional GROUP SERVER FETCH-OLD)
+
+ @var{articles} is either a range of article numbers or a list of
+ @code{Message-ID}s.  Current back ends do not fully support either---only
+ sequences (lists) of article numbers, and most back ends do not support
+ retrieval of @code{Message-ID}s.  But they should try for both.
+
+ The result data should either be HEADs or @acronym{NOV} lines, and the result
+ value should either be @code{headers} or @code{nov} to reflect this.
+ This might later be expanded to @code{various}, which will be a mixture
+ of HEADs and @acronym{NOV} lines, but this is currently not supported by Gnus.
+
+ If @var{fetch-old} is address@hidden it says to try fetching extra
+ headers'', in some meaning of the word.  This is generally done by
+ fetching (at most) @var{fetch-old} extra headers less than the smallest
+ article number in @code{articles}, and filling the gaps as well.  The
+ presence of this parameter can be ignored if the back end finds it
+ cumbersome to follow the request.  If this is address@hidden and not a
+ number, do maximum fetches.
+
+
+ @example
+ 221 1056 Article retrieved.
+ Path: ifi.uio.no!sturles
+ From: sturles@@ifi.uio.no (Sturle Sunde)
+ Newsgroups: ifi.discussion
+ Subject: Re: Something very droll
+ Date: 27 Oct 1994 14:02:57 +0100
+ Organization: Dept. of Informatics, University of Oslo, Norway
+ Lines: 26
+ Message-ID: <38o8e1$a0o@@holmenkollen.ifi.uio.no> + References: <38jdmq$4qu@@visbur.ifi.uio.no>
+ NNTP-Posting-Host: holmenkollen.ifi.uio.no
+ .
+ @end example
+
+ So a @code{headers} return value would imply that there's a number of
+ these in the data buffer.
+
+ Here's a BNF definition of such a buffer:
+
+ @example
+ error-message  = [ "4" / "5" ] 2number " " <error message> eol
+ valid-message  = "221 " <number> " Article retrieved." eol
+ @end example
+
+ @cindex BNF
+ (The version of BNF used here is the one used in RFC822.)
+
+ If the return value is @code{nov}, the data buffer should contain
+ @dfn{network overview database} lines.  These are basically fields
+ separated by tabs.
+
+ @example
+ nov-buffer = *nov-line
+ nov-line   = field 7*8[ <TAB> field ] eol
+ field      = <text except TAB>
+ @end example
+
+ For a closer look at what should be in those fields,
+
+
+ @item (nnchoke-open-server SERVER &optional DEFINITIONS)
+
+ @var{server} is here the virtual server name.  @var{definitions} is a
+ list of @code{(VARIABLE VALUE)} pairs that define this virtual server.
+
+ If the server can't be opened, no error should be signaled.  The back end
+ may then choose to refuse further attempts at connecting to this
+ server.  In fact, it should do so.
+
+ If the server is opened already, this function should return a
+ address@hidden value.  There should be no data returned.
+
+
+ @item (nnchoke-close-server &optional SERVER)
+
+ Close connection to @var{server} and free all resources connected
+ to it.  Return @code{nil} if the server couldn't be closed for some
+ reason.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-close)
+
+ Close connection to all servers and free all resources that the back end
+ have reserved.  All buffers that have been created by that back end
+ should be killed.  (Not the @code{nntp-server-buffer}, though.)  This
+ function is generally only called when Gnus is shutting down.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-server-opened &optional SERVER)
+
+ If @var{server} is the current virtual server, and the connection to the
+ physical server is alive, then this function should return a
+ address@hidden value.  This function should under no circumstances
+ attempt to reconnect to a server we have lost connection to.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-status-message &optional SERVER)
+
+ This function should return the last error message from @var{server}.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-article ARTICLE &optional GROUP SERVER TO-BUFFER)
+
+ The result data from this function should be the article specified by
+ @var{article}.  This might either be a @code{Message-ID} or a number.
+ It is optional whether to implement retrieval by @code{Message-ID}, but
+ it would be nice if that were possible.
+
+ If @var{to-buffer} is address@hidden, the result data should be returned
+ in this buffer instead of the normal data buffer.  This is to make it
+ possible to avoid copying large amounts of data from one buffer to
+ another, while Gnus mainly requests articles to be inserted directly
+ into its article buffer.
+
+ If it is at all possible, this function should return a cons cell where
+ the @code{car} is the group name the article was fetched from, and the
@code{cdr} is
+ the article number.  This will enable Gnus to find out what the real
+ group and article numbers are when fetching articles by
+ @code{Message-ID}.  If this isn't possible, @code{t} should be returned
+ on successful article retrieval.
+
+
+ @item (nnchoke-request-group GROUP &optional SERVER FAST)
+
+ Get data on @var{group}.  This function also has the side effect of
+ making @var{group} the current group.
+
+ If @var{fast}, don't bother to return useful data, just make @var{group}
+ the current group.
+
+ Here's an example of some result data and a definition of the same:
+
+ @example
+ 211 56 1000 1059 ifi.discussion
+ @end example
+
+ The first number is the status, which should be 211.  Next is the
+ total number of articles in the group, the lowest article number, the
+ highest article number, and finally the group name.  Note that the total
+ number of articles may be less than one might think while just
+ considering the highest and lowest article numbers, but some articles
+ may have been canceled.  Gnus just discards the total-number, so
+ whether one should take the bother to generate it properly (if that is a
+ problem) is left as an exercise to the reader.  If the group contains no
+ articles, the lowest article number should be reported as 1 and the
+ highest as 0.
+
+ @example
+ group-status = [ error / info ] eol
+ error        = [ "4" / "5" ] 2<number> " " <Error message>
+ info         = "211 " 3* [ <number> " " ] <string>
+ @end example
+
+
+ @item (nnchoke-close-group GROUP &optional SERVER)
+
+ Close @var{group} and free any resources connected to it.  This will be
+ a no-op on most back ends.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-list &optional SERVER)
+
+ Return a list of all groups available on @var{server}.  And that means
+ @emph{all}.
+
+ Here's an example from a server that only carries two groups:
+
+ @example
+ ifi.test 0000002200 0000002000 y
+ ifi.discussion 3324 3300 n
+ @end example
+
+ On each line we have a group name, then the highest article number in
+ that group, the lowest article number, and finally a flag.  If the group
+ contains no articles, the lowest article number should be reported as 1
+ and the highest as 0.
+
+ @example
+ active-file = *active-line
+ active-line = name " " <number> " " <number> " " flags eol
+ name        = <string>
+ flags       = "n" / "y" / "m" / "x" / "j" / "=" name
+ @end example
+
+ The flag says whether the group is read-only (@samp{n}), is moderated
+ (@samp{m}), is dead (@samp{x}), is aliased to some other group
+ (@samp{=other-group}) or none of the above (@samp{y}).
+
+
+ @item (nnchoke-request-post &optional SERVER)
+
+ This function should post the current buffer.  It might return whether
+ the posting was successful or not, but that's not required.  If, for
+ instance, the posting is done asynchronously, it has generally not been
+ completed by the time this function concludes.  In that case, this
+ function should set up some kind of sentinel to beep the user loud and
+ clear if the posting could not be completed.
+
+ There should be no result data from this function.
+
+ @end table
+
+
+ @node Optional Back End Functions
+ @subsubsection Optional Back End Functions
+
+ @table @code
+
+ @item (nnchoke-retrieve-groups GROUPS &optional SERVER)
+
+ @var{groups} is a list of groups, and this function should request data
+ on all those groups.  How it does it is of no concern to Gnus, but it
+ should attempt to do this in a speedy fashion.
+
+ The return value of this function can be either @code{active} or
+ @code{group}, which says what the format of the result data is.  The
+ former is in the same format as the data from
+ @code{nnchoke-request-list}, while the latter is a buffer full of lines
+ in the same format as @code{nnchoke-request-group} gives.
+
+ @example
+ group-buffer = *active-line / *group-status
+ @end example
+
+
+ @item (nnchoke-request-update-info GROUP INFO &optional SERVER)
+
+ A Gnus group info (@pxref{Group Info}) is handed to the back end for
+ alterations.  This comes in handy if the back end really carries all
+ the information (as is the case with virtual and imap groups).  This
+ function should destructively alter the info to suit its needs, and
+ should return a address@hidden value.
+
+ There should be no result data from this function.
+
+
+ @item (nnchoke-request-type GROUP &optional ARTICLE)
+
+ When the user issues commands for sending news'' (@kbd{F} in the
+ summary buffer, for instance), Gnus has to know whether the article the
+ user is following up on is news or mail.  This function should return
+ @code{news} if @var{article} in @var{group} is news, @code{mail} if it
+ is mail and @code{unknown} if the type can't be decided.  (The
+ @var{article} parameter is necessary in @code{nnvirtual} groups which
+ might very well combine mail groups and news groups.)  Both @var{group}
+ and @var{article} may be @code{nil}.
+
+ There should be no result data from this function.
+
+
+ @item (nnchoke-request-set-mark GROUP ACTION &optional SERVER)
+
+ Set/remove/add marks on articles.  Normally Gnus handles the article
+ marks (such as read, ticked, expired etc) internally, and store them in
+ @file{~/.newsrc.eld}.  Some back ends (such as @acronym{IMAP}) however carry
+ all information about the articles on the server, so Gnus need to
+ propagate the mark information to the server.
+
+ @var{action} is a list of mark setting requests, having this format:
+
+ @example
+ (RANGE ACTION MARK)
+ @end example
+
+ @var{range} is a range of articles you wish to update marks on.
+ @var{action} is @code{add} or @code{del}, used to add marks or remove
+ marks (preserving all marks not mentioned).  @var{mark} is a list of
+ marks; where each mark is a symbol.  Currently used marks are
+ @code{forward} and @code{recent}, but your back end should, if
+ possible, not limit itself to these.
+
+ Given contradictory actions, the last action in the list should be the
+ effective one.  That is, if your action contains a request to add the
+ @code{tick} mark on article 1 and, later in the list, a request to
+ remove the mark on the same article, the mark should in fact be removed.
+
+ An example action list:
+
+ @example
+ (((5 12 30) 'del '(tick))
+ @end example
+
+ The function should return a range of articles it wasn't able to set the
+ mark on (currently not used for anything).
+
+ There should be no result data from this function.
+
+ @item (nnchoke-request-update-mark GROUP ARTICLE MARK)
+
+ If the user tries to set a mark that the back end doesn't like, this
+ function may change the mark.  Gnus will use whatever this function
+ returns as the mark for @var{article} instead of the original
+ @var{mark}.  If the back end doesn't care, it must return the original
+ @var{mark}, and not @code{nil} or any other type of garbage.
+
+ The only use for this I can see is what @code{nnvirtual} does with
+ it---if a component group is auto-expirable, marking an article as read
+ in the virtual group should result in the article being marked as
+ expirable.
+
+ There should be no result data from this function.
+
+
+ @item (nnchoke-request-scan &optional GROUP SERVER)
+
+ This function may be called at any time (by Gnus or anything else) to
+ request that the back end check for incoming articles, in one way or
+ another.  A mail back end will typically read the spool file or query
+ the @acronym{POP} server when this function is invoked.  The
+ @var{group} doesn't have to be heeded---if the back end decides that
+ it is too much work just scanning for a single group, it may do a
+ total scan of all groups.  It would be nice, however, to keep things
+ local if that's practical.
+
+ There should be no result data from this function.
+
+
+ @item (nnchoke-request-group-description GROUP &optional SERVER)
+
+ The result data from this function should be a description of
+ @var{group}.
+
+ @example
+ description-line = name <TAB> description eol
+ name             = <string>
+ description      = <text>
+ @end example
+
+ @item (nnchoke-request-list-newsgroups &optional SERVER)
+
+ The result data from this function should be the description of all
+ groups available on the server.
+
+ @example
+ description-buffer = *description-line
+ @end example
+
+
+ @item (nnchoke-request-newgroups DATE &optional SERVER)
+
+ The result data from this function should be all groups that were
+ created after @samp{date}, which is in normal human-readable date format
+ (i.e., the date format used in mail and news headers, and returned by
+ the function @code{message-make-date} by default).  The data should be
+ in the active buffer format.
+
+ It is okay for this function to return too many'' groups; some back ends
+ might find it cheaper to return the full list of groups, rather than
+ just the new groups.  But don't do this for back ends with many groups.
+ Normally, if the user creates the groups herself, there won't be too
+ many groups, so @code{nnml} and the like are probably safe.  But for
+ back ends like @code{nntp}, where the groups have been created by the
+ server, it is quite likely that there can be many groups.
+
+
+ @item (nnchoke-request-create-group GROUP &optional SERVER)
+
+ This function should create an empty group with name @var{group}.
+
+ There should be no return data.
+
+
+ @item (nnchoke-request-expire-articles ARTICLES &optional GROUP SERVER FORCE)
+
+ This function should run the expiry process on all articles in the
+ @var{articles} range (which is currently a simple list of article
+ numbers.)  It is left up to the back end to decide how old articles
+ should be before they are removed by this function.  If @var{force} is
+ address@hidden, all @var{articles} should be deleted, no matter how new
+ they are.
+
+ This function should return a list of articles that it did not/was not
+ able to delete.
+
+ There should be no result data returned.
+
+
+ @item (nnchoke-request-move-article ARTICLE GROUP SERVER ACCEPT-FORM
&optional LAST)
+
+ This function should move @var{article} (which is a number) from
+ @var{group} by calling @var{accept-form}.
+
+ This function should ready the article in question for moving by
+ removing any header lines it has added to the article, and generally
+ should tidy up'' the article.  Then it should @code{eval}
+ @var{accept-form} in the buffer where the tidy'' article is.  This
+ will do the actual copying.  If this @code{eval} returns a
+ address@hidden value, the article should be removed.
+
+ If @var{last} is @code{nil}, that means that there is a high likelihood
+ that there will be more requests issued shortly, so that allows some
+ optimizations.
+
+ The function should return a cons where the @code{car} is the group name and
+ the @code{cdr} is the article number that the article was entered as.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-accept-article GROUP &optional SERVER LAST)
+
+ This function takes the current buffer and inserts it into @var{group}.
+ If @var{last} in @code{nil}, that means that there will be more calls to
+ this function in short order.
+
+ The function should return a cons where the @code{car} is the group name and
+ the @code{cdr} is the article number that the article was entered as.
+
+ The group should exist before the back end is asked to accept the
+ article for that group.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-replace-article ARTICLE GROUP BUFFER)
+
+ This function should remove @var{article} (which is a number) from
+ @var{group} and insert @var{buffer} there instead.
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-delete-group GROUP FORCE &optional SERVER)
+
+ This function should delete @var{group}.  If @var{force}, it should
+ really delete all the articles in the group, and then delete the group
+ itself.  (If there is such a thing as the group itself''.)
+
+ There should be no data returned.
+
+
+ @item (nnchoke-request-rename-group GROUP NEW-NAME &optional SERVER)
+
+ This function should rename @var{group} into @var{new-name}.  All
+ articles in @var{group} should move to @var{new-name}.
+
+ There should be no data returned.
+
+ @end table
+
+
+ @node Error Messaging
+ @subsubsection Error Messaging
+
+ The back ends should use the function @code{nnheader-report} to report
+ error conditions---they should not raise errors when they aren't able to
+ perform a request.  The first argument to this function is the back end
+ symbol, and the rest are interpreted as arguments to @code{format} if
+ there are multiple of them, or just a string if there is one of them.
+ This function must always returns @code{nil}.
+
+ @lisp
+ (nnheader-report 'nnchoke "You did something totally bogus")
+
+ (nnheader-report 'nnchoke "Could not request group %s" group)
+ @end lisp
+
+ Gnus, in turn, will call @code{nnheader-get-report} when it gets a
+ @code{nil} back from a server, and this function returns the most
+ recently reported message for the back end in question.  This function
+ takes one argument---the server symbol.
+
+ Internally, these functions access @address@hidden,
+ so the @code{nnchoke} back end will have its error message stored in
+ @code{nnchoke-status-string}.
+
+
+ @node Writing New Back Ends
+ @subsubsection Writing New Back Ends
+
+ Many back ends are quite similar.  @code{nnml} is just like
+ @code{nnspool}, but it allows you to edit the articles on the server.
+ @code{nnmh} is just like @code{nnml}, but it doesn't use an active file,
+ and it doesn't maintain overview databases.  @code{nndir} is just like
+ @code{nnml}, but it has no concept of groups'', and it doesn't allow
+ editing articles.
+
+ It would make sense if it were possible to inherit'' functions from
+ back ends when writing new back ends.  And, indeed, you can do that if you
+ want to.  (You don't have to if you don't want to, of course.)
+
+ All the back ends declare their public variables and functions by using a
+ package called @code{nnoo}.
+
+ To inherit functions from other back ends (and allow other back ends to
+ inherit functions from the current back end), you should use the
+ following macros:
+
+ @table @code
+
+ @item nnoo-declare
+ This macro declares the first parameter to be a child of the subsequent
+ parameters.  For instance:
+
+ @lisp
+ (nnoo-declare nndir
+   nnml nnmh)
+ @end lisp
+
+ @code{nndir} has declared here that it intends to inherit functions from
+ both @code{nnml} and @code{nnmh}.
+
+ @item defvoo
+ This macro is equivalent to @code{defvar}, but registers the variable as
+ a public server variable.  Most state-oriented variables should be
+ declared with @code{defvoo} instead of @code{defvar}.
+
+ In addition to the normal @code{defvar} parameters, it takes a list of
+ variables in the parent back ends to map the variable to when executing
+ a function in those back ends.
+
+ @lisp
+ (defvoo nndir-directory nil
+   "Where nndir will look for groups."
+   nnml-current-directory nnmh-current-directory)
+ @end lisp
+
+ This means that @code{nnml-current-directory} will be set to
+ @code{nndir-directory} when an @code{nnml} function is called on behalf
+ of @code{nndir}.  (The same with @code{nnmh}.)
+
+ @item nnoo-define-basics
+ This macro defines some common functions that almost all back ends should
+ have.
+
+ @lisp
+ (nnoo-define-basics nndir)
+ @end lisp
+
+ @item deffoo
+ This macro is just like @code{defun} and takes the same parameters.  In
+ addition to doing the normal @code{defun} things, it registers the
+ function as being public so that other back ends can inherit it.
+
+ @item nnoo-map-functions
+ This macro allows mapping of functions from the current back end to
+ functions from the parent back ends.
+
+ @lisp
+ (nnoo-map-functions nndir
+   (nnml-retrieve-headers 0 nndir-current-group 0 0)
+   (nnmh-request-article 0 nndir-current-group 0 0))
+ @end lisp
+
+ This means that when @code{nndir-retrieve-headers} is called, the first,
+ third, and fourth parameters will be passed on to
+ @code{nnml-retrieve-headers}, while the second parameter is set to the
+ value of @code{nndir-current-group}.
+
+ @item nnoo-import
+ This macro allows importing functions from back ends.  It should be the
+ last thing in the source file, since it will only define functions that
+
+ @lisp
+ (nnoo-import nndir
+   (nnmh
+    nnmh-request-list
+    nnmh-request-newgroups)
+   (nnml))
+ @end lisp
+
+ This means that calls to @code{nndir-request-list} should just be passed
+ on to @code{nnmh-request-list}, while all public functions from
+ @code{nnml} that haven't been defined in @code{nndir} yet should be
+ defined now.
+
+ @end table
+
+ Below is a slightly shortened version of the @code{nndir} back end.
+
+ @lisp
+ ;;; @r{nndir.el --- single directory newsgroup access for Gnus}
+ ;; @r{Copyright (C) 1995,96 Free Software Foundation, Inc.}
+
+ ;;; @r{Code:}
+
+ (require 'nnmh)
+ (require 'nnml)
+ (require 'nnoo)
+ (eval-when-compile (require 'cl))
+
+ (nnoo-declare nndir
+   nnml nnmh)
+
+ (defvoo nndir-directory nil
+   "Where nndir will look for groups."
+   nnml-current-directory nnmh-current-directory)
+
+ (defvoo nndir-nov-is-evil nil
+   "*Non-nil means that nndir will never retrieve NOV headers."
+   nnml-nov-is-evil)
+
+ (defvoo nndir-current-group ""
+   nil
+   nnml-current-group nnmh-current-group)
+ (defvoo nndir-top-directory nil nil nnml-directory nnmh-directory)
+ (defvoo nndir-get-new-mail nil nil nnml-get-new-mail nnmh-get-new-mail)
+
+ (defvoo nndir-status-string "" nil nnmh-status-string)
+ (defconst nndir-version "nndir 1.0")
+
+ ;;; @r{Interface functions.}
+
+ (nnoo-define-basics nndir)
+
+ (deffoo nndir-open-server (server &optional defs)
+   (setq nndir-directory
+         (or (cadr (assq 'nndir-directory defs))
+             server))
+   (unless (assq 'nndir-directory defs)
+     (push (nndir-directory ,server) defs))
+   (push (nndir-current-group
+           ,(file-name-nondirectory
+             (directory-file-name nndir-directory)))
+         defs)
+   (push (nndir-top-directory
+           ,(file-name-directory (directory-file-name nndir-directory)))
+         defs)
+   (nnoo-change-server 'nndir server defs))
+
+ (nnoo-map-functions nndir
+   (nnml-retrieve-headers 0 nndir-current-group 0 0)
+   (nnmh-request-article 0 nndir-current-group 0 0)
+   (nnmh-request-group nndir-current-group 0 0)
+   (nnmh-close-group nndir-current-group 0))
+
+ (nnoo-import nndir
+   (nnmh
+    nnmh-status-message
+    nnmh-request-list
+    nnmh-request-newgroups))
+
+ (provide 'nndir)
+ @end lisp
+
+
+ @node Hooking New Back Ends Into Gnus
+ @subsubsection Hooking New Back Ends Into Gnus
+
+ @vindex gnus-valid-select-methods
+ @findex gnus-declare-backend
+ Having Gnus start using your new back end is rather easy---you just
+ declare it with the @code{gnus-declare-backend} functions.  This will
+ enter the back end into the @code{gnus-valid-select-methods} variable.
+
+ @code{gnus-declare-backend} takes two parameters---the back end name and
+ an arbitrary number of @dfn{abilities}.
+
+ Here's an example:
+
+ @lisp
+ (gnus-declare-backend "nnchoke" 'mail 'respool 'address)
+ @end lisp
+
+ The above line would then go in the @file{nnchoke.el} file.
+
+ The abilities can be:
+
+ @table @code
+ @item mail
+ This is a mailish back end---followups should (probably) go via mail.
+ @item post
+ This is a newsish back end---followups should (probably) go via news.
+ @item post-mail
+ This back end supports both mail and news.
+ @item none
+ This is neither a post nor mail back end---it's something completely
+ different.
+ @item respool
+ It supports respooling---or rather, it is able to modify its source
+ articles and groups.
+ The name of the server should be in the virtual server name.  This is
+ true for almost all back ends.
+ The user should be prompted for an address when doing commands like
+ @kbd{B} in the group buffer.  This is true for back ends like
+ @code{nntp}, but not @code{nnmbox}, for instance.
+ @end table
+
+
+ @node Mail-like Back Ends
+ @subsubsection Mail-like Back Ends
+
+ One of the things that separate the mail back ends from the rest of the
+ back ends is the heavy dependence by most of the mail back ends on
+ common functions in @file{nnmail.el}.  For instance, here's the
+ definition of @code{nnml-request-scan}:
+
+ @lisp
+ (deffoo nnml-request-scan (&optional group server)
+   (setq nnml-article-file-alist nil)
+   (nnmail-get-new-mail 'nnml 'nnml-save-nov nnml-directory group))
+ @end lisp
+
+ It simply calls @code{nnmail-get-new-mail} with a few parameters,
+ and @code{nnmail} takes care of all the moving and splitting of the
+ mail.
+
+ This function takes four parameters.
+
+ @table @var
+ @item method
+ This should be a symbol to designate which back end is responsible for
+ the call.
+
+ @item exit-function
+ This function should be called after the splitting has been performed.
+
+ @item temp-directory
+ Where the temporary files should be stored.
+
+ @item group
+ This optional argument should be a group name if the splitting is to be
+ performed for one group only.
+ @end table
+
+ @code{nnmail-get-new-mail} will call @address@hidden to
+ save each article.  @address@hidden will be called to
+
+ The function also uses the following variables:
+ @address@hidden (to see whether to get new mail for
+ this back end); and @address@hidden and
+ @address@hidden to generate the new active file.
+ @address@hidden should be a group-active alist, like
+ this:
+
+ @example
+ (("a-group" (1 . 10))
+  ("some-group" (34 . 39)))
+ @end example
+
+
+ @node Score File Syntax
+ @subsection Score File Syntax
+
+ Score files are meant to be easily parseable, but yet extremely
+ mallable.  It was decided that something that had the same read syntax
+ as an Emacs Lisp list would fit that spec.
+
+ Here's a typical score file:
+
+ @lisp
+ (("summary"
+   ("win95" -10000 nil s)
+   ("Gnus"))
+  ("from"
+   ("Lars" -1000))
+  (mark -100))
+ @end lisp
+
+ BNF definition of a score file:
+
+ @example
+ score-file      = "" / "(" *element ")"
+ element         = rule / atom
+ rule            = string-rule / number-rule / date-rule
+ string-rule     = "(" quote string-header quote space *string-match ")"
+ number-rule     = "(" quote number-header quote space *number-match ")"
+ date-rule       = "(" quote date-header quote space *date-match ")"
+ quote           = <ascii 34>
+ string-header   = "subject" / "from" / "references" / "message-id" /
+                   "xref" / "body" / "head" / "all" / "followup"
+ number-header   = "lines" / "chars"
+ string-match    = "(" quote <string> quote [ "" / [ space score [ "" /
+                   space date [ "" / [ space string-match-t ] ] ] ] ] ")"
+ score           = "nil" / <integer>
+ date            = "nil" / <natural number>
+ string-match-t  = "nil" / "s" / "substring" / "S" / "Substring" /
+                   "r" / "regex" / "R" / "Regex" /
+                   "e" / "exact" / "E" / "Exact" /
+                   "f" / "fuzzy" / "F" / "Fuzzy"
+ number-match    = "(" <integer> [ "" / [ space score [ "" /
+                   space date [ "" / [ space number-match-t ] ] ] ] ] ")"
+ number-match-t  = "nil" / "=" / "<" / ">" / ">=" / "<="
+ date-match      = "(" quote <string> quote [ "" / [ space score [ "" /
+                   space date [ "" / [ space date-match-t ] ] ] ] ")"
+ date-match-t    = "nil" / "at" / "before" / "after"
+ atom            = "(" [ required-atom / optional-atom ] ")"
+ required-atom   = mark / expunge / mark-and-expunge / files /
+                   exclude-files / read-only / touched
+ optional-atom   = adapt / local / eval
+ mark            = "mark" space nil-or-number
+ nil-or-number   = "nil" / <integer>
+ expunge         = "expunge" space nil-or-number
+ mark-and-expunge = "mark-and-expunge" space nil-or-number
+ files           = "files" *[ space <string> ]
+ exclude-files   = "exclude-files" *[ space <string> ]
+ adapt-rule      = "(" *[ <string> *[ "(" <string> <integer> ")" ] ")"
+ local           = "local" *[ space "(" <string> space <form> ")" ]
+ eval            = "eval" space <form>
+ space           = *[ " " / <TAB> / <NEWLINE> ]
+ @end example
+
+ Any unrecognized elements in a score file should be ignored, but not
+
+ As you can see, white space is needed, but the type and amount of white
+ space is irrelevant.  This means that formatting of the score file is
+ left up to the programmer---if it's simpler to just spew it all out on
+ one looong line, then that's ok.
+
+ The meaning of the various atoms are explained elsewhere in this
+ manual (@pxref{Score File Format}).
+
+
+
+ Internally Gnus uses a format for storing article headers that
+ corresponds to the @acronym{NOV} format in a mysterious fashion.  One could
+ almost suspect that the author looked at the @acronym{NOV} specification and
+ just shamelessly @emph{stole} the entire thing, and one would be right.
+
+ @dfn{Header} is a severely overloaded term.  Header'' is used in
+ RFC 1036 to talk about lines in the head of an article (e.g.,
+ @code{From}).  It is used by many people as a synonym for
+ head''---the header and the body''.  (That should be avoided, in my
+ opinion.)  And Gnus uses a format internally that it calls header'',
+ which is what I'm talking about here.  This is a 9-element vector,
+ basically, with each header (ouch) having one slot.
+
+ These slots are, in order: @code{number}, @code{subject}, @code{from},
+ @code{date}, @code{id}, @code{references}, @code{chars}, @code{lines},
+ @code{xref}, and @code{extra}.  There are macros for accessing and
+ setting these slots---they all have predictable names beginning with
+
+ All these slots contain strings, except the @code{extra} slot, which
+ contains an alist of header/value pairs (@pxref{To From Newsgroups}).
+
+
+ @node Ranges
+ @subsection Ranges
+
+ @sc{gnus} introduced a concept that I found so useful that I've started
+ using it a lot and have elaborated on it greatly.
+
+ The question is simple: If you have a large amount of objects that are
+ identified by numbers (say, articles, to take a @emph{wild} example)
+ that you want to qualify as being included'', a normal sequence isn't
+ very useful.  (A 200,000 length sequence is a bit long-winded.)
+
+ The solution is as simple as the question: You just collapse the
+ sequence.
+
+ @example
+ (1 2 3 4 5 6 10 11 12)
+ @end exam`