X-Git-Url: http://cgit.sxemacs.org/?p=packages;a=blobdiff_plain;f=xemacs-packages%2Fgnus%2Ftexi%2Fgnus.texi;fp=xemacs-packages%2Fgnus%2Ftexi%2Fgnus.texi;h=b664c80d09f3f5a167672de0dc902966f3931692;hp=0000000000000000000000000000000000000000;hb=ddbcce55bee95abbe2d79a9aa26ee08a47b284db;hpb=e10974b04b06bb129bf57b2c9edfc950caabc073 diff --git a/xemacs-packages/gnus/texi/gnus.texi b/xemacs-packages/gnus/texi/gnus.texi new file mode 100644 index 00000000..b664c80d --- /dev/null +++ b/xemacs-packages/gnus/texi/gnus.texi @@ -0,0 +1,30723 @@ +\input texinfo + +@include gnus-overrides.texi + +@setfilename gnus.info +@settitle Gnus Manual +@include docstyle.texi +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex pg cp + +@copying +Copyright @copyright{} 1995--2016 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'', +and with the Back-Cover Texts as in (a) below. A copy of the license +is included in the section entitled ``GNU Free Documentation License''. + +(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and +modify this GNU manual.'' +@end quotation +@end copying + +@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[pdftex,bookmarks,colorlinks=true]{hyperref} +\usepackage{thumbpdf} +\pdfcompresslevel=9 +\fi + +\makeindex +\begin{document} + +% Adjust ../Makefile.in if you change the following line: +\newcommand{\gnusversionname}{Ma Gnus v0.14} +\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}$}} +\newcommand{\gnusdollar}{\$} +\newcommand{\gnusampersand}{\&} +\newcommand{\gnuspercent}{\%} +\newcommand{\gnushash}{\#} +\newcommand{\gnushat}{\symbol{"5E}} +\newcommand{\gnusunderline}{\symbol{"5F}} +\newcommand{\gnusnot}{$\neg$} +\newcommand{\gnustilde}{\symbol{"7E}} +\newcommand{\gnusless}{{$<$}} +\newcommand{\gnusgreater}{{$>$}} +\newcommand{\gnusbraceleft}{{$>$}} +\newcommand{\gnusbraceright}{{$>$}} + +\newcommand{\gnushead}{\raisebox{-1cm}{\epsfig{figure=ps/gnus-head,height=1cm}}} +\newcommand{\gnusinteresting}{ +\marginpar[\mbox{}\hfill\gnushead]{\gnushead} +} + +\newcommand{\gnuscleardoublepage}{\ifodd\count0\mbox{}\clearpage\thispagestyle{empty}\mbox{}\clearpage\else\clearpage\fi} + +\newcommand{\gnuspagechapter}[1]{ +{\mbox{}} +} + +\newdimen{\gnusdimen} +\gnusdimen 0pt + +\newcommand{\gnuschapter}[2]{ +\gnuscleardoublepage +\ifdim \gnusdimen = 0pt\setcounter{page}{1}\pagestyle{gnus}\pagenumbering{arabic} \gnusdimen 1pt\fi +\chapter{#2} +\renewcommand{\gnussectionname}{} +\renewcommand{\gnuschaptername}{#2} +\thispagestyle{empty} +\hspace*{-2cm} +\begin{picture}(500,500)(0,0) +\put(480,350){\makebox(0,0)[tr]{#1}} +\put(40,300){\makebox(500,50)[bl]{{\Huge\bf{#2}}}} +\end{picture} +\clearpage +} + +\newcommand{\gnusfigure}[3]{ +\begin{figure} +\mbox{}\ifodd\count0\hspace*{-0.8cm}\else\hspace*{-3cm}\fi\begin{picture}(440,#2) +#3 +\end{picture} +\caption{#1} +\end{figure} +} + +\newcommand{\gnusicon}[1]{ +\marginpar[\mbox{}\hfill\raisebox{-1.5cm}{\epsfig{figure=ps/#1-up,height=1.5cm}}]{\raisebox{-1cm}{\epsfig{figure=ps/#1-up,height=1cm}}} +} + +\newcommand{\gnuspicon}[1]{ +\margindex{\epsfig{figure=#1,width=2cm}} +} + +\newcommand{\gnusxface}[2]{ +\margindex{\epsfig{figure=#1,width=1cm}\epsfig{figure=#2,width=1cm}} +} + +\newcommand{\gnussmiley}[2]{ +\margindex{\makebox[2cm]{\hfill\epsfig{figure=#1,width=0.5cm}\hfill\epsfig{figure=#2,width=0.5cm}\hfill}} +} + +\newcommand{\gnusitemx}[1]{\mbox{}\vspace*{-\itemsep}\vspace*{-\parsep}\item#1} + +\newcommand{\gnussection}[1]{ +\renewcommand{\gnussectionname}{#1} +\section{#1} +} + +\newenvironment{codelist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{asislist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{kbdlist}% +{\begin{list}{}{ +\labelwidth=0cm +} +}{\end{list}} + +\newenvironment{dfnlist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{stronglist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{samplist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{varlist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newenvironment{emphlist}% +{\begin{list}{}{ +} +}{\end{list}} + +\newlength\gnusheadtextwidth +\setlength{\gnusheadtextwidth}{\headtextwidth} +\addtolength{\gnusheadtextwidth}{1cm} + +\newpagestyle{gnuspreamble}% +{ +{ +\ifodd\count0 +{ +\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\mbox{}}\textbf{\hfill\roman{page}}} +} +\else +{ +\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\roman{page}\hfill\mbox{}}} +} +} +\fi +} +} +{ +\ifodd\count0 +\mbox{} \hfill +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\else +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\hfill \mbox{} +\fi +} + +\newpagestyle{gnusindex}% +{ +{ +\ifodd\count0 +{ +\hspace*{-0.23cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\gnuschaptername\hfill\arabic{page}}}} +} +\else +{ +\hspace*{-3.25cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}} +} +\fi +} +} +{ +\ifodd\count0 +\mbox{} \hfill +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\else +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\hfill \mbox{} +\fi +} + +\newpagestyle{gnus}% +{ +{ +\ifodd\count0 +{ +\makebox[12cm]{\hspace*{3.1cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{chapter}.\arabic{section}} \textbf{\gnussectionname\hfill\arabic{page}}}}} +} +\else +{ +\makebox[12cm]{\hspace*{-2.95cm}\underline{\makebox[\gnusheadtextwidth]{\textbf{\arabic{page}\hfill\gnuschaptername}}}} +} +\fi +} +} +{ +\ifodd\count0 +\mbox{} \hfill +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\else +\raisebox{-0.5cm}{\epsfig{figure=ps/gnus-big-logo,height=1cm}} +\hfill \mbox{} +\fi +} + +\pagenumbering{roman} +\pagestyle{gnuspreamble} + +@end iflatex +@end iftex + +@iftex +@iflatex + +\begin{titlepage} +{ + +%\addtolength{\oddsidemargin}{-5cm} +%\addtolength{\evensidemargin}{-5cm} +\parindent=0cm +\addtolength{\textheight}{2cm} + +\gnustitle{\gnustitlename}\hfill\gnusversion{\gnusversionname}\\ +\rule{15cm}{1mm}\\ +\vfill +\hspace*{0cm}\epsfig{figure=ps/gnus-big-logo,height=15cm} +\vfill +\rule{15cm}{1mm}\\ +\gnusauthor{by Lars Magne Ingebrigtsen} +\newpage +} + +\mbox{} +\vfill + +\thispagestyle{empty} + +@c @insertcopying +\newpage +\end{titlepage} +@end iflatex +@end iftex + +@dircategory Emacs network features +@direntry +* Gnus: (gnus). The newsreader Gnus. +@end direntry +@iftex +@finalout +@end iftex + + +@titlepage +@ifset WEBHACKDEVEL +@title Gnus Manual (DEVELOPMENT VERSION) +@end ifset +@ifclear WEBHACKDEVEL +@title Gnus Manual +@end ifclear + +@author by Lars Magne Ingebrigtsen +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@summarycontents +@contents + +@node Top +@top The Gnus Newsreader + +@ifinfo + +You can read news (and mail) from within Emacs by using Gnus. The news +can be gotten by any nefarious means you can think of---@acronym{NNTP}, local +spool or your mbox file. All at the same time, if you want to push your +luck. + +@c Adjust ../Makefile.in if you change the following line: +This manual corresponds to Ma Gnus v0.14 + +@ifnottex +@insertcopying +@end ifnottex + +@end ifinfo + +@iftex + +@iflatex +\tableofcontents +\gnuscleardoublepage +@end iflatex + +Gnus is the advanced, self-documenting, customizable, extensible +unreal-time newsreader for GNU Emacs. + +Oops. That sounds oddly familiar, so let's start over again to avoid +being accused of plagiarism: + +Gnus is a message-reading laboratory. It will let you look at just +about anything as if it were a newsgroup. You can read mail with it, +you can browse directories with it, you can @code{ftp} with it---you +can even read news with it! + +Gnus tries to empower people who read news the same way Emacs empowers +people who edit text. Gnus sets no limits to what the user should be +allowed to do. Users are encouraged to extend Gnus to make it behave +like they want it to behave. A program should not control people; +people should be empowered to do what they want by using (or abusing) +the program. + +@c Adjust ../Makefile.in if you change the following line: +This manual corresponds to Ma Gnus v0.14 + +@heading Other related manuals +@itemize +@item Message manual: Composing messages +@item Emacs-MIME: Composing messages; @acronym{MIME}-specific parts. +@item Sieve: Managing Sieve scripts in Emacs. +@item EasyPG: @acronym{PGP/MIME} with Gnus. +@item SASL: @acronym{SASL} authentication in Emacs. +@end itemize + +@end iftex + +@menu +* Starting Up:: Finding news can be a pain. +* Group Buffer:: Selecting, subscribing and killing groups. +* Summary Buffer:: Reading, saving and posting articles. +* Article Buffer:: Displaying and handling articles. +* Composing Messages:: Information on sending mail and news. +* Select Methods:: Gnus reads all messages from various select methods. +* Scoring:: Assigning values to articles. +* Searching:: Mail and News search engines. +* Various:: General purpose settings. +* The End:: Farewell and goodbye. +* Appendices:: Terminology, Emacs intro, @acronym{FAQ}, History, Internals. +* GNU Free Documentation License:: The license for this documentation. +* Index:: Variable, function and concept index. +* Key Index:: Key Index. + +@c Doesn't work right in html. +@c FIXME Do this in a more standard way. +@ifinfo +Other related manuals + +* Message:(message). Composing messages. +* Emacs-MIME:(emacs-mime). Composing messages; @acronym{MIME}-specific parts. +* Sieve:(sieve). Managing Sieve scripts in Emacs. +* EasyPG:(epa). @acronym{PGP/MIME} with Gnus. +* SASL:(sasl). @acronym{SASL} authentication in Emacs. +@end ifinfo + +@detailmenu + --- The Detailed Node Listing --- + +Starting Gnus + +* Finding the News:: Choosing a method for getting news. +* The Server is Down:: How can I read my mail then? +* Slave Gnusae:: You can have more than one Gnus active at a time. +* Fetching a Group:: Starting Gnus just to read a group. +* New Groups:: What is Gnus supposed to do with new groups? +* Changing Servers:: You may want to move from one server to another. +* Startup Files:: Those pesky startup files---@file{.newsrc}. +* Auto Save:: Recovering from a crash. +* The Active File:: Reading the active file over a slow line Takes Time. +* Startup Variables:: Other variables you might change. + +New Groups + +* 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. + +Group Buffer + +* 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. +* Non-ASCII Group Names:: Accessing groups of non-English names. +* Misc Group Stuff:: Other stuff that you can to do. + +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. + +Group Topics + +* 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. + +Misc Group Stuff + +* 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. + +Summary Buffer + +* Summary Buffer Format:: Deciding how the summary buffer is to look. +* Summary Maneuvering:: Moving around the summary buffer. +* Choosing Articles:: Reading articles. +* Paging the Article:: Scrolling the current article. +* Reply Followup and Post:: Posting articles. +* Delayed Articles:: Send articles at a later time. +* Marking Articles:: Marking articles as read, expirable, etc. +* Limiting:: You can limit the summary buffer. +* Threading:: How threads are made. +* Sorting the Summary Buffer:: How articles and threads are sorted. +* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. +* Article Caching:: You may store articles in a cache. +* Persistent Articles:: Making articles expiry-resistant. +* Sticky Articles:: Article buffers that are not reused. +* Article Backlog:: Having already read articles hang around. +* Saving Articles:: Ways of customizing article saving. +* Decoding Articles:: Gnus can treat series of (uu)encoded articles. +* Article Treatment:: The article buffer can be mangled at will. +* MIME Commands:: Doing MIMEy things with the articles. +* Charsets:: Character set issues. +* Article Commands:: Doing various things with the article buffer. +* Summary Sorting:: Sorting the summary buffer in various ways. +* Finding the Parent:: No child support? Get the parent. +* Alternative Approaches:: Reading using non-default summaries. +* Tree Display:: A more visual display of threads. +* Mail Group Commands:: Some commands can only be used in mail groups. +* Various Summary Stuff:: What didn't fit anywhere else. +* Exiting the Summary Buffer:: Returning to the Group buffer, + or reselecting the current group. +* Crosspost Handling:: How crossposted articles are dealt with. +* Duplicate Suppression:: An alternative when crosspost handling fails. +* Security:: Decrypt and Verify. +* Mailing List:: Mailing list minor mode. + +Summary Buffer Format + +* 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. + +Choosing Articles + +* Choosing Commands:: Commands for choosing articles. +* Choosing Variables:: Variables that influence these commands. + +Reply, Followup and Post + +* Summary Mail Commands:: Sending mail. +* Summary Post Commands:: Sending news. +* Summary Message Commands:: Other Message-related commands. +* Canceling and Superseding:: + +Marking Articles + +* Unread Articles:: Marks for unread articles. +* Read Articles:: Marks for read articles. +* Other Marks:: Marks that do not affect readedness. +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. + +Threading + +* Customizing Threading:: Variables you can change to affect the threading. +* Thread Commands:: Thread based commands in the summary buffer. + +Customizing Threading + +* Loose Threads:: How Gnus gathers loose threads into bigger threads. +* Filling In Threads:: Making the threads displayed look fuller. +* More Threading:: Even more variables for fiddling with threads. +* Low-Level Threading:: You thought it was over@dots{} but you were wrong! + +Decoding Articles + +* 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? + +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. + +Article Treatment + +* 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, Gravatars +* Article Signature:: What is a signature? +* Article Miscellanea:: Various other stuff. + +Alternative Approaches + +* Pick and Read:: First mark articles and then read them. +* Binary Groups:: Auto-decode all articles. + +Various Summary Stuff + +* Summary Group Information:: Information oriented commands. +* Searching for Articles:: Multiple article commands. +* Summary Generation Commands:: +* Really Various Summary Commands:: Those pesky non-conformant commands. + +Article Buffer + +* Hiding Headers:: Deciding what headers should be displayed. +* Using MIME:: Pushing articles through @acronym{MIME} before reading them. +* HTML:: Reading @acronym{HTML} messages. +* Customizing Articles:: Tailoring the look of the articles. +* Article Keymap:: Keystrokes available in the article buffer. +* Misc Article:: Other stuff. + +Composing Messages + +* Mail:: Mailing and replying. +* Posting Server:: What server should you post and mail via? +* POP before SMTP:: You cannot send a mail unless you read a mail. +* Mail and Post:: Mailing and posting at the same time. +* Archived Messages:: Where Gnus stores the messages you've sent. +* Posting Styles:: An easier way to specify who you are. +* Drafts:: Postponing messages and rejected messages. +* Rejected Articles:: What happens if the server doesn't like your article? +* Signing and encrypting:: How to compose secure messages. + +Select Methods + +* Server Buffer:: Making and editing virtual servers. +* Getting News:: Reading USENET news with Gnus. +* Using IMAP:: Reading mail from @acronym{IMAP}. +* Getting Mail:: Reading your personal mail with Gnus. +* Browsing the Web:: Getting messages from a plethora of Web sources. +* Other Sources:: Reading directories, files. +* Combined Groups:: Combining groups into one group. +* Email Based Diary:: Using mails to manage diary events in Gnus. +* Gnus Unplugged:: Reading news and mail offline. + +Server Buffer + +* 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. + +Getting News + +* NNTP:: Reading news from an @acronym{NNTP} server. +* News Spool:: Reading news from the local spool. + +@acronym{NNTP} + +* Direct Functions:: Connecting directly to the server. +* Indirect Functions:: Connecting indirectly to the server. +* Common Variables:: Understood by several connection functions. + +Getting Mail + +* 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. + +Mail Sources + +* 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. + +Choosing a Mail Back End + +* Unix Mail Box:: Using the (quite) standard Un*x mbox. +* Babyl:: Babyl was used by older versions of Rmail. +* Mail Spool:: Store your mail in a private spool? +* MH Spool:: An mhspool-like back end. +* Maildir:: Another one-file-per-message format. +* Mail Folders:: Having one file for each group. +* Comparing Mail Back Ends:: An in-depth looks at pros and cons. + +Browsing the Web + +* Archiving Mail:: +* Web Searches:: Creating groups from articles that match a string. +* RSS:: Reading RDF site summary. + +Other Sources + +* Directory Groups:: You can read a directory as if it was a newsgroup. +* Anything Groups:: Dired? Who needs dired? +* Document Groups:: Single files can be the basis of a group. +* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. +* The Empty Backend:: The backend that never has any news. + +Document Groups + +* Document Server Internals:: How to add your own document types. + +Combined Groups + +* Virtual Groups:: Combining articles from many groups. + +Email Based Diary + +* The NNDiary Back End:: Basic setup and usage. +* The Gnus Diary Library:: Utility toolkit on top of nndiary. +* Sending or Not Sending:: A final note on sending diary messages. + +The NNDiary Back End + +* Diary Messages:: What makes a message valid for nndiary. +* Running NNDiary:: NNDiary has two modes of operation. +* Customizing NNDiary:: Bells and whistles. + +The Gnus Diary Library + +* Diary Summary Line Format:: A nicer summary buffer line format. +* Diary Articles Sorting:: A nicer way to sort messages. +* Diary Headers Generation:: Not doing it manually. +* Diary Group Parameters:: Not handling them manually. + +Gnus Unplugged + +* Agent Basics:: How it all is supposed to work. +* Agent Categories:: How to tell the Gnus Agent what to download. +* Agent Commands:: New commands for all the buffers. +* Agent Visuals:: Ways that the agent may effect your summary buffer. +* Agent as Cache:: The Agent is a big cache too. +* Agent Expiry:: How to make old articles go away. +* Agent Regeneration:: How to recover from lost connections and other accidents. +* Agent and flags:: How the Agent maintains flags. +* Agent and IMAP:: How to use the Agent with @acronym{IMAP}. +* Outgoing Messages:: What happens when you post/mail something? +* Agent Variables:: Customizing is fun. +* Example Setup:: An example @file{~/.gnus.el} file for offline people. +* Batching Agents:: How to fetch news from a @code{cron} job. +* Agent Caveats:: What you think it'll do and what it does. + +Agent Categories + +* Category Syntax:: What a category looks like. +* Category Buffer:: A buffer for maintaining categories. +* Category Variables:: Customize'r'Us. + +Agent Commands + +* 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. + +Scoring + +* Summary Score Commands:: Adding score entries for the current group. +* Group Score Commands:: General score commands. +* Score Variables:: Customize your scoring. (My, what terminology). +* Score File Format:: What a score file may contain. +* Score File Editing:: You can edit score files by hand as well. +* Adaptive Scoring:: Big Sister Gnus knows what you read. +* Home Score File:: How to say where new score entries are to go. +* Followups To Yourself:: Having Gnus notice when people answer you. +* Scoring On Other Headers:: Scoring on non-standard headers. +* Scoring Tips:: How to score effectively. +* Reverse Scoring:: That problem child of old is not problem. +* Global Score Files:: Earth-spanning, ear-splitting score files. +* Kill Files:: They are still here, but they can be ignored. +* Converting Kill Files:: Translating kill files to score files. +* Advanced Scoring:: Using logical expressions to build score rules. +* Score Decays:: It can be useful to let scores wither away. + +Advanced Scoring + +* Advanced Scoring Syntax:: A definition. +* Advanced Scoring Examples:: What they look like. +* Advanced Scoring Tips:: Getting the most out of it. + +Searching + +* nnir:: Searching with various engines. +* nnmairix:: Searching with Mairix. + +nnir + +* What is nnir?:: What does nnir do. +* Basic Usage:: How to perform simple searches. +* Setting up nnir:: How to set up nnir. + +Setting up nnir + +* Associating Engines:: How to associate engines. + +Various + +* Process/Prefix:: A convention used by many treatment commands. +* 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. +* Mode Lines:: Displaying information in the mode lines. +* Highlighting and Menus:: Making buffers look all nice and cozy. +* Daemons:: Gnus can do things behind your back. +* 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:: Simple ways to avoid unsolicited commercial email. +* Spam Package:: A package for filtering and processing spam. +* The Gnus Registry:: A package for tracking messages by Message-ID. +* Other modes:: Interaction with other modes. +* Various Various:: Things that are really various. + +Formatting Variables + +* 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. + +Image Enhancements + +* 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. +* Gravatars:: Display the avatar of people you read. +* XVarious:: Other XEmacsy Gnusey variables. + +Thwarting Email Spam + +* 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. + +Spam Package + +* Spam Package Introduction:: +* Filtering Incoming Mail:: +* Detecting Spam in Groups:: +* Spam and Ham Processors:: +* Spam Package Configuration Examples:: +* Spam Back Ends:: +* Extending the Spam package:: +* Spam Statistics Package:: + +Spam Statistics Package + +* Creating a spam-stat dictionary:: +* Splitting mail using spam-stat:: +* Low-level interface to the spam-stat dictionary:: + +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 + +History + +* Gnus Versions:: What Gnus versions 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. + +New Features + +* 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/5.11. +* No Gnus:: Very punny. Gnus 5.12/5.13 +* Ma Gnus:: Celebrating 25 years of Gnus. + +Customization + +* 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. + +Gnus Reference Guide + +* 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. +* Headers:: How Gnus stores headers internally. +* 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. + +Back End Interface + +* Required Back End Functions:: Functions that must be implemented. +* Optional Back End Functions:: Functions that need not be implemented. +* Error Messaging:: How to get messages and report errors. +* 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. + +Various File Formats + +* Active File Format:: Information on articles and groups available. +* Newsgroups File Format:: Group descriptions. + +Emacs for Heathens + +* Keystrokes:: Entering text and executing commands. +* Emacs Lisp:: The built-in Emacs programming language. + +@end detailmenu +@end menu + +@node Starting Up +@chapter Starting Gnus +@cindex starting up + +If you haven't used Emacs much before using Gnus, read @ref{Emacs for +Heathens} first. + +@kindex M-x gnus +@findex gnus +If your system administrator has set things up properly, starting Gnus +and reading news is extremely easy---you just type @kbd{M-x gnus} in +your Emacs. If not, you should customize the variable +@code{gnus-select-method} as described in @ref{Finding the News}. For a +minimal setup for posting should also customize the variables +@code{user-full-name} and @code{user-mail-address}. + +@findex gnus-other-frame +@kindex M-x gnus-other-frame +If you want to start Gnus in a different frame, you can use the command +@kbd{M-x gnus-other-frame} instead. + +If things do not go smoothly at startup, you have to twiddle some +variables in your @file{~/.gnus.el} file. This file is similar to +@file{~/.emacs}, but is read when Gnus starts. + +If you puzzle at any terms used in this manual, please refer to the +terminology section (@pxref{Terminology}). + +@menu +* Finding the News:: Choosing a method for getting news. +* The Server is Down:: How can I read my mail then? +* Slave Gnusae:: You can have more than one Gnus active at a time. +* New Groups:: What is Gnus supposed to do with new groups? +* Changing Servers:: You may want to move from one server to another. +* Startup Files:: Those pesky startup files---@file{.newsrc}. +* Auto Save:: Recovering from a crash. +* The Active File:: Reading the active file over a slow line Takes Time. +* Startup Variables:: Other variables you might change. +@end menu + + +@node Finding the News +@section Finding the News +@cindex finding news + +First of all, you should know that there is a special buffer called +@file{*Server*} that lists all the servers Gnus knows about. You can +press @kbd{^} from the Group buffer to see it. In the Server buffer, +you can press @kbd{RET} on a defined server to see all the groups it +serves (subscribed or not!). You can also add or delete servers, edit +a foreign server's definition, agentize or de-agentize a server, and +do many other neat things. @xref{Server Buffer}. +@xref{Foreign Groups}. @xref{Agent Basics}. + +@vindex gnus-select-method +@c @head +The @code{gnus-select-method} variable says where Gnus should look for +news. This variable should be a list where the first element says +@dfn{how} and the second element says @dfn{where}. This method is your +native method. All groups not fetched with this method are +secondary or foreign groups. + +For instance, if the @samp{news.somewhere.edu} @acronym{NNTP} server is where +you want to get your daily dosage of news from, you'd say: + +@lisp +(setq gnus-select-method '(nntp "news.somewhere.edu")) +@end lisp + +If you want to read directly from the local spool, say: + +@lisp +(setq gnus-select-method '(nnspool "")) +@end lisp + +If you can use a local spool, you probably should, as it will almost +certainly be much faster. But do not use the local spool if your +server is running Leafnode (which is a simple, standalone private news +server); in this case, use @code{(nntp "localhost")}. + +@vindex gnus-nntpserver-file +@cindex NNTPSERVER +@cindex @acronym{NNTP} server +If this variable is not set, Gnus will take a look at the +@env{NNTPSERVER} environment variable. If that variable isn't set, +Gnus will see whether @code{gnus-nntpserver-file} +(@file{/etc/nntpserver} by default) has any opinions on the matter. +If that fails as well, Gnus will try to use the machine running Emacs +as an @acronym{NNTP} server. That's a long shot, though. + +@findex gnus-group-browse-foreign-server +@kindex B (Group) +However, if you use one @acronym{NNTP} server regularly and are just +interested in a couple of groups from a different server, you would be +better served by using the @kbd{B} command in the group buffer. It will +let you have a look at what groups are available, and you can subscribe +to any of the groups you want to. This also makes @file{.newsrc} +maintenance much tidier. @xref{Foreign Groups}. + +@vindex gnus-secondary-select-methods +@c @head +A slightly different approach to foreign groups is to set the +@code{gnus-secondary-select-methods} variable. The select methods +listed in this variable are in many ways just as native as the +@code{gnus-select-method} server. They will also be queried for active +files during startup (if that's required), and new newsgroups that +appear on these servers will be subscribed (or not) just as native +groups are. + +For instance, if you use the @code{nnmbox} back end to read your mail, +you would typically set this variable to + +@lisp +(setq gnus-secondary-select-methods '((nnmbox ""))) +@end lisp + + + +@node The Server is Down +@section The Server is Down +@cindex server errors + +If the default server is down, Gnus will understandably have some +problems starting. However, if you have some mail groups in addition to +the news groups, you may want to start Gnus anyway. + +Gnus, being the trusting sort of program, will ask whether to proceed +without a native select method if that server can't be contacted. This +will happen whether the server doesn't actually exist (i.e., you have +given the wrong address) or the server has just momentarily taken ill +for some reason or other. If you decide to continue and have no foreign +groups, you'll find it difficult to actually do anything in the group +buffer. But, hey, that's your problem. Blllrph! + +@findex gnus-no-server +@kindex M-x gnus-no-server +@c @head +If you know that the server is definitely down, or you just want to read +your mail without bothering with the server at all, you can use the +@code{gnus-no-server} command to start Gnus. That might come in handy +if you're in a hurry as well. This command will not attempt to contact +your primary server---instead, it will just activate all groups on level +1 and 2. (You should preferably keep no native groups on those two +levels.) Also @pxref{Group Levels}. + + +@node Slave Gnusae +@section Slave Gnusae +@cindex slave + +You might want to run more than one Emacs with more than one Gnus at the +same time. If you are using different @file{.newsrc} files (e.g., if you +are using the two different Gnusae to read from two different servers), +that is no problem whatsoever. You just do it. + +The problem appears when you want to run two Gnusae that use the same +@file{.newsrc} file. + +To work around that problem some, we here at the Think-Tank at the Gnus +Towers have come up with a new concept: @dfn{Masters} and +@dfn{slaves}. (We have applied for a patent on this concept, and have +taken out a copyright on those words. If you wish to use those words in +conjunction with each other, you have to send $1 per usage instance to +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 +messages as unread that have been read in the master. + + + +@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}). + +@menu +* 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. +@end menu + + +@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 @code{gnus-check-new-newsgroups} is @code{ask-server}, Gnus will +ask the 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 (@pxref{Group Levels}) 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 (@pxref{Group Levels}). 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 +"nnml" +@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 non-@code{nil}, 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}. + +The ``options -n'' format is very simplistic. The syntax above is all +that is supports: you can force-subscribe hierarchies, or you can +deny hierarchies, and that's it. + +@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}, @code{nnimap}, and +@code{nnmaildir}) subscribed. If you don't like that, just set this +variable to @code{nil}. + +@vindex gnus-auto-subscribed-categories +As if that wasn't enough, @code{gnus-auto-subscribed-categories} also +allows you to specify that new groups should be subscribed based on the +category their select methods belong to. The default is @samp{(mail +post-mail)}, meaning that all new groups from mail-like backends +should be subscribed automatically. + +New groups that match these variables 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. + +@kindex M-x gnus-group-clear-data-on-native-groups +@findex gnus-group-clear-data-on-native-groups +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 + +Most common Unix news readers use a shared startup file called +@file{.newsrc}. This file contains all the information about what +groups are subscribed, and which articles in these groups have been +read. + +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 +@sc{gnus} and other newsreaders. + +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 +@vindex gnus-read-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 can be +convenient if you use a different news reader occasionally, and you +want to read a different subset of the available groups with that +news reader. + +@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 to keep multiple numbered backups of 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)) + +(add-hook 'gnus-save-quick-newsrc-hook 'turn-off-backup) +(add-hook 'gnus-save-standard-newsrc-hook 'turn-off-backup) +@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-init} 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). If Emacs was invoked with +the @option{-q} or @option{--no-init-file} options (@pxref{Initial +Options, ,Initial Options, emacs, The Emacs Manual}), Gnus doesn't read +@code{gnus-init-file}. + + +@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. + +@vindex gnus-always-read-dribble-file +If @code{gnus-always-read-dribble-file} is non-@code{nil}, Gnus will +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. + +@vindex gnus-read-active-file +@c @head +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 + +@item gnus-load-hook +@vindex gnus-load-hook +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 called as the first thing when Gnus is started. + +@item gnus-before-resume-hook +@vindex gnus-before-resume-hook +A hook called as the first thing when Gnus is resumed after a suspend. + +@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 non-@code{nil}, 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 non-@code{nil}, the startup message won't be displayed. That way, +your boss might not notice as easily that you are reading news instead +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-use-backend-marks +@vindex gnus-use-backend-marks +If non-@code{nil}, Gnus will store article marks both in the +@file{.newsrc.eld} file and in the backends. This will slow down +group operation some. + +@end table + + +@node Group Buffer +@chapter Group Buffer +@cindex group buffer + +@c Alex Schroeder suggests to rearrange this as follows: +@c +@c 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 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 First, "Gnus considers groups... (default 9)." +@c New, a table summarizing what levels 1 to 9 mean. +@c Third, "Gnus treats subscribed ... reasons of efficiency" +@c 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 + +@menu +* 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. +* Non-ASCII Group Names:: Accessing groups of non-English names. +* Misc Group Stuff:: Other stuff that you can to do. +@end menu + + +@node Group Buffer Format +@section Group Buffer Format + +@menu +* 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. +@end menu + +You can customize the Group Mode tool bar, see @kbd{M-x +customize-apropos RET gnus-group-tool-bar}. This feature is only +available in Emacs. + +The tool bar icons are now (de)activated correctly depending on the +cursor position. Therefore, moving around in the Group Buffer is +slower. You can disable this via the variable +@code{gnus-group-update-tool-bar}. Its default value depends on your +Emacs version. + +@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 +instead of wasting time reading news.) + +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 +Number of unread articles. + +@item I +Number of dormant articles. + +@item T +Number of ticked articles. + +@item R +Number of read articles. + +@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 +efficient access to @var{max-number} and @var{min-number} but getting +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. + +The nnml backend (@pxref{Mail Spool}) has a feature called ``group +compaction'' which circumvents this deficiency: the idea is to +renumber all articles from 1, removing all gaps between numbers, hence +getting a correct total count. Other backends may support this in the +future. In order to keep your total article count relatively up to +date, you might want to compact your groups (or even directly your +server) from time to time. @xref{Misc Group Stuff}, @xref{Server Commands}. + +@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 F +The disk space used by the articles fetched by both the cache and +agent. The value is automatically scaled to bytes(B), kilobytes(K), +megabytes(M), or gigabytes(G) to minimize the column width. A format +of %7F is sufficient for a fixed-width column. + +@item u +User defined specifier. The next character in the format string should +be a letter. Gnus will call the function +@code{gnus-user-format-function-}@samp{X}, 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 non-@code{nil}, 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) + ((zerop unread) . my-group-face-4) + (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. +@item unread +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}. + + +@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) +@findex gnus-group-next-unread-group +Go to the next group that has unread articles +(@code{gnus-group-next-unread-group}). + +@item p +@itemx DEL +@kindex DEL (Group) +@kindex p (Group) +@findex gnus-group-prev-unread-group +Go to the previous group that has unread articles +(@code{gnus-group-prev-unread-group}). + +@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) +@findex gnus-group-next-unread-group-same-level +Go to the next unread group on the same (or lower) level +(@code{gnus-group-next-unread-group-same-level}). + +@item M-p +@kindex M-p (Group) +@findex gnus-group-prev-unread-group-same-level +Go to the previous unread group on the same (or lower) level +(@code{gnus-group-prev-unread-group-same-level}). +@end table + +Three commands for jumping to groups: + +@table @kbd + +@item j +@kindex j (Group) +@findex gnus-group-jump-to-group +Jump to a group (and make it visible if it isn't already) +(@code{gnus-group-jump-to-group}). Killed groups can be jumped to, just +like living groups. + +@item , +@kindex , (Group) +@findex gnus-group-best-unread-group +Jump to the unread group with the lowest level +(@code{gnus-group-best-unread-group}). + +@item . +@kindex . (Group) +@findex gnus-group-first-unread-group +Jump to the first group with unread articles +(@code{gnus-group-first-unread-group}). +@end table + +@vindex gnus-group-goto-unread +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}. + +@vindex gnus-summary-next-group-on-exit +If @code{gnus-summary-next-group-on-exit} is @code{t}, when a summary is +exited, the point in the group buffer is moved to the next unread group. +Otherwise, the point is set to the group just exited. The default is +@code{t}. + +@node Selecting a Group +@section Selecting a Group +@cindex group selection + +@table @kbd + +@item SPACE +@kindex SPACE (Group) +@findex gnus-group-read-group +Select the current group, switch to the summary buffer and display the +first unread article (@code{gnus-group-read-group}). If there are no +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-newsgroup-maximum-articles +In groups in some news servers, there might be a big gap between a few +very old articles that will never be expired and the recent ones. In +such a case, the server will return the data like @code{(1 . 30000000)} +for the @code{LIST ACTIVE group} command, for example. Even if there +are actually only the articles 1--10 and 29999900--30000000, Gnus doesn't +know it at first and prepares for getting 30000000 articles. However, +it will consume hundreds megabytes of memories and might make Emacs get +stuck as the case may be. If you use such news servers, set the +variable @code{gnus-newsgroup-maximum-articles} to a positive number. +The value means that Gnus ignores articles other than this number of the +latest ones in every group. For instance, the value 10000 makes Gnus +get only the articles 29990001--30000000 (if the latest article number is +30000000 in a group). Note that setting this variable to a number might +prevent you from reading very old articles. The default value of the +variable @code{gnus-newsgroup-maximum-articles} is @code{nil}, which +means Gnus never ignores old articles. + +@vindex gnus-select-group-hook +@vindex gnus-auto-select-first +@vindex gnus-auto-select-subject +If @code{gnus-auto-select-first} is non-@code{nil}, select an article +automatically when entering a group with the @kbd{SPACE} command. +Which article this is controlled by the +@code{gnus-auto-select-subject} variable. Valid values for this +variable are: + +@table @code + +@item unread +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. + +@item unseen-or-unread +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 +unread article. + +@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 + +The following commands allow for managing your subscriptions in the +Group buffer. If you want to subscribe to many groups, it's probably +more convenient to go to the @ref{Server Buffer}, and choose the +server there using @kbd{RET} or @kbd{SPC}. Then you'll have the +commands listed in @ref{Browse Foreign Server} at hand. + +@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 +subscribed already, unsubscribe it instead +(@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 +read articles (@code{gnus-group-clear-data}). + +@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 store no information on what articles +you have read, etc. 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. + +@cindex zombie groups +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 non-@code{nil}, 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. +This variable can also be a function. In that case, that function will +be called and the result will be used as value. + + +@vindex gnus-group-list-inactive-groups +If @code{gnus-group-list-inactive-groups} is non-@code{nil}, 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 non-@code{nil}, 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 +read seldom you can add the @code{gnus-summary-bubble-group} function to +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 + +If you recall how to subscribe to servers (@pxref{Finding the News}) +you will remember that @code{gnus-secondary-select-methods} and +@code{gnus-select-method} let you write a definition in Emacs Lisp of +what servers you want to see when you start up. The alternate +approach is to use foreign servers and groups. ``Foreign'' here means +they are not coming from the select methods. All foreign server +configuration and subscriptions are stored only in the +@file{~/.newsrc.eld} file. + +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 point---@code{gnus-subscribe-newsgroup-method} is not +consulted. + +Changes from the group editing commands are stored in +@file{~/.newsrc.eld} (@code{gnus-startup-file}). An alternative is the +variable @code{gnus-parameters}, @xref{Group Parameters}. + +@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) +@findex gnus-group-read-ephemeral-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 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 Google +@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 +@samp{shaving group:alt.sysadmin.recovery}. + +@item G R +@kindex G R (Group) +@findex gnus-group-make-rss-group +Make a group based on an @acronym{RSS} feed +(@code{gnus-group-make-rss-group}). You will be prompted for an URL@. +@xref{RSS}. + +@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) +@findex gnus-group-add-to-virtual +Add the current group to an @code{nnvirtual} group +(@code{gnus-group-add-to-virtual}). Uses the process/prefix convention. +@end table + +@xref{Select Methods}, for more information on the various select +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. + + +The following commands create ephemeral groups. They can be called not +only from the Group buffer, but in any Gnus buffer. + +@table @code +@item gnus-read-ephemeral-gmane-group +@findex gnus-read-ephemeral-gmane-group +@vindex gnus-gmane-group-download-format +Read an ephemeral group on Gmane.org. The articles are downloaded via +HTTP using the URL specified by @code{gnus-gmane-group-download-format}. +Gnus will prompt you for a group name, the start article number and an +the article range. + +@item gnus-read-ephemeral-gmane-group-url +@findex gnus-read-ephemeral-gmane-group-url +This command is similar to @code{gnus-read-ephemeral-gmane-group}, but +the group name and the article number and range are constructed from a +given @acronym{URL}. Supported @acronym{URL} formats include: +@indicateurl{http://thread.gmane.org/gmane.foo.bar/12300/focus=12399}, +@indicateurl{http://thread.gmane.org/gmane.foo.bar/12345/}, +@indicateurl{http://article.gmane.org/gmane.foo.bar/12345/}, +@indicateurl{http://permalink.gmane.org/gmane.foo.bar/12345/}, and +@indicateurl{http://news.gmane.org/group/gmane.foo.bar/thread=12345}. + +@item gnus-read-ephemeral-emacs-bug-group +@findex gnus-read-ephemeral-emacs-bug-group +Read an Emacs bug report in an ephemeral group. Gnus will prompt for a +bug number. The default is the number at point. The @acronym{URL} is +specified in @code{gnus-bug-group-download-format-alist}. + +@item gnus-read-ephemeral-debian-bug-group +@findex gnus-read-ephemeral-debian-bug-group +Read a Debian bug report in an ephemeral group. Analog to +@code{gnus-read-ephemeral-emacs-bug-group}. +@end table + +Some of these command are also useful for article buttons, @xref{Article +Buttons}. + +Here is an example: +@lisp +(require 'gnus-art) +(add-to-list + 'gnus-button-alist + '("#\\([0-9]+\\)\\>" 1 + (string-match "\\" (or gnus-newsgroup-name "")) + gnus-read-ephemeral-emacs-bug-group 1)) +@end lisp + + +@node Group Parameters +@section Group Parameters +@cindex group parameters + +The group parameters store information local to a particular group. + +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}). +Additionally, you can set group parameters via the +@code{gnus-parameters} variable, see below. + +Here's an example group parameter list: + +@example +((to-address . "ding@@gnus.org") + (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 +@item to-address +@cindex to-address +Address used by when doing followups and new posts. + +@example +(to-address . "some@@where.com") +@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 +that members won't receive two copies of your followups. + +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 +list address instead. + +See also @code{gnus-parameter-to-address-alist}. + +@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}. +@vindex gnus-add-to-list + +@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. + +See also @code{gnus-parameter-to-list-alist}. + +@anchor{subscribed} +@item subscribed +@cindex subscribed +@cindex Mail-Followup-To +@findex gnus-find-subscribed-addresses +If this parameter is set to @code{t}, Gnus will consider the +to-address and to-list parameters for this group as addresses of +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 +following in your @file{.gnus.el} + +@lisp +(setq message-subscribed-address-functions + '(gnus-find-subscribed-addresses)) +@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. + +This parameter cannot be set via @code{gnus-parameters}. See +@code{gnus-permanently-visible-groups} as an alternative. + +@item broken-reply-to +@cindex broken-reply-to +Elements like @code{(broken-reply-to . t)} signals that @code{Reply-To} +headers in this group are to be ignored, and for the header to be hidden +if @code{reply-to} is part of @code{gnus-boring-article-headers}. This +can be useful if you're reading a mailing list group where the listserv +has inserted @code{Reply-To} headers that point back to 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 . "group")} is present, this string will +be inserted literally as a @code{Gcc:} header. It should be a group +name. The @code{gcc-self} value may also be a list of strings and +@code{t}, e.g., @code{(gcc-self "group1" "group2" t)} means to +@code{gcc} the newly composed message into the groups @code{"group1"} +and @code{"group2"}, and into the current group. The @code{gcc-self} +parameter takes precedence over any default @code{Gcc} rules as +described later (@pxref{Archived Messages}), with the exception for +messages to resend. + +@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 +@cindex expiring mail +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}. + +See also @code{gnus-auto-expirable-newsgroups}. + +@item total-expire +@cindex total-expire +@cindex expiring mail +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. + +See also @code{gnus-total-expirable-newsgroups}. + +@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. + +@item adapt-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. + +@item admin-address +@cindex admin-address +When unsubscribing from a mailing list you should never send the +unsubscription notice to the mailing list itself. Instead, you'd send +messages to the administrative address. This parameter allows you to +put the admin address somewhere convenient. + +@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 +Display all articles, both read and unread. + +@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 [unread] +Display only unread articles. + +@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}. +Predicates include @code{tick}, @code{unsend}, @code{undownload}, +@code{unread}, @code{dormant}, @code{expire}, @code{reply}, +@code{killed}, @code{bookmark}, @code{score}, @code{save}, +@code{cache}, @code{forward}, and @code{unseen}. + +@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. + +See also @code{gnus-group-charset-alist}. + +@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. + +See also @code{gnus-group-ignored-charsets-alist}. + +@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") + ("X-Message-SMTP-Method" "smtp smtp.example.org 587") + ("X-My-Header" "Funky Value") + (signature "Funky Signature")) +@end example + +If you're using topics to organize your group buffer +(@pxref{Group Topics}), note that posting styles can also be set in +the topics parameters. Posting styles in topic parameters apply to all +groups in this topic. More precisely, the posting-style settings for a +group result from the hierarchical merging of all posting-style +entries in the parameters of this group and all the topics it belongs +to. + + +@item post-method +@cindex post-method +If it is set, the value is used as the method for posting message +instead of @code{gnus-post-method}. + +@item mail-source +@cindex mail-source +If it is set, and the setting of @code{mail-sources} includes a +@code{group} mail source (@pxref{Mail Sources}), the value is a +mail source for this group. + +@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 +address "sender" "sieve-admin@@extundo.com")} group parameter, when +translating the group parameter into a Sieve script (@pxref{Sieve +Commands}) the following Sieve code is generated: + +@example +if address "sender" "sieve-admin@@extundo.com" @{ + fileinto "INBOX.list.sieve"; +@} +@end example + +To generate tests for multiple email-addresses use a group parameter +like @code{(sieve address "sender" ("name@@one.org" else@@two.org"))}. +When generating a sieve script (@pxref{Sieve Commands}) Sieve code +like the following is generated: + +@example +if address "sender" ["name@@one.org", "else@@two.org"] @{ + fileinto "INBOX.list.sieve"; +@} +@end example + +You can also use regexp expansions in the rules: + +@example +(sieve header :regex "list-id" "") +@end example + +See @pxref{Sieve Commands} for commands and variables that might be of +interest in relation to the sieve parameter. + +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 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 +that group. @code{gnus-show-threads} will be made into a local variable +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 +if and only if @var{variable} has been bound as a variable. Otherwise, +only evaluating the form will take place. So, you may want to bind the +variable in advance using @code{defvar} or other if the result of the +form needs to be set to it. + +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.el} file: + +@lisp +(add-to-list 'gnus-newsgroup-variables 'message-from-style) +@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 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. If +@code{dummy-variable} has been bound (see above), it will be set to the +(meaningless) result of the @code{(ding)} form. + +Alternatively, since the VARIABLE becomes local to the group, this +pattern can be used to temporarily change a hook. For example, if the +following is added to a group parameter + +@lisp +(gnus-summary-prepared-hook + (lambda nil (local-set-key "d" (local-key-binding "n")))) +@end lisp + +when the group is entered, the 'd' key will not mark the article as +expired. + +@end table + +@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 this +case see @code{gnus-permanently-visible-groups} as an alternative.). +For example: + +@lisp +(setq gnus-parameters + '(("mail\\..*" + (gnus-show-threads nil) + (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 + +All clauses that matches the group name will be used, but the last +setting ``wins''. So if you have two clauses that both match the +group name, and both set, say @code{display}, the last setting will +override the first. + +Parameters that are strings will be subjected to regexp substitution, +as the @code{to-group} example shows. + +@vindex gnus-parameters-case-fold-search +By default, whether comparing the group name and one of those regexps +specified in @code{gnus-parameters} is done in a case-sensitive manner +or a case-insensitive manner depends on the value of +@code{case-fold-search} at the time when the comparison is done. The +value of @code{case-fold-search} is typically @code{t}; it means, for +example, the element @code{("INBOX\\.FOO" (total-expire . t))} might be +applied to both the @samp{INBOX.FOO} group and the @samp{INBOX.foo} +group. If you want to make those regexps always case-sensitive, set the +value of the @code{gnus-parameters-case-fold-search} variable to +@code{nil}. Otherwise, set it to @code{t} if you want to compare them +always in a case-insensitive manner. + +You can define different sorting to different groups via +@code{gnus-parameters}. Here is an example to sort an @acronym{NNTP} +group by reverse date to see the latest news at the top and an +@acronym{RSS} group by subject. In this example, the first group is the +Debian daily news group @code{gmane.linux.debian.user.news} from +news.gmane.org. The @acronym{RSS} group corresponds to the Debian +weekly news RSS feed +@url{http://packages.debian.org/unstable/newpkg_main.en.rdf}, +@xref{RSS}. + +@lisp +(setq + gnus-parameters + '(("nntp.*gmane\\.debian\\.user\\.news" + (gnus-show-threads nil) + (gnus-article-sort-functions '((not gnus-article-sort-by-date))) + (gnus-use-adaptive-scoring nil) + (gnus-use-scoring nil)) + ("nnrss.*debian" + (gnus-show-threads nil) + (gnus-article-sort-functions 'gnus-article-sort-by-subject) + (gnus-use-adaptive-scoring nil) + (gnus-use-scoring t) + (gnus-score-find-score-files-function 'gnus-score-find-single) + (gnus-summary-line-format "%U%R%z%d %I%(%[ %s %]%)\n")))) +@end lisp + + +@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-ticked +List all groups with ticked articles (@code{gnus-group-list-ticked}). + +@item A / +@kindex A / (Group) +@findex gnus-group-list-limit +Further limit groups within the current selection +(@code{gnus-group-list-limit}). If you've first limited to groups +with dormant articles with @kbd{A ?}, you can then further limit with +@kbd{A / c}, which will then limit to groups with cached articles, +giving you the groups that have both dormant articles and cached +articles. + +@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 name@* +(@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 name@* +(@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 +@cindex expiring mail +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 +@cindex expiring mail +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 +@vindex gnus-browse-subscribe-newsgroup-method +Unsubscribe to the current group, or, as will be the case here, +subscribe to it (@code{gnus-browse-unsubscribe-current-group}). You +can affect the way the new group is entered into the Group buffer +using the variable @code{gnus-browse-subscribe-newsgroup-method}. See +@pxref{Subscription Methods} for available options. + +@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}). + +@item DEL +@kindex DEL (Browse) +@findex gnus-browse-delete-group +This function will delete the current group +(@code{gnus-browse-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. +@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 +dum@dots{} Nice tune, that@dots{} la la la@dots{} 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 +@cindex expiring mail +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 previous 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 +allowed---@code{visible} 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 Non-ASCII Group Names +@section Accessing groups of non-English names +@cindex non-ascii group names + +There are some news servers that provide groups of which the names are +expressed with their native languages in the world. For instance, in a +certain news server there are some newsgroups of which the names are +spelled in Chinese, where people are talking in Chinese. You can, of +course, subscribe to such news groups using Gnus. Currently Gnus +supports non-@acronym{ASCII} group names not only with the @code{nntp} +back end but also with the @code{nnml} back end and the @code{nnrss} +back end. + +Every such group name is encoded by a certain charset in the server +side (in an @acronym{NNTP} server its administrator determines the +charset, but for groups in the other back ends it is determined by you). +Gnus has to display the decoded ones for you in the group buffer and the +article buffer, and needs to use the encoded ones when communicating +with servers. However, Gnus doesn't know what charset is used for each +non-@acronym{ASCII} group name. The following two variables are just +the ones for telling Gnus what charset should be used for each group: + +@table @code +@item gnus-group-name-charset-method-alist +@vindex gnus-group-name-charset-method-alist +An alist of select methods and charsets. The default value is +@code{nil}. The names of groups in the server specified by that select +method are all supposed to use the corresponding charset. For example: + +@lisp +(setq gnus-group-name-charset-method-alist + '(((nntp "news.com.cn") . cn-gb-2312))) +@end lisp + +Charsets specified for groups with this variable are preferred to the +ones specified for the same groups with the +@code{gnus-group-name-charset-group-alist} variable (see below). + +A select method can be very long, like: + +@lisp +(nntp "gmane" + (nntp-address "news.gmane.org") + (nntp-end-of-line "\n") + (nntp-open-connection-function + nntp-open-via-rlogin-and-telnet) + (nntp-via-rlogin-command "ssh") + (nntp-via-rlogin-command-switches + ("-C" "-t" "-e" "none")) + (nntp-via-address @dots{})) +@end lisp + +In that case, you can truncate it into @code{(nntp "gmane")} in this +variable. That is, it is enough to contain only the back end name and +the server name. + +@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. +@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) + (".*" . utf-8))) +@end lisp + +Note that this variable is ignored if the match is made with +@code{gnus-group-name-charset-method-alist}. +@end table + +Those two variables are used also to determine the charset for encoding +and decoding non-@acronym{ASCII} group names that are in the back ends +other than @code{nntp}. It means that it is you who determine it. If +you do nothing, the charset used for group names in those back ends will +all be @code{utf-8} because of the last element of +@code{gnus-group-name-charset-group-alist}. + +There is one more important variable for non-@acronym{ASCII} group +names: + +@table @code +@item nnmail-pathname-coding-system +@vindex nnmail-pathname-coding-system +The value of this variable should be a coding system or @code{nil}. The +default is @code{nil} in Emacs, or is the aliasee of the coding system +named @code{file-name} (a certain coding system of which an alias is +@code{file-name}) in XEmacs. + +The @code{nnml} back end, the @code{nnrss} back end, the agent, and +the cache use non-@acronym{ASCII} group names in those files and +directories. This variable overrides the value of +@code{file-name-coding-system} which specifies the coding system used +when encoding and decoding those file names and directory names. + +In XEmacs (with the @code{mule} feature), @code{file-name-coding-system} +is the only means to specify the coding system used to encode and decode +file names. On the other hand, Emacs uses the value of +@code{default-file-name-coding-system} if @code{file-name-coding-system} +is @code{nil} or it is bound to the value of +@code{nnmail-pathname-coding-system} which is @code{nil}. + +Normally the value of @code{default-file-name-coding-system} in Emacs or +@code{nnmail-pathname-coding-system} in XEmacs is initialized according +to the locale, so you will need to do nothing if the value is suitable +to encode and decode non-@acronym{ASCII} group names. + +The value of this variable (or @code{default-file-name-coding-system}) +does not necessarily need to be the same value that is determined by +@code{gnus-group-name-charset-method-alist} and +@code{gnus-group-name-charset-group-alist}. + +If @code{default-file-name-coding-system} or this variable is +initialized by default to @code{iso-latin-1} for example, although you +want to subscribe to the groups spelled in Chinese, that is the most +typical case where you have to customize +@code{nnmail-pathname-coding-system}. The @code{utf-8} coding system is +a good candidate for it. Otherwise, you may change the locale in your +system so that @code{default-file-name-coding-system} or this variable +may be initialized to an appropriate value. +@end table + +Note that when you copy or move articles from a non-@acronym{ASCII} +group to another group, the charset used to encode and decode group +names should be the same in both groups. Otherwise the Newsgroups +header will be displayed incorrectly in the article buffer. + + +@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 v +@kindex v (Group) +@cindex keys, reserved for users (Group) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. For example: + +@lisp +(define-key gnus-group-mode-map (kbd "v j d") + (lambda () + (interactive) + (gnus-group-jump-to-group "nndraft:drafts"))) +@end lisp + +On keys reserved for users in Emacs and on keybindings in general +@xref{Keymaps, Keymaps, , emacs, The Emacs Editor}. + +@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. + +@item G z +@kindex G z (Group) +@findex gnus-group-compact-group + +Compact the group under point (@code{gnus-group-compact-group}). +Currently implemented only in nnml (@pxref{Mail Spool}). This removes +gaps between article numbers, hence getting a correct total article +count. + +@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. + +@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 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 + +To see what variables are dynamically bound (like +@code{gnus-tmp-group}), you have to look at the source code. The +variable names aren't guaranteed to be stable over Gnus versions, +either. + + +@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 transferred 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 non-@code{nil} (the default) articles is +placed in all groups that have matching rules, otherwise the article +is only placed in the group with the first matching rule. For +example, the group parameter @samp{(sieve address "sender" +"owner-ding@@hpc.uh.edu")} will generate the following piece of Sieve +code if @code{gnus-sieve-crosspost} is @code{nil}. (When +@code{gnus-sieve-crosspost} is non-@code{nil}, it looks the same +except that the line containing the call to @code{stop} is removed.) + +@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. + +You can customize the Summary Mode tool bar, see @kbd{M-x +customize-apropos RET gnus-summary-tool-bar}. This feature is only +available in Emacs. + +@kindex v (Summary) +@cindex keys, reserved for users (Summary) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. For example: +@lisp +(define-key gnus-summary-mode-map (kbd "v -") "LrS") ;; lower subthread +@end lisp + +@menu +* Summary Buffer Format:: Deciding how the summary buffer is to look. +* Summary Maneuvering:: Moving around the summary buffer. +* Choosing Articles:: Reading articles. +* Paging the Article:: Scrolling the current article. +* Reply Followup and Post:: Posting articles. +* Delayed Articles:: Send articles at a later time. +* Marking Articles:: Marking articles as read, expirable, etc. +* Limiting:: You can limit the summary buffer. +* Threading:: How threads are made. +* Sorting the Summary Buffer:: How articles and threads are sorted. +* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. +* Article Caching:: You may store articles in a cache. +* Persistent Articles:: Making articles expiry-resistant. +* Sticky Articles:: Article buffers that are not reused. +* Article Backlog:: Having already read articles hang around. +* Saving Articles:: Ways of customizing article saving. +* Decoding Articles:: Gnus can treat series of (uu)encoded articles. +* Article Treatment:: The article buffer can be mangled at will. +* MIME Commands:: Doing MIMEy things with the articles. +* Charsets:: Character set issues. +* Article Commands:: Doing various things with the article buffer. +* Summary Sorting:: Sorting the summary buffer in various ways. +* Finding the Parent:: No child support? Get the parent. +* Alternative Approaches:: Reading using non-default summaries. +* Tree Display:: A more visual display of threads. +* Mail Group Commands:: Some commands can only be used in mail groups. +* Various Summary Stuff:: What didn't fit anywhere else. +* Exiting the Summary Buffer:: Returning to the Group buffer, + or reselecting the current group. +* Crosspost Handling:: How crossposted articles are dealt with. +* Duplicate Suppression:: An alternative when crosspost handling fails. +* Security:: Decrypt and Verify. +* Mailing List:: Mailing list minor mode. +@end menu + + +@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-identifiers}. @xref{Article Hiding}. +@item s +Subject if the article is the root of the thread or the previous article +had a different subject, @code{gnus-summary-same-subject} otherwise. +(@code{gnus-summary-same-subject} defaults to @code{""}.) +@item F +Full @code{From} header. +@item n +The name (from the @code{From} header). +@item f +The name, @code{To} header or the @code{Newsgroups} header (@pxref{To +From Newsgroups}). +@item a +The name (from the @code{From} header). This differs from the @code{n} +spec in that it uses the function designated by the +@code{gnus-extract-address-components} variable, which is slower, but +may be more thorough. +@item A +The address (from the @code{From} header). This works the same way as +the @code{a} spec. +@item L +Number of lines in the article. +@item c +Number of characters in the article. This specifier is not supported +in some methods (like nnfolder). +@item k +Pretty-printed version of the number of characters in the article; +for example, @samp{1.2k} or @samp{0.4M}. +@item I +Indentation based on thread level (@pxref{Customizing Threading}). +@item B +A complex trn-style thread tree, showing response-connecting trace +lines. A thread could be drawn like this: + +@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 @var{YYYYMMDD}@code{T}@var{HHMMSS} format. +@item M +@code{Message-ID}. +@item r +@code{References}. +@item t +Number of articles in the current sub-thread. Using this spec will slow +down summary buffer generation somewhat. +@item e +An @samp{=} (@code{gnus-not-empty-thread-mark}) will be displayed if the +article has any children. +@item P +The line number. +@item O +Download mark. +@item * +Desired cursor position (instead of after first colon). +@item &user-date; +Age sensitive date format. Various date format is defined in +@code{gnus-user-date-format-alist}. +@item u +User defined specifier. The next character in the format string should +be a letter. Gnus will call the function +@code{gnus-user-format-function-@var{x}}, where @var{x} is the letter +following @samp{%u}. The function will be passed the current header as +argument. The function should return a string, which will be inserted +into the summary just like information from any other summary specifier. +@end table + +Text between @samp{%(} and @samp{%)} will be highlighted with +@code{gnus-mouse-face} when the mouse point is placed inside the area. +There can only be one such area. + +The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs +have to be handled with care. For reasons of efficiency, Gnus will +compute what column these characters will end up in, and ``hard-code'' +that. This means that it is invalid to have these specs after a +variable-length spec. Well, you might not be arrested, but your summary +buffer will look strange, which is bad enough. + +The smart choice is to have these specs as far to the left as possible. +(Isn't that the case with everything, though? But I digress.) + +This restriction may disappear in later versions of Gnus. + + +@node To From Newsgroups +@subsection To From Newsgroups +@cindex To +@cindex Newsgroups + +In some groups (particularly in archive groups), the @code{From} header +isn't very interesting, since all the articles there are written by +you. To display the information in the @code{To} or @code{Newsgroups} +headers instead, you need to decide three things: What information to +gather; where to display it; and when to display it. + +@enumerate +@item +@vindex gnus-extra-headers +The reading of extra header information is controlled by the +@code{gnus-extra-headers}. This is a list of header symbols. For +instance: + +@lisp +(setq gnus-extra-headers + '(To Newsgroups X-Newsreader)) +@end lisp + +This will result in Gnus trying to obtain these three headers, and +storing it in header structures for later easy retrieval. + +@item +@findex gnus-extra-header +The value of these extra headers can be accessed via the +@code{gnus-extra-header} function. Here's a format line spec that will +access the @code{X-Newsreader} header: + +@example +"%~(form (gnus-extra-header 'X-Newsreader))@@" +@end example + +@item +@vindex gnus-ignored-from-addresses +The @code{gnus-ignored-from-addresses} variable says when the @samp{%f} +summary line spec returns the @code{To}, @code{Newsreader} or +@code{From} header. If this regexp matches the contents of the +@code{From} header, the value of the @code{To} or @code{Newsreader} +headers are used instead. + +To distinguish regular articles from those where the @code{From} field +has been swapped, a string is prefixed to the @code{To} or +@code{Newsgroups} header in the summary line. By default the string is +@samp{-> } for @code{To} and @samp{=> } for @code{Newsgroups}, you can +customize these strings with @code{gnus-summary-to-prefix} and +@code{gnus-summary-newsgroup-prefix}. + +@end enumerate + +@vindex nnmail-extra-headers +A related variable is @code{nnmail-extra-headers}, which controls when +to include extra headers when generating overview (@acronym{NOV}) files. +If you have old overview files, you should regenerate them after +changing this variable, by entering the server buffer using @kbd{^}, +and then @kbd{g} on the appropriate mail server (e.g., nnml) to cause +regeneration. + +@vindex gnus-summary-line-format +You also have to instruct Gnus to display the data by changing the +@code{%n} spec to the @code{%f} spec in the +@code{gnus-summary-line-format} variable. + +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 non-@code{nil} 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 non-@code{nil}, all the movement commands will try to go to the next +article with the same subject as the current. (@dfn{Same} here might +mean @dfn{roughly equal}. See @code{gnus-summary-gather-subject-limit} +for details (@pxref{Customizing Threading}).) If there are no more +articles with the same subject, go to the first unread article. + +This variable is not particularly useful if you use a threaded display. + +@item gnus-summary-check-current +@vindex gnus-summary-check-current +If non-@code{nil}, all the ``unread'' movement commands will not proceed +to the next (or previous) article if the current article is unread. +Instead, they will choose the current article. + +@item gnus-auto-center-summary +@vindex gnus-auto-center-summary +If non-@code{nil}, Gnus will keep the point in the summary buffer +centered at all times. This makes things quite tidy, but if you have a +slow network connection, or simply do not like this un-Emacsism, you can +set this variable to @code{nil} to get the normal Emacs scrolling +action. This will also inhibit horizontal re-centering of the summary +buffer, which might make it more inconvenient to read extremely long +threads. + +This variable can also be a number. In that case, center the window at +the given number of lines from the top. + +@item gnus-summary-stop-at-end-of-message +@vindex gnus-summary-stop-at-end-of-message +If non-@code{nil}, don't go to the next article when hitting +@kbd{SPC}, and you're at the end of the article. + +@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 non-@code{nil}. 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. The default is +@code{nil}. If you would like each article to be saved in the Agent as +you read it, putting @code{gnus-agent-fetch-selected-article} on this +hook will do so. + +@item gnus-mark-article-hook +@vindex gnus-mark-article-hook +@findex gnus-summary-mark-unread-as-read +@findex gnus-summary-mark-read-and-unread-as-read +@findex gnus-unread-mark +This hook is called whenever an article is selected. It is intended to +be used for marking articles as read. The default value is +@code{gnus-summary-mark-read-and-unread-as-read}, and will change the +mark of almost any article you read to @code{gnus-read-mark}. The only +articles not affected by this function are ticked, dormant, and +expirable articles. If you'd instead like to just have unread articles +marked as read, you can use @code{gnus-summary-mark-unread-as-read} +instead. It will leave marks like @code{gnus-low-score-mark}, +@code{gnus-del-mark} (and so on) alone. + +@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 non-@code{nil} and the rest of +the article consists only of citations and signature, then it will be +skipped; the next article will be shown instead. You can customize +what is considered uninteresting with +@code{gnus-article-boring-faces}. You can manually view the article's +pages, no matter how boring, using @kbd{C-M-v}. + +@item DEL +@kindex DEL (Summary) +@findex gnus-summary-prev-page +Scroll the current article back one page (@code{gnus-summary-prev-page}). + +@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, show a completely ``raw'' article, just the way it +came from the server. If given a prefix twice (i.e., @kbd{C-u C-u +g'}), fetch the current article, but don't run any of the article +treatment functions. + +@cindex charset, view article with different charset +If given a numerical prefix, you can do semi-manual charset stuff. +@kbd{C-u 0 g cn-gb-2312 RET} will decode the message as if it were +encoded in the @code{cn-gb-2312} charset. If you have + +@lisp +(setq gnus-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, but only uses the headers from the +first article to determine the recipients. + +@item S L +@kindex S L (Summary) +@findex gnus-summary-reply-to-list-with-original +When replying to a message from a mailing list, send a reply to that +message to the mailing list, and include the original message +(@code{gnus-summary-reply-to-list-with-original}). + +@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 +@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 D e +@kindex S D e (Summary) +@findex gnus-summary-resend-message-edit + +Like the previous command, but will allow you to edit the message as +if it were a new message before resending. + +@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-post-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 @file{*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 non-@code{nil}, +@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 + +When delaying an article with @kbd{C-c C-j}, Message mode will +automatically add a @code{"Date"} header with the current time. In +many cases you probably want the @code{"Date"} header to reflect the +time the message is sent instead. To do this, you have to delete +@code{Date} from @code{message-draft-headers}. + + +@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. + +@ifinfo +There's a plethora of commands for manipulating these marks. +@end ifinfo + +@menu +* Unread Articles:: Marks for unread articles. +* Read Articles:: Marks for read articles. +* Other Marks:: Marks that do not affect readedness. +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. +@end menu + + +@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 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-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}). + +@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 non-@code{nil}, point will move to +the next/previous unread article. If @code{nil}, point will just move +one line up or down. As a special case, if this variable is +@code{never}, all the marking commands as well as other commands (like +@kbd{SPACE}) will move to the next article, whether it is unread or not. +The default is @code{t}. + + +@node Generic Marking Commands +@subsection Generic Marking Commands + +Some people would like the command that ticks an article (@kbd{!}) to +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 +articles 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-all}). + +@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. + +Limiting commands work on subsets of the articles already fetched from +the servers. These commands don't query the server for additional +articles. + +@table @kbd + +@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 / R +@kindex / R (Summary) +@findex gnus-summary-limit-to-recipient +Limit the summary buffer to articles that match some recipient +(@code{gnus-summary-limit-to-recipient}). If given a prefix, exclude +matching articles. + +@item / A +@kindex / A (Summary) +@findex gnus-summary-limit-to-address +Limit the summary buffer to articles in which contents of From, To or Cc +header match a given address (@code{gnus-summary-limit-to-address}). If +given a prefix, exclude matching articles. + +@item / S +@kindex / S (Summary) +@findex gnus-summary-limit-to-singletons +Limit the summary buffer to articles that aren't part of any displayed +threads (@code{gnus-summary-limit-to-singletons}). If given a prefix, +limit to articles that are part of displayed threads. + +@item / 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 +With prefix @samp{n}, limit the summary buffer to the next @samp{n} +articles. If not given a prefix, use the process marked articles +instead. (@code{gnus-summary-limit-to-articles}). + +@item / 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 / r +@kindex / r (Summary) +@findex gnus-summary-limit-to-replied +Limit the summary buffer to replied articles +(@code{gnus-summary-limit-to-replied}). If given a prefix, exclude +replied articles. + +@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 limit@* +(@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 / b +@kindex / b (Summary) +@findex gnus-summary-limit-to-bodies +Limit the summary buffer to articles that have bodies that match a +certain regexp (@code{gnus-summary-limit-to-bodies}). If given a +prefix, reverse the limit. This command is quite slow since it +requires selecting each article to find the matches. + +@item / h +@kindex / h (Summary) +@findex gnus-summary-limit-to-headers +Like the previous command, only limit to headers instead +(@code{gnus-summary-limit-to-headers}). + +@end table + + +The following commands aren't limiting commands, but use the @kbd{/} +prefix as well. + +@table @kbd +@item / N +@kindex / N (Summary) +@findex gnus-summary-insert-new-articles +Insert all new articles in the summary buffer. It scans for new emails +if @var{back-end}@code{-get-new-mail} is non-@code{nil}. + +@item / 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 over@dots{} 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 non-@code{nil}, Gnus will gather all loose subtrees into one big tree +and create a dummy root at the top. (Wait a minute. Root at the top? +Yup.) Loose subtrees occur when the real root has expired, or you've +read or killed the root in a previous session. + +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 +@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 non-@code{nil}, this variable overrides +@code{gnus-summary-gather-subject-limit}. This variable should be a +list of functions to apply to the @code{Subject} string iteratively to +arrive at the simplified version of the string. + +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 process.@* +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 non-@code{nil}, Gnus will attempt to build old threads by fetching +more old headers---headers to articles marked as read. If you would +like to display as few summary lines as possible, but still connect as +many loose threads as possible, you should set this variable to +@code{some} or a number. If you set it to a number, no more than that +number of extra old headers will be fetched. In either case, fetching +old headers only works if the back end you are using carries overview +files---this would normally be @code{nntp}, @code{nnspool}, +@code{nnml}, and @code{nnmaildir}. Also remember that if the root of +the thread has been expired by the server, there's not much Gnus can +do about that. + +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}). + +The server has to support @acronym{NOV} for any of this to work. + +@cindex Gmane, gnus-fetch-old-headers +This feature can seriously impact performance it ignores all locally +cached header entries. Setting it to @code{t} for groups for a server +that doesn't expire articles (such as news.gmane.org), leads to very +slow summary generation. + +@item 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. + +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 non-@code{nil}, all threads will be hidden when the summary buffer is +generated. + +This can also be a predicate specifier (@pxref{Predicate Specifiers}). +Available predicates are @code{gnus-article-unread-p} and +@code{gnus-article-unseen-p}. + +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 non-@code{nil}, 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 non-@code{nil}, which is the default, the subject +change is ignored. If it is @code{nil}, a change in the subject will +result in a new thread. + +@item 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 non-@code{nil}, this function will be called to allow alteration of +article header structures. The function is called with one parameter, +the article header vector, which it may alter in any way. For instance, +if you have a mail-to-news gateway which alters the @code{Message-ID}s +in systematic ways (by adding prefixes and such), you can use this +variable to un-scramble the @code{Message-ID}s so that they are more +meaningful. Here's one example: + +@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 any@* +(@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}). + +@item T M-^ +@kindex T M-^ (Summary) +@findex gnus-summary-reparent-children +Make the current article the parent of the marked articles +(@code{gnus-summary-reparent-children}). + +@end table + +The following commands are thread movement commands. They all +understand the numeric prefix. + +@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 non-@code{nil} (which it is by default), subjects will be ignored +when doing thread commands. If this variable is @code{nil}, articles in +the same thread with different subjects will not be included in the +operation in question. If this variable is @code{fuzzy}, only articles +that have subjects fuzzily equal will be included (@pxref{Fuzzy +Matching}). + + +@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-recipient +@findex gnus-thread-sort-by-number +@findex gnus-thread-sort-by-random +@vindex gnus-thread-sort-functions +@findex gnus-thread-sort-by-most-recent-number +@findex gnus-thread-sort-by-most-recent-date +If you are using a threaded summary display, you can sort the threads by +setting @code{gnus-thread-sort-functions}, which can be either a single +function, a list of functions, or a list containing functions and +@code{(not some-function)} elements. + +By default, sorting is done on article numbers. Ready-made sorting +predicate functions include @code{gnus-thread-sort-by-number}, +@code{gnus-thread-sort-by-author}, @code{gnus-thread-sort-by-recipient}, +@code{gnus-thread-sort-by-subject}, +@code{gnus-thread-sort-by-date}, +@code{gnus-thread-sort-by-score}, +@code{gnus-thread-sort-by-most-recent-number}, +@code{gnus-thread-sort-by-most-recent-date}, +@code{gnus-thread-sort-by-random} and +@code{gnus-thread-sort-by-total-score}. + +Each function takes two threads and returns non-@code{nil} if the first +thread should be sorted before the other. Note that sorting really is +normally done by looking only at the roots of each thread. Exceptions +to this rule are @code{gnus-thread-sort-by-most-recent-number} and +@code{gnus-thread-sort-by-most-recent-date}. + +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 + '((not gnus-thread-sort-by-number) + gnus-thread-sort-by-score)) +@end lisp + +By default, threads including their subthreads are sorted according to +the value of @code{gnus-thread-sort-functions}. By customizing +@code{gnus-subthread-sort-functions} you can define a custom sorting +order for subthreads. This allows for example to sort threads from +high score to low score in the summary buffer, but to have subthreads +still sorted chronologically from old to new without taking their +score into account. + +@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-most-recent-date +@findex gnus-article-sort-by-score +@findex gnus-article-sort-by-subject +@findex gnus-article-sort-by-author +@findex gnus-article-sort-by-random +@findex gnus-article-sort-by-number +@findex gnus-article-sort-by-most-recent-number +If you are using an unthreaded display for some strange reason or +other, you have to fiddle with the @code{gnus-article-sort-functions} +variable. It is very similar to the +@code{gnus-thread-sort-functions}, except that it uses slightly +different functions for article comparison. Available sorting +predicate functions are @code{gnus-article-sort-by-number}, +@code{gnus-article-sort-by-author}, +@code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date}, +@code{gnus-article-sort-by-random}, and +@code{gnus-article-sort-by-score}. + +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 + +You can define group specific sorting via @code{gnus-parameters}, +@xref{Group Parameters}. + + +@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 thing@dots{} 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-unread-p +There are probably some articles that you don't want to pre-fetch---read +articles, for instance. The @code{gnus-async-prefetch-article-p} +variable controls whether an article is to be pre-fetched. This +function should return non-@code{nil} when the article in question is +to be pre-fetched. The default is @code{gnus-async-unread-p}, which +returns @code{nil} on read articles. The function is called with an +article data structure as the only parameter. + +If, for instance, you wish to pre-fetch only unread articles shorter +than 100 lines, you could say something like: + +@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-async-post-fetch-function +@findex gnus-html-prefetch-images +After an article has been prefetched, this +@code{gnus-async-post-fetch-function} will be called. The buffer will +be narrowed to the region of the article that was fetched. A useful +value would be @code{gnus-html-prefetch-images}, which will prefetch +and store images referenced in the article, so that you don't have to +wait for them to be fetched when you read the article. This is useful +for @acronym{HTML} messages that have external images. + +@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 non-@code{nil}, 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 Sticky Articles +@section Sticky Articles +@cindex sticky articles + +When you select an article the current article buffer will be reused +according to the value of the variable +@code{gnus-single-article-buffer}. If its value is non-@code{nil} (the +default) all articles reuse the same article buffer. Else each group +has its own article buffer. + +This implies that it's not possible to have more than one article buffer +in a group at a time. But sometimes you might want to display all the +latest emails from your mother, your father, your aunt, your uncle and +your 17 cousins to coordinate the next Christmas party. + +That's where sticky articles come in handy. A sticky article buffer +basically is a normal article buffer, but it won't be reused when you +select another article. You can make an article sticky with: + +@table @kbd +@item A S +@kindex A S (Summary) +@findex gnus-sticky-article +Make the current article sticky. If a prefix arg is given, ask for a +name for this sticky article buffer. +@end table + +To close a sticky article buffer you can use these commands: + +@table @kbd +@item q +@kindex q (Article) +@findex bury-buffer +Puts this sticky article buffer at the end of the list of all buffers. + +@item k +@kindex k (Article) +@findex gnus-kill-sticky-article-buffer +Kills this sticky article buffer. +@end table + +To kill all sticky article buffers you can use: + +@defun gnus-kill-sticky-article-buffers ARG +Kill all sticky article buffers. +If a prefix ARG is given, ask for confirmation. +@end defun + +@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 non-@code{nil} and is not a number, Gnus will store +@emph{all} read articles, which means that your Emacs will grow without +bound before exploding and taking your machine down with you. I put +that in there just to keep y'all on your toes. + +The default value is 20. + + +@node 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 non-@code{nil}, 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 a Unix mail box (mbox) file +(@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}). This is mbox since Emacs 23, +Babyl in older versions. + +@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 +@vindex gnus-summary-pipe-output-default-command +Save the current article in a pipe. Uhm, like, what I mean is---Pipe +the current article to a process (@code{gnus-summary-pipe-output}). +If given a symbolic prefix (@pxref{Symbolic Prefixes}), include the +complete headers in the piped output. The symbolic prefix @code{r} is +special; it lets this command pipe a raw article including all headers. +The @code{gnus-summary-pipe-output-default-command} variable can be set +to a string containing the default command and options (default +@code{nil}). + +@item 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 eight 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, that used by the Rmail package. Since Emacs +23, Rmail uses standard mbox format. Before this, it used the +@dfn{Babyl} format. Accordingly, this command writes mbox format since +Emacs 23, unless appending to an existing Babyl file. In older versions +of Emacs, it always uses Babyl format. Uses the function in the +@code{gnus-rmail-save-name} variable to get a file name to save the +article in. The default is @code{gnus-plain-save-name}. + +@item 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-write-body-to-file +@findex gnus-summary-write-body-to-file +Write the article body straight to an ordinary file. The file is +overwritten if it exists. Uses the function in the +@code{gnus-file-save-name} variable to get a file name to save the +article in. The default is @code{gnus-numeric-save-name}. + +@item gnus-summary-save-in-folder +@findex gnus-summary-save-in-folder +@findex gnus-folder-save-name +@findex gnus-Folder-save-name +@vindex gnus-folder-save-name +@cindex rcvstore +@cindex MH folders +Save the article to an MH folder using @code{rcvstore} from the MH +library. Uses the function in the @code{gnus-folder-save-name} variable +to get a file name to save the article in. The default is +@code{gnus-folder-save-name}, but you can also use +@code{gnus-Folder-save-name}, which creates capitalized names. + +@item gnus-summary-save-in-vm +@findex gnus-summary-save-in-vm +Save the article in a VM folder. You have to have the VM mail +reader to use this setting. + +@item gnus-summary-save-in-pipe +@findex gnus-summary-save-in-pipe +Pipe the article to a shell command. This function takes optional two +arguments COMMAND and RAW@. Valid values for COMMAND include: + +@itemize @bullet +@item a string@* +The executable command name and possibly arguments. +@item @code{nil}@* +You will be prompted for the command in the minibuffer. +@item the symbol @code{default}@* +It will be replaced with the command which the variable +@code{gnus-summary-pipe-output-default-command} holds or the command +last used for saving. +@end itemize + +Non-@code{nil} value for RAW overrides @code{:decode} and +@code{:headers} properties (see below) and the raw article including all +headers will be piped. +@end table + +The symbol of each function may have the following properties: + +@table @code +@item :decode +The value non-@code{nil} means save decoded articles. This is +meaningful only with @code{gnus-summary-save-in-file}, +@code{gnus-summary-save-body-in-file}, +@code{gnus-summary-write-to-file}, +@code{gnus-summary-write-body-to-file}, and +@code{gnus-summary-save-in-pipe}. + +@item :function +The value specifies an alternative function which appends, not +overwrites, articles to a file. This implies that when saving many +articles at a time, @code{gnus-prompt-before-saving} is bound to +@code{t} and all articles are saved in a single file. This is +meaningful only with @code{gnus-summary-write-to-file} and +@code{gnus-summary-write-body-to-file}. + +@item :headers +The value specifies the symbol of a variable of which the value +specifies headers to be saved. If it is omitted, +@code{gnus-save-all-headers} and @code{gnus-saved-headers} control what +headers should be saved. +@end table + +@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 non-@code{nil} result, +the @dfn{file} will be used as a default prompt. In addition, the +result of the operation itself will be used if the function or form +called returns a string or a list of strings. + +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} groups---@kbd{G D} in the group buffer, and +the top level directory as the argument (@file{~/News/}). Then just walk +around to the groups/directories with @code{nneething}. + + +@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. + +@item X Y +@kindex X Y (Summary) +@findex gnus-uu-decode-yenc +yEnc-decode the current series and save it (@code{gnus-uu-decode-yenc}). +@end table + + +@node Decoding Variables +@subsection Decoding Variables + +Adjective, not verb. + +@menu +* Rule Variables:: Variables that say how a file is to be viewed. +* Other Decode Variables:: Other decode variables. +* Uuencoding and Posting:: Variables for customizing uuencoding. +@end menu + + +@node Rule Variables +@subsubsection Rule Variables +@cindex rule variables + +Gnus uses @dfn{rule variables} to decide how to view a file. All these +variables are of the form + +@lisp + (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 +kludgy. + +@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 +Non-@code{nil} 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 +Non-@code{nil} 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 +Non-@code{nil} 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 +Non-@code{nil} means that @code{gnus-uu} will ignore the default archive +unpacking commands. + +@item gnus-uu-kill-carriage-return +@vindex gnus-uu-kill-carriage-return +Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns +from articles. + +@item gnus-uu-unmark-articles-not-decoded +@vindex gnus-uu-unmark-articles-not-decoded +Non-@code{nil} means that @code{gnus-uu} will mark unsuccessfully +decoded articles as unread. + +@item gnus-uu-correct-stripped-uucode +@vindex gnus-uu-correct-stripped-uucode +Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix +uuencoded files that have had trailing spaces deleted. + +@item gnus-uu-pre-uudecode-hook +@vindex gnus-uu-pre-uudecode-hook +Hook run before sending a message to @code{uudecode}. + +@item gnus-uu-view-with-metamail +@vindex gnus-uu-view-with-metamail +@cindex metamail +Non-@code{nil} means that @code{gnus-uu} will ignore the viewing +commands defined by the rule variables and just fudge a @acronym{MIME} +content type based on the file name. The result will be fed to +@code{metamail} for viewing. + +@item gnus-uu-save-in-digest +@vindex gnus-uu-save-in-digest +Non-@code{nil} means that @code{gnus-uu}, when asked to save without +decoding, will save in digests. If this variable is @code{nil}, +@code{gnus-uu} will just save everything in a file without any +embellishments. The digesting almost conforms to RFC 1153---no easy way +to specify any meaningful volume and issue numbers were found, so I +simply dropped them. + +@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 +Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode +before you compose the article. If this variable is @code{t}, you can +either include an encoded file with @kbd{C-c C-i} or have one included +for you when you post the article. + +@item 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 +Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a +thread. This may not be smart, as no other decoder I have seen is able +to follow threads when collecting uuencoded articles. (Well, I have +seen one package that does that---@code{gnus-uu}, but somehow, I don't +think that counts@dots{}) Default is @code{nil}. + +@item gnus-uu-post-separate-description +@vindex gnus-uu-post-separate-description +Non-@code{nil} means that the description will be posted in a separate +article. The first article will typically be numbered (0/x). If this +variable is @code{nil}, the description the user enters will be included +at the beginning of the first article, which will be numbered (1/x). +Default is @code{t}. + +@end table + + +@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 non-@code{nil}, one +pseudo-article will be created for each file to be viewed. If +@code{nil}, all files that use the same viewing command will be given as +a list of parameters to that command. + +@vindex gnus-insert-pseudo-articles +If @code{gnus-insert-pseudo-articles} is non-@code{nil}, insert +pseudo-articles when decoding. It is @code{t} by default. + +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, Gravatars, 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 in bytes is 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. + +@item gnus-cite-ignore-quoted-from +@vindex gnus-cite-ignore-quoted-from +If non-@code{nil}, no citation highlighting will be performed on lines +beginning with @samp{>From }. Those lines may have been quoted by MTAs +in order not to mix up with the envelope From line. The default value +is @code{t}. + +@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. + +For instance: + +@lisp +(setq gnus-article-banner-alist + ((googleGroups . + "^\n*--~--~---------\\(.+\n\\)+"))) +@end lisp + +Regardless of a group, you can hide things like advertisements only when +the sender of an article has a certain mail address specified in +@code{gnus-article-address-banner-alist}. + +@table @code + +@item gnus-article-address-banner-alist +@vindex gnus-article-address-banner-alist +Alist of mail addresses and banners. Each element has the form +@code{(@var{address} . @var{banner})}, where @var{address} is a regexp +matching a mail address in the From header, @var{banner} is one of a +symbol @code{signature}, an item in @code{gnus-article-banner-alist}, +a regexp and @code{nil}. If @var{address} matches author's mail +address, it will remove things like advertisements. For example, if a +sender has the mail address @samp{hail@@yoo-hoo.co.jp} and there is a +banner something like @samp{Do You Yoo-hoo!?} in all articles he +sends, you can use the following element to remove them: + +@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 i +@kindex W i (Summary) +@findex gnus-summary-idna-message +Decode IDNA encoded domain names in the current articles. IDNA +encoded domain names looks like @samp{xn--bar}. If a string remain +unencoded after running invoking this, it is likely an invalid IDNA +string (@samp{xn--bar} is invalid). You must have GNU Libidn +(@url{http://www.gnu.org/software/libidn/}) installed for this command +to work. + +@item W 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 U +@kindex W U (Summary) +@findex gnus-article-treat-non-ascii +@cindex Unicode +@cindex Non-@acronym{ASCII} +Translate many non-@acronym{ASCII} characters into their +@acronym{ASCII} equivalents (@code{gnus-article-treat-non-ascii}). +This is mostly useful if you're on a terminal that has a limited font +and doesn't show accented characters, ``advanced'' punctuation, and the +like. For instance, @samp{»} is translated into @samp{>>}, and so on. + +@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 line.@* +(@code{gnus-article-outlook-repair-attribution}). + +@item W Y c +@kindex W Y c (Summary) +@findex gnus-article-outlook-rearrange-citation +Repair broken citations by rearranging the text. +(@code{gnus-article-outlook-rearrange-citation}). + +@item W w +@kindex W w (Summary) +@findex gnus-article-fill-cited-article +Do word wrap (@code{gnus-article-fill-cited-article}). + +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 non-@acronym{ASCII} (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 +non-@acronym{ASCII} (i.e., 8-bit) articles. Note that this is +usually done automatically by Gnus if the message in question has a +@code{Content-Transfer-Encoding} header that says that this encoding +has been done. If a prefix is given, a charset will be asked for. + +@item W Z +@kindex W Z (Summary) +@findex gnus-article-decode-HZ +Treat HZ or HZP (@code{gnus-article-decode-HZ}). HZ (or HZP) is one +common encoding employed when sending Chinese articles. It typically +makes strings look like @samp{~@{<:Ky2;S@{#,NpJ)l6HK!#~@}}. + +@item W A +@kindex W A (Summary) +@findex gnus-article-treat-ansi-sequences +@cindex @acronym{ANSI} control sequences +Translate @acronym{ANSI} SGR control sequences into overlays or +extents (@code{gnus-article-treat-ansi-sequences}). @acronym{ANSI} +sequences are used in some Chinese hierarchies for highlighting. + +@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. If it is a number, +the charset defined in @code{gnus-summary-show-article-charset-alist} +(@pxref{Paging the Article}) will be used. + +The default is to use the function specified by +@code{mm-text-html-renderer} (@pxref{Display Customization, ,Display +Customization, emacs-mime, The Emacs MIME Manual}) to convert the +@acronym{HTML}. Pre-defined functions you can use include: + +@table @code +@item shr +Use Gnus simple html renderer. + +@item gnus-w3m +Use Gnus rendered based on w3m. + +@item w3m +Use @uref{http://emacs-w3m.namazu.org/, emacs-w3m}. + +@item w3m-standalone +Use @uref{http://w3m.sourceforge.net/, 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 +message.@footnote{@acronym{PGP} keys for many hierarchies are +available at @uref{ftp://ftp.isc.org/pub/pgpcontrol/README.html}} + +@item W s +@kindex W s (Summary) +@findex gnus-summary-force-verify-and-decrypt +Verify a signed (@acronym{PGP}, @acronym{PGP/MIME} or +@acronym{S/MIME}) message +(@code{gnus-summary-force-verify-and-decrypt}). @xref{Security}. + +@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{]*\\)>}. 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 non-@code{nil}, +this is considered a match. This is useful if you want extra sifting to +avoid false matches. Often variables named +@code{gnus-button-@var{*}-level} are used here, @xref{Article Button +Levels}, but any other form may be used too. + +@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 +("]*\\)>" 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 gnus-button-@var{*}-level +@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 to do. If it is a function, this +function will be called with the string as its only argument. The +function must return @code{mid}, @code{mail}, @code{invalid} or +@code{ask}. The default value is the function +@code{gnus-button-mid-or-mail-heuristic}. + +@item 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 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 @code{gnus-button-@var{*}-level}, +the more buttons will appear. If the level is zero, no corresponding +buttons are displayed. With the default value (which is 5) you should +already see quite a lot of buttons. With higher levels, you will see +more buttons, but you may also get more false positives. To avoid them, +you can set the variables @code{gnus-button-@var{*}-level} local to +specific groups (@pxref{Group Parameters}). Here's an example for the +variable @code{gnus-parameters}: + +@lisp +;; @r{increase @code{gnus-button-*-level} in some groups:} +(setq gnus-parameters + '(("\\<\\(emacs\\|gnus\\)\\>" (gnus-button-emacs-level 10)) + ("\\" (gnus-button-man-level 10)) + ("\\" (gnus-button-tex-level 10)))) +@end lisp + +@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}. + +@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 +Date: 6 weeks, 4 days, 1 hour, 3 minutes, 8 seconds ago +@end example + +To make this line updated continually, set the +@code{gnus-article-update-date-headers} variable to the frequency in +seconds (the default is @code{nil}). + +@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 +@cindex gravatars + +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}). + +Gravatars reside on-line and are fetched from +@uref{http://www.gravatar.com/} (@pxref{Gravatars}). + +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 g +@kindex W D g (Summary) +@findex gnus-treat-from-gravatar +Gravatarify the @code{From} header (@code{gnus-treat-from-gravatar}). + +@item W D h +@kindex W D h (Summary) +@findex gnus-treat-mail-gravatar +Gravatarify all mail headers (i.e., @code{Cc}, @code{To}) +(@code{gnus-treat-from-gravatar}). + +@item W D D +@kindex W D D (Summary) +@findex gnus-article-remove-images +Remove all images from the article buffer +(@code{gnus-article-remove-images}). + +@item W D W +@kindex W D W (Summary) +@findex gnus-html-show-images +If you're reading an @acronym{HTML} article rendered with +@code{gnus-article-html}, then you can insert any blocked images in +the buffer with this command. +(@code{gnus-html-show-images}). + +@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 K v} means ``view the third @acronym{MIME} part''. + +@table @kbd +@item b +@itemx K v +@kindex b (Summary) +@kindex K v (Summary) +View the @acronym{MIME} part. + +@item K o +@kindex K o (Summary) +Save the @acronym{MIME} part. + +@item K O +@kindex K O (Summary) +Prompt for a file name, then save the @acronym{MIME} part and strip it +from the article. The stripped @acronym{MIME} object will be referred +via the message/external-body @acronym{MIME} type. + +@item K r +@kindex K r (Summary) +Replace the @acronym{MIME} part with an external body. + +@item K d +@kindex K d (Summary) +Delete the @acronym{MIME} part and add some information about the +removed part. + +@item K c +@kindex K c (Summary) +Copy the @acronym{MIME} part. + +@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 H +@kindex K H (Summary) +@findex gnus-article-browse-html-article +View @samp{text/html} parts of the current article with a WWW browser. +Inline images embedded in a message using the @code{cid} scheme, as they +are generally considered to be safe, will be processed properly. The +message header is added to the beginning of every @acronym{HTML} part +unless the prefix argument is given. + +Warning: Spammers use links to images (using the @code{http} scheme) in +@acronym{HTML} articles to verify whether you have read the message. As +this command passes the @acronym{HTML} content to the browser without +eliminating these ``web bugs'' you should only use it for mails from +trusted senders. + +If you always want to display @acronym{HTML} parts in the browser, set +@code{mm-text-html-renderer} to @code{nil}. + +This command creates temporary files to pass @acronym{HTML} contents +including images if any to the browser, and deletes them when exiting +the group (if you want). + +@item K b +@kindex K b (Summary) +Make all the @acronym{MIME} parts have buttons in front of them. This is +mostly useful if you wish to save (or perform other actions) on inlined +parts. + +@item W M h +@kindex W M h (Summary) +@findex gnus-mime-buttonize-attachments-in-header +@vindex gnus-mime-display-attachment-buttons-in-header +Display @acronym{MIME} part buttons in the end of the header of an +article (@code{gnus-mime-buttonize-attachments-in-header}). This +command toggles the display. Note that buttons to be added to the +header are only the ones that aren't inlined in the body. If you want +those buttons always to be displayed, set +@code{gnus-mime-display-attachment-buttons-in-header} to non-@code{nil}. +The default is @code{t}. To change the appearance of buttons, customize +@code{gnus-header-face-alist}. + +@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 +If non-@code{nil}, Gnus won't require the @samp{MIME-Version} header +before interpreting the message as a @acronym{MIME} message. This helps +when reading messages from certain broken mail user agents. The +default is @code{t}. + +@item gnus-article-emulate-mime +@vindex gnus-article-emulate-mime +@cindex uuencode +@cindex yEnc +There are other, non-@acronym{MIME} encoding methods used. The most common +is @samp{uuencode}, but yEncode is also getting to be popular. If +this variable is non-@code{nil}, Gnus will look in message bodies to +see if it finds these encodings, and if so, it'll run them through the +Gnus @acronym{MIME} machinery. The default is @code{t}. Only +single-part yEnc encoded attachments can be decoded. There's no support +for encoding in Gnus. + +@item gnus-unbuttonized-mime-types +@vindex gnus-unbuttonized-mime-types +This is a list of regexps. @acronym{MIME} types that match a regexp from +this list won't have @acronym{MIME} buttons inserted unless they aren't +displayed or this variable is overridden by +@code{gnus-buttonized-mime-types}. The default value is +@code{(".*/.*")}. This variable is only used when +@code{gnus-inhibit-mime-unbuttonizing} is @code{nil}. + +@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}. + +E.g., to see 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. + +You could also add @code{"multipart/alternative"} to this list to +display radio buttons that allow you to choose one of two media types +those mails include. See also @code{mm-discouraged-alternatives} +(@pxref{Display Customization, ,Display Customization, emacs-mime, The +Emacs MIME Manual}). + +@item gnus-inhibit-mime-unbuttonizing +@vindex gnus-inhibit-mime-unbuttonizing +If this is non-@code{nil}, then all @acronym{MIME} parts get buttons. The +default value is @code{nil}. + +@item gnus-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 gnus-mime-display-multipart-alternative-as-mixed +@item gnus-mime-display-multipart-alternative-as-mixed +Display "multipart/alternative" parts as "multipart/mixed". + +@vindex gnus-mime-display-multipart-related-as-mixed +@item gnus-mime-display-multipart-related-as-mixed +Display "multipart/related" parts as "multipart/mixed". + +If displaying @samp{text/html} is discouraged, see +@code{mm-discouraged-alternatives}, images or other material inside a +"multipart/related" part might be overlooked when this variable is +@code{nil}. @ref{Display Customization, Display Customization, , +emacs-mime, Emacs-Mime Manual}. + +@vindex gnus-mime-display-multipart-as-mixed +@item gnus-mime-display-multipart-as-mixed +Display "multipart" parts as "multipart/mixed". If @code{t}, it +overrides @code{nil} values of +@code{gnus-mime-display-multipart-alternative-as-mixed} and +@code{gnus-mime-display-multipart-related-as-mixed}. + +@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. + +Ready-made functions include@* +@code{mm-file-name-delete-whitespace}, +@code{mm-file-name-trim-whitespace}, +@code{mm-file-name-collapse-whitespace}, and +@code{mm-file-name-replace-whitespace}. The later uses the value of +the variable @code{mm-file-name-replace-whitespace} to replace each +whitespace character in a file name with that string; default value +is @code{"_"} (a single underscore). +@findex mm-file-name-delete-whitespace +@findex mm-file-name-trim-whitespace +@findex mm-file-name-collapse-whitespace +@findex mm-file-name-replace-whitespace +@vindex mm-file-name-replace-whitespace + +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 +to your @file{~/.gnus.el} file. + +@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}. + +@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 +quoted-printable header encoding. + +This variable is an alist of regexps and permitted unencoded charsets +for posting. Each element of the alist has the form @code{(}@var{test +header body-list}@code{)}, where: + +@table @var +@item test +is either a regular expression matching the newsgroup header or a +variable to query, +@item header +is the charset which may be left unencoded in the header (@code{nil} +means encode all charsets), +@item body-list +is a list of charsets which may be encoded using 8bit content-transfer +encoding in the body, or one of the special values @code{nil} (always +encode using quoted-printable) or @code{t} (always use 8bit). +@end table + +@cindex Russian +@cindex koi8-r +@cindex koi8-u +@cindex iso-8859-5 +@cindex coding system aliases +@cindex preferred charset + +@xref{Encoding Customization, , Encoding Customization, emacs-mime, +The Emacs MIME Manual}, for additional variables that control which +MIME charsets are used when sending messages. + +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}). + +@item A C +@vindex gnus-fetch-partial-articles +@findex gnus-summary-show-complete-article +If @code{-fetch-partial-articles} is non-@code{nil}, Gnus will +fetch partial articles, if the backend it fetches them from supports +it. Currently only @code{nnimap} does. If you're looking at a +partial article, and want to see the complete article instead, then +the @kbd{A C} command (@code{gnus-summary-show-complete-article}) will +do so. + +@end table + + +@node 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-m C-n +@kindex C-c C-s C-n (Summary) +@findex gnus-summary-sort-by-most-recent-number +Sort by most recent article number +(@code{gnus-summary-sort-by-most-recent-number}). + +@item 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-t +@kindex C-c C-s C-t (Summary) +@findex gnus-summary-sort-by-recipient +Sort by recipient (@code{gnus-summary-sort-by-recipient}). + +@item 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-m C-d +@kindex C-c C-s C-m C-d (Summary) +@findex gnus-summary-sort-by-most-recent-date +Sort by most recent date (@code{gnus-summary-sort-by-most-recent-date}). + +@item 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 +toggle whether to use threading, type @kbd{T T} (@pxref{Thread +Commands}). + +If a prefix argument if given, the sort order is reversed. + + +@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 +summary buffer, point will just move to this article. + +If given a positive numerical prefix, fetch that many articles back into +the ancestry. If given a negative numerical prefix, fetch just that +ancestor. So if you say @kbd{3 ^}, Gnus will fetch the parent, the +grandparent and the great-grandparent of the current article. If you say +@kbd{-3 ^}, Gnus will only fetch the great-grandparent 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) +@findex gnus-summary-refer-thread +@kindex A T (Summary) +Display the full thread where the current article appears +(@code{gnus-summary-refer-thread}). This command has to fetch all the +headers in the current group to work, so it usually takes a while. If +you do it often, you may consider setting @code{gnus-fetch-old-headers} +to @code{invisible} (@pxref{Filling In Threads}). This won't have any +visible effects normally, but it'll make this command work a whole lot +faster. Of course, it'll make group entry somewhat slow. + +@vindex gnus-refer-thread-limit +The @code{gnus-refer-thread-limit} variable says how many old (i.e., +articles before the first displayed in the current group) headers to +fetch when doing this command. The default is 200. If @code{t}, all +the available headers will be fetched. This variable can be overridden +by giving the @kbd{A T} command a numerical prefix. + +@item M-^ (Summary) +@findex gnus-summary-refer-article +@kindex M-^ (Summary) +@cindex Message-ID +@cindex fetching by Message-ID +You can also ask Gnus for an arbitrary article, no matter what group it +belongs to. @kbd{M-^} (@code{gnus-summary-refer-article}) will ask you +for a @code{Message-ID}, which is one of those long, hard-to-read +thingies that look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}. +You have to get it all exactly right. No fuzzy searches, I'm afraid. + +Gnus looks for the @code{Message-ID} in the headers that have already +been fetched, but also tries all the select methods specified by +@code{gnus-refer-article-method} if it is not found. +@end table + +@vindex gnus-refer-article-method +If the group you are reading is located on a back end that does not +support fetching by @code{Message-ID} very well (like @code{nnspool}), +you can set @code{gnus-refer-article-method} to an @acronym{NNTP} method. It +would, perhaps, be best if the @acronym{NNTP} server you consult is the one +updating the spool you are reading from, but that's not really +necessary. + +It can also be a list of select methods, as well as the special symbol +@code{current}, which means to use the current select method. If it +is a list, Gnus will try all the methods in the list until it finds a +match. + +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. @code{nnmh} does not support this at all. + +Fortunately, the special @code{nnregistry} back end is able to locate +articles in any groups, regardless of their back end (@pxref{Registry +Article Refer Method, fetching by @code{Message-ID} using the +registry}). + +@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 +this---@code{gnus-pick-mode}. This basically means that a few process +mark commands become one-keystroke commands to allow easy marking, and +it provides one additional command for switching to the summary buffer. + +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 non-@code{nil}, 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 non-@code{nil}, 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{((?[ . ?]) (?( . ?)) (?@{ . ?@}) (?< . ?>))}. + +@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 non-@code{nil}, Gnus will try to keep the tree +buffer as small as possible to allow more room for the other Gnus +windows. If this variable is a number, the tree buffer will never be +higher than that number. The default is @code{t}. Note that if you +have several windows displayed side-by-side in a frame and the tree +buffer is one of these, minimizing the tree window will also resize all +other windows displayed next to it. + +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 +@{***@}-(***)-[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 +@{***@} + |--------------------------\-----\-----\ +(***) [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 +@cindex expiring mail +Run all expirable articles in the current group through the expiry +process (@code{gnus-summary-expire-articles}). That is, delete all +expirable articles in the group that have been around for a while. +(@pxref{Expiring Mail}). + +@item B C-M-e +@kindex B C-M-e (Summary) +@findex gnus-summary-expire-articles-now +@cindex expiring mail +Delete all the expirable articles in the group +(@code{gnus-summary-expire-articles-now}). This means that @strong{all} +articles eligible for expiry in the current group will +disappear forever into that big @file{/dev/null} in the sky. + +@item B DEL +@kindex B DEL (Summary) +@cindex deleting mail +@findex gnus-summary-delete-article +@c @icon{gnus-summary-mail-delete} +Delete the mail article. This is ``delete'' as in ``delete it from your +disk forever and ever, never to return again.'' Use with caution. +(@code{gnus-summary-delete-article}). + +@item B m +@kindex B m (Summary) +@cindex move mail +@findex gnus-summary-move-article +@vindex gnus-preserve-marks +Move the article from one mail group to another +(@code{gnus-summary-move-article}). Marks will be preserved if +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). + +@item B c +@kindex B c (Summary) +@cindex copy mail +@findex gnus-summary-copy-article +@c @icon{gnus-summary-mail-copy} +Copy the article from one group (mail group or not) to a mail group +(@code{gnus-summary-copy-article}). Marks will be preserved if +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). + +@item B B +@kindex B B (Summary) +@cindex crosspost mail +@findex gnus-summary-crosspost-article +Crosspost the current article to some other group +(@code{gnus-summary-crosspost-article}). This will create a new copy of +the article in the other group, and the Xref headers of the article will +be properly updated. + +@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 non-@code{nil} +(which is the default). + +@item B w +@itemx e +@kindex B w (Summary) +@kindex e (Summary) +@findex gnus-summary-edit-article +@kindex C-c C-c (Article) +@findex gnus-summary-edit-article-done +Edit the current article (@code{gnus-summary-edit-article}). To finish +editing and make the changes permanent, type @kbd{C-c C-c} +(@code{gnus-summary-edit-article-done}). If you give a prefix to the +@kbd{C-c C-c} command, Gnus won't re-highlight the article. + +@item B q +@kindex B q (Summary) +@findex gnus-summary-respool-query +If you want to re-spool an article, you might be curious as to what group +the article will end up in before you do the re-spooling. This command +will tell you (@code{gnus-summary-respool-query}). + +@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 non-@code{nil}, show and update the summary buffer as it's being +built. If @code{t}, update the buffer after every line is inserted. +If the value is an integer, @var{n}, update the display every @var{n} +lines. The default is @code{nil}. + +@vindex gnus-summary-display-arrow +@item gnus-summary-display-arrow +If non-@code{nil}, display an arrow in the fringe to indicate the +current article. + +@vindex gnus-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 expressions to be evalled (when the default +values are not @code{nil}), that should be made global while the summary +buffer is active. + +Note: The default expressions will be evaluated (using function +@code{eval}) before assignment to the local variable rather than just +assigned to it. If the default expression is the symbol @code{global}, +that symbol will not be evaluated but the global value of the local +variable will be used instead. + +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 + +Also @pxref{Group Parameters}. + +@end table + + +@node Summary Group Information +@subsection Summary Group Information + +@table @kbd + +@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 M-S +@kindex M-S (Summary) +@findex gnus-summary-repeat-search-article-forward +Repeat the previous search forwards +(@code{gnus-summary-repeat-search-article-forward}). + +@item M-R +@kindex M-R (Summary) +@findex gnus-summary-repeat-search-article-backward +Repeat the previous search backwards +(@code{gnus-summary-repeat-search-article-backward}). + +@item & +@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}). + +@item Y t +@kindex Y t (Summary) +@findex gnus-summary-insert-ticked-articles +Pull all ticked articles (for the current group) into the summary buffer +(@code{gnus-summary-insert-ticked-articles}). + +@end table + + +@node 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. + +@vindex gnus-auto-select-on-ephemeral-exit +The variable @code{gnus-auto-select-on-ephemeral-exit} controls what +article should be selected after exiting a digest group. Valid values +include: + +@table @code +@item next +Select the next article. + +@item next-unread +Select the next unread article. + +@item next-noselect +Move the cursor to the next article. This is the default. + +@item next-unread-noselect +Move the cursor to the next unread article. +@end table + +If it has any other value or there is no next (unread) article, the +article selected before entering to the digest group will appear. + +@item C-M-d +@kindex C-M-d (Summary) +@findex gnus-summary-read-document +This command is very similar to the one above, but lets you gather +several documents into one biiig group +(@code{gnus-summary-read-document}). It does this by opening several +@code{nndoc} groups for each document, and then opening an +@code{nnvirtual} group on top of these @code{nndoc} groups. This +command understands the process/prefix convention +(@pxref{Process/Prefix}). + +@item C-t +@kindex C-t (Summary) +@findex gnus-summary-toggle-truncation +Toggle truncation of summary lines +(@code{gnus-summary-toggle-truncation}). This will probably confuse the +line centering function in the summary buffer, so it's not a good idea +to have truncation switched off while reading articles. + +@item = +@kindex = (Summary) +@findex gnus-summary-expand-window +Expand the summary buffer window (@code{gnus-summary-expand-window}). +If given a prefix, force an @code{article} window configuration. + +@item C-M-e +@kindex C-M-e (Summary) +@findex gnus-summary-edit-parameters +Edit the group parameters (@pxref{Group Parameters}) of the current +group (@code{gnus-summary-edit-parameters}). + +@item C-M-a +@kindex C-M-a (Summary) +@findex gnus-summary-customize-parameters +Customize the group parameters (@pxref{Group Parameters}) of the current +group (@code{gnus-summary-customize-parameters}). + +@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 p +@kindex Z p (Summary) +@findex gnus-summary-catchup-and-goto-prev-group +Mark all articles as read and go to the previous group +(@code{gnus-summary-catchup-and-goto-prev-group}). + +@item 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 @file{*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. + +Remember: Cross-posting is kinda ok, but posting the same article +separately to several groups is not. Massive cross-posting (aka. +@dfn{velveeta}) is to be avoided at all costs, and you can even use the +@code{gnus-summary-mail-crosspost-complaint} command to complain about +excessive crossposting (@pxref{Summary Mail Commands}). + +@cindex cross-posting +@cindex Xref +@cindex @acronym{NOV} +One thing that may cause Gnus to not do the cross-posting thing +correctly is if you use an @acronym{NNTP} server that supports @sc{xover} +(which is very nice, because it speeds things up considerably) which +does not include the @code{Xref} header in its @acronym{NOV} lines. This is +Evil, but all too common, alas, alack. Gnus tries to Do The Right Thing +even with @sc{xover} by registering the @code{Xref} lines of all +articles you actually read, but if you kill the articles, or just mark +them as read without reading them, Gnus will not get a chance to snoop +the @code{Xref} lines out of these articles, and will be unable to use +the cross reference mechanism. + +@cindex LIST overview.fmt +@cindex overview.fmt +To check whether your @acronym{NNTP} server includes the @code{Xref} header +in its overview files, try @samp{telnet your.nntp.server nntp}, +@samp{MODE READER} on @code{inn} servers, and then say @samp{LIST +overview.fmt}. This may not work, but if it does, and the last line you +get does not read @samp{Xref:full}, then you should shout and whine at +your news admin until she includes the @code{Xref} header in the +overview files. + +If you want Gnus to get the @code{Xref}s right all the time, you have to +set @code{nntp-nov-is-evil} to @code{t}, which slows things down +considerably. Also @pxref{Slow/Expensive Connection}. + +C'est la vie. + +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 non-@code{nil}, suppress duplicates. + +@item gnus-save-duplicate-list +@vindex gnus-save-duplicate-list +If non-@code{nil}, save the list of duplicates to a file. This will +make startup and shutdown take longer, so the default is @code{nil}. +However, this means that only duplicate articles read in a single Gnus +session are suppressed. + +@item gnus-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 Emacs is called EasyPG (@pxref{Top, ,EasyPG, +epa, EasyPG Assistant user's manual}), but PGG (@pxref{Top, ,PGG, pgg, +PGG Manual}), and Mailcrypt are also supported. + +@item +To handle @acronym{S/MIME} message, you need to install OpenSSL@. OpenSSL 0.9.6 +or newer is recommended. + +@end enumerate + +The variables that control security functionality on reading/composing +messages include: + +@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 mm-sign-option +@vindex mm-sign-option +Option of creating signed parts. @code{nil}, use default signing +keys; @code{guided}, ask user to select signing keys from the menu. + +@item mm-encrypt-option +@vindex mm-encrypt-option +Option of creating encrypted parts. @code{nil}, use the first +public-key matching the @samp{From:} header as the recipient; +@code{guided}, ask user to select recipient keys from the menu. + +@item mml1991-use +@vindex mml1991-use +Symbol indicating elisp interface to OpenPGP implementation for +@acronym{PGP} messages. The default is @code{epg}, but @code{pgg}, +and @code{mailcrypt} are also supported although +deprecated. By default, Gnus uses the first available interface in +this order. + +@item mml2015-use +@vindex mml2015-use +Symbol indicating elisp interface to OpenPGP implementation for +@acronym{PGP/MIME} messages. The default is @code{epg}, but +@code{pgg}, and @code{mailcrypt} are also supported +although deprecated. By default, Gnus uses the first available +interface in this order. + +@end table + +By default the buttons that display security information are not +shown, because they clutter reading the actual e-mail. You can type +@kbd{K b} manually to display the information. Use the +@code{gnus-buttonized-mime-types} and +@code{gnus-unbuttonized-mime-types} variables to control this +permanently. @ref{MIME Commands} for further details, and hints on +how to customize these variables to always display security +information. + +@cindex snarfing keys +@cindex importing PGP keys +@cindex PGP key ring import +Snarfing OpenPGP keys (i.e., importing keys from articles into your +key ring) is not supported explicitly through a menu item or command, +rather Gnus do detect and label keys as @samp{application/pgp-keys}, +allowing you to specify whatever action you think is appropriate +through the usual @acronym{MIME} infrastructure. You can use a +@file{~/.mailcap} entry (@pxref{mailcap, , mailcap, emacs-mime, The +Emacs MIME Manual}) such as the following to import keys using GNU +Privacy Guard when you click on the @acronym{MIME} button +(@pxref{Using MIME}). + +@example +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}. + +More information on how to set things for sending outgoing signed and +encrypted messages up can be found in the message manual +(@pxref{Security, ,Security, message, Message Manual}). + +@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-archive +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. +* HTML:: Reading @acronym{HTML} messages. +* Customizing Articles:: Tailoring the look of the articles. +* Article Keymap:: Keystrokes available in the article buffer. +* Misc Article:: Other stuff. +@end menu + + +@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 non-@code{nil}, it should be a regular expression +that says what headers you wish to keep in the article buffer. All +headers that do not match this variable will be hidden. + +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 non-@code{nil}, 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} and/or @code{Cc} header if it is very long. +@item many-to +Remove all @code{To} and/or @code{Cc} headers if there are more than one. +@end table + +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-replace-part +@item r (Article) +@kindex r (Article) +Prompt for a file name, replace the @acronym{MIME} object with an +external body referring to the file via the message/external-body +@acronym{MIME} type. (@code{gnus-mime-replace-part}). + +@findex gnus-mime-delete-part +@item d (Article) +@kindex d (Article) +Delete the @acronym{MIME} object from the article and replace it with some +information about the removed @acronym{MIME} object +(@code{gnus-mime-delete-part}). + +@c FIXME: gnus-auto-select-part should be documented here + +@findex gnus-mime-copy-part +@item c (Article) +@kindex c (Article) +Copy the @acronym{MIME} object to a fresh buffer and display this buffer +(@code{gnus-mime-copy-part}). If given a prefix, copy the raw contents +without decoding. If given a numerical prefix, you can do semi-manual +charset stuff (see @code{gnus-summary-show-article-charset-alist} in +@ref{Paging the Article}). Compressed files like @file{.gz} and +@file{.bz2} are automatically decompressed if +@code{auto-compression-mode} is enabled (@pxref{Compressed Files,, +Accessing Compressed Files, emacs, The Emacs Editor}). + +@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 @samp{text/plain}. If given a prefix, insert +the raw contents without decoding. If given a numerical prefix, you can +do semi-manual charset stuff (see +@code{gnus-summary-show-article-charset-alist} in @ref{Paging the +Article}). Compressed files like @file{.gz} and @file{.bz2} are +automatically decompressed depending on @code{jka-compr} regardless of +@code{auto-compression-mode} (@pxref{Compressed Files,, Accessing +Compressed Files, emacs, The Emacs Editor}). + +@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 HTML +@section @acronym{HTML} +@cindex @acronym{HTML} + +Gnus can display @acronym{HTML} articles nicely formatted in the +article buffer. There are many methods for doing that, but two of +them are kind of default methods. + +If your Emacs copy has been built with libxml2 support, then Gnus uses +Emacs' built-in, plain elisp Simple HTML Renderer @code{shr} +@footnote{@code{shr} displays colors as declared in the @acronym{HTML} +article but tries to adjust them in order to be readable. If you +prefer more contrast, @xref{FAQ 4-16}.} which is also used by Emacs' +browser EWW (@pxref{EWW, ,EWW, emacs, The Emacs Manual}). + +If your Emacs copy lacks libxml2 support but you have @code{w3m} +installed on your system, Gnus uses that to render @acronym{HTML} mail +and display the results in the article buffer (@code{gnus-w3m}). + +For a complete overview, consult @xref{Display Customization, ,Display +Customization, emacs-mime, The Emacs MIME Manual}. This section only +describes the default method. + +@table @code +@item mm-text-html-renderer +@vindex mm-text-html-renderer +If set to @code{shr}, Gnus uses its own simple @acronym{HTML} +renderer. If set to @code{gnus-w3m}, it uses @code{w3m}. + +@item gnus-blocked-images +@vindex gnus-blocked-images +External images that have @acronym{URL}s that match this regexp won't +be fetched and displayed. For instance, do block all @acronym{URL}s +that have the string ``ads'' in them, do the following: + +@lisp +(setq gnus-blocked-images "ads") +@end lisp + +This can also be a function to be evaluated. If so, it will be +called with the group name as the parameter. The default value is +@code{gnus-block-private-groups}, which will return @samp{"."} for +anything that isn't a newsgroup. This means that no external images +will be fetched as a result of reading mail, so that nobody can use +web bugs (and the like) to track whether you've read email. + +Also @pxref{Misc Article} for @code{gnus-inhibit-images}. + +@item gnus-html-cache-directory +@vindex gnus-html-cache-directory +Gnus will download and cache images according to how +@code{gnus-blocked-images} is set. These images will be stored in +this directory. + +@item gnus-html-cache-size +@vindex gnus-html-cache-size +When @code{gnus-html-cache-size} bytes have been used in that +directory, the oldest files will be deleted. The default is 500MB. + +@item gnus-html-frame-width +@vindex gnus-html-frame-width +The width to use when rendering HTML@. The default is 70. + +@item gnus-max-image-proportion +@vindex gnus-max-image-proportion +How big pictures displayed are in relation to the window they're in. +A value of 0.7 (the default) means that they are allowed to take up +70% of the width and height of the window. If they are larger than +this, and Emacs supports it, then the images will be rescaled down to +fit these criteria. + +@end table + +To use this, make sure that you have @code{w3m} and @code{curl} +installed. If you have, then Gnus should display @acronym{HTML} +automatically. + + + +@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{first}: Do this treatment on the first body part. + +@item +@code{last}: Do this treatment on the last body 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 + +@item +A function: the function is called with no arguments and should return +@code{nil} or non-@code{nil}. The current article is available in the +buffer named by @code{gnus-article-buffer}. + +@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. + +@ifinfo +@c Avoid sort of redundant entries in the same section for the printed +@c manual, but add them in info to allow 'i gnus-treat-foo-bar RET' or +@c 'i foo-bar'. +@vindex gnus-treat-buttonize +@vindex gnus-treat-buttonize-head +@vindex gnus-treat-capitalize-sentences +@vindex gnus-treat-overstrike +@vindex gnus-treat-strip-cr +@vindex gnus-treat-strip-headers-in-body +@vindex gnus-treat-strip-leading-blank-lines +@vindex gnus-treat-strip-multiple-blank-lines +@vindex gnus-treat-strip-pem +@vindex gnus-treat-strip-trailing-blank-lines +@vindex gnus-treat-unsplit-urls +@vindex gnus-treat-wash-html +@vindex gnus-treat-date +@vindex gnus-treat-from-picon +@vindex gnus-treat-mail-picon +@vindex gnus-treat-newsgroups-picon +@vindex gnus-treat-from-gravatar +@vindex gnus-treat-mail-gravatar +@vindex gnus-treat-display-smileys +@vindex gnus-treat-body-boundary +@vindex gnus-treat-display-x-face +@vindex gnus-treat-display-face +@vindex gnus-treat-emphasize +@vindex gnus-treat-fill-article +@vindex gnus-treat-fill-long-lines +@vindex gnus-treat-hide-boring-headers +@vindex gnus-treat-hide-citation +@vindex gnus-treat-hide-citation-maybe +@vindex gnus-treat-hide-headers +@vindex gnus-treat-hide-signature +@vindex gnus-treat-strip-banner +@vindex gnus-treat-strip-list-identifiers +@vindex gnus-treat-highlight-citation +@vindex gnus-treat-highlight-headers +@vindex gnus-treat-highlight-signature +@vindex gnus-treat-play-sounds +@vindex gnus-treat-x-pgp-sig +@vindex gnus-treat-unfold-headers +@vindex gnus-treat-fold-headers +@vindex gnus-treat-fold-newsgroups +@vindex gnus-treat-leading-whitespace +@end ifinfo + +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, first, integer) +@item gnus-treat-strip-multiple-blank-lines (t, integer) +@item gnus-treat-strip-pem (t, last, integer) +@item gnus-treat-strip-trailing-blank-lines (t, last, integer) +@item gnus-treat-unsplit-urls (t, integer) +@item gnus-treat-wash-html (t, integer) + +@xref{Article Washing}. + +@item gnus-treat-date (head) + +This will transform/add date headers according to the +@code{gnus-article-date-headers} variable. This is a list of Date +headers to display. The formats available are: + +@table @code +@item ut +Universal time, aka GMT, aka ZULU. + +@item local +The user's local time zone. + +@item english +A semi-readable English sentence. + +@item lapsed +The time elapsed since the message was posted. + +@item combined-lapsed +Both the original date header and a (shortened) elapsed time. + +@item original +The original date header. + +@item iso8601 +ISO8601 format, i.e., ``2010-11-23T22:05:21''. + +@item user-defined +A format done according to the @code{gnus-article-time-format} +variable. + +@end table + +@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-from-gravatar (head) +@item gnus-treat-mail-gravatar (head) + +@xref{Gravatars}. + +@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}. + +@vindex gnus-treat-display-x-face +@item gnus-treat-display-x-face (head) + +@xref{X-Face}. + +@vindex gnus-treat-display-face +@item gnus-treat-display-face (head) + +@xref{Face}. + +@vindex gnus-treat-emphasize +@item gnus-treat-emphasize (t, head, integer) +@vindex gnus-treat-fill-article +@item gnus-treat-fill-article (t, integer) +@vindex gnus-treat-fill-long-lines +@item gnus-treat-fill-long-lines (t, integer) +@vindex gnus-treat-hide-boring-headers +@item gnus-treat-hide-boring-headers (head) +@vindex gnus-treat-hide-citation +@item gnus-treat-hide-citation (t, integer) +@vindex gnus-treat-hide-citation-maybe +@item gnus-treat-hide-citation-maybe (t, integer) +@vindex gnus-treat-hide-headers +@item gnus-treat-hide-headers (head) +@vindex gnus-treat-hide-signature +@item gnus-treat-hide-signature (t, last) +@vindex gnus-treat-strip-banner +@item gnus-treat-strip-banner (t, last) +@vindex gnus-treat-strip-list-identifiers +@item gnus-treat-strip-list-identifiers (head) + +@xref{Article Hiding}. + +@vindex gnus-treat-highlight-citation +@item gnus-treat-highlight-citation (t, integer) +@vindex gnus-treat-highlight-headers +@item gnus-treat-highlight-headers (head) +@vindex gnus-treat-highlight-signature +@item gnus-treat-highlight-signature (t, last, integer) + +@xref{Article Highlighting}. + +@vindex gnus-treat-play-sounds +@item gnus-treat-play-sounds +@item gnus-treat-ansi-sequences (t) +@vindex gnus-treat-x-pgp-sig +@item gnus-treat-x-pgp-sig (head) + +@vindex gnus-treat-unfold-headers +@item gnus-treat-unfold-headers (head) +@vindex gnus-treat-fold-headers +@item gnus-treat-fold-headers (head) +@vindex gnus-treat-fold-newsgroups +@item gnus-treat-fold-newsgroups (head) +@vindex gnus-treat-leading-whitespace +@item gnus-treat-leading-whitespace (head) + +@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. + +@kindex v (Article) +@cindex keys, reserved for users (Article) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. + +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 the region is active, +only yank the text in the region. + +@item S W +@kindex S W (Article) +@findex gnus-article-wide-reply-with-original +Send a wide reply to the current article and yank the current article +(@code{gnus-article-wide-reply-with-original}). If the region is +active, only yank the text in the region. + +@item F +@kindex F (Article) +@findex gnus-article-followup-with-original +Send a followup to the current article and yank the current article +(@code{gnus-article-followup-with-original}). If the region is active, +only yank the text in the region. + + +@end table + + +@node Misc Article +@section Misc Article + +@table @code + +@item gnus-single-article-buffer +@vindex gnus-single-article-buffer +@cindex article buffers, several +If non-@code{nil}, use the same article buffer for all the groups. +(This is the default.) If @code{nil}, each group will have its own +article buffer. + +@item gnus-widen-article-window +@cindex gnus-widen-article-window +If non-@code{nil}, selecting the article buffer with the @kbd{h} +command will ``widen'' the article window to take the entire frame. + +@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 non-@code{nil}, 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{Summary Buffer Mode +Line}). 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 emphasized 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 non-@code{nil}, the articles will be divided into pages whenever a +page delimiter appears in the article. If this variable is @code{nil}, +paging will not be done. + +@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. @xref{IDNA, ,IDNA,message, The Message Manual}, +for how to compose such messages. This requires +@uref{http://www.gnu.org/software/libidn/, GNU Libidn}, and this +variable is only enabled if you have installed it. + +@vindex gnus-inhibit-images +@item gnus-inhibit-images +If this is non-@code{nil}, inhibit displaying of images inline in the +article body. It is effective to images that are in articles as +@acronym{MIME} parts, and images in @acronym{HTML} articles rendered +when @code{mm-text-html-renderer} (@pxref{Display Customization, +,Display Customization, emacs-mime, The Emacs MIME Manual}) is +@code{shr} or @code{gnus-w3m}. + +@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? +* POP before SMTP:: You cannot send a mail unless you read a mail. +* Mail and Post:: Mailing and posting at the same time. +* Archived Messages:: Where Gnus stores the messages you've sent. +* Posting Styles:: An easier way to specify who you are. +* Drafts:: Postponing messages and rejected messages. +* Rejected Articles:: What happens if the server doesn't like your article? +* Signing and encrypting:: How to compose secure messages. +@end menu + +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 non-@code{nil}, 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 +If non-@code{nil}, Gnus will ask you for a confirmation when you are +about to reply to news articles by mail. If it is @code{nil}, nothing +interferes in what you want to do. This can also be a function +receiving the group name as the only parameter which should return +non-@code{nil} if a confirmation is needed, or a regular expression +matching group names, where confirmation should be asked for. + +If you find yourself never wanting to reply to mail, but occasionally +press @kbd{R} anyway, this variable might be for you. + +@item gnus-confirm-treat-mail-like-news +@vindex gnus-confirm-treat-mail-like-news +If non-@code{nil}, Gnus also requests confirmation according to +@code{gnus-confirm-mail-reply-to-news} when replying to mail. This is +useful for treating mailing lists like newsgroups. + +@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}. + +@vindex message-send-mail-function +When sending mail, Message invokes the function specified by the +variable @code{message-send-mail-function}. Gnus tries to set it to a +value suitable for your system. +@xref{Mail Variables, ,Mail Variables,message,Message manual}, for more +information. + + +@node POP before SMTP +@section POP before SMTP +@cindex pop before smtp +@findex mail-source-touch-pop + +Does your @acronym{ISP} use @acronym{POP}-before-@acronym{SMTP} +authentication? This authentication method simply requires you to +contact the @acronym{POP} server before sending email. To do that, +put the following lines in your @file{~/.gnus.el} file: + +@lisp +(add-hook 'message-send-mail-hook 'mail-source-touch-pop) +@end lisp + +@noindent +The @code{mail-source-touch-pop} function does @acronym{POP} +authentication according to the value of @code{mail-sources} without +fetching mails, just before sending a mail. @xref{Mail Sources}. + +If you have two or more @acronym{POP} mail servers set in +@code{mail-sources}, you may want to specify one of them to +@code{mail-source-primary-source} as the @acronym{POP} mail server to be +used for the @acronym{POP}-before-@acronym{SMTP} authentication. If it +is your primary @acronym{POP} mail server (i.e., you are fetching mails +mainly from that server), you can set it permanently as follows: + +@lisp +(setq mail-source-primary-source + '(pop :server "pop3.mail.server" + :password "secret")) +@end lisp + +@noindent +Otherwise, bind it dynamically only when performing the +@acronym{POP}-before-@acronym{SMTP} authentication as follows: + +@lisp +(add-hook 'message-send-mail-hook + (lambda () + (let ((mail-source-primary-source + '(pop :server "pop3.mail.server" + :password "secret"))) + (mail-source-touch-pop)))) +@end lisp + + +@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 a list of symbols or a string. Valid +symbols are @code{gnus} (show Gnus version) and @code{emacs} (show Emacs +version). In addition to the Emacs version, you can add @code{codename} +(show (S)XEmacs codename) or either @code{config} (show system +configuration) or @code{type} (show system type). If you set it to a +string, be sure to use a valid format, see RFC 2616. + +@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. + +@vindex gnus-message-highlight-citation +If @code{gnus-message-highlight-citation} is @code{t}, different levels of +citations are highlighted like in Gnus article buffers also in message +mode buffers. + +@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}. The +default is @code{"sent.%Y-%m"}, which gives you one archive group per month. + +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 @code{"archive"}, and when +actually being used it is expanded into: + +@lisp +(nnfolder "archive" + (nnfolder-directory "~/Mail/archive") + (nnfolder-active-file "~/Mail/archive/active") + (nnfolder-get-new-mail nil) + (nnfolder-inhibit-expiry t)) +@end lisp + +@quotation +@vindex gnus-update-message-archive-method +Note: a server like this is saved in the @file{~/.newsrc.eld} file first +so that it may be used as a real method of the server which is named +@code{"archive"} (that is, for the case where +@code{gnus-message-archive-method} is set to @code{"archive"}) ever +since. If it once has been saved, it will never be updated by default +even if you change the value of @code{gnus-message-archive-method} +afterward. Therefore, the server @code{"archive"} doesn't necessarily +mean the @code{nnfolder} server like this at all times. If you want the +saved method to reflect always the value of +@code{gnus-message-archive-method}, set the +@code{gnus-update-message-archive-method} variable to a non-@code{nil} +value. The default value of this variable is @code{nil}. +@end quotation + +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. +@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 + +Now, when you send a message off, it will be stored in the appropriate +group. (If you want to disable storing for just one particular message, +you can just remove the @code{Gcc} header that has been inserted.) The +archive group will appear in the group buffer the next time you start +Gnus, or the next time you press @kbd{F} in the group buffer. You can +enter it and read the articles in it just like you'd read any other +group. If the group gets really big and annoying, you can simply rename +if (using @kbd{G r} in the group buffer) to something +nice---@samp{misc-mail-september-1995}, or whatever. New messages will +continue to be stored in the old (now empty) group. + +@table @code +@item gnus-gcc-mark-as-read +@vindex gnus-gcc-mark-as-read +If non-@code{nil}, automatically mark @code{Gcc} articles as read. + +@item gnus-gcc-externalize-attachments +@vindex gnus-gcc-externalize-attachments +If @code{nil}, attach files as normal parts in Gcc copies; if a regexp +and matches the Gcc group name, attach files as external parts; if it is +@code{all}, attach local files as external parts; if it is other +non-@code{nil}, the behavior is the same as @code{all}, but it may be +changed in the future. + +@item gnus-gcc-self-resent-messages +@vindex gnus-gcc-self-resent-messages +Like the @code{gcc-self} group parameter, applied only for unmodified +messages that @code{gnus-summary-resend-message} (@pxref{Summary Mail +Commands}) resends. Non-@code{nil} value of this variable takes +precedence over any existing @code{Gcc} header. + +If this is @code{none}, no @code{Gcc} copy will be made. If this is +@code{t}, messages resent will be @code{Gcc} copied to the current +group. If this is a string, it specifies a group to which resent +messages will be @code{Gcc} copied. If this is @code{nil}, @code{Gcc} +will be done according to existing @code{Gcc} header(s), if any. If +this is @code{no-gcc-self}, that is the default, resent messages will be +@code{Gcc} copied to groups that existing @code{Gcc} header specifies, +except for the current group. + +@item gnus-gcc-pre-body-encode-hook +@vindex gnus-gcc-pre-body-encode-hook +@itemx gnus-gcc-post-body-encode-hook +@vindex gnus-gcc-post-body-encode-hook + +These hooks are run before/after encoding the message body of the Gcc +copy of a sent message. The current buffer (when the hook is run) +contains the message including the message header. Changes made to +the message will only affect the Gcc copy, but not the original +message. You can use these hooks to edit the copy (and influence +subsequent transformations), e.g., remove MML secure tags +(@pxref{Signing and encrypting}). + +@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 non-@code{nil} 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. In +addition, you can also use the @code{(@var{name} :file @var{value})} +form or the @code{(@var{name} :value @var{value})} form. Where +@code{:file} signifies @var{value} represents a file name and its +contents should be used as the attribute value, @code{:value} signifies +@var{value} does not represent a file name explicitly. The attribute +name can be one of: + +@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 + +Note that the @code{signature-file} attribute honors the variable +@code{message-signature-directory}. + +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, 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. + +In the case of a string value, if the @code{match} is a regular +expression, or if it takes the form @code{(header @var{match} +@var{regexp})}, a @samp{gnus-match-substitute-replacement} is proceed +on the value to replace the positional parameters @samp{\@var{n}} by +the corresponding parenthetical matches (see @xref{Replacing Match,, +Replacing the Text that Matched, elisp, The Emacs Lisp Reference +Manual}.) + +@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-face-file "~/.xface") + (x-url (getenv "WWW_HOME")) + (organization "People's Front Against MWM")) + ("^rec.humor" + (signature my-funny-signature-randomizer)) + ((equal (system-name) "gnarly") ;; @r{A form} + (signature my-quote-randomizer)) + (message-news-p ;; @r{A function symbol} + (signature my-news-signature)) + (window-system ;; @r{A value symbol} + ("X-Window-System" (format "%s" window-system))) + ;; @r{If I'm replying to Larsi, set the Organization header.} + ((header "from" "larsi.*org") + (Organization "Somewhere, Inc.")) + ;; @r{Reply to a message from the same subaddress the message} + ;; @r{was sent to.} + ((header "x-original-to" "me\\(\\+.+\\)@@example.org") + (address "me\\1@@example.org")) + ((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.") + ("X-Message-SMTP-Method" "smtp smtp.example.org 587") + (organization "Important Work, Inc")) + ("nnml:.*" + (From (with-current-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. +You may also use @code{message-alternative-emails} instead. +@xref{Message Headers, ,Message Headers, message, Message Manual}. + +Of particular interest in the ``work-mail'' style is the +@samp{X-Message-SMTP-Method} header. It specifies how to send the +outgoing email. You may want to sent certain emails through certain +@acronym{SMTP} servers due to company policies, for instance. +@xref{Mail Variables, ,Message Variables, message, Message Manual}. + + +@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. + +Finally, if you want to delete a draft, use the normal @kbd{B DEL} +command (@pxref{Mail Group Commands}). + + +@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. +* Using IMAP:: Reading mail from @acronym{IMAP}. +* Getting Mail:: Reading your personal mail with Gnus. +* Browsing the Web:: Getting messages from a plethora of Web sources. +* Other Sources:: Reading directories, files. +* Combined Groups:: Combining groups into one group. +* Email Based Diary:: Using mails to manage diary events in Gnus. +* Gnus Unplugged:: Reading news and mail offline. +@end menu + + +@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. + +@item a +Whether this server is agentized. +@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 v +@kindex v (Server) +@cindex keys, reserved for users (Server) +The key @kbd{v} is reserved for users. You can bind it to some +command or better use it as a prefix key. + +@item 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 S +@kindex S (Server) +@findex gnus-server-show-server +Show the definition of a server (@code{gnus-server-show-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. + +@item z +@kindex z (Server) +@findex gnus-server-compact-server + +Compact all groups in the server under point +(@code{gnus-server-compact-server}). Currently implemented only in +nnml (@pxref{Mail Spool}). This removes gaps between article numbers, +hence getting a correct total article count. + +@end table + +Some more commands for closing, disabling, and re-opening servers are +listed in @ref{Unavailable Servers}. + + +@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 connect with +@uref{http://netcat.sourceforge.net/, netcat} from there to the +@acronym{NNTP} server. +Doing this can be rather fiddly, but your virtual server definition +should probably look something like this: + +@lisp +(nntp "firewall" + (nntp-open-connection-function nntp-open-via-rlogin-and-netcat) + (nntp-via-address "the.firewall.machine") + (nntp-address "the.real.nntp.host")) +@end lisp + +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}. Here's an example for +an indirect connection: + +@lisp +(setq gnus-select-method + '(nntp "indirect" + (nntp-address "news.server.example") + (nntp-via-user-name "intermediate_user_name") + (nntp-via-address "intermediate.host.example") + (nntp-via-rlogin-command "ssh") + (nntp-via-rlogin-command-switches ("-C")) + (nntp-open-connection-function nntp-open-via-rlogin-and-netcat))) +@end lisp + +This means that you have to have set up @code{ssh-agent} correctly to +provide automatic authorization, of course. + +If you're behind a firewall, but have direct access to the outside world +through a wrapper command like "runsocks", you could open a socksified +netcat connection to the news server as follows: + +@lisp +(nntp "outside" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-netcat-stream) + (nntp-address "the.news.server")) +@end lisp + + +@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 c +@kindex c (Server) +@findex gnus-server-copy-server +Copy a server and give it a new name +(@code{gnus-server-copy-server}). This can be useful if you have a +complex method definition, and want to use the same definition towards +a different (physical) server. + +@item L +@kindex L (Server) +@findex gnus-server-offline-server +Set server status to offline (@code{gnus-server-offline-server}). + +@end table + + +@node 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 authentication +@cindex nntp authentication +@findex nntp-send-authinfo +@findex nntp-send-mode-reader +is run after a connection has been made. It can be used to send +commands to the @acronym{NNTP} server after it has been contacted. By +default it sends the command @code{MODE READER} to the server with the +@code{nntp-send-mode-reader} function. This function should always be +present in this hook. + +@item nntp-authinfo-function +@vindex nntp-authinfo-function +@findex nntp-send-authinfo +@vindex nntp-authinfo-file +This function will be used to send @samp{AUTHINFO} to the @acronym{NNTP} +server. The default function is @code{nntp-send-authinfo}, which looks +through your @file{~/.authinfo} (or whatever you've set the +@code{nntp-authinfo-file} variable to) for applicable entries. If none +are found, it will prompt you for a login name and a password. The +format of the @file{~/.authinfo} file is (almost) the same as the +@code{ftp} @file{~/.netrc} file, which is defined in the @code{ftp} +manual page, but here are the salient facts: + +@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. + +@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-xref-number-is-evil +@vindex nntp-xref-number-is-evil +When Gnus refers to an article having the @code{Message-ID} that a user +specifies or having the @code{Message-ID} of the parent article of the +current one (@pxref{Finding the Parent}), Gnus sends a @code{HEAD} +command to the @acronym{NNTP} server to know where it is, and the server +returns the data containing the pairs of a group and an article number +in the @code{Xref} header. Gnus normally uses the article number to +refer to the article if the data shows that that article is in the +current group, while it uses the @code{Message-ID} otherwise. However, +some news servers, e.g., ones running Diablo, run multiple engines +having the same articles but article numbers are not kept synchronized +between them. In that case, the article number that appears in the +@code{Xref} header varies by which engine is chosen, so you cannot refer +to the parent article that is in the current group, for instance. If +you connect to such a server, set this variable to a non-@code{nil} +value, and Gnus never uses article numbers. For example: + +@lisp +(setq gnus-select-method + '(nntp "newszilla" + (nntp-address "newszilla.example.com") + (nntp-xref-number-is-evil t) + @dots{})) +@end lisp + +The default value of this server variable is @code{nil}. + +@item nntp-prepare-server-hook +@vindex nntp-prepare-server-hook +A hook run before attempting to connect to an @acronym{NNTP} server. + +@item nntp-record-commands +@vindex nntp-record-commands +If non-@code{nil}, @code{nntp} will log all commands it sends to the +@acronym{NNTP} server (along with a timestamp) in the @file{*nntp-log*} +buffer. This is useful if you are debugging a Gnus/@acronym{NNTP} connection +that doesn't seem to work. + +@item nntp-open-connection-function +@vindex nntp-open-connection-function +It is possible to customize how the connection to the nntp server will +be opened. If you specify an @code{nntp-open-connection-function} +parameter, Gnus will use that function to establish the connection. +Seven pre-made functions are supplied. These functions can be grouped +in two categories: direct connection functions (four pre-made), and +indirect ones (three pre-made). + +@item nntp-never-echoes-commands +@vindex nntp-never-echoes-commands +Non-@code{nil} means the nntp server never echoes commands. It is +reported that some nntps server doesn't echo commands. So, you may want +to set this to non-@code{nil} in the method for such a server setting +@code{nntp-open-connection-function} to @code{nntp-open-ssl-stream} for +example. The default value is @code{nil}. Note that the +@code{nntp-open-connection-functions-never-echo-commands} variable +overrides the @code{nil} value of this variable. + +@item nntp-open-connection-functions-never-echo-commands +@vindex nntp-open-connection-functions-never-echo-commands +List of functions that never echo commands. Add or set a function which +you set to @code{nntp-open-connection-function} to this list if it does +not echo commands. Note that a non-@code{nil} value of the +@code{nntp-never-echoes-commands} variable overrides this variable. The +default value is @code{(nntp-open-network-stream)}. + +@item nntp-prepare-post-hook +@vindex nntp-prepare-post-hook +A hook run just before posting an article. If there is no +@code{Message-ID} header in the article and the news server provides the +recommended ID, it will be added to the article before running this +hook. It is useful to make @code{Cancel-Lock} headers even if you +inhibit Gnus to add a @code{Message-ID} header, you could say: + +@lisp +(add-hook 'nntp-prepare-post-hook 'canlock-insert-header) +@end lisp + +Note that not all servers support the recommended ID@. This works for +INN versions 2.3.0 and later, for instance. + +@item nntp-server-list-active-group +If @code{nil}, then always use @samp{GROUP} instead of @samp{LIST +ACTIVE}. This is usually slower, but on misconfigured servers that +don't update their active files often, this can help. + + +@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. If both Emacs and the server supports it, the +connection will be upgraded to an encrypted @acronym{STARTTLS} +connection automatically. + +@item network-only +The same as the above, but don't do automatic @acronym{STARTTLS} upgrades. + +@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 563) + (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} +@ignore +@c Defunct URL, ancient package, so don't mention it. +or @uref{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL, SSLeay} +@end ignore +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-netcat-stream +@item nntp-open-netcat-stream +Opens a connection to an @acronym{NNTP} server using the @code{netcat} +program. You might wonder why this function exists, since we have +the default @code{nntp-open-network-stream} which would do the job. (One +of) the reason(s) is that if you are behind a firewall but have direct +connections to the outside world thanks to a command wrapper like +@code{runsocks}, you can use it like this: + +@lisp +(nntp "socksified" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-netcat-stream) + (nntp-address "the.news.server")) +@end lisp + +With the default method, you would need to wrap your whole Emacs +session, which is not a good idea. + +@findex nntp-open-telnet-stream +@item nntp-open-telnet-stream +Like @code{nntp-open-netcat-stream}, but uses @code{telnet} rather than +@code{netcat}. @code{telnet} is a bit less robust because of things +like line-end-conversion, but sometimes netcat is simply +not available. The previous example would turn into: + +@lisp +(nntp "socksified" + (nntp-pre-command "runsocks") + (nntp-open-connection-function nntp-open-telnet-stream) + (nntp-address "the.news.server") + (nntp-end-of-line "\n")) +@end lisp +@end table + + +@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-netcat +@findex nntp-open-via-rlogin-and-netcat +Does an @samp{rlogin} on a remote system, and then uses @code{netcat} to connect +to the real @acronym{NNTP} server from there. This is useful for instance if +you need to connect to a firewall machine first. + +@code{nntp-open-via-rlogin-and-netcat}-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. +@end table + +@item nntp-open-via-rlogin-and-telnet +@findex nntp-open-via-rlogin-and-telnet +Does essentially the same, but uses @code{telnet} instead of @samp{netcat} +to connect to the real @acronym{NNTP} server from the intermediate host. +@code{telnet} is a bit less robust because of things like +line-end-conversion, but sometimes @code{netcat} is simply not available. + +@code{nntp-open-via-rlogin-and-telnet}-specific variables: + +@table @code +@item nntp-telnet-command +@vindex nntp-telnet-command +Command used to connect to the real @acronym{NNTP} server from the +intermediate host. The default is @samp{telnet}. + +@item nntp-telnet-switches +@vindex nntp-telnet-switches +List of strings to be used as the switches to the +@code{nntp-telnet-command} command. The default is @code{("-8")}. + +@item 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}. If you use @samp{ssh}, you may need to set +this to @samp{("-t" "-e" "none")} or @samp{("-C" "-t" "-e" "none")} if +the telnet command requires a pseudo-tty allocation on an intermediate +host. The default is @code{nil}. +@end table + +Note that you may want to change the value for @code{nntp-end-of-line} +to @samp{\n} (@pxref{Common Variables}). + +@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 non-@code{nil}, the intermediate @code{telnet} session (client and +server both) will support the @code{ENVIRON} option and not prompt for +login name. This works for Solaris @code{telnet}, for instance. + +@item 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 + +Note that you may want to change the value for @code{nntp-end-of-line} +to @samp{\n} (@pxref{Common Variables}). +@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 (the values of the following variables will be used as the +default if each virtual @code{nntp} server doesn't specify those server +variables individually). + +@table @code + +@item 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 telnet connection function. + +@item nntp-netcat-command +@vindex nntp-netcat-command +Command to use when connecting to the @acronym{NNTP} server through +@samp{netcat}. This is @emph{not} for an intermediate host. This is +just for the real @acronym{NNTP} server. The default is +@samp{nc}. + +@item nntp-netcat-switches +@vindex nntp-netcat-switches +A list of switches to pass to @code{nntp-netcat-command}. The default +is @samp{()}. + +@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 articles---@samp{alt.binaries.pictures.furniture}, 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 normally@* +@file{/usr/spool/news/over.view/}. + +@item nnspool-lib-dir +@vindex nnspool-lib-dir +Where the news lib dir is (@file{/usr/lib/news/} by default). + +@item nnspool-active-file +@vindex nnspool-active-file +The name of the active file. + +@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 non-@code{nil}, @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 non-@code{nil}, which is the default, use @code{sed} to get the +relevant portion from the overview file. If @code{nil}, +@code{nnspool} will load the entire file into a buffer and process it +there. + +@end table + + +@node Using IMAP +@section Using IMAP +@cindex imap + +The most popular mail backend is probably @code{nnimap}, which +provides access to @acronym{IMAP} servers. @acronym{IMAP} servers +store mail remotely, so the client doesn't store anything locally. +This means that it's a convenient choice when you're reading your mail +from different locations, or with different user agents. + +@menu +* Connecting to an IMAP Server:: Getting started with @acronym{IMAP}. +* Customizing the IMAP Connection:: Variables for @acronym{IMAP} connection. +* Client-Side IMAP Splitting:: Put mail in the correct mail box. +* Support for IMAP Extensions:: Getting extensions and labels from servers. +@end menu + + +@node Connecting to an IMAP Server +@subsection Connecting to an IMAP Server + +Connecting to an @acronym{IMAP} can be very easy. Type @kbd{B} in the +group buffer, or (if your primary interest is reading email), say +something like: + +@example +(setq gnus-select-method + '(nnimap "imap.gmail.com")) +@end example + +You'll be prompted for a user name and password. If you grow tired of +that, then add the following to your @file{~/.authinfo} file: + +@example +machine imap.gmail.com login password port imap +@end example + +That should basically be it for most users. + + +@node Customizing the IMAP Connection +@subsection Customizing the IMAP Connection + +Here's an example method that's more complex: + +@example +(nnimap "imap.gmail.com" + (nnimap-inbox "INBOX") + (nnimap-split-methods default) + (nnimap-expunge t) + (nnimap-stream ssl)) +@end example + +@table @code +@item nnimap-address +The address of the server, like @samp{imap.gmail.com}. + +@item nnimap-server-port +If the server uses a non-standard port, that can be specified here. A +typical port would be @code{"imap"} or @code{"imaps"}. + +@item nnimap-stream +How @code{nnimap} should connect to the server. Possible values are: + +@table @code +@item undecided +This is the default, and this first tries the @code{ssl} setting, and +then tries the @code{network} setting. + +@item ssl +This uses standard @acronym{TLS}/@acronym{SSL} connections. + +@item network +Non-encrypted and unsafe straight socket connection, but will upgrade +to encrypted @acronym{STARTTLS} if both Emacs and the server +supports it. + +@item starttls +Encrypted @acronym{STARTTLS} over the normal @acronym{IMAP} port. + +@item shell +If you need to tunnel via other systems to connect to the server, you +can use this option, and customize @code{nnimap-shell-program} to be +what you need. + +@item plain +Non-encrypted and unsafe straight socket connection. +@acronym{STARTTLS} will not be used even if it is available. + +@end table + +@item nnimap-authenticator +Some @acronym{IMAP} servers allow anonymous logins. In that case, +this should be set to @code{anonymous}. If this variable isn't set, +the normal login methods will be used. If you wish to specify a +specific login method to be used, you can set this variable to either +@code{login} (the traditional @acronym{IMAP} login method), +@code{plain} or @code{cram-md5}. + +@item nnimap-expunge +If non-@code{nil}, expunge articles after deleting them. This is always done +if the server supports UID EXPUNGE, but it's not done by default on +servers that doesn't support that command. + +@item nnimap-streaming +Virtually all @acronym{IMAP} server support fast streaming of data. +If you have problems connecting to the server, try setting this to +@code{nil}. + +@item nnimap-fetch-partial-articles +If non-@code{nil}, fetch partial articles from the server. If set to +a string, then it's interpreted as a regexp, and parts that have +matching types will be fetched. For instance, @samp{"text/"} will +fetch all textual parts, while leaving the rest on the server. + +@item nnimap-record-commands +If non-@code{nil}, record all @acronym{IMAP} commands in the +@samp{"*imap log*"} buffer. + +@end table + + +@node Client-Side IMAP Splitting +@subsection Client-Side IMAP Splitting + +Many people prefer to do the sorting/splitting of mail into their mail +boxes on the @acronym{IMAP} server. That way they don't have to +download the mail they're not all that interested in. + +If you do want to do client-side mail splitting, then the following +variables are relevant: + +@table @code +@item nnimap-inbox +This is the @acronym{IMAP} mail box that will be scanned for new +mail. This can also be a list of mail box names. + +@item nnimap-split-methods +Uses the same syntax as @code{nnmail-split-methods} (@pxref{Splitting +Mail}), except the symbol @code{default}, which means that it should +use the value of the @code{nnmail-split-methods} variable. + +@item nnimap-split-fancy +Uses the same syntax as @code{nnmail-split-fancy}. + +@item nnimap-unsplittable-articles +List of flag symbols to ignore when doing splitting. That is, +articles that have these flags won't be considered when splitting. +The default is @samp{(%Deleted %Seen)}. + +@end table + +Here's a complete example @code{nnimap} backend with a client-side +``fancy'' splitting method: + +@example +(nnimap "imap.example.com" + (nnimap-inbox "INBOX") + (nnimap-split-methods + (| ("MailScanner-SpamCheck" "spam" "spam.detected") + (to "foo@@bar.com" "foo") + "undecided"))) +@end example + + +@node Support for IMAP Extensions +@subsection Support for IMAP Extensions + +@cindex Gmail +@cindex X-GM-LABELS +@cindex IMAP labels + +If you're using Google's Gmail, you may want to see your Gmail labels +when reading your mail. Gnus can give you this information if you ask +for @samp{X-GM-LABELS} in the variable @code{gnus-extra-headers}. For +example: + +@example +(setq gnus-extra-headers + '(To Newsgroups X-GM-LABELS)) +@end example + +This will result in Gnus storing your labels in message header +structures for later use. The content is always a parenthesized +(possible empty) list. + + + +@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 + +@noindent +In that case, @code{nnmail-split-lowercase-expanded} controls whether +the inserted text should be made lowercase. @xref{Fancy Mail Splitting}. + +The second element can also be a function. In that case, it will be +called narrowed to the headers with the first element of the rule as the +argument. It should return a non-@code{nil} value if it thinks that the +mail belongs in that group. + +@cindex @samp{bogus} group +The last of these groups should always be a general one, and the regular +expression should @emph{always} be @samp{""} so that it matches any mails +that haven't been matched by any of the other regexps. (These rules are +processed from the beginning of the alist toward the end. The first rule +to make a match will ``win'', unless you have crossposting enabled. In +that case, all matching rules will ``win''.) If no rule matched, the mail +will end up in the @samp{bogus} group. When new groups are created by +splitting mail, you may want to run @code{gnus-group-find-new-groups} to +see the new groups. This also applies to the @samp{bogus} group. + +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. + +This variable can also be a fancy split method. For the syntax, +see @ref{Fancy Mail Splitting}. + +Note that the mail back ends are free to maul the poor, innocent, +incoming headers all they want to. They all add @code{Lines} headers; +some add @code{X-Gnus-Group} headers; most rename the Unix mbox +@code{From} line to something else. + +@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-decodes +@vindex nnmail-mail-splitting-charset +By default, splitting does not decode headers, so you can not match on +non-@acronym{ASCII} strings. But it is useful if you want to match +articles based on the raw header data. To enable it, set the +@code{nnmail-mail-splitting-decodes} variable to a non-@code{nil} value. +In addition, the value of the @code{nnmail-mail-splitting-charset} +variable is used for decoding non-@acronym{MIME} encoded string when +@code{nnmail-mail-splitting-decodes} is non-@code{nil}. The default +value is @code{nil} which means not to decode non-@acronym{MIME} encoded +string. A suitable value for you will be @code{undecided} or be the +charset used normally in mails you are interested in. + +@vindex nnmail-resplit-incoming +By default, splitting is performed on all incoming messages. If you +specify a @code{directory} entry for the variable @code{mail-sources} +(@pxref{Mail Source Specifiers}), however, then splitting does +@emph{not} happen by default. You can set the variable +@code{nnmail-resplit-incoming} to a non-@code{nil} value to make +splitting happen even in this case. (This variable has no effect on +other kinds of entries.) + +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 Functions:: +* 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 @code{mail-sources} is global for all mail groups. You can specify +an additional mail source for a particular group by including the +@code{group} mail specifier in @code{mail-sources}, and setting a +@code{mail-source} group parameter (@pxref{Group Parameters}) specifying +a single mail source. When this is used, @code{mail-sources} is +typically just @code{(group)}; the @code{mail-source} parameter for a +group might look like this: + +@lisp +(mail-source . (file :path "home/user/spools/foo.spool")) +@end lisp + +This means that the group's (and only this group's) messages will be +fetched from the spool file @samp{/user/spools/foo.spool}. + +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 the @samp{movemail} and temporary +file 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 non-@code{nil} forces +Gnus to scan the mail source only once. This is particularly useful +if you want to scan mail groups at a specified level. + +@vindex nnmail-resplit-incoming +There is also the variable @code{nnmail-resplit-incoming}, if you set +that to a non-@code{nil} value, then the normal splitting process is +applied to all the files from the directory, @ref{Splitting Mail}. + +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 non-@code{nil} are returned. +The default is @code{identity}. This is used as an additional +filter---only files that have the right suffix @emph{and} satisfy this +predicate are considered. + +@item :prescript +@itemx :postscript +Script run before/after fetching mail. + +@end table + +An example directory mail source: + +@lisp +(directory :path "/home/user-name/procmail-dir/" + :suffix ".prcml") +@end lisp + +@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 (e.g., +@samp{:port 1234}) or a string (e.g., @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. + +One popular way to use this is to set up an SSH tunnel to access the +@acronym{POP} server. Here's an example: + +@lisp +(pop :server "127.0.0.1" + :port 1234 + :user "foo" + :password "secret" + :prescript + "nohup ssh -f -L 1234:pop.server:110 remote.host sleep 3600 &") +@end lisp + +@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}. + +@item :leave +Non-@code{nil} if the mail is to be left on the @acronym{POP} server +after fetching. Only the built-in @code{pop3-movemail} program (the +default) supports this keyword. + +If this is a number, leave mails on the server for this many days since +you first checked new mails. In that case, mails once fetched will +never be fetched again by the @acronym{UIDL} control. If this is +@code{nil} (the default), mails will be deleted on the server right +after fetching. If this is neither @code{nil} nor a number, all mails +will be left on the server, and you will end up getting the same mails +again and again. + +@vindex pop3-uidl-file +The @code{pop3-uidl-file} variable specifies the file to which the +@acronym{UIDL} data are locally stored. The default value is +@file{~/.pop3-uidl}. + +Note that @acronym{POP} servers maintain no state information between +sessions, so what the client believes is there and what is actually +there may not match up. If they do not, then you may get duplicate +mails or the whole thing can fall apart and leave you with a corrupt +mailbox. + +@end table + +@findex pop3-movemail +@vindex pop3-leave-mail-on-server +If the @code{:program} and @code{:function} keywords aren't specified, +@code{pop3-movemail} will be used. + +Here are some examples for getting mail from a @acronym{POP} server. + +Fetch from the default @acronym{POP} server, using the default user +name, and default fetcher: + +@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 + +Leave mails on the server for 14 days: + +@lisp +(pop :server "my.pop.server" + :user "user-name" :password "secret" + :leave 14) +@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 (i.e., +with nnimap), for some reason or other, Gnus let you treat it similar +to a @acronym{POP} server and fetches articles from a given +@acronym{IMAP} mailbox. @xref{Using IMAP}, for more information. + +Keywords: + +@table @code +@item :server +The name of the @acronym{IMAP} server. The default is taken from the +@env{MAILHOST} environment variable. + +@item :port +The port number of the @acronym{IMAP} server. The default is @samp{143}, or +@samp{993} for @acronym{TLS}/@acronym{SSL} connections. + +@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 @samp{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 + +Make sure nothing is interfering with the output of the program, e.g., +don't forget to redirect the error output to the void. The valid format +specifier characters are: + +@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 receives incoming mail. Instead of +a single mailbox, this can be a list of mailboxes to fetch mail from. + +@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 non-@code{nil}, 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 group +Get the actual mail source from the @code{mail-source} group parameter, +@xref{Group Parameters}. + +@end table + +@table @dfn +@item Common Keywords +Common keywords can be used in any type of mail source. + +Keywords: + +@table @code +@item :plugged +If non-@code{nil}, fetch the mail even when Gnus is unplugged. If you +use directory source to get mail, you can specify it as in this +example: + +@lisp +(setq mail-sources + '((directory :path "/home/pavel/.Spool/" + :suffix "" + :plugged t))) +@end lisp + +Gnus will then fetch your mail even when you are unplugged. This is +useful when you use local mail and news. + +@end table +@end table + +@node Mail Source Functions +@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 is@* +@file{~/.emacs-mail-crash-box}. + +@cindex Incoming* +@item mail-source-delete-incoming +@vindex mail-source-delete-incoming +If non-@code{nil}, delete incoming files after handling them. If +@code{t}, delete the files immediately, if @code{nil}, never delete any +files. If a positive number, delete files older than number of days +(the deletion will only happen when receiving new mail). You may also +set @code{mail-source-delete-incoming} to @code{nil} and call +@code{mail-source-delete-old-incoming} from a hook or interactively. +@code{mail-source-delete-incoming} defaults to @code{10} in alpha Gnusae +and @code{2} in released Gnusae. @xref{Gnus Development}. + +@item mail-source-delete-old-incoming-confirm +@vindex mail-source-delete-old-incoming-confirm +If non-@code{nil}, ask for confirmation before deleting old incoming +files. This variable only applies when +@code{mail-source-delete-incoming} is a positive number. + +@item mail-source-ignore-errors +@vindex mail-source-ignore-errors +If non-@code{nil}, ignore errors when reading mail from a mail source. + +@item mail-source-directory +@vindex mail-source-directory +Directory where incoming mail source files (if any) will be stored. The +default is @file{~/Mail/}. At present, the only thing this is used for +is to say where the incoming files will be stored if the variable +@code{mail-source-delete-incoming} is @code{nil} or a number. + +@item mail-source-incoming-file-prefix +@vindex mail-source-incoming-file-prefix +Prefix for file name for storing incoming mail. The default is +@file{Incoming}, in which case files will end up with names like +@file{Incoming30630D_} or @file{Incoming298602ZD}. This is really only +relevant if @code{mail-source-delete-incoming} is @code{nil} or a +number. + +@item mail-source-default-file-modes +@vindex mail-source-default-file-modes +All new mail files will get this file mode. The default is @code{#o600}. + +@item mail-source-movemail-program +@vindex mail-source-movemail-program +If non-@code{nil}, name of program for fetching new mail. If +@code{nil}, @code{movemail} in @var{exec-directory}. + +@end table + + +@node Fetching Mail +@subsubsection Fetching Mail + +@vindex mail-sources +The way to actually tell Gnus where to get new mail from is to set +@code{mail-sources} to a list of mail source specifiers +(@pxref{Mail Source Specifiers}). + +If this variable 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 +mail---@code{nnmail-pre-get-new-mail-hook} (is called just before +starting to handle the new mail) and +@code{nnmail-post-get-new-mail-hook} (is called when the mail handling +is done). Here's and example of using these two hooks to change the +default file modes the new mail files get: + +@lisp +(add-hook 'nnmail-pre-get-new-mail-hook + (lambda () (set-default-file-modes #o700))) + +(add-hook 'nnmail-post-get-new-mail-hook + (lambda () (set-default-file-modes #o775))) +@end lisp + +@item nnmail-use-long-file-names +@vindex nnmail-use-long-file-names +If non-@code{nil}, the mail back ends will use long file and directory +names. Groups like @samp{mail.misc} will end up in directories +(assuming use of @code{nnml} back end) or files (assuming use of +@code{nnfolder} back end) like @file{mail.misc}. If it is @code{nil}, +the same group will end up in @file{mail/misc}. + +@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 non-@code{nil}, put the @code{Message-ID}s of articles imported into +the back end (via @code{Gcc}, for instance) into the mail duplication +discovery cache. The default is @code{nil}. + +@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 lists@dots{}} + (any "procmail@@informatik\\.rwth-aachen\\.de" "procmail.list") + (any "SmartList@@informatik\\.rwth-aachen\\.de" "SmartList.list") + ;; @r{Both lists below have the same suffix, so prevent} + ;; @r{cross-posting to mkpkg.list of messages posted only to} + ;; @r{the bugs- list, but allow cross-posting when the} + ;; @r{message was really cross-posted.} + (any "bugs-mypackage@@somewhere" "mypkg.bugs") + (any "mypackage@@somewhere" - "bugs-mypackage" "mypkg.list") + ;; @r{People@dots{}} + (any "larsi@@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) + ;; @r{Unmatched mail goes to the catch all group.} + "misc.misc") +@end lisp + +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. + +@c Don't fold this line. +@item (@var{field} @var{value} [- @var{restrict} [@dots{}] ] @var{split} [@var{invert-partial}]) +The split can be a list containing at least three elements. If the +first element @var{field} (a regexp matching a header) contains +@var{value} (also a regexp) then store the message as specified by +@var{split}. + +If @var{restrict} (yet another regexp) matches some string after +@var{field} and before the end of the matched @var{value}, the +@var{split} is ignored. If none of the @var{restrict} clauses match, +@var{split} is processed. + +The last element @var{invert-partial} is optional. If it is +non-@code{nil}, the match-partial-words behavior controlled by the +variable @code{nnmail-split-fancy-match-partial-words} (see below) is +be inverted. (New in Gnus 5.10.7) + +@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 header of the message in question when +@var{function} is run. That's why @code{(widen)} needs to be called +after @code{save-excursion} and @code{save-restriction} in the example +above. Also note that with the nnimap backend, message bodies will +not be downloaded by default. You need to set +@code{nnimap-split-download-body} to @code{t} to do that +(@pxref{Client-Side IMAP Splitting}). + +@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. + +Normally, @var{value} in these splits must match a complete @emph{word} +according to the fundamental mode syntax table. In other words, all +@var{value}'s will be implicitly surrounded by @code{\<...\>} markers, +which are word delimiters. Therefore, if you use the following split, +for example, + +@example +(any "joe" "joemail") +@end example + +@noindent +messages sent from @samp{joedavis@@foo.org} will normally not be filed +in @samp{joemail}. If you want to alter this behavior, you can use any +of the following three ways: + +@enumerate +@item +@vindex nnmail-split-fancy-match-partial-words +You can set the @code{nnmail-split-fancy-match-partial-words} variable +to non-@code{nil} in order to ignore word boundaries and instead the +match becomes more like a grep. This variable controls whether partial +words are matched during fancy splitting. The default value is +@code{nil}. + +Note that it influences all @var{value}'s in your split rules. + +@item +@var{value} beginning with @code{.*} ignores word boundaries in front of +a word. Similarly, if @var{value} ends with @code{.*}, word boundaries +in the rear of a word will be ignored. For example, the @var{value} +@code{"@@example\\.com"} does not match @samp{foo@@example.com} but +@code{".*@@example\\.com"} does. + +@item +You can set the @var{invert-partial} flag in your split rules of the +@samp{(@var{field} @var{value} @dots{})} types, aforementioned in this +section. If the flag is set, word boundaries on both sides of a word +are ignored even if @code{nnmail-split-fancy-match-partial-words} is +@code{nil}. Contrarily, if the flag is set, word boundaries are not +ignored even if @code{nnmail-split-fancy-match-partial-words} is +non-@code{nil}. (New in Gnus 5.10.7) +@end enumerate + +@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-lowercase-expanded +Where @code{nnmail-split-lowercase-expanded} controls whether the +lowercase of the matched string should be used for the substitution. +Setting it as non-@code{nil} is useful to avoid the creation of multiple +groups when users send to an address using different case +(i.e., mailing-list@@domain vs Mailing-List@@Domain). The default value +is @code{t}. + +@findex nnmail-split-fancy-with-parent +@code{nnmail-split-fancy-with-parent} is a function which allows you to +split followups into the same groups their parents are in. Sometimes +you can't make splitting rules for all your mail. For example, your +boss might send you personal mail regarding different projects you are +working on, and as you can't tell your boss to put a distinguishing +string into the subject line, you have to resort to manually moving the +messages into the right group. With this function, you only have to do +it once per thread. + +To use this feature, you have to set @code{nnmail-treat-duplicates} +and @code{nnmail-cache-accepted-message-ids} to a non-@code{nil} +value. And then you can include @code{nnmail-split-fancy-with-parent} +using the colon feature, like so: +@lisp +(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 +non-@code{nil}, Gnus records the message id of every message it sees +in the file specified by the variable +@code{nnmail-message-id-cache-file}, together with the group it is in +(the group is omitted for non-mail messages). When mail splitting is +invoked, the function @code{nnmail-split-fancy-with-parent} then looks +at the References (and In-Reply-To) header of each message to split +and searches the file specified by @code{nnmail-message-id-cache-file} +for the message ids. When it has found a parent, it returns the +corresponding group name unless the group name matches the regexp +@code{nnmail-split-fancy-with-parent-ignore-groups}. It is +recommended that you set @code{nnmail-message-id-cache-length} to a +somewhat higher number than the default so that the message ids are +still in the cache. (A value of 5000 appears to create a file some +300 kBytes in size.) +@vindex nnmail-cache-accepted-message-ids +When @code{nnmail-cache-accepted-message-ids} is non-@code{nil}, Gnus +also records the message ids of moved articles, so that the followup +messages goes into the new group. + +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 non-@code{nil}, @code{gnus-group-split-update} +will be added to @code{nnmail-pre-get-new-mail-hook}, so you won't ever +have to worry about updating @code{nnmail-split-fancy} again. If you +don't omit @var{catch-all} (it's optional, equivalent to @code{nil}), +@code{gnus-group-split-default-catch-all-group} will be set to its +value. + +@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 +@cindex expiring mail + +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. + +@vindex gnus-auto-expirable-marks +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. @code{gnus-auto-expirable-marks} has the full list of +these marks. + +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 non-@code{nil}, 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 non-@code{nil}, user marking +commands will not mark an article as expirable, even if the group has +auto-expire turned on. + +@vindex gnus-mark-copied-or-moved-articles-as-expirable +The expirable marks of articles will be removed when copying or moving +them to a group in which auto-expire is not turned on. This is for +preventing articles from being expired unintentionally. On the other +hand, to a group that has turned auto-expire on, the expirable marks of +articles that are copied or moved will not be changed by default. I.e., +when copying or moving to such a group, articles that were expirable +will be left expirable and ones that were not expirable will not be +marked as expirable. So, even though in auto-expire groups, some +articles will never get expired (unless you read them again). If you +don't side with that behavior that unexpirable articles may be mixed +into auto-expire groups, you can set +@code{gnus-mark-copied-or-moved-articles-as-expirable} to a +non-@code{nil} value. In that case, articles that have been read will +be marked as expirable automatically when being copied or moved to a +group that has auto-expire turned on. The default value is @code{nil}. + + +@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-ignore-broken-references +@findex nnmail-ignore-broken-references +@c @findex nnmail-fix-eudora-headers +@cindex Eudora +@cindex Pegasus +Some mail user agents (e.g., Eudora and Pegasus) produce broken +@code{References} headers, but correct @code{In-Reply-To} headers. This +function will get rid of the @code{References} header if the headers +contain a line matching the regular expression +@code{nnmail-broken-references-mailers}. + +@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 (pre-Emacs +23) Rmail file you have stashed away with @code{nnbabyl}. All back ends have +variables called back-end-@code{get-new-mail}. If you want to disable +the @code{nnbabyl} mail reading, you edit the virtual server for the +group to have a setting where @code{nnbabyl-get-new-mail} to @code{nil}. + +All the mail back ends will call @code{nn}*@code{-prepare-save-mail-hook} +narrowed to the article to be saved before saving it when reading +incoming mail. + + +@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. +* Babyl:: Babyl was used by older versions of Rmail. +* Mail Spool:: Store your mail in a private spool? +* MH Spool:: An mhspool-like back end. +* Maildir:: Another one-file-per-message format. +* nnmaildir Group Parameters:: +* Article Identification:: +* NOV Data:: +* Article Marks:: +* 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 non-@code{nil}, @code{nnmbox} will read incoming mail and split it +into groups. Default is @code{t}. +@end table + + +@node Babyl +@subsubsection Babyl +@cindex nnbabyl + +@vindex nnbabyl-active-file +@vindex nnbabyl-mbox-file +The @dfn{nnbabyl} back end will use a Babyl mail box to store mail. +@code{nnbabyl} will add extra headers to each mail article to say which +group it belongs in. + +Virtual server settings: + +@table @code +@item nnbabyl-mbox-file +@vindex nnbabyl-mbox-file +The name of the Babyl file. The default is @file{~/RMAIL} + +@item nnbabyl-active-file +@vindex nnbabyl-active-file +The name of the active file for the Babyl file. The default is +@file{~/.rmail-active} + +@item nnbabyl-get-new-mail +@vindex nnbabyl-get-new-mail +If non-@code{nil}, @code{nnbabyl} will read incoming mail. Default is +@code{t} +@end table + + +@node 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. + +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 non-@code{nil}, @code{nnml} will read incoming mail. The default is +@code{t}. + +@item nnml-nov-is-evil +@vindex nnml-nov-is-evil +If non-@code{nil}, this back end will ignore any @acronym{NOV} files. The +default is @code{nil}. + +@item 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-use-compressed-files +@vindex nnml-use-compressed-files +If non-@code{nil}, @code{nnml} will allow using compressed message +files. This requires @code{auto-compression-mode} to be enabled +(@pxref{Compressed Files, ,Compressed Files, emacs, The Emacs Manual}). +If the value of @code{nnml-use-compressed-files} is a string, it is used +as the file extension specifying the compression program. You can set it +to @samp{.bz2} if your Emacs supports it. A value of @code{t} is +equivalent to @samp{.gz}. + +@item nnml-compressed-files-size-threshold +@vindex nnml-compressed-files-size-threshold +Default size threshold for compressed message files. Message files with +bodies larger than that many characters will be automatically compressed +if @code{nnml-use-compressed-files} is non-@code{nil}. + +@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 non-@code{nil}, @code{nnmh} will read incoming mail. The default is +@code{t}. + +@item nnmh-be-safe +@vindex nnmh-be-safe +If non-@code{nil}, @code{nnmh} will go to ridiculous lengths to make +sure that the articles in the folder are actually what Gnus thinks +they are. It will check date stamps and stat everything in sight, so +setting this to @code{t} will mean a serious slow-down. If you never +use anything but Gnus to read the @code{nnmh} articles, you do not +have to set this variable to @code{t}. The default is @code{nil}. +@end table + + +@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 non-@code{nil}, then after scanning for new mail in the group +maildirs themselves as usual, this server will also incorporate mail +the conventional Gnus way, from @code{mail-sources} according to +@code{nnmail-split-methods} or @code{nnmail-split-fancy}. The default +value is @code{nil}. + +Do @emph{not} use the same maildir both in @code{mail-sources} and as +an @code{nnmaildir} group. The results might happen to be useful, but +that would be by chance, not by design, and the results might be +different in the future. If your split rules create new groups, +remember to supply a @code{create-directory} server parameter. +@end table + +@node nnmaildir Group Parameters +@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 (the +@code{expiry-wait} group parameter overrides @code{nnmail-expiry-wait} +and makes @code{nnmail-expiry-wait-function} ineffective). If you +wanted a value of 3 days, you could use something like @code{[(* 3 24 +60 60)]}; @code{nnmaildir} will evaluate the form and use the result. +An article's age is measured starting from the article file's +modification time. Normally, this is the same as the article's +delivery time, but editing an article makes it younger. Moving an +article (other than via expiry) may also make an article younger. + +@item expire-group +If this is set to a string such as a full Gnus group name, like +@example +"backend+server.address.string:group.name" +@end example +and if it is not the name of the same group that the parameter belongs +to, then articles will be moved to the specified group during expiry +before being deleted. @emph{If this is set to an @code{nnmaildir} +group, the article will be just as old in the destination group as it +was in the source group.} So be careful with @code{expire-age} in the +destination group. If this is set to the name of the same group that +the parameter belongs to, then the article is not expired at all. If +you use the vector form, the first element is evaluated once for each +article. So that form can refer to +@code{nnmaildir-article-file-name}, etc., to decide where to put the +article. @emph{Even if this parameter is not set, @code{nnmaildir} +does not fall back to the @code{expiry-target} group parameter or the +@code{nnmail-expiry-target} variable.} + +@item 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 non-@code{nil}, @code{nnmaildir} will always count the lines of an +article, rather than use the @code{Lines:} header field. If +@code{nil}, the header field will be used if present. + +@item 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 + +@node Article Identification +@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. + +@node NOV Data +@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. + +@node Article Marks +@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. + +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 non-@code{nil}, @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 non-@code{nil}, 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. + +@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's first mail reader, it was written by Richard Stallman, +and Stallman came out of that TOPS/Babyl environment, so he wrote Rmail +to understand the mail files folks already had in existence. Gnus (and +VM, for that matter) continue to support this format because it's +perceived as having some good qualities in those mailer-specific +headers/status bits stuff. Rmail itself still exists as well, of +course, and is still maintained within Emacs. Since Emacs 23, it +uses standard mbox format rather than Babyl. + +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 support---@code{nnmh} +is considered to be semantically equivalent to ``@code{nnml} without +active file or overviews''. This is arguably the worst choice, because +one gets the slowness of individual file creation married to the +slowness of access parsing when learning what's new in one's groups. + +@item 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, a 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{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. +* RSS:: Reading RDF site summary. +@end menu + +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. + +@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. + +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 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/site/recent-changes}). + +@acronym{RSS} has a quite regular and nice interface, and it's +possible to get the information Gnus needs to keep groups updated. + +Note: you had better use Emacs which supports the @code{utf-8} coding +system because @acronym{RSS} uses UTF-8 for encoding non-@acronym{ASCII} +text by default. It is also used by default for non-@acronym{ASCII} +group names. + +@kindex G R (Group) +Use @kbd{G R} from the group buffer to subscribe to a feed---you will be +prompted for the location, the title and the description of the feed. +The title, which allows any characters, will be used for the group name +and the name of the group data file. The description can be omitted. + +An easy way to get started with @code{nnrss} is to say something like +the following in the group buffer: @kbd{B nnrss RET RET y}, then +subscribe to groups. + +The @code{nnrss} back end saves the group data file in +@code{nnrss-directory} (see below) for each @code{nnrss} group. File +names containing non-@acronym{ASCII} characters will be encoded by the +coding system specified with the @code{nnmail-pathname-coding-system} +variable or other. Also @xref{Non-ASCII Group Names}, for more +information. + +The @code{nnrss} back end generates @samp{multipart/alternative} +@acronym{MIME} articles in which each contains a @samp{text/plain} part +and a @samp{text/html} part. + +@cindex OPML +You can also use the following commands to import and export your +subscriptions from a file in @acronym{OPML} format (Outline Processor +Markup Language). + +@defun nnrss-opml-import file +Prompt for an @acronym{OPML} file, and subscribe to each feed in the +file. +@end defun + +@defun nnrss-opml-export +Write your current @acronym{RSS} subscriptions to a buffer in +@acronym{OPML} format. +@end defun + +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-file-coding-system +@vindex nnrss-file-coding-system +The coding system used when reading and writing the @code{nnrss} groups +data files. The default is the value of +@code{mm-universal-coding-system} (which defaults to @code{emacs-mule} +in Emacs or @code{escape-quoted} in XEmacs). + +@item nnrss-ignore-article-fields +@vindex nnrss-ignore-article-fields +Some feeds update constantly article fields during their publications, +e.g., to indicate the number of comments. However, if there is +a difference between the local article and the distant one, the latter +is considered to be new. To avoid this and discard some fields, set this +variable to the list of fields to be ignored. The default is +@code{'(slash:comments)}. + +@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 "") 'browse-nnrss-url)) +(add-to-list 'nnmail-extra-headers nnrss-url-field) +@end lisp + +Even if you have added @samp{text/html} to the +@code{mm-discouraged-alternatives} variable (@pxref{Display +Customization, ,Display Customization, emacs-mime, The Emacs MIME +Manual}) since you don't want to see @acronym{HTML} parts, it might be +more useful especially in @code{nnrss} groups to display +@samp{text/html} parts. Here's an example of setting +@code{mm-discouraged-alternatives} as a group parameter (@pxref{Group +Parameters}) in order to display @samp{text/html} parts only in +@code{nnrss} groups: + +@lisp +;; @r{Set the default value of @code{mm-discouraged-alternatives}.} +(eval-after-load "gnus-sum" + '(add-to-list + 'gnus-newsgroup-variables + '(mm-discouraged-alternatives + . '("text/html" "image/.*")))) + +;; @r{Display @samp{text/html} parts in @code{nnrss} groups.} +(add-to-list + 'gnus-parameters + '("\\`nnrss:" (mm-discouraged-alternatives nil))) +@end lisp + + +@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. +* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. +* The Empty Backend:: The backend that never has any news. +@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 +non-@code{nil}, 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 +@item babyl +The Babyl format. + +@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. + +@cindex rnews batch files +@item rnews +The rnews batch transport format. + +@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. + +@cindex git commit messages +@item git +@code{git} commit messages. + +@cindex forwarded messages +@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. To do more +complicated things that cannot be dealt with a simple regexp, you can +use @code{article-begin-function} instead of this. + +@item article-begin-function +If present, this should be a function that moves point to the beginning +of each article. This setting overrides @code{article-begin}. + +@item head-begin +If present, this should be a regexp that matches the head of the +article. To do more complicated things that cannot be dealt with a +simple regexp, you can use @code{head-begin-function} instead of this. + +@item head-begin-function +If present, this should be a function that moves point to the head of +the article. This setting overrides @code{head-begin}. + +@item head-end +This should match the end of the head of the article. It defaults to +@samp{^$}---the empty line. + +@item body-begin +This should match the beginning of the body of the article. It defaults +to @samp{^\n}. To do more complicated things that cannot be dealt with +a simple regexp, you can use @code{body-begin-function} instead of this. + +@item body-begin-function +If present, this function should move point to the beginning of the body +of the article. This setting overrides @code{body-begin}. + +@item body-end +If present, this should match the end of the body of the article. To do +more complicated things that cannot be dealt with a simple regexp, you +can use @code{body-end-function} instead of this. + +@item body-end-function +If present, this function should move point to the end of the body of +the article. This setting overrides @code{body-end}. + +@item file-begin +If present, this should match the beginning of the file. All text +before this regexp will be totally ignored. + +@item file-end +If present, this should match the end of the file. All text after this +regexp will be totally ignored. + +@end table + +So, using these variables @code{nndoc} is able to dissect a document +file into a series of articles, each with a head and a body. However, a +few more variables are needed since not all document types are all that +news-like---variables needed to transform the head or the body into +something that's palatable for Gnus: + +@table @code +@item prepare-body-function +If present, this function will be called when requesting an article. It +will be called with point at the start of the body, and is useful if the +document has encoded some parts of its contents. + +@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. + +@item generate-head-function +If present, this function is called to generate a head that Gnus can +understand. It is called with the article number as a parameter, and is +expected to generate a nice head for the article in question. It is +called when requesting the headers of all articles. + +@item generate-article-function +If present, this function is called to generate an entire article that +Gnus can understand. It is called with the article number as a +parameter when requesting all articles. + +@item dissection-function +If present, this function is called to dissect a document by itself, +overriding @code{first-article}, @code{article-begin}, +@code{article-begin-function}, @code{head-begin}, +@code{head-begin-function}, @code{head-end}, @code{body-begin}, +@code{body-begin-function}, @code{body-end}, @code{body-end-function}, +@code{file-begin}, and @code{file-end}. + +@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 +@code{nndoc-@var{type}-type-p} is called for a given type @var{type}. +So @code{nndoc-mmdf-type-p} is called to see whether a document is of +@code{mmdf} type, and so on. These type predicates should return +@code{nil} if the document is not of the correct type; @code{t} if it +is of the correct type; and a number if the document might be of the +correct type. A high number means high probability; a low number +means low probability with @samp{0} being the lowest valid number. + + +@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 +@item nngateway-address +@vindex nngateway-address +This is the address of the mail-to-news gateway. + +@item nngateway-header-transformation +@vindex nngateway-header-transformation +News headers often have to be transformed in some odd way or other +for the mail-to-news gateway to accept it. This variable says what +transformation should be called, and defaults to +@code{nngateway-simple-header-transformation}. The function is called +narrowed to the headers to be transformed and with one parameter---the +gateway address. + +This default function just inserts a new @code{To} header based on the +@code{Newsgroups} header and the gateway address. +For instance, an article with this @code{Newsgroups} header: + +@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: + +@findex nngateway-simple-header-transformation +@table @code + +@item nngateway-simple-header-transformation +Creates a @code{To} header that looks like +@var{newsgroup}@@@code{nngateway-address}. + +@findex nngateway-mail2news-header-transformation + +@item nngateway-mail2news-header-transformation +Creates a @code{To} header that looks like +@code{nngateway-address}. +@end table + +@end table + +Here's an example: + +@lisp +(setq gnus-post-method + '(nngateway + "mail2news@@replay.com" + (nngateway-header-transformation + nngateway-mail2news-header-transformation))) +@end lisp + +So, to use this, simply say something like: + +@lisp +(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS")) +@end lisp + + +@node The Empty Backend +@subsection The Empty Backend +@cindex nnnil + +@code{nnnil} is a backend that can be used as a placeholder if you +have to specify a backend somewhere, but don't really want to. The +classical example is if you don't want to have a primary select +methods, but want to only use secondary ones: + +@lisp +(setq gnus-select-method '(nnnil "")) +(setq gnus-secondary-select-methods + '((nnimap "foo") + (nnml ""))) +@end lisp + + +@node Combined Groups +@section Combined Groups + +Gnus allows combining a mixture of all the other group types into bigger +groups. + +@menu +* Virtual Groups:: Combining articles from many groups. +@end menu + + +@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} variable is non-@code{nil} (which +is the default), @code{nnvirtual} will always scan groups for unread +articles when entering a virtual group. If this variable is @code{nil} +and you read articles in a component group after the virtual group has +been activated, the read articles from the component group will show up +when you enter the virtual group. You'll also see this effect if you +have two virtual groups that have a component group in common. If +that's the case, you should set this variable to @code{t}. Or you can +just tap @code{M-g} on the virtual group every time before you enter +it---it'll have much the same effect. + +@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 Email Based Diary +@section Email Based Diary +@cindex diary +@cindex email based diary +@cindex calendar + +This section describes a special mail back end called @code{nndiary}, +and its companion library @code{gnus-diary}. It is ``special'' in the +sense that it is not meant to be one of the standard alternatives for +reading mail with Gnus. See @ref{Choosing a Mail Back End} for that. +Instead, it is used to treat @emph{some} of your mails in a special way, +namely, as event reminders. + +Here is a typical scenario: + +@itemize @bullet +@item +You've got a date with Andy Mc Dowell or Bruce Willis (select according +to your sexual preference) in one month. You don't want to forget it. +@item +So you send a ``reminder'' message (actually, a diary one) to yourself. +@item +You forget all about it and keep on getting and reading new mail, as usual. +@item +From time to time, as you type @kbd{g} in the group buffer and as the date +is getting closer, the message will pop up again to remind you of your +appointment, just as if it were new and unread. +@item +Read your ``new'' messages, this one included, and start dreaming again +of the night you're gonna have. +@item +Once the date is over (you actually fell asleep just after dinner), the +message will be automatically deleted if it is marked as expirable. +@end itemize + +The Gnus Diary back end has the ability to handle regular appointments +(that wouldn't ever be deleted) as well as punctual ones, operates as a +real mail back end and is configurable in many ways. All of this is +explained in the sections below. + +@menu +* The NNDiary Back End:: Basic setup and usage. +* The Gnus Diary Library:: Utility toolkit on top of nndiary. +* Sending or Not Sending:: A final note on sending diary messages. +@end menu + + +@node The NNDiary Back End +@subsection The NNDiary Back End +@cindex nndiary +@cindex the nndiary back end + +@code{nndiary} is a back end very similar to @code{nnml} (@pxref{Mail +Spool}). Actually, it could appear as a mix of @code{nnml} and +@code{nndraft}. If you know @code{nnml}, you're already familiar with +the message storing scheme of @code{nndiary}: one file per message, one +directory per group. + + Before anything, there is one requirement to be able to run +@code{nndiary} properly: you @emph{must} use the group timestamp feature +of Gnus. This adds a timestamp to each group's parameters. @ref{Group +Timestamp} to see how it's done. + +@menu +* Diary Messages:: What makes a message valid for nndiary. +* Running NNDiary:: NNDiary has two modes of operation. +* Customizing NNDiary:: Bells and whistles. +@end menu + +@node Diary Messages +@subsubsection Diary Messages +@cindex nndiary messages +@cindex nndiary mails + +@code{nndiary} messages are just normal ones, except for the mandatory +presence of 7 special headers. These headers are of the form +@code{X-Diary-}, @code{} being one of +@code{Minute}, @code{Hour}, @code{Dom}, @code{Month}, @code{Year}, +@code{Time-Zone} and @code{Dow}. @code{Dom} means ``Day of Month'', and +@code{dow} means ``Day of Week''. These headers actually behave like +crontab specifications and define the event date(s): + +@itemize @bullet +@item +For all headers except the @code{Time-Zone} one, a header value is +either a star (meaning all possible values), or a list of fields +(separated by a comma). +@item +A field is either an integer, or a range. +@item +A range is two integers separated by a dash. +@item +Possible integer values are 0--59 for @code{Minute}, 0--23 for +@code{Hour}, 1--31 for @code{Dom}, 1--12 for @code{Month}, above 1971 +for @code{Year} and 0--6 for @code{Dow} (0 meaning Sunday). +@item +As a special case, a star in either @code{Dom} or @code{Dow} doesn't +mean ``all possible values'', but ``use only the other field''. Note +that if both are star'ed, the use of either one gives the same result. +@item +The @code{Time-Zone} header is special in that it can only have one +value (@code{GMT}, for instance). A star doesn't mean ``all possible +values'' (because it makes no sense), but ``the current local time +zone''. Most of the time, you'll be using a star here. However, for a +list of available time zone values, see the variable +@code{nndiary-headers}. +@end itemize + +As a concrete example, here are the diary headers to add to your message +for specifying ``Each Monday and each 1st of month, at 12:00, 20:00, +21:00, 22:00, 23:00 and 24:00, from 1999 to 2010'' (I'll let you find +what to do then): + +@example +X-Diary-Minute: 0 +X-Diary-Hour: 12, 20-24 +X-Diary-Dom: 1 +X-Diary-Month: * +X-Diary-Year: 1999-2010 +X-Diary-Dow: 1 +X-Diary-Time-Zone: * +@end example + +@node Running NNDiary +@subsubsection Running NNDiary +@cindex running nndiary +@cindex nndiary operation modes + +@code{nndiary} has two modes of operation: ``traditional'' (the default) +and ``autonomous''. In traditional mode, @code{nndiary} does not get new +mail by itself. You have to move (@kbd{B m}) or copy (@kbd{B c}) mails +from your primary mail back end to nndiary groups in order to handle them +as diary messages. In autonomous mode, @code{nndiary} retrieves its own +mail and handles it independently from your primary mail back end. + +One should note that Gnus is not inherently designed to allow several +``master'' mail back ends at the same time. However, this does make +sense with @code{nndiary}: you really want to send and receive diary +messages to your diary groups directly. So, @code{nndiary} supports +being sort of a ``second primary mail back end'' (to my knowledge, it is +the only back end offering this feature). However, there is a limitation +(which I hope to fix some day): respooling doesn't work in autonomous +mode. + +In order to use @code{nndiary} in autonomous mode, you have several +things to do: + +@itemize @bullet +@item +Allow @code{nndiary} to retrieve new mail by itself. Put the following +line in your @file{~/.gnus.el} file: + +@lisp +(setq nndiary-get-new-mail t) +@end lisp +@item +You must arrange for diary messages (those containing @code{X-Diary-*} +headers) to be split in a private folder @emph{before} Gnus treat them. +Again, this is needed because Gnus cannot (yet ?) properly handle +multiple primary mail back ends. Getting those messages from a separate +source will compensate this misfeature to some extent. + +As an example, here's my procmailrc entry to store diary files in +@file{~/.nndiary} (the default @code{nndiary} mail source file): + +@example +:0 HD : +* ^X-Diary +.nndiary +@end example +@end itemize + +Once this is done, you might want to customize the following two options +that affect the diary mail retrieval and splitting processes: + +@defvar nndiary-mail-sources +This is the diary-specific replacement for the standard +@code{mail-sources} variable. It obeys the same syntax, and defaults to +@code{(file :path "~/.nndiary")}. +@end defvar + +@defvar nndiary-split-methods +This is the diary-specific replacement for the standard +@code{nnmail-split-methods} variable. It obeys the same syntax. +@end defvar + + Finally, you may add a permanent @code{nndiary} virtual server +(something like @code{(nndiary "diary")} should do) to your +@code{gnus-secondary-select-methods}. + + Hopefully, almost everything (see the TODO section in +@file{nndiary.el}) will work as expected when you restart Gnus: in +autonomous mode, typing @kbd{g} and @kbd{M-g} in the group buffer, will +also get your new diary mails and split them according to your +diary-specific rules, @kbd{F} will find your new diary groups etc. + +@node Customizing NNDiary +@subsubsection Customizing NNDiary +@cindex customizing nndiary +@cindex nndiary customization + +Now that @code{nndiary} is up and running, it's time to customize it. +The custom group is called @code{nndiary} (no, really ?!). You should +browse it to figure out which options you'd like to tweak. The following +two variables are probably the only ones you will want to change: + +@defvar nndiary-reminders +This is the list of times when you want to be reminded of your +appointments (e.g., 3 weeks before, then 2 days before, then 1 hour +before and that's it). Remember that ``being reminded'' means that the +diary message will pop up as brand new and unread again when you get new +mail. +@end defvar + +@defvar nndiary-week-starts-on-monday +Rather self-explanatory. Otherwise, Sunday is assumed (this is the +default). +@end defvar + + +@node The Gnus Diary Library +@subsection The Gnus Diary Library +@cindex gnus-diary +@cindex the gnus diary library + +Using @code{nndiary} manually (I mean, writing the headers by hand and +so on) would be rather boring. Fortunately, there is a library called +@code{gnus-diary} written on top of @code{nndiary}, that does many +useful things for you. + + In order to use it, add the following line to your @file{~/.gnus.el} file: + +@lisp +(require 'gnus-diary) +@end lisp + + Also, you shouldn't use any @code{gnus-user-format-function-[d|D]} +(@pxref{Summary Buffer Lines}). @code{gnus-diary} provides both of these +(sorry if you used them before). + + +@menu +* Diary Summary Line Format:: A nicer summary buffer line format. +* Diary Articles Sorting:: A nicer way to sort messages. +* Diary Headers Generation:: Not doing it manually. +* Diary Group Parameters:: Not handling them manually. +@end menu + +@node Diary Summary Line Format +@subsubsection Diary Summary Line Format +@cindex diary summary buffer line +@cindex diary summary line format + +Displaying diary messages in standard summary line format (usually +something like @samp{From Joe: Subject}) is pretty useless. Most of +the time, you're the one who wrote the message, and you mostly want to +see the event's date. + + @code{gnus-diary} provides two supplemental user formats to be used in +summary line formats. @code{D} corresponds to a formatted time string +for the next occurrence of the event (e.g., ``Sat, Sep 22 01, 12:00''), +while @code{d} corresponds to an approximate remaining time until the +next occurrence of the event (e.g., ``in 6 months, 1 week''). + + For example, here's how Joe's birthday is displayed in my +@code{nndiary+diary:birthdays} summary buffer (note that the message is +expirable, but will never be deleted, as it specifies a periodic event): + +@example + E Sat, Sep 22 01, 12:00: Joe's birthday (in 6 months, 1 week) +@end example + +In order to get something like the above, you would normally add the +following line to your diary groups'parameters: + +@lisp +(gnus-summary-line-format "%U%R%z %uD: %(%s%) (%ud)\n") +@end lisp + +However, @code{gnus-diary} does it automatically (@pxref{Diary Group +Parameters}). You can however customize the provided summary line format +with the following user options: + +@defvar gnus-diary-summary-line-format +Defines the summary line format used for diary groups (@pxref{Summary +Buffer Lines}). @code{gnus-diary} uses it to automatically update the +diary groups'parameters. +@end defvar + +@defvar gnus-diary-time-format +Defines the format to display dates in diary summary buffers. This is +used by the @code{D} user format. See the docstring for details. +@end defvar + +@defvar gnus-diary-delay-format-function +Defines the format function to use for displaying delays (remaining +times) in diary summary buffers. This is used by the @code{d} user +format. There are currently built-in functions for English and French; +you can also define your own. See the docstring for details. +@end defvar + +@node Diary Articles Sorting +@subsubsection Diary Articles Sorting +@cindex diary articles sorting +@cindex diary summary lines sorting +@findex gnus-summary-sort-by-schedule +@findex gnus-thread-sort-by-schedule +@findex gnus-article-sort-by-schedule + +@code{gnus-diary} provides new sorting functions (@pxref{Sorting the +Summary Buffer} ) called @code{gnus-summary-sort-by-schedule}, +@code{gnus-thread-sort-by-schedule} and +@code{gnus-article-sort-by-schedule}. These functions let you organize +your diary summary buffers from the closest event to the farthest one. + +@code{gnus-diary} automatically installs +@code{gnus-summary-sort-by-schedule} as a menu item in the summary +buffer's ``sort'' menu, and the two others as the primary (hence +default) sorting functions in the group parameters (@pxref{Diary Group +Parameters}). + +@node Diary Headers Generation +@subsubsection Diary Headers Generation +@cindex diary headers generation +@findex gnus-diary-check-message + +@code{gnus-diary} provides a function called +@code{gnus-diary-check-message} to help you handle the @code{X-Diary-*} +headers. This function ensures that the current message contains all the +required diary headers, and prompts you for values or corrections if +needed. + + This function is hooked into the @code{nndiary} back end, so that +moving or copying an article to a diary group will trigger it +automatically. It is also bound to @kbd{C-c C-f d} in +@code{message-mode} and @code{article-edit-mode} in order to ease the +process of converting a usual mail to a diary one. + + This function takes a prefix argument which will force prompting of +all diary headers, regardless of their presence or validity. That way, +you can very easily reschedule an already valid diary message, for +instance. + +@node Diary Group Parameters +@subsubsection Diary Group Parameters +@cindex diary group parameters + +When you create a new diary group, or visit one, @code{gnus-diary} +automatically checks your group parameters and if needed, sets the +summary line format to the diary-specific value, installs the +diary-specific sorting functions, and also adds the different +@code{X-Diary-*} headers to the group's posting-style. It is then easier +to send a diary message, because if you use @kbd{C-u a} or @kbd{C-u m} +on a diary group to prepare a message, these headers will be inserted +automatically (although not filled with proper values yet). + +@node Sending or Not Sending +@subsection Sending or Not Sending + +Well, assuming you've read all of the above, here are two final notes on +mail sending with @code{nndiary}: + +@itemize @bullet +@item +@code{nndiary} is a @emph{real} mail back end. You really send real diary +messages for real. This means for instance that you can give +appointments to anybody (provided they use Gnus and @code{nndiary}) by +sending the diary message to them as well. +@item +However, since @code{nndiary} also has a @code{request-post} method, you +can also use @kbd{C-u a} instead of @kbd{C-u m} on a diary group and the +message won't actually be sent; just stored locally in the group. This +comes in very handy for private appointments. +@end itemize + +@node Gnus Unplugged +@section Gnus Unplugged +@cindex offline +@cindex unplugged +@cindex agent +@cindex Gnus agent +@cindex Gnus unplugged + +In olden times (ca. February '88), people used to run their newsreaders +on big machines with permanent connections to the net. News transport +was dealt with by news servers, and all the newsreaders had to do was to +read news. Believe it or not. + +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 have to configure anything as the agent is now enabled +by default (@pxref{Agent Variables, gnus-agent}). + +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 flags:: How the Agent maintains flags. +* Agent and IMAP:: How to use the Agent with @acronym{IMAP}. +* Outgoing Messages:: What happens when you post/mail something? +* Agent Variables:: Customizing is fun. +* Example Setup:: An example @file{~/.gnus.el} file for offline people. +* Batching Agents:: How to fetch news from a @code{cron} job. +* Agent Caveats:: What you think it'll do and what it does. +@end menu + + +@node Agent 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, +no servers 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 +Uhm@dots{} 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 agent-groups +The list of groups that are in this category. + +@item agent-predicate +A predicate which (generally) gives a rough outline of which articles +are eligible for downloading; and + +@item agent-score +a score rule which (generally) gives you a finer granularity when +deciding what articles to download. (Note that this @dfn{download +score} is not necessarily related to normal scores.) + +@item agent-enable-expiration +a boolean indicating whether the agent should expire old articles in +this group. Most groups should be expired to conserve disk space. In +fact, its probably safe to say that the gnus.* hierarchy contains the +only groups that should not be expired. + +@item agent-days-until-old +an integer indicating the number of days that the agent should wait +before deciding that a read article is safe to expire. + +@item agent-low-score +an integer that overrides the value of @code{gnus-agent-low-score}. + +@item agent-high-score +an integer that overrides the value of @code{gnus-agent-high-score}. + +@item agent-short-article +an integer that overrides the value of +@code{gnus-agent-short-article}. + +@item agent-long-article +an integer that overrides the value of @code{gnus-agent-long-article}. + +@item agent-enable-undownloaded-faces +a symbol indicating whether the summary buffer should display +undownloaded articles using the @code{gnus-summary-*-undownloaded-face} +faces. Any symbol other than @code{nil} will enable the use of +undownloaded faces. +@end table + +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 if the article is shorter than @code{gnus-agent-short-article} +lines; default 100. + +@item long +True if the article is longer than @code{gnus-agent-long-article} +lines; default 200. + +@item low +True if the article has a download score less than +@code{gnus-agent-low-score}; default 0. + +@item high +True if the article has a download score greater than +@code{gnus-agent-high-score}; default 0. + +@item spam +True if the Gnus Agent guesses that the article is spam. The +heuristics may change over time, but at present it just computes a +checksum and sees whether articles match. + +@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-summary-fetch-series +Download all processable articles in this group. +(@code{gnus-agent-summary-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 those +users using the agent to improve online performance by caching the NOV +database (most users since 5.10.2), the undownloaded faces may appear +to be an absolutely horrible idea. The issue being that, since none +of their articles have been fetched into the Agent, all of the +normal faces will be obscured by the undownloaded faces. + +If you would like to use the undownloaded faces, you must enable the +undownloaded faces by setting the @code{agent-enable-undownloaded-faces} +group parameter to @code{t}. This parameter, like all other agent +parameters, may be set on an Agent Category (@pxref{Agent Categories}), +a Group Topic (@pxref{Topic Parameters}), or an individual group +(@pxref{Group Parameters}). + +The one problem common to all users using the agent is how quickly it +can consume disk space. If you using the agent on many groups, it is +even more difficult to effectively recover disk space. One solution +is the @samp{%F} format available in @code{gnus-group-line-format}. +This format will display the actual disk space used by articles +fetched into both the agent and cache. By knowing which groups use +the most space, users know where to focus their efforts when ``agent +expiring'' articles. + +@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, in Gnus agent + +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 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 non-@code{nil}, the agent +expiration commands will expire all articles---unread, read, ticked +and dormant. If @code{nil} (which is the default), only read articles +are eligible for expiry, and unread, ticked and dormant articles will +be kept indefinitely. + +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 flags +@subsection Agent and flags + +The Agent works with any Gnus back end including those, such as +nnimap, that store flags (read, ticked, etc.)@: on the server. Sadly, +the Agent does not actually know which backends keep their flags in +the backend server rather than in @file{.newsrc}. This means that the +Agent, while unplugged or disconnected, will always record all changes +to the flags in its own files. + +When you plug back in, Gnus will then check to see if you have any +changed any flags and ask if you wish to synchronize these with the +server. This behavior is customizable by @code{gnus-agent-synchronize-flags}. + +@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. + +Technical note: the synchronization algorithm does not work by ``pushing'' +all local flags to the server, but rather by incrementally updated the +server view of flags by changing only those flags that were changed by +the user. Thus, if you set one flag on an article, quit the group then +re-select the group and remove the flag; the flag will be set and +removed from the server when you ``synchronize''. The queued flag +operations can be found in the per-server @code{flags} file in the Agent +directory. It's emptied when you synchronize flags. + +@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. + +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 + +@node Outgoing Messages +@subsection Outgoing Messages + +By default, when Gnus is unplugged, all outgoing messages (both mail +and news) are stored in the draft group ``queue'' (@pxref{Drafts}). +You can view them there after posting, and edit them at will. + +You can control the circumstances under which outgoing mail is queued +(see @code{gnus-agent-queue-mail}, @pxref{Agent Variables}). Outgoing +news is always queued when Gnus is unplugged, and never otherwise. + +You can send the messages either from the draft group with the special +commands available there, or you can use the @kbd{J S} command in the +group buffer to send all the sendable messages in the draft group. +Posting news will only work when Gnus is plugged, but you can send +mail at any time. + +If sending mail while unplugged does not work for you and you worry +about hitting @kbd{J S} by accident when unplugged, you can have Gnus +ask you to confirm your action (see +@code{gnus-agent-prompt-send-queue}, @pxref{Agent Variables}). + +@node Agent Variables +@subsection Agent Variables + +@table @code +@item gnus-agent +@vindex gnus-agent +Is the agent enabled? The default is @code{t}. When first enabled, +the agent will use @code{gnus-agent-auto-agentize-methods} to +automatically mark some back ends as agentized. You may change which +back ends are agentized using the agent commands in the server buffer. + +To enter the server buffer, use the @kbd{^} +(@code{gnus-group-enter-server-mode}) command in the group buffer. + + +@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 non-@code{nil}, 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 non-@code{nil}, +mark articles as unread after downloading. This is usually a safe +thing to do as the newly downloaded article has obviously not been +read. The default is @code{t}. + +@item gnus-agent-synchronize-flags +@vindex gnus-agent-synchronize-flags +If @code{gnus-agent-synchronize-flags} is @code{nil}, the Agent will +never automatically synchronize flags. If it is @code{ask}, which is +the default, the Agent will check if you made any changes and if so +ask if you wish to synchronize these when you re-connect. If it has +any other value, all flags will be synchronized automatically. + +@item gnus-agent-consider-all-articles +@vindex gnus-agent-consider-all-articles +If @code{gnus-agent-consider-all-articles} is non-@code{nil}, the +agent will let the agent predicate decide whether articles need to be +downloaded or not, for all articles. When @code{nil}, the default, +the agent will only let the predicate decide whether unread articles +are downloaded or not. If you enable this, you may also want to look +into the agent expiry settings (@pxref{Category Variables}), so that +the agent doesn't download articles which the agent will later expire, +over and over again. + +@item gnus-agent-max-fetch-size +@vindex gnus-agent-max-fetch-size +The agent fetches articles into a temporary buffer prior to parsing +them into individual files. To avoid exceeding the max. buffer size, +the agent alternates between fetching and parsing until all articles +have been fetched. @code{gnus-agent-max-fetch-size} provides a size +limit to control how often the cycling occurs. A large value improves +performance. A small value minimizes the time lost should the +connection be lost while fetching (You may need to run +@code{gnus-agent-regenerate-group} to update the group's state. +However, all articles parsed prior to losing the connection will be +available while unplugged). The default is 10M so it is unusual to +see any cycling. + +@item 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 valid values are @code{nil} (maneuver to any article), +@code{undownloaded} (maneuvering while unplugged ignores articles that +have not been fetched), @code{always-undownloaded} (maneuvering always +ignores articles that have not been fetched), @code{unfetched} +(maneuvering ignores articles whose headers have not been fetched). + +@item gnus-agent-queue-mail +@vindex gnus-agent-queue-mail +When @code{gnus-agent-queue-mail} is @code{always}, Gnus will always +queue mail rather than sending it straight away. When @code{t}, Gnus +will queue mail when unplugged only. When @code{nil}, never queue +mail. The default is @code{t}. + +@item gnus-agent-prompt-send-queue +@vindex gnus-agent-prompt-send-queue +When @code{gnus-agent-prompt-send-queue} is non-@code{nil} Gnus will +prompt you to confirm that you really wish to proceed if you hit +@kbd{J S} while unplugged. The default is @code{nil}. + +@item gnus-agent-auto-agentize-methods +@vindex gnus-agent-auto-agentize-methods +If you have never used the Agent before (or more technically, if +@file{~/News/agent/lib/servers} does not exist), Gnus will +automatically agentize a few servers for you. This variable control +which back ends should be auto-agentized. It is typically only useful +to agentize remote back ends. The auto-agentizing has the same effect +as running @kbd{J a} on the servers (@pxref{Server Agent Commands}). +If the file exist, you must manage the servers manually by adding or +removing them, this variable is only applicable the first time you +start Gnus. The default is @samp{nil}. + +@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 -l ~/.gnus.el -f 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 behavior, 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. +* 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 @file{*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 @samp{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 e +@kindex W e (Group) +@findex gnus-score-edit-all-score +Edit the apply-to-all-groups all.SCORE file. You will be popped into +a @code{gnus-score-mode} buffer (@pxref{Score File Editing}). + +@item W f +@kindex W f (Group) +@findex gnus-score-flush-cache +Gnus maintains a cache of score alists to avoid having to reload them +all the time. This command will flush the cache +(@code{gnus-score-flush-cache}). + +@end table + +You can do scoring from the command line by saying something like: + +@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, this might make your Emacs grow big and +bloated, so this regexp can be used to weed out score files unlikely +to be needed again. It would be a bad idea to deny caching of +@file{all.SCORE}, while it might be a good idea to not cache +@file{comp.infosystems.www.authoring.misc.ADAPT}. In fact, this +variable is @samp{ADAPT$} by default, so no adaptive score files will +be cached. + +@item gnus-save-score +@vindex gnus-save-score +If you have really complicated score files, and do lots of batch +scoring, then you might set this variable to @code{t}. This will make +Gnus save the scores into the @file{.newsrc.eld} file. + +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 non-@code{nil}, temporary score entries that have +been triggered (matched) will have their dates updated. (This is how Gnus +controls expiry---all non-matched-entries will become too old while +matched entries will stay fresh and young.) However, if you set this +variable to @code{nil}, even matched entries will grow old and will +have to face that oh-so grim reaper. + +@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 non-@code{nil}, article subjects will be +simplified for subject scoring purposes in the same manner as with +threading---according to the current value of +@code{gnus-simplify-subject-functions}. If the scoring entry uses +@code{substring} or @code{exact} matching, the match will also be +simplified in this manner. + +@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 non-@code{nil}. 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 first---@var{YYYYMMDD}@code{T}@var{HHMMSS}. If +you want to match all articles that have been posted on April 1st in +every year, you could use @samp{....0401.........} as a match string, +for instance. (Note that the date is kept in its original time zone, so +this will match articles that were posted when it was April 1st where +the article was posted from. Time zones are such wholesome fun for the +whole family, eh?) + +@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 to 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 +nondeterministic 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}ed. 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-exit +Save the changes you have made and return to the summary buffer +(@code{gnus-score-edit-exit}). + +@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-adaptive-pretty-print +Adaptive score files can get huge and are not meant to be edited by +human hands. If @code{gnus-adaptive-pretty-print} is @code{nil} (the +default) those files will not be written in a human readable way. + +@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 non-@code{nil}, the result will +be used as the home score file. The function will be called with the +name of the group as the parameter. + +@item +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 + + +@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" + ("" + 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'' +headers---@samp{From}, @samp{Subject} and so on. However, scoring +other headers requires writing a @code{head} scoring rule, which means +that Gnus has to request every single article from the back end to find +matches. This takes a long time in big groups. + +@vindex gnus-inhibit-slow-scoring +You can inhibit this slow scoring on headers or body by setting the +variable @code{gnus-inhibit-slow-scoring}. If +@code{gnus-inhibit-slow-scoring} is regexp, slow scoring is inhibited if +the group matches the regexp. If it is @code{t}, slow scoring on it is +inhibited for all groups. + +Now, there's not much you can do about the slowness for news groups, but for +mail groups, you have greater control. In @ref{To From Newsgroups}, +it's explained in greater detail what this mechanism does, but here's +a cookbook example for @code{nnml} on how to allow scoring on the +@samp{To} and @samp{Cc} headers. + +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 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 non-@code{nil}, 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 Emacs by default. +You can fetch it from the contrib directory of the Gnus distribution or +from +@uref{http://heim.ifi.uio.no/~larsi/ding-various/gnus-kill-to-score.el}. + +If your old kill files are very complex---if they contain more +non-@code{gnus-kill} forms than not, you'll have to convert them by +hand. Or just let them be as they are. Gnus will still use them as +before. + + +@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 +non-@code{nil} 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 Eigil 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 + +Suppose you're reading a high volume group and you're only interested +in replies. The plan is to score down all articles that don't have +subject that begin with "Re:", "Fw:" or "Fwd:" and then score up all +parents of articles that have subjects that begin with reply marks. + +@example +((! ("subject" "re:\\|fwd?:" r)) + -200) +((1- ("subject" "re:\\|fwd?:" r)) + 200) +@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 +non-@code{nil}, Gnus will run the score files through the decaying +mechanism thereby lowering the scores of all non-permanent score rules. +If @code{gnus-decay-scores} is a regexp, only score files matching this +regexp are treated. E.g., you may set it to @samp{\\.ADAPT\\'} if only +@emph{adaptive} score files should be decayed. The decay itself if +performed by the @code{gnus-decay-score-function} function, which is +@code{gnus-decay-score} by default. Here's the definition of that +function: + +@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's 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. + +@node Searching +@chapter Searching +@cindex searching + +FIXME: Add a brief overview of Gnus search capabilities. A brief +comparison of nnir, nnmairix, contrib/gnus-namazu would be nice +as well. + +This chapter describes tools for searching groups and servers for +articles matching a query and then retrieving those articles. Gnus +provides a simpler mechanism for searching through articles in a summary buffer +to find those matching a pattern. @xref{Searching for Articles}. + +@menu +* nnir:: Searching with various engines. +* nnmairix:: Searching with Mairix. +@end menu + +@node nnir +@section nnir +@cindex nnir + +This section describes how to use @code{nnir} to search for articles +within gnus. + +@menu +* What is nnir?:: What does @code{nnir} do? +* Basic Usage:: How to perform simple searches. +* Setting up nnir:: How to set up @code{nnir}. +@end menu + +@node What is nnir? +@subsection What is nnir? + +@code{nnir} is a Gnus interface to a number of tools for searching +through mail and news repositories. Different backends (like +@code{nnimap} and @code{nntp}) work with different tools (called +@dfn{engines} in @code{nnir} lingo), but all use the same basic search +interface. + +The @code{nnimap} and @code{gmane} search engines should work with no +configuration. Other engines require a local index that needs to be +created and maintained outside of Gnus. + + +@node Basic Usage +@subsection Basic Usage + +In the group buffer typing @kbd{G G} will search the group on the +current line by calling @code{gnus-group-make-nnir-group}. This prompts +for a query string, creates an ephemeral @code{nnir} group containing +the articles that match this query, and takes you to a summary buffer +showing these articles. Articles may then be read, moved and deleted +using the usual commands. + +The @code{nnir} group made in this way is an @code{ephemeral} group, +and some changes are not permanent: aside from reading, moving, and +deleting, you can't act on the original article. But there is an +alternative: you can @emph{warp} (i.e., jump) to the original group +for the article on the current line with @kbd{A W}, aka +@code{gnus-warp-to-article}. Even better, the function +@code{gnus-summary-refer-thread}, bound by default in summary buffers +to @kbd{A T}, will first warp to the original group before it works +its magic and includes all the articles in the thread. From here you +can read, move and delete articles, but also copy them, alter article +marks, whatever. Go nuts. + +You say you want to search more than just the group on the current line? +No problem: just process-mark the groups you want to search. You want +even more? Calling for an nnir search with the cursor on a topic heading +will search all the groups under that heading. + +Still not enough? OK, in the server buffer +@code{gnus-group-make-nnir-group} (now bound to @kbd{G}) will search all +groups from the server on the current line. Too much? Want to ignore +certain groups when searching, like spam groups? Just customize +@code{nnir-ignored-newsgroups}. + +One more thing: individual search engines may have special search +features. You can access these special features by giving a prefix-arg +to @code{gnus-group-make-nnir-group}. If you are searching multiple +groups with different search engines you will be prompted for the +special search features for each engine separately. + + +@node Setting up nnir +@subsection Setting up nnir + +To set up nnir you may need to do some prep work. Firstly, you may need +to configure the search engines you plan to use. Some of them, like +@code{imap} and @code{gmane}, need no special configuration. Others, +like @code{namazu} and @code{swish}, require configuration as described +below. Secondly, you need to associate a search engine with a server or +a backend. + +If you just want to use the @code{imap} engine to search @code{nnimap} +servers, and the @code{gmane} engine to search @code{gmane} then you +don't have to do anything. But you might want to read the details of the +query language anyway. + +@menu +* Associating Engines:: How to associate engines. +* The imap Engine:: Imap configuration and usage. +* The gmane Engine:: Gmane configuration and usage. +* The swish++ Engine:: Swish++ configuration and usage. +* The swish-e Engine:: Swish-e configuration and usage. +* The namazu Engine:: Namazu configuration and usage. +* The notmuch Engine:: Notmuch configuration and usage. +* The hyrex Engine:: Hyrex configuration and usage. +* Customizations:: User customizable settings. +@end menu + +@node Associating Engines +@subsubsection Associating Engines + + +When searching a group, @code{nnir} needs to know which search engine to +use. You can configure a given server to use a particular engine by +setting the server variable @code{nnir-search-engine} to the engine +name. For example to use the @code{namazu} engine to search the server +named @code{home} you can use + +@lisp +(setq gnus-secondary-select-methods + '((nnml "home" + (nnimap-address "localhost") + (nnir-search-engine namazu)))) +@end lisp + +Alternatively you might want to use a particular engine for all servers +with a given backend. For example, you might want to use the @code{imap} +engine for all servers using the @code{nnimap} backend. In this case you +can customize the variable @code{nnir-method-default-engines}. This is +an alist of pairs of the form @code{(backend . engine)}. By default this +variable is set to use the @code{imap} engine for all servers using the +@code{nnimap} backend, and the @code{gmane} backend for @code{nntp} +servers. (Don't worry, the @code{gmane} search engine won't actually try +to search non-gmane @code{nntp} servers.) But if you wanted to use +@code{namazu} for all your servers with an @code{nnimap} backend you +could change this to + +@lisp +'((nnimap . namazu) + (nntp . gmane)) +@end lisp + +@node The imap Engine +@subsubsection The imap Engine + +The @code{imap} engine requires no configuration. + +Queries using the @code{imap} engine follow a simple query language. +The search is always case-insensitive and supports the following +features (inspired by the Google search input language): + +@table @samp + +@item Boolean query operators +AND, OR, and NOT are supported, and parentheses can be used to control +operator precedence, e.g., (emacs OR xemacs) AND linux. Note that +operators must be written with all capital letters to be +recognized. Also preceding a term with a @minus{} sign is equivalent +to NOT term. + +@item Automatic AND queries +If you specify multiple words then they will be treated as an AND +expression intended to match all components. + +@item Phrase searches +If you wrap your query in double-quotes then it will be treated as a +literal string. + +@end table + +By default the whole message will be searched. The query can be limited +to a specific part of a message by using a prefix-arg. After inputting +the query this will prompt (with completion) for a message part. +Choices include ``Whole message'', ``Subject'', ``From'', and +``To''. Any unrecognized input is interpreted as a header name. For +example, typing @kbd{Message-ID} in response to this prompt will limit +the query to the Message-ID header. + +Finally selecting ``Imap'' will interpret the query as a raw +@acronym{IMAP} search query. The format of such queries can be found in +RFC3501. + +If you don't like the default of searching whole messages you can +customize @code{nnir-imap-default-search-key}. For example to use +@acronym{IMAP} queries by default + +@lisp +(setq nnir-imap-default-search-key "Imap") +@end lisp + +@node The gmane Engine +@subsubsection The gmane Engine + +The @code{gmane} engine requires no configuration. + +Gmane queries follow a simple query language: + +@table @samp +@item Boolean query operators +AND, OR, NOT (or AND NOT), and XOR are supported, and brackets can be +used to control operator precedence, e.g., (emacs OR xemacs) AND linux. +Note that operators must be written with all capital letters to be +recognized. + +@item Required and excluded terms ++ and @minus{} can be used to require or exclude terms, e.g., football +@minus{}american + +@item Unicode handling +The search engine converts all text to utf-8, so searching should work +in any language. + +@item Stopwords +Common English words (like 'the' and 'a') are ignored by default. You +can override this by prefixing such words with a + (e.g., +the) or +enclosing the word in quotes (e.g., "the"). + +@end table + +The query can be limited to articles by a specific author using a +prefix-arg. After inputting the query this will prompt for an author +name (or part of a name) to match. + +@node The swish++ Engine +@subsubsection The swish++ Engine + +FIXME: Say something more here. + +Documentation for swish++ may be found at the swish++ sourceforge page: +@uref{http://swishplusplus.sourceforge.net} + +@table @code + +@item nnir-swish++-program +The name of the swish++ executable. Defaults to @code{search} + +@item nnir-swish++-additional-switches +A list of strings to be given as additional arguments to +swish++. @code{nil} by default. + +@item nnir-swish++-remove-prefix +The prefix to remove from each file name returned by swish++ in order +to get a group name. By default this is @code{$HOME/Mail}. + +@end table + +@node The swish-e Engine +@subsubsection The swish-e Engine + +FIXME: Say something more here. + +Documentation for swish-e may be found at the swish-e homepage +@uref{http://swish-e.org} + +@table @code + +@item nnir-swish-e-program +The name of the swish-e search program. Defaults to @code{swish-e}. + +@item nnir-swish-e-additional-switches +A list of strings to be given as additional arguments to +swish-e. @code{nil} by default. + +@item nnir-swish-e-remove-prefix +The prefix to remove from each file name returned by swish-e in order +to get a group name. By default this is @code{$HOME/Mail}. + +@end table + +@node The namazu Engine +@subsubsection The namazu Engine + +Using the namazu engine requires creating and maintaining index files. +One directory should contain all the index files, and nnir must be told +where to find them by setting the @code{nnir-namazu-index-directory} +variable. + +To work correctly the @code{nnir-namazu-remove-prefix} variable must +also be correct. This is the prefix to remove from each file name +returned by Namazu in order to get a proper group name (albeit with @samp{/} +instead of @samp{.}). + +For example, suppose that Namazu returns file names such as +@samp{/home/john/Mail/mail/misc/42}. For this example, use the +following setting: @code{(setq nnir-namazu-remove-prefix +"/home/john/Mail/")} Note the trailing slash. Removing this prefix from +the directory gives @samp{mail/misc/42}. @code{nnir} knows to remove +the @samp{/42} and to replace @samp{/} with @samp{.} to arrive at the +correct group name @samp{mail.misc}. + +Extra switches may be passed to the namazu search command by setting the +variable @code{nnir-namazu-additional-switches}. It is particularly +important not to pass any any switches to namazu that will change the +output format. Good switches to use include @option{--sort}, +@option{--ascending}, @option{--early} and @option{--late}. +Refer to the Namazu documentation for further +information on valid switches. + +Mail must first be indexed with the @command{mknmz} program. Read the +documentation for namazu to create a configuration file. Here is an +example: + +@cartouche +@example + package conf; # Don't remove this line! + + # Paths which will not be indexed. Don't use '^' or '$' anchors. + $EXCLUDE_PATH = "spam|sent"; + + # Header fields which should be searchable. case-insensitive + $REMAIN_HEADER = "from|date|message-id|subject"; + + # Searchable fields. case-insensitive + $SEARCH_FIELD = "from|date|message-id|subject"; + + # The max length of a word. + $WORD_LENG_MAX = 128; + + # The max length of a field. + $MAX_FIELD_LENGTH = 256; +@end example +@end cartouche + +For this example, mail is stored in the directories @samp{~/Mail/mail/}, +@samp{~/Mail/lists/} and @samp{~/Mail/archive/}, so to index them go to +the index directory set in @code{nnir-namazu-index-directory} and issue +the following command: + +@example +mknmz --mailnews ~/Mail/archive/ ~/Mail/mail/ ~/Mail/lists/ +@end example + +For maximum searching efficiency you might want to have a cron job run +this command periodically, say every four hours. + + +@node The notmuch Engine +@subsubsection The notmuch Engine + +@table @code +@item nnir-notmuch-program +The name of the notmuch search executable. Defaults to +@samp{notmuch}. + +@item nnir-notmuch-additional-switches +A list of strings, to be given as additional arguments to notmuch. + +@item nnir-notmuch-remove-prefix +The prefix to remove from each file name returned by notmuch in order +to get a group name (albeit with @samp{/} instead of @samp{.}). This +is a regular expression. + +@end table + + +@node The hyrex Engine +@subsubsection The hyrex Engine +This engine is obsolete. + +@node Customizations +@subsubsection Customizations + +@table @code + +@item nnir-method-default-engines +Alist of pairs of server backends and search engines. The default +associations are +@example +(nnimap . imap) +(nntp . gmane) +@end example + +@item nnir-ignored-newsgroups +A regexp to match newsgroups in the active file that should be skipped +when searching all groups on a server. + +@item nnir-summary-line-format +The format specification to be used for lines in an nnir summary buffer. +All the items from @code{gnus-summary-line-format} are available, along with +three items unique to nnir summary buffers: + +@example +%Z Search retrieval score value (integer) +%G Article original full group name (string) +%g Article original short group name (string) +@end example + +If @code{nil} (the default) this will use @code{gnus-summary-line-format}. + +@item nnir-retrieve-headers-override-function +If non-@code{nil}, a function that retrieves article headers rather than using +the gnus built-in function. This function takes an article list and +group as arguments and populates the @code{nntp-server-buffer} with the +retrieved headers. It should then return either 'nov or 'headers +indicating the retrieved header format. Failure to retrieve headers +should return @code{nil}. + +If this variable is @code{nil}, or if the provided function returns +@code{nil} for a search result, @code{gnus-retrieve-headers} will be +called instead." + + +@end table + + +@node nnmairix +@section nnmairix + +@cindex mairix +@cindex nnmairix +This paragraph describes how to set up mairix and the back end +@code{nnmairix} for indexing and searching your mail from within +Gnus. Additionally, you can create permanent ``smart'' groups which are +bound to mairix searches and are automatically updated. + +@menu +* About mairix:: About the mairix mail search engine +* nnmairix requirements:: What you will need for using nnmairix +* What nnmairix does:: What does nnmairix actually do? +* Setting up mairix:: Set up your mairix installation +* Configuring nnmairix:: Set up the nnmairix back end +* nnmairix keyboard shortcuts:: List of available keyboard shortcuts +* Propagating marks:: How to propagate marks from nnmairix groups +* nnmairix tips and tricks:: Some tips, tricks and examples +* nnmairix caveats:: Some more stuff you might want to know +@end menu + +@c FIXME: The markup in this section might need improvement. +@c E.g., adding @samp, @var, @file, @command, etc. +@c Cf. (info "(texinfo)Indicating") + +@node About mairix +@subsection About mairix + +Mairix is a tool for indexing and searching words in locally stored +mail. It was written by Richard Curnow and is licensed under the +GPL@. Mairix comes with most popular GNU/Linux distributions, but it also +runs under Windows (with cygwin), Mac OS X and Solaris. The homepage can +be found at +@uref{http://www.rpcurnow.force9.co.uk/mairix/index.html} + +Though mairix might not be as flexible as other search tools like +swish++ or namazu, which you can use via the @code{nnir} back end, it +has the prime advantage of being incredibly fast. On current systems, it +can easily search through headers and message bodies of thousands and +thousands of mails in well under a second. Building the database +necessary for searching might take a minute or two, but only has to be +done once fully. Afterwards, the updates are done incrementally and +therefore are really fast, too. Additionally, mairix is very easy to set +up. + +For maximum speed though, mairix should be used with mails stored in +@code{Maildir} or @code{MH} format (this includes the @code{nnml} back +end), although it also works with mbox. Mairix presents the search +results by populating a @emph{virtual} maildir/MH folder with symlinks +which point to the ``real'' message files (if mbox is used, copies are +made). Since mairix already presents search results in such a virtual +mail folder, it is very well suited for using it as an external program +for creating @emph{smart} mail folders, which represent certain mail +searches. + +@node nnmairix requirements +@subsection nnmairix requirements + +Mairix searches local mail---that means, mairix absolutely must have +direct access to your mail folders. If your mail resides on another +server (e.g., an @acronym{IMAP} server) and you happen to have shell +access, @code{nnmairix} supports running mairix remotely, e.g., via ssh. + +Additionally, @code{nnmairix} only supports the following Gnus back +ends: @code{nnml}, @code{nnmaildir}, and @code{nnimap}. You must use +one of these back ends for using @code{nnmairix}. Other back ends, like +@code{nnmbox}, @code{nnfolder} or @code{nnmh}, won't work. + +If you absolutely must use mbox and still want to use @code{nnmairix}, +you can set up a local @acronym{IMAP} server, which you then access via +@code{nnimap}. This is a rather massive setup for accessing some mbox +files, so just change to MH or Maildir already... However, if you're +really, really passionate about using mbox, you might want to look into +the package @file{mairix.el}, which comes with Emacs 23. + +@node What nnmairix does +@subsection What nnmairix does + +The back end @code{nnmairix} enables you to call mairix from within Gnus, +either to query mairix with a search term or to update the +database. While visiting a message in the summary buffer, you can use +several pre-defined shortcuts for calling mairix, e.g., to quickly +search for all mails from the sender of the current message or to +display the whole thread associated with the message, even if the +mails are in different folders. + +Additionally, you can create permanent @code{nnmairix} groups which are bound +to certain mairix searches. This way, you can easily create a group +containing mails from a certain sender, with a certain subject line or +even for one specific thread based on the Message-ID@. If you check for +new mail in these folders (e.g., by pressing @kbd{g} or @kbd{M-g}), they +automatically update themselves by calling mairix. + +You might ask why you need @code{nnmairix} at all, since mairix already +creates the group, populates it with links to the mails so that you can +then access it with Gnus, right? Well, this @emph{might} work, but often +does not---at least not without problems. Most probably you will get +strange article counts, and sometimes you might see mails which Gnus +claims have already been canceled and are inaccessible. This is due to +the fact that Gnus isn't really amused when things are happening behind +its back. Another problem can be the mail back end itself, e.g., if you +use mairix with an @acronym{IMAP} server (I had Dovecot complaining +about corrupt index files when mairix changed the contents of the search +group). Using @code{nnmairix} should circumvent these problems. + +@code{nnmairix} is not really a mail back end---it's actually more like +a wrapper, sitting between a ``real'' mail back end where mairix stores +the searches and the Gnus front end. You can choose between three +different mail back ends for the mairix folders: @code{nnml}, +@code{nnmaildir} or @code{nnimap}. @code{nnmairix} will call the mairix +binary so that the search results are stored in folders named +@code{zz_mairix--} on this mail back end, but it will +present these folders in the Gnus front end only with @code{}. +You can use an existing mail back end where you already store your mail, +but if you're uncomfortable with @code{nnmairix} creating new mail +groups alongside your other mail, you can also create, e.g., a new +@code{nnmaildir} or @code{nnml} server exclusively for mairix, but then +make sure those servers do not accidentally receive your new mail +(@pxref{nnmairix caveats}). A special case exists if you want to use +mairix remotely on an IMAP server with @code{nnimap}---here the mairix +folders and your other mail must be on the same @code{nnimap} back end. + +@node Setting up mairix +@subsection Setting up mairix + +First: create a backup of your mail folders (@pxref{nnmairix caveats}). + +Setting up mairix is easy: simply create a @file{.mairixrc} file with +(at least) the following entries: + +@example +# Your Maildir/MH base folder +base=~/Maildir +@end example + +This is the base folder for your mails. All the following directories +are relative to this base folder. If you want to use @code{nnmairix} +with @code{nnimap}, this base directory has to point to the mail +directory where the @acronym{IMAP} server stores the mail folders! + +@example +maildir= ... your maildir folders which should be indexed ... +mh= ... your nnml/mh folders which should be indexed ... +mbox = ... your mbox files which should be indexed ... +@end example + +This specifies all your mail folders and mbox files (relative to the +base directory!) you want to index with mairix. Note that the +@code{nnml} back end saves mails in MH format, so you have to put those +directories in the @code{mh} line. See the example at the end of this +section and mairixrc's man-page for further details. + +@example +omit=zz_mairix-* +@end example + +@vindex nnmairix-group-prefix +This should make sure that you don't accidentally index the mairix +search results. You can change the prefix of these folders with the +variable @code{nnmairix-group-prefix}. + +@example +mformat= ... 'maildir' or 'mh' ... +database= ... location of database file ... +@end example + +The @code{format} setting specifies the output format for the mairix +search folder. Set this to @code{mh} if you want to access search results +with @code{nnml}. Otherwise choose @code{maildir}. + +To summarize, here is my shortened @file{.mairixrc} file as an example: + +@example +base=~/Maildir +maildir=.personal:.work:.logcheck:.sent +mh=../Mail/nnml/*... +mbox=../mboxmail/mailarchive_year* +mformat=maildir +omit=zz_mairix-* +database=~/.mairixdatabase +@end example + +In this case, the base directory is @file{~/Maildir}, where all my Maildir +folders are stored. As you can see, the folders are separated by +colons. If you wonder why every folder begins with a dot: this is +because I use Dovecot as @acronym{IMAP} server, which again uses +@code{Maildir++} folders. For testing nnmairix, I also have some +@code{nnml} mail, which is saved in @file{~/Mail/nnml}. Since this has +to be specified relative to the @code{base} directory, the @code{../Mail} +notation is needed. Note that the line ends in @code{*...}, which means +to recursively scan all files under this directory. Without the three +dots, the wildcard @code{*} will not work recursively. I also have some +old mbox files with archived mail lying around in @file{~/mboxmail}. +The other lines should be obvious. + +See the man page for @code{mairixrc} for details and further options, +especially regarding wildcard usage, which may be a little different +than you are used to. + +Now simply call @code{mairix} to create the index for the first time. +Note that this may take a few minutes, but every following index will do +the updates incrementally and hence is very fast. + +@node Configuring nnmairix +@subsection Configuring nnmairix + +In group mode, type @kbd{G b c} +(@code{nnmairix-create-server-and-default-group}). This will ask you for all +necessary information and create a @code{nnmairix} server as a foreign +server. You will have to specify the following: + +@itemize @bullet + +@item +The @strong{name} of the @code{nnmairix} server---choose whatever you +want. + +@item +The name of the @strong{back end server} where mairix should store its +searches. This must be a full server name, like @code{nnml:mymail}. +Just hit @kbd{TAB} to see the available servers. Currently, servers +which are accessed through @code{nnmaildir}, @code{nnimap} and +@code{nnml} are supported. As explained above, for locally stored +mails, this can be an existing server where you store your mails. +However, you can also create, e.g., a new @code{nnmaildir} or @code{nnml} +server exclusively for @code{nnmairix} in your secondary select methods +(@pxref{Finding the News}). If you use a secondary @code{nnml} server +just for mairix, make sure that you explicitly set the server variable +@code{nnml-get-new-mail} to @code{nil}, or you might lose mail +(@pxref{nnmairix caveats}). If you want to use mairix remotely on an +@acronym{IMAP} server, you have to choose the corresponding +@code{nnimap} server here. + +@item +@vindex nnmairix-mairix-search-options +The @strong{command} to call the mairix binary. This will usually just +be @code{mairix}, but you can also choose something like @code{ssh +SERVER mairix} if you want to call mairix remotely, e.g., on your +@acronym{IMAP} server. If you want to add some default options to +mairix, you could do this here, but better use the variable +@code{nnmairix-mairix-search-options} instead. + +@item +The name of the @strong{default search group}. This will be the group +where all temporary mairix searches are stored, i.e., all searches which +are not bound to permanent @code{nnmairix} groups. Choose whatever you +like. + +@item +If the mail back end is @code{nnimap} or @code{nnmaildir}, you will be +asked if you work with @strong{Maildir++}, i.e., with hidden maildir +folders (=beginning with a dot). For example, you have to answer +@samp{yes} here if you work with the Dovecot @acronym{IMAP} +server. Otherwise, you should answer @samp{no} here. + +@end itemize + +@node nnmairix keyboard shortcuts +@subsection nnmairix keyboard shortcuts + +In group mode: + +@table @kbd + +@item G b c +@kindex G b c (Group) +@findex nnmairix-create-server-and-default-group +Creates @code{nnmairix} server and default search group for this server +(@code{nnmairix-create-server-and-default-group}). You should have done +this by now (@pxref{Configuring nnmairix}). + +@item G b s +@kindex G b s (Group) +@findex nnmairix-search +Prompts for query which is then sent to the mairix binary. Search +results are put into the default search group which is automatically +displayed (@code{nnmairix-search}). + +@item G b m +@kindex G b m (Group) +@findex nnmairix-widget-search +Allows you to create a mairix search or a permanent group more +comfortably using graphical widgets, similar to a customization +group. Just try it to see how it works (@code{nnmairix-widget-search}). + +@item G b i +@kindex G b i (Group) +@findex nnmairix-search-interactive +Another command for creating a mairix query more comfortably, but uses +only the minibuffer (@code{nnmairix-search-interactive}). + +@item G b g +@kindex G b g (Group) +@findex nnmairix-create-search-group +Creates a permanent group which is associated with a search query +(@code{nnmairix-create-search-group}). The @code{nnmairix} back end +automatically calls mairix when you update this group with @kbd{g} or +@kbd{M-g}. + +@item G b q +@kindex G b q (Group) +@findex nnmairix-group-change-query-this-group +Changes the search query for the @code{nnmairix} group under cursor +(@code{nnmairix-group-change-query-this-group}). + +@item G b t +@kindex G b t (Group) +@findex nnmairix-group-toggle-threads-this-group +Toggles the 'threads' parameter for the @code{nnmairix} group under cursor, +i.e., if you want see the whole threads of the found messages +(@code{nnmairix-group-toggle-threads-this-group}). + +@item G b u +@kindex G b u (Group) +@findex nnmairix-update-database +@vindex nnmairix-mairix-update-options +Calls mairix binary for updating the database +(@code{nnmairix-update-database}). The default parameters are @code{-F} +and @code{-Q} for making this as fast as possible (see variable +@code{nnmairix-mairix-update-options} for defining these default +options). + +@item G b r +@kindex G b r (Group) +@findex nnmairix-group-toggle-readmarks-this-group +Keep articles in this @code{nnmairix} group always read or unread, or leave the +marks unchanged (@code{nnmairix-group-toggle-readmarks-this-group}). + +@item G b d +@kindex G b d (Group) +@findex nnmairix-group-delete-recreate-this-group +Recreate @code{nnmairix} group on the ``real'' mail back end +(@code{nnmairix-group-delete-recreate-this-group}). You can do this if +you always get wrong article counts with a @code{nnmairix} group. + +@item G b a +@kindex G b a (Group) +@findex nnmairix-group-toggle-allowfast-this-group +Toggles the @code{allow-fast} parameters for group under cursor +(@code{nnmairix-group-toggle-allowfast-this-group}). The default +behavior of @code{nnmairix} is to do a mairix search every time you +update or enter the group. With the @code{allow-fast} parameter set, +mairix will only be called when you explicitly update the group, but not +upon entering. This makes entering the group faster, but it may also +lead to dangling symlinks if something changed between updating and +entering the group which is not yet in the mairix database. + +@item G b p +@kindex G b p (Group) +@findex nnmairix-group-toggle-propmarks-this-group +Toggle marks propagation for this group +(@code{nnmairix-group-toggle-propmarks-this-group}). (@pxref{Propagating +marks}). + +@item G b o +@kindex G b o (Group) +@findex nnmairix-propagate-marks +Manually propagate marks (@code{nnmairix-propagate-marks}); needed only when +@code{nnmairix-propagate-marks-upon-close} is set to @code{nil}. + +@end table + +In summary mode: + +@table @kbd + +@item $ m +@kindex $ m (Summary) +@findex nnmairix-widget-search-from-this-article +Allows you to create a mairix query or group based on the current +message using graphical widgets (same as @code{nnmairix-widget-search}) +(@code{nnmairix-widget-search-from-this-article}). + +@item $ g +@kindex $ g (Summary) +@findex nnmairix-create-search-group-from-message +Interactively creates a new search group with query based on the current +message, but uses the minibuffer instead of graphical widgets +(@code{nnmairix-create-search-group-from-message}). + +@item $ t +@kindex $ t (Summary) +@findex nnmairix-search-thread-this-article +Searches thread for the current article +(@code{nnmairix-search-thread-this-article}). This is effectively a +shortcut for calling @code{nnmairix-search} with @samp{m:msgid} of the +current article and enabled threads. + +@item $ f +@kindex $ f (Summary) +@findex nnmairix-search-from-this-article +Searches all messages from sender of the current article +(@code{nnmairix-search-from-this-article}). This is a shortcut for +calling @code{nnmairix-search} with @samp{f:From}. + +@item $ o +@kindex $ o (Summary) +@findex nnmairix-goto-original-article +(Only in @code{nnmairix} groups!) Tries determine the group this article +originally came from and displays the article in this group, so that, +e.g., replying to this article the correct posting styles/group +parameters are applied (@code{nnmairix-goto-original-article}). This +function will use the registry if available, but can also parse the +article file name as a fallback method. + +@item $ u +@kindex $ u (Summary) +@findex nnmairix-remove-tick-mark-original-article +Remove possibly existing tick mark from original article +(@code{nnmairix-remove-tick-mark-original-article}). (@pxref{nnmairix +tips and tricks}). + +@end table + +@node Propagating marks +@subsection Propagating marks + +First of: you really need a patched mairix binary for using the marks +propagation feature efficiently. Otherwise, you would have to update +the mairix database all the time. You can get the patch at + +@uref{http://www.randomsample.de/mairix-maildir-patch.tar} + +You need the mairix v0.21 source code for this patch; everything else +is explained in the accompanied readme file. If you don't want to use +marks propagation, you don't have to apply these patches, but they also +fix some annoyances regarding changing maildir flags, so it might still +be useful to you. + +With the patched mairix binary, you can use @code{nnmairix} as an +alternative to mail splitting (@pxref{Fancy Mail Splitting}). For +example, instead of splitting all mails from @samp{david@@foobar.com} +into a group, you can simply create a search group with the query +@samp{f:david@@foobar.com}. This is actually what ``smart folders'' are +all about: simply put everything in one mail folder and dynamically +create searches instead of splitting. This is more flexible, since you +can dynamically change your folders any time you want to. This also +implies that you will usually read your mails in the @code{nnmairix} +groups instead of your ``real'' mail groups. + +There is one problem, though: say you got a new mail from +@samp{david@@foobar.com}; it will now show up in two groups, the +``real'' group (your INBOX, for example) and in the @code{nnmairix} +search group (provided you have updated the mairix database). Now you +enter the @code{nnmairix} group and read the mail. The mail will be +marked as read, but only in the @code{nnmairix} group---in the ``real'' +mail group it will be still shown as unread. + +You could now catch up the mail group (@pxref{Group Data}), but this is +tedious and error prone, since you may overlook mails you don't have +created @code{nnmairix} groups for. Of course, you could first use +@code{nnmairix-goto-original-article} (@pxref{nnmairix keyboard +shortcuts}) and then read the mail in the original group, but that's +even more cumbersome. + +Clearly, the easiest way would be if marks could somehow be +automatically set for the original article. This is exactly what +@emph{marks propagation} is about. + +Marks propagation is inactive by default. You can activate it for a +certain @code{nnmairix} group with +@code{nnmairix-group-toggle-propmarks-this-group} (bound to @kbd{G b +p}). This function will warn you if you try to use it with your default +search group; the reason is that the default search group is used for +temporary searches, and it's easy to accidentally propagate marks from +this group. However, you can ignore this warning if you really want to. + +With marks propagation enabled, all the marks you set in a @code{nnmairix} +group should now be propagated to the original article. For example, +you can now tick an article (by default with @kbd{!}) and this mark should +magically be set for the original article, too. + +A few more remarks which you may or may not want to know: + +@vindex nnmairix-propagate-marks-upon-close +Marks will not be set immediately, but only upon closing a group. This +not only makes marks propagation faster, it also avoids problems with +dangling symlinks when dealing with maildir files (since changing flags +will change the file name). You can also control when to propagate marks +via @code{nnmairix-propagate-marks-upon-close} (see the doc-string for +details). + +Obviously, @code{nnmairix} will have to look up the original group for every +article you want to set marks for. If available, @code{nnmairix} will first +use the registry for determining the original group. The registry is very +fast, hence you should really, really enable the registry when using +marks propagation. If you don't have to worry about RAM and disc space, +set @code{gnus-registry-max-entries} to a large enough value; to be on +the safe side, choose roughly the amount of mails you index with mairix. + +@vindex nnmairix-only-use-registry +If you don't want to use the registry or the registry hasn't seen the +original article yet, @code{nnmairix} will use an additional mairix +search for determining the file name of the article. This, of course, is +way slower than the registry---if you set hundreds or even thousands of +marks this way, it might take some time. You can avoid this situation by +setting @code{nnmairix-only-use-registry} to @code{t}. + +Maybe you also want to propagate marks the other way round, i.e., if you +tick an article in a "real" mail group, you'd like to have the same +article in a @code{nnmairix} group ticked, too. For several good +reasons, this can only be done efficiently if you use maildir. To +immediately contradict myself, let me mention that it WON'T work with +@code{nnmaildir}, since @code{nnmaildir} stores the marks externally and +not in the file name. Therefore, propagating marks to @code{nnmairix} +groups will usually only work if you use an IMAP server which uses +maildir as its file format. + +@vindex nnmairix-propagate-marks-to-nnmairix-groups +If you work with this setup, just set +@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t} and see what +happens. If you don't like what you see, just set it to @code{nil} again. +One problem might be that you get a wrong number of unread articles; this +usually happens when you delete or expire articles in the original +groups. When this happens, you can recreate the @code{nnmairix} group on +the back end using @kbd{G b d}. + +@node nnmairix tips and tricks +@subsection nnmairix tips and tricks + +@itemize +@item +Checking Mail + +@findex nnmairix-update-groups +I put all my important mail groups at group level 1. The mairix groups +have group level 5, so they do not get checked at start up (@pxref{Group +Levels}). + +I use the following to check for mails: + +@lisp +(defun my-check-mail-mairix-update (level) + (interactive "P") + ;; if no prefix given, set level=1 + (gnus-group-get-new-news (or level 1)) + (nnmairix-update-groups "mairixsearch" t t) + (gnus-group-list-groups)) + +(define-key gnus-group-mode-map "g" 'my-check-mail-mairix-update) +@end lisp + +Instead of @samp{"mairixsearch"} use the name of your @code{nnmairix} +server. See the doc string for @code{nnmairix-update-groups} for +details. + +@item +Example: search group for ticked articles + +For example, you can create a group for all ticked articles, where the +articles always stay unread: + +Hit @kbd{G b g}, enter group name (e.g., @samp{important}), use +@samp{F:f} as query and do not include threads. + +Now activate marks propagation for this group by using @kbd{G b p}. Then +activate the always-unread feature by using @kbd{G b r} twice. + +So far so good---but how do you remove the tick marks in the @code{nnmairix} +group? There are two options: You may simply use +@code{nnmairix-remove-tick-mark-original-article} (bound to @kbd{$ u}) to remove +tick marks from the original article. The other possibility is to set +@code{nnmairix-propagate-marks-to-nnmairix-groups} to @code{t}, but see the above +comments about this option. If it works for you, the tick marks should +also exist in the @code{nnmairix} group and you can remove them as usual, +e.g., by marking an article as read. + +When you have removed a tick mark from the original article, this +article should vanish from the @code{nnmairix} group after you have updated the +mairix database and updated the group. Fortunately, there is a function +for doing exactly that: @code{nnmairix-update-groups}. See the previous code +snippet and the doc string for details. + +@item +Dealing with auto-subscription of mail groups + +As described before, all @code{nnmairix} groups are in fact stored on +the mail back end in the form @samp{zz_mairix--}. You can +see them when you enter the back end server in the server buffer. You +should not subscribe these groups! Unfortunately, these groups will +usually get @emph{auto-subscribed} when you use @code{nnmaildir} or +@code{nnml}, i.e., you will suddenly see groups of the form +@samp{zz_mairix*} pop up in your group buffer. If this happens to you, +simply kill these groups with C-k. For avoiding this, turn off +auto-subscription completely by setting the variable +@code{gnus-auto-subscribed-groups} to @code{nil} (@pxref{Filtering New +Groups}), or if you like to keep this feature use the following kludge +for turning it off for all groups beginning with @samp{zz_}: + +@lisp +(setq gnus-auto-subscribed-groups + "^\\(nnml\\|nnfolder\\|nnmbox\\|nnmh\\|nnbabyl\\|nnmaildir\\).*:\\([^z]\\|z$\\|\\z[^z]\\|zz$\\|zz[^_]\\|zz_$\\).*") +@end lisp + +@end itemize + +@node nnmairix caveats +@subsection nnmairix caveats + +@itemize +@item +You can create a secondary @code{nnml} server just for nnmairix, but then +you have to explicitly set the corresponding server variable +@code{nnml-get-new-mail} to @code{nil}. Otherwise, new mail might get +put into this secondary server (and would never show up again). Here's +an example server definition: + +@lisp +(nnml "mairix" (nnml-directory "mairix") (nnml-get-new-mail nil)) +@end lisp + +(The @code{nnmaildir} back end also has a server variable +@code{get-new-mail}, but its default value is @code{nil}, so you don't +have to explicitly set it if you use a @code{nnmaildir} server just for +mairix.) + +@item +If you use the Gnus registry: don't use the registry with +@code{nnmairix} groups (put them in +@code{gnus-registry-unfollowed-groups}; this is the default). Be +@emph{extra careful} if you use +@code{gnus-registry-split-fancy-with-parent}; mails which are split +into @code{nnmairix} groups are usually gone for good as soon as you +check the group for new mail (yes, it has happened to me...). + +@item +Therefore: @emph{Never ever} put ``real'' mails into @code{nnmairix} +groups (you shouldn't be able to, anyway). + +@item +If you use the Gnus agent (@pxref{Gnus Unplugged}): don't agentize +@code{nnmairix} groups (though I have no idea what happens if you do). + +@item +mairix does only support us-ascii characters. + +@item +@code{nnmairix} uses a rather brute force method to force Gnus to +completely reread the group on the mail back end after mairix was +called---it simply deletes and re-creates the group on the mail +back end. So far, this has worked for me without any problems, and I +don't see how @code{nnmairix} could delete other mail groups than its +own, but anyway: you really should have a backup of your mail +folders. + +@item +All necessary information is stored in the group parameters +(@pxref{Group Parameters}). This has the advantage that no active file +is needed, but also implies that when you kill a @code{nnmairix} group, +it is gone for good. + +@item +@findex nnmairix-purge-old-groups +If you create and kill a lot of @code{nnmairix} groups, the +``zz_mairix-*'' groups will accumulate on the mail back end server. To +delete old groups which are no longer needed, call +@code{nnmairix-purge-old-groups}. Note that this assumes that you don't +save any ``real'' mail in folders of the form +@code{zz_mairix--}. You can change the prefix of +@code{nnmairix} groups by changing the variable +@code{nnmairix-group-prefix}. + +@item +The following only applies if you @emph{don't} use the mentioned patch +for mairix (@pxref{Propagating marks}): + +A problem can occur when using @code{nnmairix} with maildir folders and +comes with the fact that maildir stores mail flags like @samp{Seen} or +@samp{Replied} by appending chars @samp{S} and @samp{R} to the message +file name, respectively. This implies that currently you would have to +update the mairix database not only when new mail arrives, but also when +mail flags are changing. The same applies to new mails which are indexed +while they are still in the @samp{new} folder but then get moved to +@samp{cur} when Gnus has seen the mail. If you don't update the database +after this has happened, a mairix query can lead to symlinks pointing to +non-existing files. In Gnus, these messages will usually appear with +``(none)'' entries in the header and can't be accessed. If this happens +to you, using @kbd{G b u} and updating the group will usually fix this. + +@end itemize + +@iftex +@iflatex +@chapter Message +@include message.texi +@chapter Emacs MIME +@include emacs-mime.texi +@chapter Sieve +@include sieve.texi +@chapter EasyPG +@include epa.texi +@chapter SASL +@include sasl.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. +* Mode Lines:: Displaying information in the mode lines. +* Highlighting and Menus:: Making buffers look all nice and cozy. +* Daemons:: Gnus can do things behind your back. +* Undo:: Some actions can be undone. +* Predicate Specifiers:: Specifying predicates. +* Moderation:: What to do if you're a moderator. +* Fetching a Group:: Starting Gnus just to read a group. +* Image Enhancements:: Modern versions of Emacs/XEmacs can display images. +* Fuzzy Matching:: What's the big fuzz? +* Thwarting Email Spam:: Simple ways to avoid unsolicited commercial email. +* Spam Package:: A package for filtering and processing spam. +* The Gnus Registry:: A package for tracking messages by Message-ID. +* 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 non-@code{nil} 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 non-@code{nil}, 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 non-@code{nil}, you will seldom be asked any +questions by Gnus. It will simply assume you know what you're doing, +no matter how strange. For example, quitting Gnus, exiting a group +without an update, catching up with a group, deleting expired +articles, and replying by mail to a news message will not require +confirmation. + +@item gnus-interactive-catchup +@vindex gnus-interactive-catchup +Require confirmation before catching up a group if non-@code{nil}. It +is @code{t} by default. + +@item gnus-interactive-exit +@vindex gnus-interactive-exit +If non-@code{nil}, require a confirmation when exiting Gnus. If +@code{quiet}, update any active summary buffers automatically without +querying. The default value is @code{t}. +@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, really---@samp{%%} 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 format---@samp{19960809T230410}. +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. + + +@node User-Defined Specs +@subsection User-Defined Specs + +All the specs allow for inserting user defined specifiers---@samp{u}. +The next character in the format string should be a letter. Gnus +will call the function @code{gnus-user-format-function-}@samp{X}, 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 @code{gnus-user-format-function-}@samp{foo}. + +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 + +@cindex %(, %) +@vindex gnus-mouse-face +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. + +@cindex %@{, %@} +@vindex gnus-face-0 +Text inside the @samp{%@{} and @samp{%@}} specifiers will have their +normal faces set using @code{gnus-face-0}, which is @code{bold} by +default. If you say @samp{%1@{}, 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}. + +@cindex %<<, %>>, guillemets +@c @cindex %<<, %>>, %«, %», guillemets +@vindex gnus-balloon-face-0 +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 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 + "%M%S%3@{%5y%@}%2[:%] %(%1@{%g%@}%)\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 behavior 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 specs---@samp{%=}. There are two +different types---@dfn{hard 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} non-@code{nil}, 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))) + (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) + (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 non-@code{nil}, it will +be used as a split. + +Not complicated enough for you? Well, try this on for size: + +@lisp +(article (horizontal 1.0 + (vertical 0.5 + (group 1.0)) + (vertical 1.0 + (summary 0.25 point) + (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 non-@code{nil}. + +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 Window Configuration Names + +Here's a list of most of the currently known window configurations, +and when they're used: + +@table @code +@item group +The group buffer. + +@item summary +Entering a group and showing only the summary. + +@item article +Selecting an article. + +@item server +The server buffer. + +@item browse +Browsing groups from the server buffer. + +@item message +Composing a (new) message. + +@item only-article +Showing only the article buffer. + +@item edit-article +Editing an article. + +@item edit-form +Editing group parameters and the like. + +@item edit-score +Editing a server definition. + +@item post +Composing a news message. + +@item reply +Replying or following up an article without yanking the text. + +@item forward +Forwarding a message. + +@item reply-yank +Replying or following up an article with yanking the text. + +@item mail-bound +Bouncing a message. + +@item pipe +Sending an article to an external process. + +@item bug +Sending a bug report. + +@item score-trace +Displaying the score trace. + +@item score-words +Displaying the score words. + +@item split-trace +Displaying the split trace. + +@item compose-bounce +Composing a bounce message. + +@item mml-preview +Previewing a @acronym{MIME} part. + +@end table + + +@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 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 Potortì +@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 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-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-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 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 non-@code{nil}, 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 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 Image Enhancements +@section Image Enhancements + +XEmacs, as well as Emacs 21@footnote{Emacs 21 on MS Windows doesn't +support images, Emacs 22 does.} and up, are 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. +* Gravatars:: Display the avatar of people you read. +* 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} + +Viewing an @code{X-Face} header either requires an Emacs that has +@samp{compface} support (which most XEmacs versions have), or that you +have suitable conversion or display programs installed. If your Emacs +has image support the default action is to display the face before the +@code{From} header. 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 friends, see below. For XEmacs it's +faster if XEmacs has been compiled with @code{X-Face} support. The +default action under Emacs without image support is to fork off the +@code{display} program. + +On a GNU/Linux system, the @code{display} program is included in the +ImageMagick package. For external conversion programs look for packages +with names like @code{netpbm}, @code{libgr-progs} and @code{compface}. +On Windows, you may use the packages @code{netpbm} and @code{compface} +from @url{http://gnuwin32.sourceforge.net}. You need to add the +@code{bin} directory to your @code{PATH} environment variable. +@c In fact only the following DLLs and binaries seem to be required: +@c compface1.dll uncompface.exe libnetpbm10.dll icontopbm.exe + +The variable @code{gnus-article-x-face-command} controls which programs +are used to display the @code{X-Face} header. 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 @code{gnus-article-x-face-too-ugly} (which is a regexp) matches the +@code{From} header, the face will not be shown. + +(Note: @code{x-face} is used in the variable/function names, not +@code{xface}). + +@noindent +Face and variable: + +@table @code +@item gnus-x-face +@vindex gnus-x-face +Face to show X-Face. The colors from this face are used as the +foreground and background colors of the displayed X-Faces. The +default colors are black and white. + +@item gnus-face-properties-alist +@vindex gnus-face-properties-alist +Alist of image types and properties applied to Face (@pxref{Face}) and +X-Face images. The default value is @code{((pbm . (:face gnus-x-face)) +(png . nil))} for Emacs or @code{((xface . (:face gnus-x-face)))} for +XEmacs. Here are examples: + +@lisp +;; Specify the altitude of Face and X-Face images in the From header. +(setq gnus-face-properties-alist + '((pbm . (:face gnus-x-face :ascent 80)) + (png . (:ascent 80)))) + +;; Show Face and X-Face images as pressed buttons. +(setq gnus-face-properties-alist + '((pbm . (:face gnus-x-face :relief -2)) + (png . (:relief -2)))) +@end lisp + +@pxref{Image Descriptors, ,Image Descriptors, elisp, The Emacs Lisp +Reference Manual} for the valid properties for various image types. +Currently, @code{pbm} is used for X-Face images and @code{png} is used +for Face images in Emacs. Only the @code{:face} property is effective +on the @code{xface} image type in XEmacs if it is built with the +@samp{libcompface} library. +@end table + +If you use posting styles, you can use an @code{x-face-file} entry in +@code{gnus-posting-styles}, @xref{Posting Styles}. If you don't, Gnus +provides a few convenience functions and variables to allow easier +insertion of X-Face headers in outgoing messages. You also need the +above mentioned ImageMagick, netpbm or other image conversion packages +(depending the values of the variables below) for these functions. + +@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. + +The @code{gnus-face-properties-alist} variable affects the appearance of +displayed Face images. @xref{X-Face}. + +Viewing a @code{Face} header requires an Emacs that is able to display +PNG images. +@c Maybe add this: +@c (if (featurep 'xemacs) +@c (featurep 'png) +@c (image-type-available-p 'png)) + +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 faces---@samp{:-)}, @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 the appearance of the smileys: + +@table @code + +@item smiley-style +@vindex smiley-style +Specifies the smiley style. Predefined smiley styles include +@code{low-color} (small 13x14 pixel, three-color images), @code{medium} +(more colorful images, 16x16 pixel), and @code{grayscale} (grayscale +images, 14x14 pixel). The default depends on the height of the default +face. + +@item smiley-data-directory +@vindex smiley-data-directory +Where Smiley will look for smiley faces files. You shouldn't set this +variable anymore. Customize @code{smiley-style} instead. + +@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 + +So@dots{} 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. + +@vindex gnus-picon-style +The variable @code{gnus-picon-style} controls how picons are displayed. +If @code{inline}, the textual representation is replaced. If +@code{right}, picons are added right to the textual representation. + +@vindex gnus-picon-properties +The value of the variable @code{gnus-picon-properties} is a list of +properties applied to picons. + +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. + +@item gnus-picon-inhibit-top-level-domains +@vindex gnus-picon-inhibit-top-level-domains +If non-@code{nil} (which is the default), don't display picons for +things like @samp{.net} and @samp{.de}, which aren't usually very +interesting. + +@end table + +@node Gravatars +@subsection Gravatars + +@iftex +@iflatex +\include{gravatars} +@end iflatex +@end iftex + +A gravatar is an image registered to an e-mail address. + +You can submit yours on-line at @uref{http://www.gravatar.com}. + +The following variables offer control over how things are displayed. + +@table @code + +@item gnus-gravatar-size +@vindex gnus-gravatar-size +The size in pixels of gravatars. Gravatars are always square, so one +number for the size is enough. + +@item gnus-gravatar-properties +@vindex gnus-gravatar-properties +List of image properties applied to Gravatar images. + +@item gnus-gravatar-too-ugly +@vindex gnus-gravatar-too-ugly +Regexp that matches mail addresses or names of people of which avatars +should not be displayed, or @code{nil}. It default to the value of +@code{gnus-article-x-face-too-ugly} (@pxref{X-Face}). + +@end table + +If you want to see them in the From field, set: +@lisp +(setq gnus-treat-from-gravatar 'head) +@end lisp + +If you want to see them in the Cc and To fields, set: + +@lisp +(setq gnus-treat-mail-gravatar 'head) +@end lisp + + +@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-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 +This variable specifies the position to display the toolbar. If +@code{nil}, don't display toolbars. If it is non-@code{nil}, it should +be one of the symbols @code{default}, @code{top}, @code{bottom}, +@code{right}, and @code{left}. @code{default} means to use the default +toolbar, the rest mean to display the toolbar on the place which those +names show. The default is @code{default}. + +@item gnus-toolbar-thickness +@vindex gnus-toolbar-thickness +Cons of the height and the width specifying the thickness of a toolbar. +The height is used for the toolbar displayed on the top or the bottom, +the width is used for the toolbar displayed on the right or the left. +The default is that of the default 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. +@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 Bulgaria, for example, you try to filter all mail +from Bulgarian IPs. + +This, unfortunately, is a great way to discard legitimate e-mail. The +risks of blocking a whole country (Bulgaria, Norway, Nigeria, China, +etc.)@: or even a continent (Asia, Africa, Europe, etc.)@: from contacting +you should be obvious, so don't do it if you have the choice. + +In another 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. 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 analysis. 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 \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 back end, message bodies will not be +downloaded by default. You need to set +@code{nnimap-split-download-body} to @code{t} to do that +(@pxref{Client-Side IMAP Splitting}). + +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-save-in-pipe "razor-report -f -d" t) + (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 and demonstrably unique 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.hashcash.org/}. Even more information can be found +at @uref{http://www.camram.org/}. + +If you wish to generate hashcash for each message you send, you can +customize @code{message-generate-hashcash} (@pxref{Mail Headers, ,Mail +Headers,message, The Message Manual}), as in: + +@lisp +(setq message-generate-hashcash t) +@end lisp + +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 20. 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-path +@vindex hashcash-path +Where the @code{hashcash} binary is installed. This variable should +be automatically set by @code{executable-find}, but if it's @code{nil} +(usually because the @code{hashcash} binary is not in your path) +you'll get a warning when you check hashcash payments and an error +when you generate hashcash payments. + +@end table + +Gnus can verify hashcash cookies, although this can also be done by +hand customized mail filtering scripts. To verify a hashcash cookie +in a message, use the @code{mail-check-payment} function in the +@code{hashcash.el} library. You can also use the @code{spam.el} +package with the @code{spam-use-hashcash} back end to validate hashcash +cookies in incoming mail and filter mail accordingly (@pxref{Anti-spam +Hashcash Payments}). + +@node Spam Package +@section Spam Package +@cindex spam filtering +@cindex spam + +The Spam package provides Gnus with a centralized mechanism for +detecting and filtering spam. It filters new mail, and processes +messages according to whether they are spam or ham. (@dfn{Ham} is the +name used throughout this manual to indicate non-spam messages.) + +@menu +* Spam Package Introduction:: +* Filtering Incoming Mail:: +* Detecting Spam in Groups:: +* Spam and Ham Processors:: +* Spam Package Configuration Examples:: +* Spam Back Ends:: +* Extending the Spam package:: +* Spam Statistics Package:: +@end menu + +@node Spam Package Introduction +@subsection Spam Package Introduction +@cindex spam filtering +@cindex spam filtering sequence of events +@cindex spam + +You must read this section to understand how the Spam package works. +Do not skip, speed-read, or glance through this section. + +Make sure you read the section on the @code{spam.el} sequence of +events. See @xref{Extending the Spam package}. + +@cindex spam-initialize +@vindex spam-use-stat +To use the Spam package, you @strong{must} first run the function +@code{spam-initialize}: + +@example +(spam-initialize) +@end example + +This autoloads @code{spam.el} and installs the various hooks necessary +to let the Spam package do its job. In order to make use of the Spam +package, you have to set up certain group parameters and variables, +which we will describe below. All of the variables controlling the +Spam package can be found in the @samp{spam} customization group. + +There are two ``contact points'' between the Spam package and the rest +of Gnus: checking new mail for spam, and leaving a group. + +Checking new mail for spam is done in one of two ways: while splitting +incoming mail, or when you enter a group. + +The first way, checking for spam while splitting incoming mail, is +suited to mail back ends such as @code{nnml} or @code{nnimap}, where +new mail appears in a single spool file. The Spam package processes +incoming mail, and sends mail considered to be spam to a designated +``spam'' group. @xref{Filtering Incoming Mail}. + +The second way is suited to back ends such as @code{nntp}, which have +no incoming mail spool, or back ends where the server is in charge of +splitting incoming mail. In this case, when you enter a Gnus group, +the unseen or unread messages in that group are checked for spam. +Detected spam messages are marked as spam. @xref{Detecting Spam in +Groups}. + +@cindex spam back ends +In either case, you have to tell the Spam package what method to use +to detect spam messages. There are several methods, or @dfn{spam back +ends} (not to be confused with Gnus back ends!) to choose from: spam +``blacklists'' and ``whitelists'', dictionary-based filters, and so +forth. @xref{Spam Back Ends}. + +In the Gnus summary buffer, messages that have been identified as spam +always appear with a @samp{$} symbol. + +The Spam package divides Gnus groups into three categories: ham +groups, spam groups, and unclassified groups. You should mark each of +the groups you subscribe to as either a ham group or a spam group, +using the @code{spam-contents} group parameter (@pxref{Group +Parameters}). Spam groups have a special property: when you enter a +spam group, all unseen articles are marked as spam. Thus, mail split +into a spam group is automatically marked as spam. + +Identifying spam messages is only half of the Spam package's job. The +second half comes into play whenever you exit a group buffer. At this +point, the Spam package does several things: + +First, it calls @dfn{spam and ham processors} to process the articles +according to whether they are spam or ham. There is a pair of spam +and ham processors associated with each spam back end, and what the +processors do depends on the back end. At present, the main role of +spam and ham processors is for dictionary-based spam filters: they add +the contents of the messages in the group to the filter's dictionary, +to improve its ability to detect future spam. The @code{spam-process} +group parameter specifies what spam processors to use. @xref{Spam and +Ham Processors}. + +If the spam filter failed to mark a spam message, you can mark it +yourself, so that the message is processed as spam when you exit the +group: + +@table @kbd +@item $ +@itemx M-d +@itemx M s x +@itemx S x +@kindex $ (Summary) +@kindex M-d (Summary) +@kindex S x (Summary) +@kindex M s x (Summary) +@findex gnus-summary-mark-as-spam +@findex gnus-summary-mark-as-spam +Mark current article as spam, showing it with the @samp{$} mark +(@code{gnus-summary-mark-as-spam}). +@end table + +@noindent +Similarly, you can unmark an article if it has been erroneously marked +as spam. @xref{Setting Marks}. + +Normally, a ham message found in a non-ham group is not processed as +ham---the rationale is that it should be moved into a ham group for +further processing (see below). However, you can force these articles +to be processed as ham by setting +@code{spam-process-ham-in-spam-groups} and +@code{spam-process-ham-in-nonham-groups}. + +@vindex gnus-ham-process-destinations +@vindex gnus-spam-process-destinations +The second thing that the Spam package does when you exit a group is +to move ham articles out of spam groups, and spam articles out of ham +groups. Ham in a spam group is moved to the group specified by the +variable @code{gnus-ham-process-destinations}, or the group parameter +@code{ham-process-destination}. Spam in a ham group is moved to the +group specified by the variable @code{gnus-spam-process-destinations}, +or the group parameter @code{spam-process-destination}. If these +variables are not set, the articles are left in their current group. +If an article cannot be moved (e.g., with a read-only backend such +as @acronym{NNTP}), it is copied. + +If an article is moved to another group, it is processed again when +you visit the new group. Normally, this is not a problem, but if you +want each article to be processed only once, load the +@code{gnus-registry.el} package and set the variable +@code{spam-log-to-registry} to @code{t}. @xref{Spam Package +Configuration Examples}. + +Normally, spam groups ignore @code{gnus-spam-process-destinations}. +However, if you set @code{spam-move-spam-nonspam-groups-only} to +@code{nil}, spam will also be moved out of spam groups, depending on +the @code{spam-process-destination} parameter. + +The final thing the Spam package does is to mark spam articles as +expired, which is usually the right thing to do. + +If all this seems confusing, don't worry. Soon it will be as natural +as typing Lisp one-liners on a neural interface@dots{} err, sorry, that's +50 years in the future yet. Just trust us, it's not so bad. + +@node Filtering Incoming Mail +@subsection Filtering Incoming Mail +@cindex spam filtering +@cindex spam filtering incoming mail +@cindex spam + +To use the Spam package to filter incoming mail, you must first set up +fancy mail splitting. @xref{Fancy Mail Splitting}. The Spam package +defines a special splitting function that you can add to your fancy +split variable (either @code{nnmail-split-fancy} or +@code{nnimap-split-fancy}, depending on your mail back end): + +@example +(: spam-split) +@end example + +@vindex spam-split-group +@noindent +The @code{spam-split} function scans incoming mail according to your +chosen spam back end(s), and sends messages identified as spam to a +spam group. By default, the spam group is a group named @samp{spam}, +but you can change this by customizing @code{spam-split-group}. Make +sure the contents of @code{spam-split-group} are an unqualified group +name. For instance, in an @code{nnimap} server @samp{your-server}, +the value @samp{spam} means @samp{nnimap+your-server:spam}. The value +@samp{nnimap+server:spam} is therefore wrong---it gives the group +@samp{nnimap+your-server:nnimap+server:spam}. + +@code{spam-split} does not modify the contents of messages in any way. + +@vindex nnimap-split-download-body +Note for IMAP users: if you use the @code{spam-check-bogofilter}, +@code{spam-check-ifile}, and @code{spam-check-stat} spam back ends, +you should also set the variable @code{nnimap-split-download-body} to +@code{t}. These spam back ends are most useful when they can ``scan'' +the full message body. By default, the nnimap back end only retrieves +the message headers; @code{nnimap-split-download-body} tells it to +retrieve the message bodies as well. We don't set this by default +because it will slow @acronym{IMAP} down, and that is not an +appropriate decision to make on behalf of the user. @xref{Client-Side +IMAP Splitting}. + +You have to specify one or more spam back ends for @code{spam-split} +to use, by setting the @code{spam-use-*} variables. @xref{Spam Back +Ends}. Normally, @code{spam-split} simply uses all the spam back ends +you enabled in this way. However, you can tell @code{spam-split} to +use only some of them. Why this is useful? Suppose you are using the +@code{spam-use-regex-headers} and @code{spam-use-blackholes} spam back +ends, and the following split rule: + +@example + nnimap-split-fancy '(| + (any "ding" "ding") + (: spam-split) + ;; @r{default mailbox} + "mail") +@end example + +@noindent +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. + +The solution is to let SpamAssassin headers supersede ding rules, and +perform the other @code{spam-split} rules (including a second +invocation of the regex-headers check) after the ding rule. This is +done by passing a parameter to @code{spam-split}: + +@example +nnimap-split-fancy + '(| + ;; @r{spam detected by @code{spam-use-regex-headers} goes to @samp{regex-spam}} + (: spam-split "regex-spam" 'spam-use-regex-headers) + (any "ding" "ding") + ;; @r{all other spam detected by spam-split goes to @code{spam-split-group}} + (: spam-split) + ;; @r{default mailbox} + "mail") +@end example + +@noindent +This lets you invoke specific @code{spam-split} checks depending on +your particular needs, and 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 set the @code{spam-use-*} variables for whatever spam back +ends you intend to use. 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. @xref{Spam Back Ends}. + +@c @emph{TODO: spam.el needs to provide a uniform way of training all the +@c statistical databases. Some have that functionality built-in, others +@c don't.} + +@node Detecting Spam in Groups +@subsection Detecting Spam in Groups + +To detect spam when visiting a group, set the group's +@code{spam-autodetect} and @code{spam-autodetect-methods} group +parameters. These are accessible with @kbd{G c} or @kbd{G p}, as +usual (@pxref{Group Parameters}). + +You should set the @code{spam-use-*} variables for whatever spam back +ends you intend to use. 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. + +By default, only unseen articles are processed for spam. You can +force Gnus to recheck all messages in the group by setting the +variable @code{spam-autodetect-recheck-messages} to @code{t}. + +If you use the @code{spam-autodetect} method of checking for spam, you +can specify different spam detection methods for different groups. +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. Unlike with @code{spam-split}, you don't have any control +over the @emph{sequence} of checks, but this is probably unimportant. + +@node Spam and Ham Processors +@subsection Spam and Ham Processors +@cindex spam filtering +@cindex spam filtering variables +@cindex spam variables +@cindex spam + +@vindex gnus-spam-process-newsgroups +Spam and ham processors specify special actions to take when you exit +a group buffer. Spam processors act on spam messages, and ham +processors on ham messages. At present, the main role of these +processors is to update the dictionaries of dictionary-based spam back +ends such as Bogofilter (@pxref{Bogofilter}) and the Spam Statistics +package (@pxref{Spam Statistics Filtering}). + +The spam and ham processors that apply to each group are determined by +the group's@code{spam-process} group parameter. If this group +parameter is not defined, they are determined by the variable +@code{gnus-spam-process-newsgroups}. + +@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 @kbd{M-x +customize-variable @key{RET} gnus-ham-process-destinations}). Each +group name list is a standard Lisp list, if you prefer to customize +the variable manually. If the @code{ham-process-destination} +parameter is not set, ham articles are left in place. If the +@code{spam-mark-ham-unread-before-move-from-spam-group} parameter is +set, the ham articles are marked as unread before being moved. + +If ham can not be moved---because of a read-only back end such as +@acronym{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 @kbd{M-x customize-variable @key{RET} +gnus-spam-process-destinations}). Each group name list is a standard +Lisp list, if you prefer to customize the variable manually. 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 back end such as +@acronym{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 +@code{nil}, unread articles will also be marked as spam. + +@vindex spam-mark-ham-unread-before-move-from-spam-group +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 @code{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 Package Configuration Examples +@subsection Spam Package Configuration Examples +@cindex spam filtering +@cindex spam filtering configuration examples +@cindex spam configuration examples +@cindex spam + +@subsubheading Ted's setup + +From Ted Zlatanov . +@example +;; @r{for @code{gnus-registry-split-fancy-with-parent} and spam autodetection} +;; @r{see @file{gnus-registry.el} for more information} +(gnus-registry-initialize) +(spam-initialize) + +(setq + spam-log-to-registry t ; @r{for spam autodetection} + spam-use-BBDB t + spam-use-regex-headers t ; @r{catch X-Spam-Flag (SpamAssassin)} + ;; @r{all groups with @samp{spam} in the name contain spam} + gnus-spam-newsgroup-contents + '(("spam" gnus-group-spam-classification-spam)) + ;; @r{see documentation for these} + spam-move-spam-nonspam-groups-only nil + spam-mark-only-unseen-as-spam t + spam-mark-ham-unread-before-move-from-spam-group t + ;; @r{understand what this does before you copy it to your own setup!} + ;; @r{for nnimap you'll probably want to set nnimap-split-methods, see the manual} + nnimap-split-fancy '(| + ;; @r{trace references to parents and put in their group} + (: gnus-registry-split-fancy-with-parent) + ;; @r{this will catch server-side SpamAssassin tags} + (: spam-split 'spam-use-regex-headers) + (any "ding" "ding") + ;; @r{note that spam by default will go to @samp{spam}} + (: spam-split) + ;; @r{default mailbox} + "mail")) + +;; @r{my parameters, set with @kbd{G p}} + +;; @r{all nnml groups, and all nnimap groups except} +;; @r{@samp{nnimap+mail.lifelogs.com:train} and} +;; @r{@samp{nnimap+mail.lifelogs.com:spam}: any spam goes to nnimap training,} +;; @r{because it must have been detected manually} + +((spam-process-destination . "nnimap+mail.lifelogs.com:train")) + +;; @r{all @acronym{NNTP} groups} +;; @r{autodetect spam with the blacklist and ham with the BBDB} +((spam-autodetect-methods spam-use-blacklist spam-use-BBDB) +;; @r{send all spam to the training group} + (spam-process-destination . "nnimap+mail.lifelogs.com:train")) + +;; @r{only some @acronym{NNTP} groups, where I want to autodetect spam} +((spam-autodetect . t)) + +;; @r{my nnimap @samp{nnimap+mail.lifelogs.com:spam} group} + +;; @r{this is a spam group} +((spam-contents gnus-group-spam-classification-spam) + + ;; @r{any spam (which happens when I enter for all unseen messages,} + ;; @r{because of the @code{gnus-spam-newsgroup-contents} setting above), goes to} + ;; @r{@samp{nnimap+mail.lifelogs.com:train} unless I mark it as ham} + + (spam-process-destination "nnimap+mail.lifelogs.com:train") + + ;; @r{any ham goes to my @samp{nnimap+mail.lifelogs.com:mail} folder, but} + ;; @r{also to my @samp{nnimap+mail.lifelogs.com:trainham} folder for training} + + (ham-process-destination "nnimap+mail.lifelogs.com:mail" + "nnimap+mail.lifelogs.com:trainham") + ;; @r{in this group, only @samp{!} marks are ham} + (ham-marks + (gnus-ticked-mark)) + ;; @r{remembers senders in the blacklist on the way out---this is} + ;; @r{definitely not needed, it just makes me feel better} + (spam-process (gnus-group-spam-exit-processor-blacklist))) + +;; @r{Later, on the @acronym{IMAP} server I use the @samp{train} group for training} +;; @r{SpamAssassin to recognize spam, and the @samp{trainham} group fora} +;; @r{recognizing ham---but Gnus has nothing to do with it.} + +@end example + +@subsubheading Using @code{spam.el} on an IMAP server with a statistical filter on the server +From Reiner Steib . + +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 and Ham Processors}). On group exit, +those messages are copied to both groups, @samp{INBOX} (where 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.spam}. +@end itemize + +@subsubheading Reporting spam articles in Gmane groups with @code{spam-report.el} + +From Reiner Steib . + +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 @code{(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 Spam Back Ends +@subsection Spam Back Ends +@cindex spam back ends + +The spam package offers a variety of back ends for detecting spam. +Each back end defines a set of methods for detecting spam +(@pxref{Filtering Incoming Mail}, @pxref{Detecting Spam in Groups}), +and a pair of spam and ham processors (@pxref{Spam and Ham +Processors}). + +@menu +* Blacklists and Whitelists:: +* BBDB Whitelists:: +* Gmane Spam Reporting:: +* Anti-spam Hashcash Payments:: +* Blackholes:: +* Regular Expressions Header Matching:: +* Bogofilter:: +* SpamAssassin back end:: +* ifile spam filtering:: +* Spam Statistics Filtering:: +* SpamOracle:: +@end menu + +@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. + +@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. + +While @code{spam-use-BBDB-exclusive} @emph{can} be used as an alias +for @code{spam-use-BBDB} as far as @code{spam.el} is concerned, it is +@emph{not} a separate back end. If you set +@code{spam-use-BBDB-exclusive} to @code{t}, @emph{all} your BBDB splitting +will be exclusive. + +@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. + +@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 fetch the number from the article headers. + +@end defvar + +@defvar spam-report-user-mail-address + +Mail address exposed in the User-Agent spam reports to Gmane. It allows +the Gmane administrators to contact you in case of misreports. The +default is @code{user-mail-address}. + +@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. 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 +@code{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 + +@table @kbd +@item M s t +@itemx S t +@kindex M s t +@kindex S t +@findex spam-bogofilter-score +Get the Bogofilter spamicity score (@code{spam-bogofilter-score}). +@end table + +@defvar spam-use-bogofilter-headers + +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} + +Instead of the obsolete +@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. + +@emph{WARNING} + +Instead of the obsolete +@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 +@code{spam-use-bogofilter} and @code{spam-use-bogofilter-headers} +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 SpamAssassin back end +@subsubsection SpamAssassin back end +@cindex spam filtering +@cindex spamassassin, spam filtering +@cindex spam + +@defvar spam-use-spamassassin + +Set this variable if you want @code{spam-split} to use SpamAssassin. + +SpamAssassin assigns a score to each article based on a set of rules +and tests, including a Bayesian filter. The Bayesian filter can be +trained by associating the @samp{$} mark for spam articles. The +spam score can be viewed by using the command @kbd{S t} in summary +mode. + +If you set this variable, each article will be processed by +SpamAssassin when @code{spam-split} is called. If your mail is +preprocessed by SpamAssassin, and you want to just use the +SpamAssassin headers, set @code{spam-use-spamassassin-headers} +instead. + +You should not enable this if you use +@code{spam-use-spamassassin-headers}. + +@end defvar + +@defvar spam-use-spamassassin-headers + +Set this variable if your mail is preprocessed by SpamAssassin and +want @code{spam-split} to split based on the SpamAssassin headers. + +You should not enable this if you use @code{spam-use-spamassassin}. + +@end defvar + +@defvar spam-spamassassin-program + +This variable points to the SpamAssassin executable. If you have +@code{spamd} running, you can set this variable to the @code{spamc} +executable for faster processing. See the SpamAssassin documentation +for more information on @code{spamd}/@code{spamc}. + +@end defvar + +SpamAssassin is a powerful and flexible spam filter that uses a wide +variety of tests to identify spam. A ham and a spam processors are +provided, plus the @code{spam-use-spamassassin} and +@code{spam-use-spamassassin-headers} variables to indicate to +spam-split that SpamAssassin should be either used, or has already +been used on the article. The 2.63 version of SpamAssassin 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 + +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 Statistics Filtering +@subsubsection Spam Statistics Filtering +@cindex spam filtering +@cindex spam-stat, spam filtering +@cindex spam-stat +@cindex spam + +This back end uses the Spam Statistics Emacs Lisp package to perform +statistics-based filtering (@pxref{Spam Statistics Package}). Before +using this, you may want to perform some additional steps to +initialize your Spam Statistics dictionary. @xref{Creating a +spam-stat dictionary}. + +@defvar spam-use-stat + +@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} + +Instead of the obsolete +@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. + +@emph{WARNING} + +Instead of the obsolete +@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 @code{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 advantage that the user can see the @emph{X-Spam} headers. + +The easiest method is to make @file{spam.el} (@pxref{Spam Package}) +call SpamOracle. + +@vindex spam-use-spamoracle +To enable SpamOracle usage by @code{spam.el}, set the variable +@code{spam-use-spamoracle} to @code{t} and configure the +@code{nnmail-split-fancy} or @code{nnimap-split-fancy}. @xref{Spam +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" + ;; @r{for nnimap you'll probably want to set nnimap-split-methods, see the manual} + nnimap-split-inbox '("INBOX") + 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 analysis. 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 characteristics of your spam mails. Using the @emph{add} mode +(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{Spam 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} + +Instead of the obsolete +@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 group's @code{spam-process} parameter, the ham-marked articles in +@emph{ham} groups will be sent to the SpamOracle as samples of ham +messages. + +@emph{WARNING} + +Instead of the obsolete +@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 package +@subsection Extending the Spam 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 + +Write @code{spam-check-blackbox} if Blackbox can check incoming mail. + +Write @code{spam-blackbox-register-routine} and +@code{spam-blackbox-unregister-routine} using the bogofilter +register/unregister routines as a start, or other register/unregister +routines more appropriate to Blackbox, if Blackbox can +register/unregister spam and ham. + +@item +Functionality + +The @code{spam-check-blackbox} function 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. + +@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 + +Add +@lisp +(const :tag "Spam: Blackbox" (spam spam-use-blackbox)) +(const :tag "Ham: Blackbox" (ham spam-use-blackbox)) +@end lisp +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. + +Add +@lisp +(variable-item spam-use-blackbox) +@end lisp +to the @code{spam-autodetect-methods} group parameter in +@code{gnus.el} if Blackbox can check incoming mail for spam contents. + +Finally, use the appropriate @code{spam-install-*-backend} function in +@code{spam.el}. Here are the available functions. + + +@enumerate + +@item +@code{spam-install-backend-alias} + +This function will simply install an alias for a back end that does +everything like the original back end. It is currently only used to +make @code{spam-use-BBDB-exclusive} act like @code{spam-use-BBDB}. + +@item +@code{spam-install-nocheck-backend} + +This function installs a back end that has no check function, but can +register/unregister ham or spam. The @code{spam-use-gmane} back end is +such a back end. + +@item +@code{spam-install-checkonly-backend} + +This function will install a back end that can only check incoming mail +for spam contents. It can't register or unregister messages. +@code{spam-use-blackholes} and @code{spam-use-hashcash} are such +back ends. + +@item +@code{spam-install-statistical-checkonly-backend} + +This function installs a statistical back end (one which requires the +full body of a message to check it) that can only check incoming mail +for contents. @code{spam-use-regex-body} is such a filter. + +@item +@code{spam-install-statistical-backend} + +This function install a statistical back end with incoming checks and +registration/unregistration routines. @code{spam-use-bogofilter} is +set up this way. + +@item +@code{spam-install-backend} + +This is the most normal back end installation, where a back end that can +check and register/unregister messages is set up without statistical +abilities. The @code{spam-use-BBDB} is such a back end. + +@item +@code{spam-install-mover-backend} + +Mover back ends are internal to @code{spam.el} and specifically move +articles around when the summary is exited. You will very probably +never install such a back end. +@end enumerate + +@end enumerate + +@node Spam Statistics Package +@subsection Spam Statistics Package +@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. + +The Spam Statistics package adds support to Gnus for this kind of +filtering. It can be used as one of the back ends of the Spam package +(@pxref{Spam Package}), or by itself. + +Before using the Spam Statistics package, you need to set it 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. + +@menu +* Creating a spam-stat dictionary:: +* Splitting mail using spam-stat:: +* Low-level interface to the spam-stat dictionary:: +@end menu + +@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 to +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 to 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 + +This section describes how to use the Spam statistics +@emph{independently} of the @xref{Spam Package}. + +First, add the following to your @file{~/.gnus.el} file: + +@lisp +(require 'spam-stat) +(spam-stat-load) +@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 + +@defun spam-stat-load +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) +(spam-stat-load) +@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 The Gnus Registry +@section The Gnus Registry +@cindex registry +@cindex split +@cindex track + +The Gnus registry is a package that tracks messages by their +Message-ID across all backends. This allows Gnus users to do several +cool things, be the envy of the locals, get free haircuts, and be +experts on world issues. Well, maybe not all of those, but the +features are pretty cool. + +Although they will be explained in detail shortly, here's a quick list +of said features in case your attention span is... never mind. + +@enumerate +@item +Split messages to their parent + +This keeps discussions in the same group. You can use the subject and +the sender in addition to the Message-ID@. Several strategies are +available. + +@item +Refer to messages by ID + +Commands like @code{gnus-summary-refer-parent-article} can take +advantage of the registry to jump to the referred article, regardless +of the group the message is in. + +@item +Store custom flags and keywords + +The registry can store custom flags and keywords for a message. For +instance, you can mark a message ``To-Do'' this way and the flag will +persist whether the message is in the nnimap, nnml, nnmaildir, +etc.@: backends. + +@item +Store arbitrary data + +Through a simple ELisp API, the registry can remember any data for a +message. A built-in inverse map, when activated, allows quick lookups +of all messages matching a particular set of criteria. +@end enumerate + +@menu +* Gnus Registry Setup:: +* Registry Article Refer Method:: +* Fancy splitting to parent:: +* Store custom flags and keywords:: +* Store arbitrary data:: +@end menu + +@node Gnus Registry Setup +@subsection Gnus Registry Setup + +Fortunately, setting up the Gnus registry is pretty easy: + +@lisp +(setq gnus-registry-max-entries 2500) + +(gnus-registry-initialize) +@end lisp + +This adds registry saves to Gnus newsrc saves (which happen on exit +and when you press @kbd{s} from the @file{*Group*} buffer. It also +adds registry calls to article actions in Gnus (copy, move, etc.)@: so +it's not easy to undo the initialization. See +@code{gnus-registry-initialize} for the gory details. + +Here are other settings used by the author of the registry (understand +what they do before you copy them blindly). + +@lisp +(setq + gnus-registry-split-strategy 'majority + gnus-registry-ignored-groups '(("nntp" t) + ("nnrss" t) + ("spam" t) + ("train" t)) + gnus-registry-max-entries 500000 + ;; this is the default + gnus-registry-track-extra '(sender subject)) +@end lisp + +They say: keep a lot of messages around, track messages by sender and +subject (not just parent Message-ID), and when the registry splits +incoming mail, use a majority rule to decide where messages should go +if there's more than one possibility. In addition, the registry +should ignore messages in groups that match ``nntp'', ``nnrss'', +``spam'', or ``train.'' + +You are doubtless impressed by all this, but you ask: ``I am a Gnus +user, I customize to live. Give me more.'' Here you go, these are +the general settings. + +@defvar gnus-registry-unfollowed-groups +The groups that will not be followed by +@code{gnus-registry-split-fancy-with-parent}. They will still be +remembered by the registry. This is a list of regular expressions. +By default any group name that ends with ``delayed'', ``drafts'', +``queue'', or ``INBOX'', belongs to the nnmairix backend, or contains +the word ``archive'' is not followed. +@end defvar + +@defvar gnus-registry-max-entries +The number (an integer or @code{nil} for unlimited) of entries the +registry will keep. If the registry has reached or exceeded this +size, it will reject insertion of new entries. +@end defvar + +@defvar gnus-registry-prune-factor +This option (a float between 0 and 1) controls how much the registry +is cut back during pruning. In order to prevent constant pruning, the +registry will be pruned back to less than +@code{gnus-registry-max-entries}. This option controls exactly how +much less: the target is calculated as the maximum number of entries +minus the maximum number times this factor. The default is 0.1: +i.e., if your registry is limited to 50000 entries, pruning will try to +cut back to 45000 entries. Entries with keys marked as precious will +not be pruned. +@end defvar + +@defvar gnus-registry-default-sort-function +This option specifies how registry entries are sorted during pruning. +If a function is given, it should sort least valuable entries first, +as pruning starts from the beginning of the list. The default value +is @code{gnus-registry-sort-by-creation-time}, which proposes the +oldest entries for pruning. Set to nil to perform no sorting, which +will speed up the pruning process. +@end defvar + +@defvar gnus-registry-cache-file +The file where the registry will be stored between Gnus sessions. By +default the file name is @code{.gnus.registry.eieio} in the same +directory as your @code{.newsrc.eld}. +@end defvar + +@node Registry Article Refer Method +@subsection Fetching by @code{Message-ID} Using the Registry + +The registry knows how to map each @code{Message-ID} to the group it's +in. This can be leveraged to enhance the ``article refer method'', +the thing that tells Gnus how to look up an article given its +Message-ID (@pxref{Finding the Parent}). + +@vindex nnregistry +@vindex gnus-refer-article-method + +The @code{nnregistry} refer method does exactly that. It has the +advantage that an article may be found regardless of the group it's +in---provided its @code{Message-ID} is known to the registry. It can +be enabled by augmenting the start-up file with something along these +lines: + +@example +;; Keep enough entries to have a good hit rate when referring to an +;; article using the registry. Use long group names so that Gnus +;; knows where the article is. +(setq gnus-registry-max-entries 2500) + +(gnus-registry-initialize) + +(setq gnus-refer-article-method + '(current + (nnregistry) + (nnweb "gmane" (nnweb-type gmane)))) +@end example + +The example above instructs Gnus to first look up the article in the +current group, or, alternatively, using the registry, and finally, if +all else fails, using Gmane. + +@node Fancy splitting to parent +@subsection Fancy splitting to parent + +Simply put, this lets you put followup e-mail where it belongs. + +Every message has a Message-ID, which is unique, and the registry +remembers it. When the message is moved or copied, the registry will +notice this and offer the new group as a choice to the splitting +strategy. + +When a followup is made, usually it mentions the original message's +Message-ID in the headers. The registry knows this and uses that +mention to find the group where the original message lives. You only +have to put a rule like this: + +@lisp +(setq nnimap-my-split-fancy '(| + + ;; split to parent: you need this + (: gnus-registry-split-fancy-with-parent) + + ;; other rules, as an example + (: spam-split) + ;; default mailbox + "mail") +@end lisp + +in your fancy split setup. In addition, you may want to customize the +following variables. + +@defvar gnus-registry-track-extra +This is a list of symbols, so it's best to change it from the +Customize interface. By default it's @code{(subject sender recipient)}, +which may work for you. It can be annoying if your mail flow is large +and people don't stick to the same groups. + +When you decide to stop tracking any of those extra data, you can use +the command @code{gnus-registry-remove-extra-data} to purge it from +the existing registry entries. +@end defvar + +@defvar gnus-registry-split-strategy +This is a symbol, so it's best to change it from the Customize +interface. By default it's @code{nil}, but you may want to set it to +@code{majority} or @code{first} to split by sender or subject based on +the majority of matches or on the first found. I find @code{majority} +works best. +@end defvar + +@node Store custom flags and keywords +@subsection Store custom flags and keywords + +The registry lets you set custom flags and keywords per message. You +can use the Gnus->Registry Marks menu or the @kbd{M M x} keyboard +shortcuts, where @code{x} is the first letter of the mark's name. + +@defvar gnus-registry-marks +The custom marks that the registry can use. You can modify the +default list, if you like. If you do, you'll have to exit Emacs +before they take effect (you can also unload the registry and reload +it or evaluate the specific macros you'll need, but you probably don't +want to bother). Use the Customize interface to modify the list. + +By default this list has the @code{Important}, @code{Work}, +@code{Personal}, @code{To-Do}, and @code{Later} marks. They all have +keyboard shortcuts like @kbd{M M i} for Important, using the first +letter. +@end defvar + +@defun gnus-registry-mark-article +Call this function to mark an article with a custom registry mark. It +will offer the available marks for completion. +@end defun + +You can use @code{defalias} to install a summary line formatting +function that will show the registry marks. There are two flavors of +this function, either showing the marks as single characters, using +their @code{:char} property, or showing the marks as full strings. + +@lisp +;; show the marks as single characters (see the :char property in +;; 'gnus-registry-marks'): +;; (defalias 'gnus-user-format-function-M 'gnus-registry-article-marks-to-chars) + +;; show the marks by name (see 'gnus-registry-marks'): +;; (defalias 'gnus-user-format-function-M 'gnus-registry-article-marks-to-names) +@end lisp + + +@node Store arbitrary data +@subsection Store arbitrary data + +The registry has a simple API that uses a Message-ID as the key to +store arbitrary data (as long as it can be converted to a list for +storage). + +@defun gnus-registry-set-id-key (id key value) +Store @code{value} under @code{key} for message @code{id}. +@end defun + +@defun gnus-registry-get-id-key (id key) +Get the data under @code{key} for message @code{id}. +@end defun + +@defvar gnus-registry-extra-entries-precious +If any extra entries are precious, their presence will make the +registry keep the whole entry forever, even if there are no groups for +the Message-ID and if the size limit of the registry is reached. By +default this is just @code{(marks)} so the custom registry marks are +precious. +@end defvar + +@node Other modes +@section Interaction with other modes + +@subsection Dired +@cindex dired + +@code{gnus-dired-minor-mode} provides some useful functions for dired +buffers. It is enabled with +@lisp +(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) +@end lisp + +@table @kbd +@item C-c C-m C-a +@findex gnus-dired-attach +@cindex attachments, selection via dired +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. + +@item gnus-add-timestamp-to-message +@vindex gnus-add-timestamp-to-message +This variable controls whether to add timestamps to messages that are +controlled by @code{gnus-verbose} and @code{gnus-verbose-backends} and +are issued. The default value is @code{nil} which means never to add +timestamp. If it is @code{log}, add timestamps to only the messages +that go into the @file{*Messages*} buffer (in XEmacs, it is the +@w{@file{ *Message-Log*}} buffer). If it is neither @code{nil} nor +@code{log}, add timestamps not only to log messages but also to the ones +displayed in the echo area. + +@item nnheader-max-head-length +@vindex nnheader-max-head-length +When the back ends read straight heads of articles, they all try to read +as little as possible. This variable (default 8192) 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}. + +@item nnheader-head-chop-length +@vindex nnheader-head-chop-length +This variable (default 2048) says how big a piece of each article to +read when doing the operation described above. + +@item nnheader-file-name-translation-alist +@vindex nnheader-file-name-translation-alist +@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 +(setq nnheader-file-name-translation-alist + '((?: . ?_))) +@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. + +@item gnus-parse-headers-hook +@vindex gnus-parse-headers-hook +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. + +@item gnus-safe-html-newsgroups +@vindex gnus-safe-html-newsgroups +Groups in which links in html articles are considered all safe. The +value may be a regexp matching those groups, a list of group names, or +@code{nil}. This overrides @code{mm-w3m-safe-url-regexp}. The default +value is @code{"\\`nnrss[+:]"}. This is effective only when emacs-w3m +renders html articles, i.e., in the case @code{mm-text-html-renderer} is +set to @code{w3m}. @xref{Display Customization, ,Display Customization, +emacs-mime, The Emacs MIME Manual}. + +@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 +Not for victory@* +but for the day's work done@* +as well as I was able;@* +not for a seat upon the dais@* +but at the common table.@* +@end quotation + + +@node Appendices +@chapter Appendices + +@menu +* 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 +@end menu + + +@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{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. +``@sc{gnus}''. New vs. old. + +@menu +* Gnus Versions:: What Gnus versions 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. +@end menu + + +@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 Ma 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. +It 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 and was released as +Gnus 5.10 on May 1st 2003 (24 releases). + +On the January 4th 2004, No Gnus was begun. + +On April 19, 2010 Gnus development was moved to Git. See +http://git.gnus.org for details (http://www.gnus.org will be updated +with the information when possible). + +On the January 31th 2012, Ma 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'', ``No Gnus'', ``Ma 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 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 + +@item X-Newsreader +@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 +it wasn't for the @code{X-Newsreader} header. +@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 +Message Mode is able to request notifications from the receiver. + +@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 +non-@acronym{MIME} 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 RFC 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 + +This version of Gnus should work on: + +@itemize @bullet + +@item +Emacs 23.1 and up. + +@item +XEmacs 21.4 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. Particularly, Gnus 5.10.8 should also work on Emacs +20.7 and XEmacs 21.1. + +@c No-merge comment: The paragraph added in v5-10 here must not be +@c synced here! + +@node Gnus Development +@subsection Gnus Development + +Gnus is developed in a two-phased cycle. The first phase involves much +discussion on the development mailing list @samp{ding@@gnus.org}, 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 ``Oort Gnus'' and ``No Gnus''. @xref{Gnus Versions}. + +After futzing around for 10--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.10.1'' instead. Normal people are +supposed to be able to use these, and these are mostly discussed on the +@samp{gnu.emacs.gnus} newsgroup. This newgroup is mirrored to the +mailing list @samp{info-gnus-english@@gnu.org} which is carried on Gmane +as @samp{gmane.emacs.gnus.user}. These releases are finally integrated +in Emacs. + +@cindex Incoming* +@vindex mail-source-delete-incoming +Some variable defaults differ between alpha Gnusae and released Gnusae, +in particular, @code{mail-source-delete-incoming}. This is to prevent +lossage of mail if an alpha release hiccups while handling the mail. +@xref{Mail Source Customization}. + +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 +either discarded or totally rewritten. People reading the mailing list +usually keep up with these rapid changes, while people on the newsgroup +can't be assumed to do so. + +So if you have problems with or questions about the alpha versions, +direct those to the ding mailing list @samp{ding@@gnus.org}. This list +is also available on Gmane as @samp{gmane.emacs.gnus.general}. + +@cindex Incoming* +@vindex mail-source-delete-incoming +Some variable defaults differ between alpha Gnusae and released Gnusae, +in particular, @code{mail-source-delete-incoming}. This is to prevent +lossage of mail if an alpha release hiccups while handling the mail. +@xref{Mail Source Customization}. + +@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 , yup, I'll release it right away no wait, that doesn't +work at all , yup, I'll ship that one off right away 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 for@dots{} 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, +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 Hardaker---@file{gnus-picon.el} and the manual section on +@dfn{picons} (@pxref{Picons}). + +@item +Kim-Minh Kaplan---further work on the picon code. + +@item +Brad Miller---@file{gnus-gl.el} and the GroupLens manual section. + +@item +Sudish Joseph---innumerable bug fixes. + +@item +Ilja Weis---@file{gnus-topic.el}. + +@item +Steven L. Baur---lots and lots and lots of bug detection 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 Byer---@file{nnfolder.el} 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 Edmonds---@file{gnus-bbdb.el}. + +@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@aa{}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, +Tassilo Horn, +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/5.11. +* No Gnus:: Very punny. Gnus 5.12/5.13. +* Ma Gnus:: Celebrating 25 years of Gnus. +@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 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}). + +@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. + +@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. + +@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 +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 extensible (@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 added---@kbd{C-M-d} +(@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-IDs. + +@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 @code{gnus-boring-article-headers}---@code{long-to}. + +@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 +text---@kbd{W d}. + +@item +For easier debugging of @code{nntp}, you can set +@code{nntp-record-commands} to a non-@code{nil} 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 added---@code{article-date-iso8601}. + +@item +Subjects can be simplified when threading by setting +@code{gnus-score-thread-simplify}. + +@item +A new function for citing in Message has been +added---@code{message-cite-original-without-signature}. + +@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 Installation changes +@c *********************** + +@itemize @bullet +@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 +Lisp files are now installed in @file{.../site-lisp/gnus/} by default. +It defaulted to @file{.../site-lisp/} formerly. In addition to this, +the new installer issues a warning if other Gnus installations which +will shadow the latest one are detected. You can then remove those +shadows manually or remove them using @code{make +remove-installed-shadows}. + +@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, if 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 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} and @file{xemacs.mak} +superfluous, so they have been removed. + +@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. + +@c FIXME: 'gnus-load' is mentioned in README, which is not included in +@c the repository. We should find a better place for this item. +@item +@code{(require 'gnus-load)} + +If you use a stand-alone Gnus distribution, you'd better add +@code{(require 'gnus-load)} into your @file{~/.emacs} after adding the Gnus +lisp directory into load-path. + +File @file{gnus-load.el} contains autoload commands, functions and variables, +some of which may not be included in distributions of Emacsen. + +@end itemize + +@item New packages and libraries within Gnus +@c ***************************************** + +@itemize @bullet + +@item +The revised Gnus @acronym{FAQ} is included in the manual, +@xref{Frequently Asked Questions}. + +@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. + +@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. @ref{Thwarting Email Spam} and @ref{Spam Package}. +@c FIXME: @xref{Spam Package}?. Should this be under Misc? + +@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}. + +@end itemize + +@item Changes in group mode +@c ************************ + +@itemize @bullet + +@item +@code{gnus-group-read-ephemeral-group} can be called interactively, +using @kbd{G M}. + +@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 +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{~/.gnus.el} 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 +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{nnimap-fixup-unread-after-getting-new-news} from the +@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 +want to add @code{nnimap-fixup-unread-after-getting-new-news} again. If +you were happy with the estimate and want to save some (minimal) time +when getting new mail, remove the function. + +@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 +@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 +Old intermediate incoming mail files (@file{Incoming*}) are deleted +after a couple of days, not immediately. @xref{Mail Source +Customization}. (New in Gnus 5.10.10 / Emacs 22.2) + +@end itemize + +@item Changes in summary and article mode +@c ************************************** + +@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 +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 +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 @code{gnus-button-@var{*}-level} can be used to control the +appearance of all article buttons. @xref{Article Button Levels}. + +@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 non-@code{nil}, a +boundary line is drawn at the end of the headers. + +@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 +non-@code{nil}, the summary buffer is shown and updated as it's being +built. + +@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 +diffs are automatically highlighted in groups matching +@code{mm-uu-diff-groups-regexp} + +@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. + +The new command @kbd{W Y f} +(@code{gnus-article-outlook-deuglify-article}) allows deuglifying broken +Outlook (Express) articles. + +@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 +Smileys (@samp{:-)}, @samp{;-)} etc.)@: are now displayed graphically in +Emacs too. + +Put @code{(setq gnus-treat-display-smileys nil)} in @file{~/.gnus.el} to +disable it. + +@item +Face headers handling. @xref{Face}. + +@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 +@code{gnus-summary-line-format} + +The default value changed to @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) +%s\n}. Moreover @code{gnus-extra-headers}, +@code{nnmail-extra-headers} and @code{gnus-ignored-from-addresses} +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 +Deleting of attachments. + +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{current-language-environment} variable, instead of +@code{iso-8859-1}. Also the @samp{.*} item in +@code{gnus-group-charset-alist} is removed. + +@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 +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 +@code{gnus-user-format-function-@var{foo}}. 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. +@c FIXME: Was this a user-visible change? + +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} +(@code{gnus-summary-limit-to-@{subject,author,extra@}}) respectively, the +result will be to display all articles that do not match the expression. + +@item +Gnus inlines external parts (message/external). + +@end itemize + +@item Changes in Message mode and related Gnus features +@c **************************************************** + +@itemize @bullet + +@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 the new option @code{nnml-use-compressed-files} is non-@code{nil}, +the nnml back end allows compressed message files. + +@item +The new option @code{gnus-gcc-mark-as-read} automatically marks +Gcc articles as read. + +@item +Externalizing of attachments + +If @code{gnus-gcc-externalize-attachments} or +@code{message-fcc-externalize-attachments} is non-@code{nil}, attach +local files as external parts. + +@item +The envelope sender address can be customized when using Sendmail. +@xref{Mail Variables, Mail Variables,, message, Message Manual}. + +@item +Gnus no longer generate the Sender: header automatically. + +Earlier it was generated when 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}, +@code{message-required-news-headers}, and +@code{message-required-mail-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: )} 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 @code{message-cross-post-@var{*}}). + +@item +References and X-Draft-From headers are no longer generated when you +start composing messages and @code{message-generate-headers-first} is +@code{nil}. + +@item +Easy inclusion of X-Faces headers. @xref{X-Face}. + +@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 +@code{message-insinuate-rmail} + +@c FIXME should that not be 'message-user-agent? +Adding @code{(message-insinuate-rmail)} and @code{(setq +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 +@code{gnus-posting-styles} + +Add a new format of match like +@lisp +((header "to" "larsi.*org") + (Organization "Somewhere, Inc.")) +@end lisp +The old format like the lines below is obsolete, but still accepted. +@lisp +(header "to" "larsi.*org" + (Organization "Somewhere, Inc.")) +@end lisp + +@item +@code{message-ignored-news-headers} and @code{message-ignored-mail-headers} + +@samp{X-Draft-From} and @samp{X-Gnus-Agent-Meta-Information} have been +added into these two variables. If you customized those, perhaps you +need add those two headers too. + +@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 +The option @code{mm-fill-flowed} can be used to disable treatment of +``format=flowed'' messages. Also, flowed text is disabled when sending +inline PGP signed messages. @xref{Flowed text, , Flowed text, +emacs-mime, The Emacs MIME Manual}. (New in Gnus 5.10.7) +@c This entry is also present in the node "No Gnus". + +@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 +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 behavior can be changed by customizing @code{message-insert-canlock}. + +@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 +additional Lisp libraries. This add several menu items to the +Attachments menu, and @kbd{C-c RET} key bindings, when composing +messages. This also obsoletes @code{gnus-article-hide-pgp-hook}. + +@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 the symbol +@code{best}. + +The behavior 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. + +@item +If @code{auto-compression-mode} is enabled, attachments are automatically +decompressed when activated. +@c FIXME: Does this affect article or message mode? + +@item +Support for non-@acronym{ASCII} domain names + +Message supports non-@acronym{ASCII} 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 non-@acronym{ASCII} domain names in From:, To: +and Cc: when you view a message. The variable @code{gnus-use-idna} +controls this. + +@item You can now drag and drop attachments to the Message buffer. +See @code{mml-dnd-protocol-alist} and @code{mml-dnd-attach-options}. +@xref{MIME, ,MIME, message, Message Manual}. +@c New in 5.10.9 / 5.11 (Emacs 22.1) + +@item @code{auto-fill-mode} is enabled by default in Message mode. +See @code{message-fill-column}. @xref{Various Message Variables, , +Message Headers, message, Message Manual}. +@c New in Gnus 5.10.12 / 5.11 (Emacs 22.3) + +@end itemize + +@item Changes in back ends +@c *********************** + +@itemize @bullet +@item +Gnus can display RSS newsfeeds as a newsgroup. @xref{RSS}. + +@item +The nndoc back end now supports mailman digests and exim bounces. + +@item +Gnus supports Maildir groups. + +Gnus includes a new back end @file{nnmaildir.el}. @xref{Maildir}. + +@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 @file{@var{groupname}.mrk} (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. + +@end itemize + +@item Appearance +@c ************* + +@itemize @bullet + +@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 ``@acronym{MML}'' 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 +The tool bars have been updated to use GNOME icons in Group, Summary and +Message mode. You can also customize the tool bars: @kbd{M-x +customize-apropos RET -tool-bar$} should get you started. This is a new +feature in Gnus 5.10.10. (Only for Emacs, not in XEmacs.) + +@item The tool bar icons are now (de)activated correctly +in the group buffer, see the variable @code{gnus-group-update-tool-bar}. +Its default value depends on your Emacs version. This is a new feature +in Gnus 5.10.9. +@end itemize + + +@item Miscellaneous changes +@c ************************ + +@itemize @bullet + +@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 +enabled, headers are now also retrieved from the Agent cache instead +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 +behavior 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 +Gnus reads the @acronym{NOV} and articles in the Agent if plugged. + +If one reads an article while plugged, and the article already exists +in the Agent, it won't get downloaded once more. @code{(setq +gnus-agent-cache nil)} reverts to the old behavior. + +@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 +The format spec @code{%C} for positioning point has changed to @code{%*}. + +@item +@code{gnus-slave-unplugged} + +A new command which starts Gnus offline in slave mode. + +@end itemize + +@end itemize + +@node No Gnus +@subsubsection No Gnus +@cindex No Gnus + +New features in No Gnus: +@c FIXME: Gnus 5.12? + +@include gnus-news.texi + +@node Ma Gnus +@subsubsection Ma Gnus +@cindex Ma Gnus + +I'm sure there will be lots of text here. It's really spelled 真 +Gnus. + +New features in Ma Gnus: + +@itemize @bullet + +@item Installation changes +@c *********************** + +@itemize @bullet +@item +Lisp source files and info files to be installed will be compressed by +gzip by default. + +If you don't want those files to be compressed, use the configure option +@samp{--without-compress-install}. Lisp source files that don't have +the compiled elc version in the installation directory will not be +compressed. + +@end itemize + +@item Changes in summary and article mode +@c ************************************** + +@itemize @bullet + +@item +By default, @acronym{MIME} part buttons for attachments (if any) will +appear in the end of the article header in addition to the bottom of the +article body, so you can easily find them without scrolling the article +again and again. @xref{MIME Commands}. + +@end itemize + +@item Changes in Message mode and related Gnus features +@c **************************************************** + +@itemize @bullet + +@item +The new hooks @code{gnus-gcc-pre-body-encode-hook} and +@code{gnus-gcc-post-body-encode-hook} are run before/after encoding +the message body of the Gcc copy of a sent message. See +@xref{Archived Messages}. + +@end itemize + +@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 +@c @head +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 go 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 different. + + +@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. + +@item reply +@cindex reply +Send a mail to the person who has written what you are reading. + +@item follow up +@cindex follow up +Post an article to the current newsgroup responding to the article you +are reading. + +@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. Groups from the native select method +have names like @samp{gnu.emacs.gnus}. + +@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. Foreign groups have names like +@samp{nntp+news.gmane.org:gmane.emacs.gnus.devel}. + +@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, but they, too +have names like @samp{nntp+news.gmane.org:gmane.emacs.gnus.devel}. + +@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 + +@item head +@cindex head +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. + +@item header +@cindex header +A line from the head of an article. + +@item headers +@cindex headers +A collection of such lines, or a collection of heads. Or even a +collection of @acronym{NOV} lines. + +@item @acronym{NOV} +@cindex @acronym{NOV} +@acronym{NOV} stands for News OverView, which is a type of news server +header which provide datas containing the condensed header information +of articles. They are produced by the server itself; in the @code{nntp} +back end Gnus uses the ones that the @acronym{NNTP} server makes, but +Gnus makes them by itself for some backends (in particular, @code{nnml}). + +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 +normal @sc{head} format. + +The @acronym{NOV} data consist of one or more text lines (@pxref{Text +Lines, ,Motion by Text Lines, elisp, The Emacs Lisp Reference Manual}) +where each line has the header information of one article. The header +information is a tab-separated series of the header's contents including +an article number, a subject, an author, a date, a message-id, +references, etc. + +Those data enable Gnus to generate summary lines quickly. However, if +the server does not support @acronym{NOV} or you disable it purposely or +for some reason, Gnus will try to generate the header information by +parsing each article's headers one by one. It will take time. +Therefore, it is not usually a good idea to set nn*-nov-is-evil +(@pxref{Slow/Expensive Connection}) to a non-@code{nil} value unless you +know that the server makes wrong @acronym{NOV} data. + +@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 spool +@cindex spool +News servers store their articles locally in one fashion or other. +One old-fashioned storage method is to have just one file per +article. That's called a ``traditional spool''. + +@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. + +@item threading +@cindex threading +To put responses to articles directly after the articles they respond +to---in a hierarchical fashion. + +@item root +@cindex root +@cindex thread root +The first article in a thread is the root. It is the ancestor of all +articles in the thread. + +@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, terminology +@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. + +@menu +* 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. +@end menu + + +@node Slow/Expensive Connection +@subsection Slow/Expensive 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 server. + +@table @code + +@item gnus-read-active-file +Set this to @code{nil}, which will inhibit Gnus from requesting the +entire active file from the server. This file is often very 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 +@vindex gnus-nov-is-evil +Usually this one must @emph{always} be @code{nil} (which is the +default). If, for example, you wish to not use @acronym{NOV} +(@pxref{Terminology}) with the @code{nntp} back end (@pxref{Crosspost +Handling}), set @code{nntp-nov-is-evil} to a non-@code{nil} value +instead of setting this. But you normally do not need to set +@code{nntp-nov-is-evil} since Gnus by itself will detect whether the +@acronym{NNTP} server supports @acronym{NOV}. Anyway, grabbing article +headers from the @acronym{NNTP} server will not be very fast if you tell +Gnus not to use @acronym{NOV}. + +As the variables for the other back ends, there are +@code{nndiary-nov-is-evil}, @code{nndir-nov-is-evil}, +@code{nnfolder-nov-is-evil}, @code{nnimap-nov-is-evil}, +@code{nnml-nov-is-evil}, and @code{nnspool-nov-is-evil}. Note that a +non-@code{nil} value for @code{gnus-nov-is-evil} overrides all those +variables. +@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. + +@item gnus-visible-headers +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. + +Use the following to enable all the available hiding features: +@lisp +(setq gnus-treat-hide-headers 'head + 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. + +@item gnus-thread-hide-subtree +If this is non-@code{nil}, 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. + +@item gnus-read-newsrc-file +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. + +Set @code{gnus-show-threads}, @code{gnus-use-cross-reference} and +@code{gnus-nov-is-evil} to @code{nil} to make entering and exiting the +summary buffer faster. Also @pxref{Slow/Expensive Connection}. + + +@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 @c +@samp{Ma Gnus v0.14} @c Adjust ../Makefile.in if you change this line! +@c +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 +mail you and ask for more info, and everything takes more time. + +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 behavior 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 +@samp{gnu.emacs.gnus}. I'm not very helpful. You can also ask 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. + +@menu +* 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. +* Headers:: How Gnus stores headers internally. +* 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. +@end menu + + +@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} (@pxref{Group Info}). + +@item gnus-group-unread +@findex gnus-group-unread +The number of unread articles in @var{group}, or @code{t} if that is +unknown. + +@item gnus-active +@findex gnus-active +The active entry (i.e., a cons cell containing the lowest and highest +article numbers) for @var{group}. + +@item gnus-set-active +@findex gnus-set-active +Set the active entry for @var{group}. + +@item gnus-add-current-to-buffer-list +@findex gnus-add-current-to-buffer-list +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. + +@item gnus-group-read-only-p +@findex gnus-group-read-only-p +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 essentially equal. For instance, +two virtual servers may have server parameters in different order, but +this function will consider them 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} (@pxref{Group Parameters}). +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 non-@code{nil}. + +@lisp +(gnus-check-backend-function "request-scan" "nnml:misc") +@result{} t +@end lisp + +@item gnus-read-method +@findex gnus-read-method +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-address "ifi.uio.no") + (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 +mightily confused.@footnote{See the function +@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 +@file{nnheader.el}, @file{nnmail.el} and @file{nnoo.el}. + +In the examples and definitions I will refer to the imaginary back end +@code{nnchoke}. + +@cindex @code{nnchoke} + +@menu +* Required Back End Functions:: Functions that must be implemented. +* Optional Back End Functions:: Functions that need not be implemented. +* Error Messaging:: How to get messages and report errors. +* 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. +@end menu + + +@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 non-@code{nil} 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 non-@code{nil} and not a +number, do maximum fetches. + +Here's an example HEAD: + +@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 +headers = *head +head = error / valid-head +error-message = [ "4" / "5" ] 2number " " eol +valid-head = valid-message *header "." eol +valid-message = "221 " " Article retrieved." eol +header = 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[ field ] eol +field = +@end example + +For a closer look at what should be in those fields, +@pxref{Headers}. + + +@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 +non-@code{nil} 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 +non-@code{nil} 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 non-@code{nil}, 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 INFO) + +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. + +If @var{info}, it allows the backend to update the group info +structure. + +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 " " +info = "211 " 3* [ " " ] +@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 " " " " " " flags eol +name = +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 non-@code{nil} value (exceptionally, +@code{nntp-request-update-info} always returns @code{nil} not to waste +the network resources). + +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{read}, @code{tick}, @code{reply}, @code{expire}, @code{killed}, +@code{dormant}, @code{save}, @code{download}, @code{unsend}, and +@code{forward}, 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)) + ((10 . 90) 'add '(read expire)) + ((92 94) 'del '(read))) +@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 description eol +name = +description = +@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 +non-@code{nil}, 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 +non-@code{nil} 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 + +@findex nnheader-report +@findex nnheader-get-report +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 @var{back-end}@code{-status-string}, +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 +haven't already been defined. + +@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,1996 Free Software Foundation, Inc.} + +;;; @r{Code:} + +(require 'nnheader) +(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. +@item address +The name of the server should be in the virtual server name. This is +true for almost all back ends. +@item prompt-address +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 @var{back-end}@code{-save-mail} to +save each article. @var{back-end}@code{-active-number} will be called to +find the article number assigned to this article. + +The function also uses the following variables: +@var{back-end}@code{-get-new-mail} (to see whether to get new mail for +this back end); and @var{back-end}@code{-group-alist} and +@var{back-end}@code{-active-file} to generate the new active file. +@var{back-end}@code{-group-alist} 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 parsable, but yet extremely +malleable. 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" + ("Windows 95" -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 = +string-header = "subject" / "from" / "references" / "message-id" / + "xref" / "body" / "head" / "all" / "followup" +number-header = "lines" / "chars" +date-header = "date" +string-match = "(" quote quote [ "" / [ space score [ "" / + space date [ "" / [ space string-match-t ] ] ] ] ] ")" +score = "nil" / +date = "nil" / +string-match-t = "nil" / "s" / "substring" / "S" / "Substring" / + "r" / "regex" / "R" / "Regex" / + "e" / "exact" / "E" / "Exact" / + "f" / "fuzzy" / "F" / "Fuzzy" +number-match = "(" [ "" / [ space score [ "" / + space date [ "" / [ space number-match-t ] ] ] ] ] ")" +number-match-t = "nil" / "=" / "<" / ">" / ">=" / "<=" +date-match = "(" quote 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" / +expunge = "expunge" space nil-or-number +mark-and-expunge = "mark-and-expunge" space nil-or-number +files = "files" *[ space ] +exclude-files = "exclude-files" *[ space ] +read-only = "read-only" [ space "nil" / space "t" ] +adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ] +adapt-rule = "(" *[ *[ "(" ")" ] ")" +local = "local" *[ space "(" space
")" ] +eval = "eval" space +space = *[ " " / / ] +@end example + +Any unrecognized elements in a score file should be ignored, but not +discarded. + +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}). + + +@node Headers +@subsection Headers + +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 +@code{mail-header-} and @code{mail-header-set-}, respectively. + +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 example + +is transformed into + +@example +((1 . 6) (10 . 12)) +@end example + +To avoid having those nasty @samp{(13 . 13)} elements to denote a +lonesome object, a @samp{13} is a valid element: + +@example +((1 . 6) 7 (10 . 12)) +@end example + +This means that comparing two ranges to find out whether they are equal +is slightly tricky: + +@example +((1 . 5) 7 8 (10 . 12)) +@end example + +and + +@example +((1 . 5) (7 . 8) (10 . 12)) +@end example + +are equal. In fact, any non-descending list is a range: + +@example +(1 2 3 4 5) +@end example + +is a perfectly valid range, although a pretty long-winded one. This is +also valid: + +@example +(1 . 5) +@end example + +and is equal to the previous range. + +Here's a BNF definition of ranges. Of course, one must remember the +semantic requirement that the numbers are non-descending. (Any number +of repetition of the same number is allowed, but apt to disappear in +range handling.) + +@example +range = simple-range / normal-range +simple-range = "(" number " . " number ")" +normal-range = "(" start-contents ")" +contents = "" / simple-range *[ " " contents ] / + number *[ " " contents ] +@end example + +Gnus currently uses ranges to keep track of read articles and article +marks. I plan on implementing a number of range operators in C if The +Powers That Be are willing to let me. (I haven't asked yet, because I +need to do some more thinking on what operators I need to make life +totally range-based without ever having to convert back to normal +sequences.) + + +@node Group Info +@subsection Group Info + +Gnus stores all permanent info on groups in a @dfn{group info} list. +This list is from three to six elements (or more) long and exhaustively +describes the group. + +Here are two example group infos; one is a very simple group while the +second is a more complex one: + +@example +("no.group" 5 ((1 . 54324))) + +("nnml:my.mail" 3 ((1 . 5) 9 (20 . 55)) + ((tick (15 . 19)) (replied 3 6 (19 . 3))) + (nnml "") + ((auto-expire . t) (to-address . "ding@@gnus.org"))) +@end example + +The first element is the @dfn{group name}---as Gnus knows the group, +anyway. The second element is the @dfn{subscription level}, which +normally is a small integer. (It can also be the @dfn{rank}, which is a +cons cell where the @code{car} is the level and the @code{cdr} is the +score.) The third element is a list of ranges of read articles. The +fourth element is a list of lists of article marks of various kinds. +The fifth element is the select method (or virtual server, if you like). +The sixth element is a list of @dfn{group parameters}, which is what +this section is about. + +Any of the last three elements may be missing if they are not required. +In fact, the vast majority of groups will normally only have the first +three elements, which saves quite a lot of cons cells. + +Here's a BNF definition of the group info format: + +@example +info = "(" group space ralevel space read + [ "" / [ space marks-list [ "" / [ space method [ "" / + space parameters ] ] ] ] ] ")" +group = quote quote +ralevel = rank / level +level = +rank = "(" level "." score ")" +score = +read = range +marks-lists = nil / "(" *marks ")" +marks = "(" range ")" +method = "(" *elisp-forms ")" +parameters = "(" *elisp-forms ")" +@end example + +Actually that @samp{marks} rule is a fib. A @samp{marks} is a +@samp{} consed on to a @samp{range}, but that's a bitch to say +in pseudo-BNF. + +If you have a Gnus info and want to access the elements, Gnus offers a +series of macros for getting/setting these elements. + +@table @code +@item gnus-info-group +@itemx gnus-info-set-group +@findex gnus-info-group +@findex gnus-info-set-group +Get/set the group name. + +@item gnus-info-rank +@itemx gnus-info-set-rank +@findex gnus-info-rank +@findex gnus-info-set-rank +Get/set the group rank (@pxref{Group Score}). + +@item gnus-info-level +@itemx gnus-info-set-level +@findex gnus-info-level +@findex gnus-info-set-level +Get/set the group level. + +@item gnus-info-score +@itemx gnus-info-set-score +@findex gnus-info-score +@findex gnus-info-set-score +Get/set the group score (@pxref{Group Score}). + +@item gnus-info-read +@itemx gnus-info-set-read +@findex gnus-info-read +@findex gnus-info-set-read +Get/set the ranges of read articles. + +@item gnus-info-marks +@itemx gnus-info-set-marks +@findex gnus-info-marks +@findex gnus-info-set-marks +Get/set the lists of ranges of marked articles. + +@item gnus-info-method +@itemx gnus-info-set-method +@findex gnus-info-method +@findex gnus-info-set-method +Get/set the group select method. + +@item gnus-info-params +@itemx gnus-info-set-params +@findex gnus-info-params +@findex gnus-info-set-params +Get/set the group parameters. +@end table + +All the getter functions take one parameter---the info list. The setter +functions take two parameters---the info list and the new value. + +The last three elements in the group info aren't mandatory, so it may be +necessary to extend the group info before setting the element. If this +is necessary, you can just pass on a non-@code{nil} third parameter to +the three final setter functions to have this happen automatically. + + +@node Extended Interactive +@subsection Extended Interactive +@cindex interactive +@findex gnus-interactive + +Gnus extends the standard Emacs @code{interactive} specification +slightly to allow easy use of the symbolic prefix (@pxref{Symbolic +Prefixes}). Here's an example of how this is used: + +@lisp +(defun gnus-summary-increase-score (&optional score symp) + (interactive (gnus-interactive "P\ny")) + ... + ) +@end lisp + +The best thing to do would have been to implement +@code{gnus-interactive} as a macro which would have returned an +@code{interactive} form, but this isn't possible since Emacs checks +whether a function is interactive or not by simply doing an @code{assq} +on the lambda form. So, instead we have @code{gnus-interactive} +function that takes a string and returns values that are usable to +@code{interactive}. + +This function accepts (almost) all normal @code{interactive} specs, but +adds a few more. + +@table @samp +@item y +@vindex gnus-current-prefix-symbol +The current symbolic prefix---the @code{gnus-current-prefix-symbol} +variable. + +@item Y +@vindex gnus-current-prefix-symbols +A list of the current symbolic prefixes---the +@code{gnus-current-prefix-symbol} variable. + +@item A +The current article number---the @code{gnus-summary-article-number} +function. + +@item H +The current article header---the @code{gnus-summary-article-header} +function. + +@item g +The current group name---the @code{gnus-group-group-name} +function. + +@end table + + +@node Emacs/XEmacs Code +@subsection Emacs/XEmacs Code +@cindex XEmacs +@cindex Emacsen + +While Gnus runs under Emacs, XEmacs and Mule, I decided that one of the +platforms must be the primary one. I chose Emacs. Not because I don't +like XEmacs or Mule, but because it comes first alphabetically. + +This means that Gnus will byte-compile under Emacs with nary a warning, +while XEmacs will pump out gigabytes of warnings while byte-compiling. +As I use byte-compilation warnings to help me root out trivial errors in +Gnus, that's very useful. + +I've also consistently used Emacs function interfaces, but have used +Gnusey aliases for the functions. To take an example: Emacs defines a +@code{run-at-time} function while XEmacs defines a @code{start-itimer} +function. I then define a function called @code{gnus-run-at-time} that +takes the same parameters as the Emacs @code{run-at-time}. When running +Gnus under Emacs, the former function is just an alias for the latter. +However, when running under XEmacs, the former is an alias for the +following function: + +@lisp +(defun gnus-xmas-run-at-time (time repeat function &rest args) + (start-itimer + "gnus-run-at-time" + `(lambda () + (,function ,@@args)) + time repeat)) +@end lisp + +This sort of thing has been done for bunches of functions. Gnus does +not redefine any native Emacs functions while running under XEmacs---it +does this @code{defalias} thing with Gnus equivalents instead. Cleaner +all over. + +In the cases where the XEmacs function interface was obviously cleaner, +I used it instead. For example @code{gnus-region-active-p} is an alias +for @code{region-active-p} in XEmacs, whereas in Emacs it is a function. + +Of course, I could have chosen XEmacs as my native platform and done +mapping functions the other way around. But I didn't. The performance +hit these indirections impose on Gnus under XEmacs should be slight. + + +@node Various File Formats +@subsection Various File Formats + +@menu +* Active File Format:: Information on articles and groups available. +* Newsgroups File Format:: Group descriptions. +@end menu + + +@node Active File Format +@subsubsection Active File Format + +The active file lists all groups available on the server in +question. It also lists the highest and lowest current article numbers +in each group. + +Here's an excerpt from a typical active file: + +@example +soc.motss 296030 293865 y +alt.binaries.pictures.fractals 3922 3913 n +comp.sources.unix 1605 1593 m +comp.binaries.ibm.pc 5097 5089 y +no.general 1000 900 y +@end example + +Here's a pseudo-BNF definition of this file: + +@example +active = *group-line +group-line = group spc high-number spc low-number spc flag +group = +spc = " " +high-number = +low-number = +flag = "y" / "n" / "m" / "j" / "x" / "=" group +@end example + +For a full description of this file, see the manual pages for +@samp{innd}, in particular @samp{active(5)}. + + +@node Newsgroups File Format +@subsubsection Newsgroups File Format + +The newsgroups file lists groups along with their descriptions. Not all +groups on the server have to be listed, and not all groups in the file +have to exist on the server. The file is meant purely as information to +the user. + +The format is quite simple; a group name, a tab, and the description. +Here's the definition: + +@example +newsgroups = *line +line = group tab description +group = +tab = +description = +@end example + + +@page +@node Emacs for Heathens +@section Emacs for Heathens + +Believe it or not, but some people who use Gnus haven't really used +Emacs much before they embarked on their journey on the Gnus Love Boat. +If you are one of those unfortunates whom ``@kbd{C-M-a}'', ``kill the +region'', and ``set @code{gnus-flargblossen} to an alist where the key +is a regexp that is used for matching on the group name'' are magical +phrases with little or no meaning, then this appendix is for you. If +you are already familiar with Emacs, just ignore this and go fondle your +cat instead. + +@menu +* Keystrokes:: Entering text and executing commands. +* Emacs Lisp:: The built-in Emacs programming language. +@end menu + + +@node Keystrokes +@subsection Keystrokes + +@itemize @bullet +@item +Q: What is an experienced Emacs user? + +@item +A: A person who wishes that the terminal had pedals. +@end itemize + +Yes, when you use Emacs, you are apt to use the control key, the shift +key and the meta key a lot. This is very annoying to some people +(notably @code{vi}le users), and the rest of us just love the hell out +of it. Just give up and submit. Emacs really does stand for +``Escape-Meta-Alt-Control-Shift'', and not ``Editing Macros'', as you +may have heard from other disreputable sources (like the Emacs author). + +The shift keys are normally located near your pinky fingers, and are +normally used to get capital letters and stuff. You probably use it all +the time. The control key is normally marked ``CTRL'' or something like +that. The meta key is, funnily enough, never marked as such on any +keyboard. The one I'm currently at has a key that's marked ``Alt'', +which is the meta key on this keyboard. It's usually located somewhere +to the left hand side of the keyboard, usually on the bottom row. + +Now, us Emacs people don't say ``press the meta-control-m key'', +because that's just too inconvenient. We say ``press the @kbd{C-M-m} +key''. @kbd{M-} is the prefix that means ``meta'' and ``C-'' is the +prefix that means ``control''. So ``press @kbd{C-k}'' means ``press +down the control key, and hold it down while you press @kbd{k}''. +``Press @kbd{C-M-k}'' means ``press down and hold down the meta key and +the control key and then press @kbd{k}''. Simple, ay? + +This is somewhat complicated by the fact that not all keyboards have a +meta key. In that case you can use the ``escape'' key. Then @kbd{M-k} +means ``press escape, release escape, press @kbd{k}''. That's much more +work than if you have a meta key, so if that's the case, I respectfully +suggest you get a real keyboard with a meta key. You can't live without +it. + + + +@node Emacs Lisp +@subsection Emacs Lisp + +Emacs is the King of Editors because it's really a Lisp interpreter. +Each and every key you tap runs some Emacs Lisp code snippet, and since +Emacs Lisp is an interpreted language, that means that you can configure +any key to run any arbitrary code. You just, like, do it. + +Gnus is written in Emacs Lisp, and is run as a bunch of interpreted +functions. (These are byte-compiled for speed, but it's still +interpreted.) If you decide that you don't like the way Gnus does +certain things, it's trivial to have it do something a different way. +(Well, at least if you know how to write Lisp code.) However, that's +beyond the scope of this manual, so we are simply going to talk about +some common constructs that you normally use in your @file{~/.gnus.el} +file to customize Gnus. (You can also use the @file{~/.emacs} file, but +in order to set things of Gnus up, it is much better to use the +@file{~/.gnus.el} file, @xref{Startup Files}.) + +If you want to set the variable @code{gnus-florgbnize} to four (4), you +write the following: + +@lisp +(setq gnus-florgbnize 4) +@end lisp + +This function (really ``special form'') @code{setq} is the one that can +set a variable to some value. This is really all you need to know. Now +you can go and fill your @file{~/.gnus.el} file with lots of these to +change how Gnus works. + +If you have put that thing in your @file{~/.gnus.el} file, it will be +read and @code{eval}ed (which is Lisp-ese for ``run'') the next time you +start Gnus. If you want to change the variable right away, simply say +@kbd{C-x C-e} after the closing parenthesis. That will @code{eval} the +previous ``form'', which is a simple @code{setq} statement here. + +Go ahead---just try it, if you're located at your Emacs. After you +@kbd{C-x C-e}, you will see @samp{4} appear in the echo area, which +is the return value of the form you @code{eval}ed. + +Some pitfalls: + +If the manual says ``set @code{gnus-read-active-file} to @code{some}'', +that means: + +@lisp +(setq gnus-read-active-file 'some) +@end lisp + +On the other hand, if the manual says ``set @code{gnus-nntp-server-file} to +@samp{/etc/nntpserver}'', that means: + +@lisp +(setq gnus-nntp-server-file "/etc/nntpserver") +@end lisp + +So be careful not to mix up strings (the latter) with symbols (the +former). The manual is unambiguous, but it can be confusing. + +@page +@include gnus-faq.texi + +@node GNU Free Documentation License +@chapter GNU Free Documentation License +@include doclicense.texi + +@node Index +@chapter Index +@printindex cp + +@node Key Index +@chapter Key Index +@printindex ky + +@bye + +@iftex +@iflatex +\end{document} +@end iflatex +@end iftex + +@c Local Variables: +@c mode: texinfo +@c coding: utf-8 +@c End: