mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-27 07:37:33 +00:00
8198803f66
* doc/misc/gnus.texi (HTML): Delete entries for custom variables
removed in commit 2c8b2fc8d5
. (Bug#61054)
31342 lines
1.1 MiB
31342 lines
1.1 MiB
\input texinfo
|
|
|
|
@setfilename ../../info/gnus.info
|
|
@settitle Gnus Manual
|
|
@include docstyle.texi
|
|
@syncodeindex fn cp
|
|
@syncodeindex vr cp
|
|
@syncodeindex pg cp
|
|
|
|
@copying
|
|
Copyright @copyright{} 1995--2023 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}{Gnus v5.13}
|
|
\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 Gnus v5.13
|
|
|
|
@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 Gnus v5.13
|
|
|
|
@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
|
|
* Don't Panic:: Your first 20 minutes with Gnus.
|
|
* 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?
|
|
* Child 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 Fontifying:: 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.
|
|
|
|
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.
|
|
* Virtual Groups:: Combining articles and groups together.
|
|
* 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.
|
|
|
|
Using IMAP
|
|
|
|
* 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.
|
|
|
|
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 Functions::
|
|
* 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.
|
|
* 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.
|
|
|
|
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.
|
|
|
|
Virtual Groups
|
|
|
|
* Selection Groups:: Articles selected from many places.
|
|
* Combined Groups:: Combining multiple groups.
|
|
|
|
Email Based Diary
|
|
|
|
* The NNDiary Back End:: Basic setup and usage.
|
|
* The Gnus Diary Library:: Utility toolkit on top of nndiary.
|
|
|
|
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
|
|
|
|
* Search Engines:: Selecting and configuring search engines.
|
|
* Creating Search Groups:: How and where.
|
|
* Search Queries:: Gnus' built-in search syntax.
|
|
* nnmairix:: Searching with Mairix.
|
|
* nnir::
|
|
|
|
nnmairix
|
|
|
|
* 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
|
|
|
|
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.
|
|
* Tabbed Interface:: Configuring the Gnus tabs.
|
|
* 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:: Emacs 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.
|
|
* The Gnus Cloud:: A package for synchronizing Gnus marks.
|
|
* D-Bus Integration:: Closing Gnus servers on system sleep.
|
|
* 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.
|
|
|
|
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.
|
|
|
|
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 Back Ends
|
|
|
|
* 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::
|
|
|
|
Spam Statistics Package
|
|
|
|
* Creating a spam-stat dictionary::
|
|
* Splitting mail using spam-stat::
|
|
* Low-level interface to the spam-stat dictionary::
|
|
|
|
The Gnus Registry
|
|
|
|
* Gnus Registry Setup::
|
|
* Registry Article Refer Method::
|
|
* Fancy splitting to parent::
|
|
* Store custom flags and keywords::
|
|
* Store arbitrary data::
|
|
|
|
The Gnus Cloud
|
|
|
|
* Gnus Cloud Setup::
|
|
* Gnus Cloud Usage::
|
|
|
|
Appendices
|
|
|
|
* 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?
|
|
* Conformity:: Gnus tries to conform to all standards.
|
|
* 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.
|
|
* 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 Don't Panic
|
|
@chapter Don't Panic
|
|
@cindex don't panic
|
|
@cindex introduction to Gnus
|
|
|
|
Welcome, gentle user, to the Gnus newsreader and email client! Gnus
|
|
is unlike most clients, in part because of its endless
|
|
configurability, in part because of its historical origins. Gnus is
|
|
now a fully-featured email client, but it began life as a Usenet-style
|
|
newsreader, and its genes are still newsreader genes. Thus it behaves
|
|
a little differently than most mail clients.
|
|
|
|
The typical assumptions of a newsreader are:
|
|
|
|
@enumerate
|
|
@item
|
|
The server offers a potentially enormous number of newsgroups on a
|
|
variety of subjects. The user may only be interested in some of those
|
|
groups, and more interested in some than others.
|
|
@item
|
|
Many groups see a high volume of articles, and the user won't want to
|
|
read all of them. Mechanisms are needed for foregrounding interesting
|
|
articles, and backgrounding uninteresting articles.
|
|
@item
|
|
Once a group has been scanned and dealt with by the user, it's
|
|
unlikely to be of further interest until new articles come in.
|
|
@end enumerate
|
|
|
|
These assumptions lead to certain default Gnus behaviors:
|
|
|
|
@enumerate
|
|
@item
|
|
Not all interesting groups are equally interesting, thus groups have
|
|
varying degrees of ``subscribedness'', with different behavior
|
|
depending on ``how subscribed'' a group is.
|
|
@item
|
|
There are many commands and tools for scoring and sorting articles,
|
|
or otherwise sweeping them under the rug.
|
|
@item
|
|
Gnus will only show you groups with unread or ticked articles;
|
|
groups with no new articles are hidden.
|
|
@item
|
|
When entering a group, only unread or ticked articles are shown,
|
|
all other articles are hidden.
|
|
@end enumerate
|
|
|
|
If this seems draconian, think of it as Automatic Inbox Zero. This is
|
|
the way Gnus works by default. It is possible to make it work more
|
|
like an email client (always showing read groups and read articles),
|
|
but that takes some effort on the part of the user.
|
|
|
|
The brief introduction below should be enough to get you off the
|
|
ground.
|
|
|
|
@heading The Basics of Servers, Groups, and Articles
|
|
@cindex servers
|
|
@cindex groups
|
|
@cindex articles
|
|
|
|
The fundamental building blocks of Gnus are @dfn{servers},
|
|
@dfn{groups}, and @dfn{articles}. Servers can be local or remote.
|
|
Each server maintains a list of groups, and those groups contain
|
|
articles. Because Gnus presents a unified interface to a wide variety
|
|
of servers, the vocabulary doesn't always quite line up (@pxref{FAQ
|
|
- Glossary}, for a more complete glossary). Thus a local Maildir is
|
|
referred to as a ``server'' (@pxref{Finding the News}) the same as a
|
|
Usenet or IMAP server is; ``groups'' (@pxref{Group Buffer}) might mean
|
|
an NNTP group, IMAP folder, or local mail directory; and an
|
|
``article'' (@pxref{Summary Buffer}) might elsewhere be known as a
|
|
message or an email. Gnus employs unified terms for all these things.
|
|
|
|
Servers fall into two general categories: ``news-like'', meaning that
|
|
the articles are part of a public archive and can't be manipulated by
|
|
the user; and ``mail-like'', meaning that the articles are owned by
|
|
the user, who can freely edit them, move them around, and delete
|
|
them.
|
|
|
|
For news-like servers, which typically offer hundreds or thousands of
|
|
groups, it's important to be able to subscribe to a subset of those
|
|
groups. For mail-like servers, the user is generally automatically
|
|
subscribed to all groups (though IMAP, for example, also allows
|
|
selective subscription). To change group subscription, enter the
|
|
Server buffer (with @kbd{^}) and press @kbd{@key{RET}} on the server
|
|
in question. From here, Gnus provides commands to change or toggle
|
|
your group subscriptions (@pxref{Browse Foreign Server}).
|
|
|
|
A Gnus installation is basically just a list of one or more servers,
|
|
plus the user's subscribed groups from those servers, plus articles in
|
|
those groups.
|
|
|
|
Servers can be added and configured in two places: in the user's
|
|
gnus.el startup file, using the @code{gnus-select-method} and
|
|
@code{gnus-secondary-select-methods} options, or within Gnus itself
|
|
using interactive commands in the Server buffer. @xref{Finding
|
|
the News}, for details.
|
|
|
|
|
|
@heading Fetching Mail
|
|
|
|
New mail has to come from somewhere. Some servers, such as NNTP or
|
|
IMAP, are themselves responsible for fetching newly-arrived articles.
|
|
Others, such as Maildir or mbox servers, only store articles and don't
|
|
fetch them from anywhere.
|
|
|
|
In the latter case, Gnus provides for @code{mail sources}: places
|
|
where new mail is fetched from. A mail source might be a local spool,
|
|
or a remote POP server, or some other source of incoming articles.
|
|
Mail sources are usually configured globally, but can be specified
|
|
per-group (@pxref{Mail Sources} for more information).
|
|
|
|
@xref{Scanning New Messages}, for details on fetching new mail.
|
|
|
|
@heading Viewing Mail
|
|
|
|
By default, Gnus's Group buffer only displays groups with unread
|
|
articles. It is always possible to display all the groups temporarily
|
|
with @kbd{L}, and to configure Gnus to always display some groups
|
|
(@pxref{Listing Groups}).
|
|
|
|
@xref{Selecting a Group}, for how to enter a group, and @pxref{Summary
|
|
Buffer} for what to do once you're there.
|
|
|
|
@heading Sending Mail
|
|
|
|
New message composition can be initiated from the Group buffer
|
|
(@pxref{Misc Group Stuff}). If you're in a Summary buffer, you can
|
|
compose replies and forward emails in addition to starting new
|
|
messages, see @ref{Summary Mail Commands}, for details.
|
|
|
|
For information about what happens once you've started composing a
|
|
message, see @ref{Composing Messages}. For information on setting up
|
|
@acronym{SMTP} servers in particular, see @ref{Mail Variables, ,Mail
|
|
Variables,message,Message manual}.
|
|
|
|
@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.
|
|
|
|
@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
|
|
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?
|
|
* Child 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{@key{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 @r{(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
|
|
@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 Child Gnusae
|
|
@section Child Gnusae
|
|
@cindex child
|
|
|
|
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{Parents} and
|
|
@dfn{children}.
|
|
|
|
@findex gnus-child
|
|
Anyway, you start one Gnus up the normal way with @kbd{M-x gnus} (or
|
|
however you do it). Each subsequent child Gnusae should be started with
|
|
@kbd{M-x gnus-child}. These children won't save normal @file{.newsrc}
|
|
files, but instead save @dfn{child files} that contain information only
|
|
on what groups have been read in the child session. When a parent Gnus
|
|
starts, it will read (and delete) these child files, incorporating all
|
|
information from them. (The child files will be read in the sequence
|
|
they were created, so the latest changes will have precedence.)
|
|
|
|
Information from the child files has, of course, precedence over the
|
|
information in the normal (i.e., parent) @file{.newsrc} file.
|
|
|
|
If the @file{.newsrc*} files have not been saved in the parent when the
|
|
child starts, you may be prompted as to whether to read an auto-save
|
|
file. If you answer ``yes'', the unsaved changes to the parent will be
|
|
incorporated into the child. If you answer ``no'', the child may see some
|
|
messages as unread that have been read in the parent.
|
|
|
|
|
|
|
|
@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.
|
|
|
|
@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.
|
|
|
|
@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-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.
|
|
|
|
@end table
|
|
|
|
|
|
@node Group Buffer
|
|
@chapter Group Buffer
|
|
@cindex group buffer
|
|
|
|
@c Alex Schroeder suggests to rearrange this as follows:
|
|
@c
|
|
@c <kensanata> ok, just save it for reference. I'll go to bed in a minute.
|
|
@c 1. Selecting a Group, 2. (new) Finding a Group, 3. Group Levels,
|
|
@c 4. Subscription Commands, 5. Group Maneuvering, 6. Group Data,
|
|
@c 7. Group Score, 8. Group Buffer Format
|
|
@c <kensanata> Group Levels should have more information on levels 5 to 9. I
|
|
@c suggest to split the 4th paragraph ("Gnus considers groups...") as follows:
|
|
@c <kensanata> First, "Gnus considers groups... (default 9)."
|
|
@c <kensanata> New, a table summarizing what levels 1 to 9 mean.
|
|
@c <kensanata> Third, "Gnus treats subscribed ... reasons of efficiency"
|
|
@c <kensanata> Then expand the next paragraph or add some more to it.
|
|
@c This short one sentence explains levels 1 and 2, therefore I understand
|
|
@c that I should keep important news at 3 and boring news at 4.
|
|
@c Say so! Then go on to explain why I should bother with levels 6 to 9.
|
|
@c Maybe keep those that you don't want to read temporarily at 6,
|
|
@c those that you never want to read at 8, those that offend your
|
|
@c human rights at 9...
|
|
|
|
|
|
The @dfn{group buffer} lists all (or parts) of the available groups. It
|
|
is the first buffer shown when Gnus starts, and will never be killed as
|
|
long as Gnus is active.
|
|
|
|
@iftex
|
|
@iflatex
|
|
\gnusfigure{The Group Buffer}{320}{
|
|
\put(75,50){\epsfig{figure=ps/group,height=9cm}}
|
|
\put(120,37){\makebox(0,0)[t]{Buffer name}}
|
|
\put(120,38){\vector(1,2){10}}
|
|
\put(40,60){\makebox(0,0)[r]{Mode line}}
|
|
\put(40,58){\vector(1,0){30}}
|
|
\put(200,28){\makebox(0,0)[t]{Native select method}}
|
|
\put(200,26){\vector(-1,2){15}}
|
|
}
|
|
@end iflatex
|
|
@end iftex
|
|
|
|
@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 @key{RET} gnus-group-tool-bar}.
|
|
|
|
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 @r{(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 @key{DEL}
|
|
@kindex DEL @r{(Group)}
|
|
@kindex p @r{(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 @r{(Group)}
|
|
@findex gnus-group-next-group
|
|
Go to the next group (@code{gnus-group-next-group}).
|
|
|
|
@item P
|
|
@kindex P @r{(Group)}
|
|
@findex gnus-group-prev-group
|
|
Go to the previous group (@code{gnus-group-prev-group}).
|
|
|
|
@item M-n
|
|
@kindex M-n @r{(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 @r{(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 @r{(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 , @r{(Group)}
|
|
@findex gnus-group-best-unread-group
|
|
Jump to the unread group with the lowest level
|
|
(@code{gnus-group-best-unread-group}).
|
|
|
|
@item .
|
|
@kindex . @r{(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 @key{SPC}
|
|
@kindex SPC @r{(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{@key{SPC}} enters the group normally, @kbd{C-u @key{SPC}}
|
|
offers old articles, @kbd{C-u 4 2 @key{SPC}} fetches the 42 newest
|
|
articles, and @kbd{C-u - 4 2 @key{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 @key{RET}
|
|
@kindex RET @r{(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-@key{RET}
|
|
@kindex M-RET @r{(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-@key{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-@key{SPC}
|
|
@kindex M-SPC @r{(Group)}
|
|
@findex gnus-group-visible-select-group
|
|
This is yet one more command that does the same as the @kbd{@key{RET}}
|
|
command, but this one does it without expunging and hiding dormants
|
|
(@code{gnus-group-visible-select-group}).
|
|
|
|
@item C-M-@key{RET}
|
|
@kindex C-M-RET @r{(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 (@minus{}@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{@key{SPC}} 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{@key{RET}} or @kbd{@key{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 @r{(Group)}
|
|
@kindex u @r{(Group)}
|
|
@findex gnus-group-toggle-subscription-at-point
|
|
@c @icon{gnus-group-toggle-subscription-at-point}
|
|
Toggle subscription to group under point
|
|
(@code{gnus-group-toggle-subscription-at-point}).
|
|
|
|
@item S s
|
|
@itemx U
|
|
@kindex S s @r{(Group)}
|
|
@kindex U @r{(Group)}
|
|
@findex gnus-group-toggle-subscription
|
|
Prompt for group, and toggle its subscription.
|
|
(@code{gnus-group-toggle-subscription}).
|
|
|
|
@item S k
|
|
@itemx C-k
|
|
@kindex S k @r{(Group)}
|
|
@kindex C-k @r{(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 @r{(Group)}
|
|
@kindex C-y @r{(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 @r{(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 @r{(Group)}
|
|
@kindex C-w @r{(Group)}
|
|
@findex gnus-group-kill-region
|
|
Kill all groups in the region (@code{gnus-group-kill-region}).
|
|
|
|
@item S z
|
|
@kindex S z @r{(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 @r{(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 @r{(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 @r{(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 @r{(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
|
|
@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 @r{(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 # @r{(Group)}
|
|
@itemx M m
|
|
@kindex M m @r{(Group)}
|
|
@findex gnus-group-mark-group
|
|
Toggle the process mark for the current group
|
|
(@code{gnus-group-mark-group}).@*
|
|
If @code{gnus-process-mark-toggle} is @code{nil}, set the process mark
|
|
for the current group.
|
|
|
|
@item M-#
|
|
@kindex M-# @r{(Group)}
|
|
@itemx M u
|
|
@kindex M u @r{(Group)}
|
|
@findex gnus-group-unmark-group
|
|
Remove the process mark, if any, from the current group
|
|
(@code{gnus-group-unmark-group}).
|
|
|
|
@item M U
|
|
@kindex M U @r{(Group)}
|
|
@findex gnus-group-unmark-all-groups
|
|
Remove the process mark from all groups (@code{gnus-group-unmark-all-groups}).
|
|
|
|
@item M w
|
|
@kindex M w @r{(Group)}
|
|
@findex gnus-group-mark-region
|
|
Mark groups in region (@code{gnus-group-mark-region}).
|
|
|
|
@item M b
|
|
@kindex M b @r{(Group)}
|
|
@findex gnus-group-mark-buffer
|
|
Mark all groups in the buffer (@code{gnus-group-mark-buffer}).
|
|
|
|
@item M r
|
|
@kindex M r @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 @r{(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 @r{(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 @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 @r{(Group)}
|
|
@cindex customizing
|
|
@findex gnus-group-customize
|
|
Customize the group parameters (@code{gnus-group-customize}).
|
|
|
|
@item G e
|
|
@kindex G e @r{(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 @r{(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 @r{(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 @r{(Group)}
|
|
@findex gnus-group-make-directory-group
|
|
@cindex nndir
|
|
Make a directory group (@pxref{Directory Groups}). You will be prompted
|
|
for the directory's name (@code{gnus-group-make-directory-group}).
|
|
|
|
@item G h
|
|
@kindex G h @r{(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 @r{(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 @r{(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 @r{(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 @r{(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} and @code{dejanews}.
|
|
@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 @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 @key{DEL}
|
|
@kindex G DEL @r{(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 @r{(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 @r{(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-emacs-bug-group
|
|
@findex gnus-read-ephemeral-emacs-bug-group
|
|
Read an Emacs bug report in an ephemeral group. Gnus will prompt for
|
|
multiple bug numbers. The default is the number at point. The
|
|
@acronym{URL} template 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 "\\<emacs\\>" (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.
|
|
|
|
@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}
|
|
settings (@pxref{Expiring Mail}) when expiring expirable messages.
|
|
The value can be either a number of days (not necessarily an integer),
|
|
or one of 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" "<c++std-\\1.accu.org>")
|
|
@end example
|
|
|
|
@xref{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 match-list
|
|
@cindex match-list
|
|
If this parameter is set to @code{t} and @code{nnmail-split-method} is
|
|
set to @code{gnus-group-split}, Gnus will match @code{to-address},
|
|
@code{to-list}, @code{extra-aliases} and @code{split-regexp} against
|
|
the @code{list} split abbreviation. The split regexp is modified to
|
|
match either a @code{@@} or a dot @code{.} in mail addresses to
|
|
conform to RFC2919 @code{List-ID}.
|
|
|
|
See @code{nnmail-split-abbrev-alist} for the regular expression
|
|
matching mailing-list headers.
|
|
|
|
@xref{Group Mail Splitting}, for details on how to automatically split
|
|
on group parameters.
|
|
|
|
@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 match 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{https://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 @r{(Group)}
|
|
@kindex l @r{(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 @r{(Group)}
|
|
@kindex L @r{(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 @r{(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 @r{(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 @r{(Group)}
|
|
@findex gnus-group-list-zombies
|
|
List all zombie groups (@code{gnus-group-list-zombies}).
|
|
|
|
@item A m
|
|
@kindex A m @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Group)}
|
|
@findex gnus-group-list-cached
|
|
List all groups with cached articles (@code{gnus-group-list-cached}).
|
|
|
|
@item A ?
|
|
@kindex A ? @r{(Group)}
|
|
@findex gnus-group-list-dormant
|
|
List all groups with dormant articles (@code{gnus-group-list-dormant}).
|
|
|
|
@item A !
|
|
@kindex A ! @r{(Group)}
|
|
@findex gnus-group-list-ticked
|
|
List all groups with ticked articles (@code{gnus-group-list-ticked}).
|
|
|
|
@item A /
|
|
@kindex A / @r{(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 @r{(Group)}
|
|
@findex gnus-group-list-flush
|
|
Flush groups from the current selection (@code{gnus-group-list-flush}).
|
|
|
|
@item A p
|
|
@kindex A p @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(Group)}
|
|
@findex gnus-group-check-bogus-groups
|
|
Find bogus groups and delete them
|
|
(@code{gnus-group-check-bogus-groups}).
|
|
|
|
@item F
|
|
@kindex F @r{(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 @r{(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 @r{(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 @r{(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 @r{(Browse)}
|
|
@findex gnus-group-next-group
|
|
Go to the next group (@code{gnus-group-next-group}).
|
|
|
|
@item p
|
|
@kindex p @r{(Browse)}
|
|
@findex gnus-group-prev-group
|
|
Go to the previous group (@code{gnus-group-prev-group}).
|
|
|
|
@item @key{SPC}
|
|
@kindex SPC @r{(Browse)}
|
|
@findex gnus-browse-read-group
|
|
Enter the current group and display the first article
|
|
(@code{gnus-browse-read-group}).
|
|
|
|
@item @key{RET}
|
|
@kindex RET @r{(Browse)}
|
|
@findex gnus-browse-select-group
|
|
Enter the current group (@code{gnus-browse-select-group}).
|
|
|
|
@item u
|
|
@kindex u @r{(Browse)}
|
|
@findex gnus-browse-toggle-subscription
|
|
@vindex gnus-browse-subscribe-newsgroup-method
|
|
Toggle subscription of the current group
|
|
(@code{gnus-browse-toggle-subscription}). 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 @r{(Browse)}
|
|
@kindex l @r{(Browse)}
|
|
@findex gnus-browse-exit
|
|
Exit browse mode (@code{gnus-browse-exit}).
|
|
|
|
@item d
|
|
@kindex d @r{(Browse)}
|
|
@findex gnus-browse-describe-group
|
|
Describe the current group (@code{gnus-browse-describe-group}).
|
|
|
|
@item ?
|
|
@kindex ? @r{(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 @key{DEL}
|
|
@kindex DEL @r{(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 @r{(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 @r{(Group)}
|
|
@findex gnus-group-exit
|
|
@c @icon{gnus-group-exit}
|
|
Quit Gnus (@code{gnus-group-exit}).
|
|
|
|
@item Q
|
|
@kindex Q @r{(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 @r{(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 @r{(Topic)}
|
|
@findex gnus-topic-create-topic
|
|
Prompt for a new topic name and create it
|
|
(@code{gnus-topic-create-topic}).
|
|
|
|
@item T @key{TAB}
|
|
@itemx @key{TAB}
|
|
@kindex T TAB @r{(Topic)}
|
|
@kindex TAB @r{(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-@key{TAB}
|
|
@kindex M-TAB @r{(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 @r{(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 @r{(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 @key{RET}
|
|
@kindex RET @r{(Topic)}
|
|
@findex gnus-topic-select-group
|
|
@itemx @key{SPC}
|
|
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 @r{(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 @r{(Topic)}
|
|
@findex gnus-topic-jump-to-topic
|
|
Go to a topic (@code{gnus-topic-jump-to-topic}).
|
|
|
|
@item T c
|
|
@kindex T c @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Topic)}
|
|
@findex gnus-topic-toggle-display-empty-topics
|
|
Toggle hiding empty topics
|
|
(@code{gnus-topic-toggle-display-empty-topics}).
|
|
|
|
@item T #
|
|
@kindex T # @r{(Topic)}
|
|
@findex gnus-topic-mark-topic
|
|
Toggle the process mark for all groups in the current topic
|
|
(@code{gnus-topic-mark-topic}). This command works recursively on
|
|
sub-topics unless given a prefix.@*
|
|
If @code{gnus-process-mark-toggle} is @code{nil}, set the process mark
|
|
for the current topic.
|
|
|
|
@item T M-#
|
|
@kindex T M-# @r{(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 @r{(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 @r{(Topic)}
|
|
@findex gnus-topic-rename
|
|
Rename a topic (@code{gnus-topic-rename}).
|
|
|
|
@item T @key{DEL}
|
|
@kindex T DEL @r{(Topic)}
|
|
@findex gnus-topic-delete
|
|
Delete an empty topic (@code{gnus-topic-delete}).
|
|
|
|
@item A T
|
|
@kindex A T @r{(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 @r{(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 @r{(Topic)}
|
|
@findex gnus-topic-goto-previous-topic
|
|
Go to the previous topic (@code{gnus-topic-goto-previous-topic}).
|
|
|
|
@item G p
|
|
@kindex G p @r{(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 G
|
|
Number of groups in the topic and all its subtopics.
|
|
@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}.
|
|
|
|
@vindex gnus-topic-display-predicate
|
|
If @code{gnus-topic-display-predicate} is non-@code{nil}, it should be
|
|
a function that says whether the topic is to be displayed or not.
|
|
The function will be called with one parameter (the name of the topic)
|
|
and should return non-@code{nil} is the topic is to be displayed.
|
|
|
|
For instance, if you don't even want to be reminded that work exists
|
|
outside of office hours, you can gather all the work-related groups
|
|
into a topic called @samp{"Work"}, and then say something like the
|
|
following:
|
|
|
|
@lisp
|
|
(setq gnus-topic-display-predicate
|
|
(lambda (name)
|
|
(or (not (equal name "Work"))
|
|
(< 090000
|
|
(string-to-number (format-time-string "%H%M%S"))
|
|
170000))))
|
|
@end lisp
|
|
|
|
@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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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.
|
|
|
|
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.
|
|
|
|
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} 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-unix} 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-unix} 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 @r{(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 key bindings in general
|
|
@xref{Keymaps, Keymaps, , emacs, The Emacs Editor}.
|
|
|
|
@item ^
|
|
@kindex ^ @r{(Group)}
|
|
@findex gnus-group-enter-server-mode
|
|
Enter the server buffer (@code{gnus-group-enter-server-mode}).
|
|
@xref{Server Buffer}.
|
|
|
|
@item a
|
|
@kindex a @r{(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 @r{(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 @r{(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 @r{(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-prepared-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 @r{(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 @r{(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 @r{(Group)}
|
|
Activate absolutely all groups (@code{gnus-activate-all-groups}).
|
|
|
|
@item R
|
|
@kindex R @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 @r{(Group)}
|
|
@kindex C-c C-d @r{(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 @r{(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 @r{(Group)}
|
|
@kindex H v @r{(Group)}
|
|
@cindex version
|
|
@findex gnus-version
|
|
Display current Gnus version numbers (@code{gnus-version}).
|
|
|
|
@item ?
|
|
@kindex ? @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(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 @key{RET} gnus-summary-tool-bar}.
|
|
|
|
@kindex v @r{(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 Z
|
|
Retrieval Score Value (RSV) of the article; nil if not in an nnselect
|
|
group.
|
|
@item G
|
|
Originating group name of the article; nil if not in an nnselect
|
|
group.
|
|
@item g
|
|
Short form of the originating group name of the article; nil if not in
|
|
an nnselect group.
|
|
@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}). This can be
|
|
customized using following settings:
|
|
|
|
@table @code
|
|
@item gnus-sum-opening-bracket
|
|
@vindex gnus-sum-opening-bracket
|
|
Opening bracket for normal (non-adopted) articles. The default is
|
|
@samp{[}.
|
|
|
|
@item gnus-sum-opening-bracket-adopted
|
|
@vindex gnus-sum-opening-bracket-adopted
|
|
Opening bracket for adopted articles. The default is @samp{<}.
|
|
|
|
@end table
|
|
|
|
@item ]
|
|
Closing bracket, which is normally @samp{]}, but can also be @samp{>}
|
|
for adopted articles. This can be customized using following settings:
|
|
|
|
@table @code
|
|
@item gnus-sum-closing-bracket
|
|
@vindex gnus-sum-closing-bracket
|
|
Closing bracket for normal (non-adopted) articles. The default is
|
|
@samp{]}.
|
|
|
|
@item gnus-sum-closing-bracket-adopted
|
|
@vindex gnus-sum-opening-bracket-adopted
|
|
Closing bracket for adopted articles. The default is @samp{>}.
|
|
|
|
@end table
|
|
|
|
@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. The variable may be a regexp or a predicate
|
|
function. If this 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. Otherwise, you
|
|
have to disable fetching headers with @samp{XOVER}:
|
|
|
|
@lisp
|
|
(setq nntp-nov-is-evil t
|
|
gnus-nov-is-evil t)
|
|
@end lisp
|
|
|
|
Be aware, though, that this will make entering an @acronym{NNTP} group
|
|
much, much slower, so this is not recommended.
|
|
|
|
One particular scenario in which it can be desirable to not use
|
|
@samp{XOVER} is for @code{nnvirtual} groups in order to support
|
|
limiting by extra headers (e.g., by the newsgroup of its component
|
|
groups). Because group parameters are not inherited, a separate
|
|
select method for the component groups with the appropriate
|
|
@code{nov-is-evil} set as a method variable is required.
|
|
|
|
@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 @r{(Summary)}
|
|
@kindex G M-n @r{(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 @r{(Summary)}
|
|
@kindex G M-p @r{(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 @r{(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-paging-select-next
|
|
@vindex gnus-paging-select-next
|
|
Control whether to select the next/previous article when paging (with
|
|
commands like @kbd{SPC} or @kbd{DEL}). If non-@code{nil}, select the
|
|
next article when reaching the end of the article (or the previous
|
|
article when paging backwards).
|
|
|
|
If @code{nil}, don't do anything at the end/start of the articles.
|
|
|
|
@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{@key{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 @key{SPC}
|
|
@kindex SPC @r{(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{@key{SPC}}
|
|
again, the article will be scrolled. This lets you conveniently
|
|
@kbd{@key{SPC}} through an entire newsgroup. @xref{Paging the Article}.
|
|
|
|
@item G n
|
|
@itemx n
|
|
@kindex n @r{(Summary)}
|
|
@kindex G n @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex G N @r{(Summary)}
|
|
@findex gnus-summary-next-article
|
|
Go to the next article (@code{gnus-summary-next-article}).
|
|
|
|
@item G P
|
|
@itemx P
|
|
@kindex P @r{(Summary)}
|
|
@kindex G P @r{(Summary)}
|
|
@findex gnus-summary-prev-article
|
|
Go to the previous article (@code{gnus-summary-prev-article}).
|
|
|
|
@item G u
|
|
@itemx ]
|
|
@kindex ] @r{(Summary)}
|
|
@kindex G u @r{(Summary)}
|
|
@findex gnus-summary-next-unseen-article
|
|
Go to the next unseen article (@code{gnus-summary-next-unseen-article}).
|
|
|
|
@item G U
|
|
@itemx [
|
|
@kindex [ @r{(Summary)}
|
|
@kindex G U @r{(Summary)}
|
|
@findex gnus-summary-prev-unseen-article
|
|
Go to the previous unseen article (@code{gnus-summary-prev-unseen-article}).
|
|
|
|
@item G C-n
|
|
@kindex G C-n @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex . @r{(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 @r{(Summary)}
|
|
@kindex , @r{(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 @r{(Summary)}
|
|
@kindex G l @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex G j @r{(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 @key{SPC}
|
|
@kindex SPC @r{(Summary)}
|
|
@findex gnus-summary-next-page
|
|
Pressing @kbd{@key{SPC}} 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 @key{DEL}
|
|
@kindex DEL @r{(Summary)}
|
|
@findex gnus-summary-prev-page
|
|
Scroll the current article back one page (@code{gnus-summary-prev-page}).
|
|
|
|
@item @key{RET}
|
|
@kindex RET @r{(Summary)}
|
|
@findex gnus-summary-scroll-up
|
|
Scroll the current article one line forward
|
|
(@code{gnus-summary-scroll-up}).
|
|
|
|
@item M-@key{RET}
|
|
@kindex M-RET @r{(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 @r{(Summary)}
|
|
@kindex g @r{(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 @key{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 < @r{(Summary)}
|
|
@kindex A < @r{(Summary)}
|
|
@findex gnus-summary-beginning-of-article
|
|
Scroll to the beginning of the article
|
|
(@code{gnus-summary-beginning-of-article}).
|
|
|
|
@item A >
|
|
@itemx >
|
|
@kindex > @r{(Summary)}
|
|
@kindex A > @r{(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 @r{(Summary)}
|
|
@kindex s @r{(Summary)}
|
|
@findex gnus-summary-isearch-article
|
|
Perform an isearch in the article buffer
|
|
(@code{gnus-summary-isearch-article}).
|
|
|
|
@item h
|
|
@kindex h @r{(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 @r{(Summary)}
|
|
@kindex r @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 @r{(Summary)}
|
|
@kindex S R @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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @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 @r{(Summary)}
|
|
@kindex C-c C-f @r{(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 forwarded message is inlined into the mail.
|
|
|
|
@item S m
|
|
@itemx m
|
|
@kindex m @r{(Summary)}
|
|
@kindex S m @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex S p @r{(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 @r{(Summary)}
|
|
@kindex S f @r{(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 @r{(Summary)}
|
|
@kindex F @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-yank-message
|
|
Yank the current article into an already existing Message composition
|
|
buffer (@code{gnus-summary-yank-message}). This command prompts for
|
|
what message buffer you want to yank into, and understands the
|
|
process/prefix convention (@pxref{Process/Prefix}).
|
|
|
|
@item S A
|
|
@kindex S A @r{(Summary)}
|
|
@findex gnus-summary-attach-article
|
|
Attach the current article into an already existing Message
|
|
composition buffer (@code{gnus-summary-attach-message}). If no such
|
|
buffer exists, a new one is created. 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 @r{(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 @r{(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 @key{SPC}
|
|
@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 @r{(Summary)}
|
|
@kindex M-u @r{(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 ! @r{(Summary)}
|
|
@kindex M t @r{(Summary)}
|
|
@findex gnus-summary-tick-article-forward
|
|
Tick the current article (@code{gnus-summary-tick-article-forward}).
|
|
@xref{Article Caching}.
|
|
|
|
@item M ?
|
|
@itemx ?
|
|
@kindex ? @r{(Summary)}
|
|
@kindex M ? @r{(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 @r{(Summary)}
|
|
@kindex d @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex M k @r{(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 @r{(Summary)}
|
|
@kindex C-k @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex E @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-set-bookmark
|
|
Set a bookmark in the current article
|
|
(@code{gnus-summary-set-bookmark}).
|
|
|
|
@item M B
|
|
@kindex M B @r{(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 @r{(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 @r{(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 @r{(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{@key{SPC}}) 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 # @r{(Summary)}
|
|
@kindex M P p @r{(Summary)}
|
|
@findex gnus-summary-mark-as-processable
|
|
Toggle the process mark for the current article
|
|
(@code{gnus-summary-mark-as-processable}).@*
|
|
If @code{gnus-process-mark-toggle} is @code{nil}, set the process mark
|
|
for the current article.
|
|
|
|
@item M P u
|
|
@itemx M-#
|
|
@kindex M P u @r{(Summary)}
|
|
@kindex M-# @r{(Summary)}
|
|
@findex gnus-summary-unmark-as-processable
|
|
Remove the process mark, if any, from the current article
|
|
(@code{gnus-summary-unmark-as-processable}).
|
|
|
|
@item M P U
|
|
@kindex M P U @r{(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 @r{(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 @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 @r{(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 @r{(Summary)}
|
|
@findex gnus-uu-mark-region
|
|
Mark articles in region (@code{gnus-uu-mark-region}).
|
|
|
|
@item M P g
|
|
@kindex M P g @r{(Summary)}
|
|
@findex gnus-uu-unmark-region
|
|
Unmark articles in region (@code{gnus-uu-unmark-region}).
|
|
|
|
@item M P t
|
|
@kindex M P t @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 / / @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex x @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 / . @r{(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 @r{(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}). If given a prefix, below
|
|
some score.
|
|
|
|
@item / p
|
|
@kindex / p @r{(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 @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 @r{(Summary)}
|
|
@kindex / E @r{(Summary)}
|
|
@findex gnus-summary-limit-include-expunged
|
|
Include all expunged articles in the limit
|
|
(@code{gnus-summary-limit-include-expunged}).
|
|
|
|
@item / D
|
|
@kindex / D @r{(Summary)}
|
|
@findex gnus-summary-limit-include-dormant
|
|
Include all dormant articles in the limit
|
|
(@code{gnus-summary-limit-include-dormant}).
|
|
|
|
@item / *
|
|
@kindex / * @r{(Summary)}
|
|
@findex gnus-summary-limit-include-cached
|
|
Include all cached articles in the limit
|
|
(@code{gnus-summary-limit-include-cached}).
|
|
|
|
@item / d
|
|
@kindex / d @r{(Summary)}
|
|
@findex gnus-summary-limit-exclude-dormant
|
|
Exclude all dormant articles from the limit
|
|
(@code{gnus-summary-limit-exclude-dormant}).
|
|
|
|
@item / M
|
|
@kindex / M @r{(Summary)}
|
|
@findex gnus-summary-limit-exclude-marks
|
|
Exclude all marked articles (@code{gnus-summary-limit-exclude-marks}).
|
|
|
|
@item / T
|
|
@kindex / T @r{(Summary)}
|
|
@findex gnus-summary-limit-include-thread
|
|
Include all the articles in the current thread in the limit.
|
|
|
|
@item / c
|
|
@kindex / c @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 <mernst@cs.rice.edu>
|
|
@lisp
|
|
(setq gnus-simplify-ignored-prefixes
|
|
(concat
|
|
"\\`\\[?\\("
|
|
(regexp-opt '("looking"
|
|
"wanted" "followup" "summary" "summary of"
|
|
"help" "query" "problem" "question"
|
|
"answer" "reference" "announce"
|
|
"How can I" "How to" "Comparison of"
|
|
;; ...
|
|
))
|
|
"\\)\\s *\\("
|
|
(regexp-opt '("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, @code{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 @r{(Summary)}
|
|
@kindex C-M-k @r{(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 @r{(Summary)}
|
|
@kindex C-M-l @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-raise-thread
|
|
Increase the score of the current (sub-)thread
|
|
(@code{gnus-summary-raise-thread}).
|
|
|
|
@item T #
|
|
@kindex T # @r{(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-# @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-toggle-threads
|
|
Toggle threading (@code{gnus-summary-toggle-threads}).
|
|
|
|
@item T s
|
|
@kindex T s @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-hide-thread
|
|
Hide the current (sub-)thread (@code{gnus-summary-hide-thread}).
|
|
|
|
@item T S
|
|
@kindex T S @r{(Summary)}
|
|
@findex gnus-summary-show-all-threads
|
|
Expose all hidden threads (@code{gnus-summary-show-all-threads}).
|
|
|
|
@item T H
|
|
@kindex T H @r{(Summary)}
|
|
@findex gnus-summary-hide-all-threads
|
|
Hide all threads (@code{gnus-summary-hide-all-threads}).
|
|
|
|
@item T t
|
|
@kindex T t @r{(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 ^ @r{(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-^ @r{(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 @r{(Summary)}
|
|
@itemx C-M-f
|
|
@kindex C-M-n @r{(Summary)}
|
|
@itemx M-@key{DOWN}
|
|
@kindex M-DOWN @r{(Summary)}
|
|
@findex gnus-summary-next-thread
|
|
Go to the next thread (@code{gnus-summary-next-thread}).
|
|
|
|
@item T p
|
|
@kindex T p @r{(Summary)}
|
|
@itemx C-M-b
|
|
@kindex C-M-p @r{(Summary)}
|
|
@itemx M-@key{UP}
|
|
@kindex M-UP @r{(Summary)}
|
|
@findex gnus-summary-prev-thread
|
|
Go to the previous thread (@code{gnus-summary-prev-thread}).
|
|
|
|
@item T d
|
|
@kindex T d @r{(Summary)}
|
|
@findex gnus-summary-down-thread
|
|
Descend the thread (@code{gnus-summary-down-thread}).
|
|
|
|
@item T u
|
|
@kindex T u @r{(Summary)}
|
|
@findex gnus-summary-up-thread
|
|
Ascend the thread (@code{gnus-summary-up-thread}).
|
|
|
|
@item T o
|
|
@kindex T o @r{(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-newsgroups
|
|
@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-newsgroups} and
|
|
@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-newsgroups
|
|
@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-newsgroups}, @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 * @r{(Summary)}
|
|
@findex gnus-cache-enter-article
|
|
Make the current article persistent (@code{gnus-cache-enter-article}).
|
|
|
|
@item M-*
|
|
@kindex M-* @r{(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 @r{(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 @r{@r{(Article)}}
|
|
@findex bury-buffer
|
|
Puts this sticky article buffer at the end of the list of all buffers.
|
|
|
|
@item k
|
|
@kindex k @r{(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.
|
|
A directory name (ending in @samp{/}) causes the target
|
|
to be a file under that directory. 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 @r{(Summary)}
|
|
@kindex o @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex | @r{(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 @r{(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{https://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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-uu-decode-unshar
|
|
Unshars the current series (@code{gnus-uu-decode-unshar}).
|
|
|
|
@item X S
|
|
@kindex X S @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-uu-decode-postscript
|
|
Unpack the current PostScript series (@code{gnus-uu-decode-postscript}).
|
|
|
|
@item X P
|
|
@kindex X P @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-uu-decode-save
|
|
Save the current series
|
|
(@code{gnus-uu-decode-save}).
|
|
|
|
@item X b
|
|
@kindex X b @r{(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 @r{(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-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 Fontifying:: 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 @r{(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 @r{(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 @r{(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 @r{(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 Fontifying
|
|
@subsection Article Fontifying
|
|
@cindex emphasis
|
|
@cindex article emphasis
|
|
|
|
@findex gnus-article-emphasize
|
|
@kindex W e @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-article-hide-headers
|
|
Hide headers (@code{gnus-article-hide-headers}). @xref{Hiding
|
|
Headers}.
|
|
|
|
@item W W b
|
|
@kindex W W b @r{(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 @r{(Summary)}
|
|
@findex gnus-article-hide-signature
|
|
Hide signature (@code{gnus-article-hide-signature}). @xref{Article
|
|
Signature}.
|
|
|
|
@item W W l
|
|
@kindex W W l @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(Summary)}
|
|
@findex gnus-summary-morse-message
|
|
Morse decode the article buffer (@code{gnus-summary-morse-message}).
|
|
|
|
@item W i
|
|
@kindex W i @r{(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{https://www.gnu.org/software/libidn/}) installed for this command
|
|
to work.
|
|
|
|
@item W t
|
|
@item t
|
|
@kindex W t @r{(Summary)}
|
|
@kindex t @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-article-treat-overstrike
|
|
Treat overstrike (@code{gnus-article-treat-overstrike}).
|
|
|
|
@item W d
|
|
@kindex W d @r{(Summary)}
|
|
@findex gnus-article-treat-smartquotes
|
|
@vindex gnus-article-smartquotes-map
|
|
@cindex Smartquotes
|
|
@cindex M****s*** sm*rtq**t*s
|
|
@cindex Latin 1
|
|
Treat ``Microsoft smartquotes'' according to
|
|
@code{gnus-article-smartquotes-map}
|
|
(@code{gnus-article-treat-smartquotes}). Note that this function guesses
|
|
whether a character is a smartquote or not, so it should only be used
|
|
interactively.
|
|
|
|
Smartquotes are Microsoft'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 @r{(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 @r{(Summary)}
|
|
@findex gnus-article-outlook-deuglify-article
|
|
@cindex Outlook Express
|
|
Full deuglify of broken Outlook (Express) articles: Treat
|
|
\"smartquotes\", unwrap lines, repair attribution and rearrange
|
|
citation (@code{gnus-article-outlook-deuglify-article}).
|
|
|
|
@item W Y u
|
|
@kindex W Y u @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-article-fill-long-lines
|
|
Fill long lines (@code{gnus-article-fill-long-lines}).
|
|
|
|
You can give the command a numerical prefix to specify the width to use
|
|
when filling.
|
|
|
|
@item W C
|
|
@kindex W C @r{(Summary)}
|
|
@findex gnus-article-capitalize-sentences
|
|
Capitalize the first word in each sentence
|
|
(@code{gnus-article-capitalize-sentences}).
|
|
|
|
@item W c
|
|
@kindex W c @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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{https://w3m.sourceforge.net/, w3m}.
|
|
|
|
@item links
|
|
Use @uref{http://links.twibright.com/, Links}.
|
|
|
|
@item lynx
|
|
Use @uref{https://lynx.browser.org/, Lynx}.
|
|
|
|
@end table
|
|
|
|
@item W D F
|
|
@kindex W D F @r{(Summary)}
|
|
@findex gnus-article-toggle-fonts
|
|
Toggle proportional fonts for @acronym{HTML} articles. This temporarily
|
|
changes the @code{shr-use-fonts} variable in the current article buffer.
|
|
|
|
@item W b
|
|
@kindex W b @r{(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 @r{(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 @r{(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{https://ftp.isc.org/pub/pgpcontrol/README.html}}
|
|
|
|
@item W s
|
|
@kindex W s @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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{@key{RET}} or use the middle mouse
|
|
button on these references.
|
|
|
|
@vindex gnus-button-man-handler
|
|
Gnus adds @dfn{buttons} to certain standard references by default:
|
|
Well-formed URLs, mail addresses, Message-IDs, Info links, man pages and
|
|
Emacs or Gnus related references. This is controlled by two variables,
|
|
one that handles article bodies and one that handles article heads:
|
|
|
|
@table @code
|
|
|
|
@item gnus-button-alist
|
|
@vindex gnus-button-alist
|
|
This is an alist where each entry has this form:
|
|
|
|
@lisp
|
|
(@var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par})
|
|
@end lisp
|
|
|
|
@table @var
|
|
|
|
@item regexp
|
|
All text that match this regular expression (case insensitive) will be
|
|
considered an external reference. Here's a typical regexp that matches
|
|
embedded URLs: @samp{<URL:\\([^\n\r>]*\\)>}. This can also be a
|
|
variable containing a regexp, useful variables to use include
|
|
@code{gnus-button-url-regexp} and @code{gnus-button-mid-or-mail-regexp}.
|
|
|
|
@item button-par
|
|
Gnus has to know which parts of the matches is to be highlighted. This
|
|
is a number that says what sub-expression of the regexp is to be
|
|
highlighted. If you want it all highlighted, you use 0 here.
|
|
|
|
@item use-p
|
|
This form will be @code{eval}ed, and if the result is 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
|
|
("<URL:\\([^\n\r>]*\\)>" 0 t gnus-button-url 1)
|
|
@end lisp
|
|
|
|
@item gnus-header-button-alist
|
|
@vindex gnus-header-button-alist
|
|
This is just like the other alist, except that it is applied to the
|
|
article head only, and that each entry has an additional element that is
|
|
used to say what headers to apply the buttonize coding to:
|
|
|
|
@lisp
|
|
(@var{header} @var{regexp} @var{button-par} @var{use-p} @var{function} @var{data-par})
|
|
@end lisp
|
|
|
|
@var{header} is a regular expression.
|
|
@end table
|
|
|
|
@subsubsection Related variables and functions
|
|
|
|
@table @code
|
|
@item 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 ID, @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))
|
|
("\\<unix\\>" (gnus-button-man-level 10))
|
|
("\\<tex\\>" (gnus-button-tex-level 10))))
|
|
@end lisp
|
|
|
|
@table @code
|
|
|
|
@item gnus-button-browse-level
|
|
@vindex gnus-button-browse-level
|
|
Controls the display of references to message IDs, mail addresses and
|
|
news URLs. Related variables and functions include
|
|
@code{gnus-button-url-regexp}, @code{browse-url}, and
|
|
@code{browse-url-browser-function}.
|
|
|
|
@item gnus-button-emacs-level
|
|
@vindex gnus-button-emacs-level
|
|
Controls the display of Emacs or Gnus references. Related functions are
|
|
@code{gnus-button-handle-custom},
|
|
@code{gnus-button-handle-describe-function},
|
|
@code{gnus-button-handle-describe-variable},
|
|
@code{gnus-button-handle-symbol},
|
|
@code{gnus-button-handle-describe-key},
|
|
@code{gnus-button-handle-apropos},
|
|
@code{gnus-button-handle-apropos-command},
|
|
@code{gnus-button-handle-apropos-variable},
|
|
@code{gnus-button-handle-apropos-documentation}, and
|
|
@code{gnus-button-handle-library}.
|
|
|
|
@item gnus-button-man-level
|
|
@vindex gnus-button-man-level
|
|
Controls the display of references to (Unix) man pages.
|
|
See @code{gnus-button-man-handler}.
|
|
|
|
@item gnus-button-message-level
|
|
@vindex gnus-button-message-level
|
|
Controls the display of message IDs, mail addresses and news URLs.
|
|
Related variables and functions include
|
|
@code{gnus-button-mid-or-mail-regexp},
|
|
@code{gnus-button-prefer-mid-or-mail},
|
|
@code{gnus-button-mid-or-mail-heuristic}, and
|
|
@code{gnus-button-mid-or-mail-heuristic-alist}.
|
|
|
|
@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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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{https://en.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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-treat-smiley
|
|
Display smileys (@code{gnus-treat-smiley}).
|
|
|
|
@item W D f
|
|
@kindex W D f @r{(Summary)}
|
|
@findex gnus-treat-from-picon
|
|
Piconify the @code{From} header (@code{gnus-treat-from-picon}).
|
|
|
|
@item W D m
|
|
@kindex W D m @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-treat-from-gravatar
|
|
Gravatarify the @code{From} header (@code{gnus-treat-from-gravatar}).
|
|
|
|
@item W D h
|
|
@kindex W D h @r{(Summary)}
|
|
@findex gnus-treat-mail-gravatar
|
|
Gravatarify all mail headers (i.e., @code{Cc}, @code{To})
|
|
(@code{gnus-treat-from-gravatar}).
|
|
|
|
@item W D e
|
|
@kindex W D e @r{(Summary)}
|
|
@findex gnus-article-emojize-symbols
|
|
Some symbols have both a non-emoji presentation and an emoji
|
|
presentation. This command will make Gnus choose the emoji presentation
|
|
(@code{gnus-article-emojize-symbols}).
|
|
|
|
@item W D D
|
|
@kindex W D D @r{(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 @r{(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 RFC 5536. 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 @r{(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 @r{(Summary)}
|
|
@kindex K v @r{(Summary)}
|
|
View the @acronym{MIME} part.
|
|
|
|
@item K o
|
|
@kindex K o @r{(Summary)}
|
|
Save the @acronym{MIME} part.
|
|
|
|
@item K O
|
|
@kindex K O @r{(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 @r{(Summary)}
|
|
Replace the @acronym{MIME} part with an external body.
|
|
|
|
@item K d
|
|
@kindex K d @r{(Summary)}
|
|
Delete the @acronym{MIME} part and add some information about the
|
|
removed part.
|
|
|
|
@item K c
|
|
@kindex K c @r{(Summary)}
|
|
Copy the @acronym{MIME} part.
|
|
|
|
@item K e
|
|
@kindex K e @r{(Summary)}
|
|
View the @acronym{MIME} part externally.
|
|
|
|
@item K i
|
|
@kindex K i @r{(Summary)}
|
|
View the @acronym{MIME} part internally.
|
|
|
|
@item K |
|
|
@kindex K | @r{(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 @r{(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.
|
|
|
|
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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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{<backend>-fetch-partial-articles} is non-@code{nil}, Gnus will
|
|
fetch partial articles, if the backend it fetches them from supports
|
|
it. Currently only @code{nnimap} does. If you're looking at a
|
|
partial article, and want to see the complete article instead, then
|
|
the @kbd{A C} command (@code{gnus-summary-show-complete-article}) will
|
|
do so.
|
|
|
|
@item w
|
|
@itemx A w
|
|
@kindex w @r{(Summary)}
|
|
@kindex A w @r{(Summary)}
|
|
@cindex web
|
|
@cindex url
|
|
@findex gnus-summary-browse-url
|
|
Scan the article buffer for links, and offer them to the user for
|
|
browsing with @code{browse-url}. With a prefix argument, browse with
|
|
@code{browse-url-secondary-browser-function} instead.
|
|
|
|
@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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-sort-by-chars
|
|
Sort by article length (@code{gnus-summary-sort-by-chars}).
|
|
|
|
@item C-c C-s C-m C-m
|
|
@kindex C-c C-s C-m C-m @r{(Summary)}
|
|
@findex gnus-summary-sort-by-marks
|
|
Sort by article ``readedness'' marks (@code{gnus-summary-sort-by-marks}).
|
|
|
|
@item C-c C-s C-i
|
|
@kindex C-c C-s C-i @r{(Summary)}
|
|
@findex gnus-summary-sort-by-score
|
|
Sort by score (@code{gnus-summary-sort-by-score}).
|
|
|
|
@item C-c C-s C-u
|
|
@kindex C-c C-s C-u @r{(Summary)}
|
|
@findex gnus-summary-sort-by-newsgroups
|
|
Sort by newsgroups (@code{gnus-summary-sort-by-newsgroups}).
|
|
|
|
@item C-c C-s C-x
|
|
@kindex C-c C-s C-x @r{(Summary)}
|
|
@findex gnus-summary-sort-by-extra
|
|
Prompts for extra header to sort by (@code{gnus-summary-sort-by-extra}).
|
|
An error will be raised if no sort functions for the header are defined.
|
|
|
|
@item C-c C-s C-r
|
|
@kindex C-c C-s C-r @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 @r{(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 ^ @r{(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 @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 @r{(Summary)}
|
|
Display the full thread where the current article appears
|
|
(@code{gnus-summary-refer-thread}). By default this command looks for
|
|
articles only in the current group. Some backends (currently only
|
|
@code{nnimap}) know how to find articles in the thread directly. In
|
|
other cases each header in the current group must be fetched and
|
|
examined, 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-use-search
|
|
If @code{gnus-refer-thread-use-search} is non-@code{nil} then those backends
|
|
that know how to find threads directly will search not just in the
|
|
current group but all groups on the same server.
|
|
|
|
@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.
|
|
|
|
@vindex gnus-refer-thread-limit-to-thread
|
|
In most cases @code{gnus-refer-thread} adds any articles it finds to
|
|
the current summary buffer. (When @code{gnus-refer-thread-use-search}
|
|
is true and the initial referral starts from a summary buffer for a
|
|
non-virtual group this may not be possible. In this case a new
|
|
summary buffer is created holding a virtual group with the result of
|
|
the thread search.) If @code{gnus-refer-thread-limit-to-thread} is
|
|
non-@code{nil} then the summary buffer will be limited to articles in the
|
|
thread.
|
|
|
|
@item M-^ (Summary)
|
|
@findex gnus-summary-refer-article
|
|
@kindex M-^ @r{(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
|
|
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 . @r{(Pick)}
|
|
@findex gnus-pick-article-or-thread
|
|
Pick the article or thread on the current line or unpick it if is
|
|
already picked (@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.) If
|
|
@code{gnus-process-mark-toggle} is @code{nil}, this key will pick an
|
|
article or thread.
|
|
|
|
@item @key{SPC}
|
|
@kindex SPC @r{(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 @r{(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 @key{RET}
|
|
@kindex RET @r{(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
|
|
If you spend much time in binary groups, you may grow tired of hitting
|
|
@kbd{X u}, @kbd{n}, @kbd{@key{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 @r{(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 @r{(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 @r{(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 @key{DEL}
|
|
@kindex B DEL @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(Summary)}
|
|
@kindex e @r{(Summary)}
|
|
@findex gnus-summary-edit-article
|
|
@kindex C-c C-c @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 M-s
|
|
@kindex M-s M-s @r{(Summary)}
|
|
@findex gnus-summary-search-article-forward
|
|
Search through all subsequent (raw) articles for a regexp
|
|
(@code{gnus-summary-search-article-forward}).
|
|
|
|
@item M-s M-r
|
|
@kindex M-s M-r @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 @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-repeat-search-article-backward
|
|
Repeat the previous search backwards
|
|
(@code{gnus-summary-repeat-search-article-backward}).
|
|
|
|
@item &
|
|
@kindex & @r{(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{& @key{RET} some.*string @key{RET} #} will put the
|
|
process mark on all articles that have heads or bodies that match
|
|
@samp{some.*string}.
|
|
|
|
@item M-&
|
|
@kindex M-& @r{(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 @r{(Summary)}
|
|
@findex gnus-summary-prepare
|
|
Regenerate the current summary buffer (@code{gnus-summary-prepare}).
|
|
|
|
@item Y c
|
|
@kindex Y c @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex A D @r{(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 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 @r{(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 @r{(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 = @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex Z Q @r{(Summary)}
|
|
@kindex q @r{(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 @r{(Summary)}
|
|
@kindex Q @r{(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 @r{(Summary)}
|
|
@kindex c @r{(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 @r{(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 @r{(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 @r{(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 @r{(Summary)}
|
|
@kindex C-x C-s @r{(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 @r{(Summary)}
|
|
@kindex M-g @r{(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 @r{(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 @r{(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 @r{(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 Mailcrypt is 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{mailcrypt} is 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{mailcrypt} is 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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @key{RET} (Article)
|
|
@kindex RET @r{(Article)}
|
|
@itemx @key{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-@key{RET} (Article)
|
|
@kindex M-RET @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(Article)}
|
|
View the @acronym{MIME} object with an external viewer.
|
|
(@code{gnus-mime-view-part-externally}).
|
|
|
|
@findex gnus-mime-pipe-part
|
|
@item | (Article)
|
|
@kindex | @r{(Article)}
|
|
Output the @acronym{MIME} object to a process (@code{gnus-mime-pipe-part}).
|
|
|
|
@findex gnus-mime-action-on-part
|
|
@item . (Article)
|
|
@kindex . @r{(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, to 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.
|
|
|
|
@vindex gnus-global-groups
|
|
If you have specific private groups that you want to have treated as
|
|
if they were public groups, you can add the name of that group to the
|
|
@code{gnus-global-groups} list.
|
|
|
|
Also @pxref{Misc Article} for @code{gnus-inhibit-images}.
|
|
|
|
@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.
|
|
|
|
@item gnus-article-show-cursor
|
|
@vindex gnus-article-show-cursor
|
|
If non-@code{nil}, display the cursor in the article buffer even when
|
|
the article buffer isn't the current buffer.
|
|
@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 @key{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-emojize-symbols
|
|
@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-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-emojize-symbols (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 combined-local-lapsed
|
|
Both the time in the user's local time zone 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}.
|
|
|
|
@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 @r{(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 @key{SPC}
|
|
@kindex SPC @r{(Article)}
|
|
@findex gnus-article-next-page
|
|
Scroll forwards one page (@code{gnus-article-next-page}).
|
|
This is exactly the same as @kbd{h @key{SPC} h}.
|
|
|
|
@item @key{DEL}
|
|
@kindex DEL @r{(Article)}
|
|
@findex gnus-article-prev-page
|
|
Scroll backwards one page (@code{gnus-article-prev-page}).
|
|
This is exactly the same as @kbd{h @key{DEL} h}.
|
|
|
|
@item C-c ^
|
|
@kindex C-c ^ @r{(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 @r{(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 @r{(Article)}
|
|
@findex gnus-article-show-summary
|
|
Reconfigure the buffers so that the summary buffer becomes visible
|
|
(@code{gnus-article-show-summary}).
|
|
|
|
@item ?
|
|
@kindex ? @r{(Article)}
|
|
@findex gnus-article-describe-briefly
|
|
Give a very brief description of the available keystrokes
|
|
(@code{gnus-article-describe-briefly}).
|
|
|
|
@item @key{TAB}
|
|
@kindex TAB @r{(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-@key{TAB}
|
|
@kindex M-TAB @r{(Article)}
|
|
@findex gnus-article-prev-button
|
|
Go to the previous button, if any (@code{gnus-article-prev-button}).
|
|
|
|
@item R
|
|
@kindex R @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 @r{(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 @r{(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
|
|
@vindex 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{https://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 @r{(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{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.
|
|
|
|
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 (@pxref{Replacing Match,,
|
|
Replacing the Text that Matched, elisp, The Emacs Lisp Reference
|
|
Manual}.)
|
|
|
|
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 @r{(Post)}
|
|
@c @findex gnus-associate-buffer-with-draft
|
|
@c @kindex C-c C-d (Mail)
|
|
@c @kindex C-c C-d @r{(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 @r{(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 @r{(Draft)}
|
|
@findex gnus-draft-send-message
|
|
@kindex D S @r{(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 @r{(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 @key{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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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.
|
|
* Virtual Groups:: Combining articles and groups together.
|
|
* 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
|
|
|
|
The following key bindings are available in the server buffer. Be aware
|
|
that some of the commands will only work on servers that you've added
|
|
through this interface (with @kbd{a}), not with servers you've defined
|
|
in your init files.
|
|
|
|
@table @kbd
|
|
|
|
@item v
|
|
@kindex v @r{(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 @r{(Server)}
|
|
@findex gnus-server-add-server
|
|
Add a new server (@code{gnus-server-add-server}).
|
|
|
|
@item e
|
|
@kindex e @r{(Server)}
|
|
@findex gnus-server-edit-server
|
|
Edit a server (@code{gnus-server-edit-server}).
|
|
|
|
@item S
|
|
@kindex S @r{(Server)}
|
|
@findex gnus-server-show-server
|
|
Show the definition of a server (@code{gnus-server-show-server}).
|
|
|
|
@item @key{SPC}
|
|
@kindex SPC @r{(Server)}
|
|
@findex gnus-server-read-server
|
|
Browse the current server (@code{gnus-server-read-server}).
|
|
|
|
@item q
|
|
@kindex q @r{(Server)}
|
|
@findex gnus-server-exit
|
|
Return to the group buffer (@code{gnus-server-exit}).
|
|
|
|
@item k
|
|
@kindex k @r{(Server)}
|
|
@findex gnus-server-kill-server
|
|
Kill the current server (@code{gnus-server-kill-server}).
|
|
|
|
@item y
|
|
@kindex y @r{(Server)}
|
|
@findex gnus-server-yank-server
|
|
Yank the previously killed server (@code{gnus-server-yank-server}).
|
|
|
|
@item c
|
|
@kindex c @r{(Server)}
|
|
@findex gnus-server-copy-server
|
|
Copy the current server (@code{gnus-server-copy-server}).
|
|
|
|
@item l
|
|
@kindex l @r{(Server)}
|
|
@findex gnus-server-list-servers
|
|
List all servers (@code{gnus-server-list-servers}).
|
|
|
|
@item s
|
|
@kindex s @r{(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 @r{(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 @r{(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{https://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 @key{RET} cache @key{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{@key{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 @r{(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 @r{(Server)}
|
|
@findex gnus-server-close-server
|
|
Close the connection (if any) to the server
|
|
(@code{gnus-server-close-server}).
|
|
|
|
@item D
|
|
@kindex D @r{(Server)}
|
|
@findex gnus-server-deny-server
|
|
Mark the current server as unreachable
|
|
(@code{gnus-server-deny-server}). This will effectively disable the
|
|
server.
|
|
|
|
@item M-o
|
|
@kindex M-o @r{(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 @r{(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 @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 @r{(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 @r{(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
|
|
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} 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{https://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
|
|
|
|
@c FIXME openssl s_client should be deprecated in favor of gnutls.
|
|
@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{https://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 <username> password <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}, @code{cram-md5} or @code{xoauth2}. (The latter method
|
|
requires using the @file{oauth2.el} library.)
|
|
|
|
@item nnimap-expunge
|
|
When to expunge deleted messages. If @code{never}, deleted articles
|
|
are marked with the IMAP @code{\\Delete} flag but not automatically
|
|
expunged. If @code{immediately}, deleted articles are immediately expunged
|
|
(this requires the server to support the UID EXPUNGE command). If
|
|
@code{on-exit}, deleted articles are flagged, and all flagged articles are
|
|
expunged when the group is closed.
|
|
|
|
For backwards compatibility, this variable may also be set to t
|
|
or nil. If the server supports UID EXPUNGE, both t and nil are
|
|
equivalent to @code{immediately}. If the server does not support UID
|
|
EXPUNGE nil is equivalent to @code{never}, while t will immediately
|
|
expunge ALL articles that are currently flagged as deleted
|
|
(i.e., potentially not only the article that was just deleted).
|
|
|
|
@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.
|
|
|
|
@item nnimap-use-namespaces
|
|
If non-@code{nil}, omit the IMAP namespace prefix in nnimap group
|
|
names. If your IMAP mailboxes are called something like @samp{INBOX}
|
|
and @samp{INBOX.Lists.emacs}, but you'd like the nnimap group names to
|
|
be @samp{INBOX} and @samp{Lists.emacs}, you should enable this option.
|
|
|
|
@item nnimap-keepalive-intervals
|
|
By default, nnimap will send occasional @samp{NOOP} (keepalive)
|
|
commands to the server, to keep the connection alive. This option
|
|
governs how often that happens. It is a cons of two integers,
|
|
representing seconds: first how often to run the keepalive check, and
|
|
the second how many seconds of user inactivity are required to
|
|
actually send the command. The default, @code{(900 . 300)}, means run
|
|
the check every fifteen minutes and, if the user has been inactive for
|
|
five minutes, send the keepalive command. Set to @code{nil} to
|
|
disable keepalive commands altogether.
|
|
|
|
@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
|
|
|
|
@vindex nnimap-split-download-body
|
|
By default, the nnimap back end only retrieves the message headers;
|
|
the option @code{nnimap-split-download-body} (which is a regular
|
|
customization option, not a server variable) 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.
|
|
|
|
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-fancy
|
|
(| ("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.
|
|
|
|
If multiple rules match (excluding the general @samp{""} group), mail
|
|
is crossposted to all these groups. However, if
|
|
@code{nnmail-crosspost} is set to @code{nil}, the first rule to make a
|
|
match 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@key{SPC}} 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.)
|
|
|
|
@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.
|
|
|
|
@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-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 @code{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.
|
|
@item list
|
|
Matches the @samp{List-ID}, @samp{List-Post}, @samp{X-Mailing-List},
|
|
@samp{X-BeenThere} and @samp{X-Loop} fields.
|
|
@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.
|
|
|
|
If @code{nnmail-debug-splitting} is non-@code{nil}, the mail splitting
|
|
code will log all splitting decisions to the @samp{*nnmail split*} buffer.
|
|
|
|
|
|
@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{gnus-get-top-new-news-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{@key{SPC}} 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. The value of this variable can be
|
|
either a number of days (not necessarily an integer), or one of the
|
|
symbols @code{immediate} or @code{never}, meaning an article is
|
|
immediately or never expirable, respectively.
|
|
|
|
Gnus starts counting days from when the message @emph{arrived}, not
|
|
from when it was sent. The default is seven days.
|
|
|
|
@vindex nnmail-expiry-wait-function
|
|
The @code{nnmail-expiry-wait-function} variable lets you fine-tune how
|
|
long articles are to live, based on what group they are in. When set
|
|
to a function, its returned value, if non-@code{nil}, overrides that
|
|
of @code{nnmail-expiry-wait}. Otherwise, the value of
|
|
@code{nnmail-expiry-wait} is used instead.
|
|
|
|
For example, let's say you want to have a 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.
|
|
This can be achieved as follows:
|
|
|
|
@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.
|
|
|
|
As an alternative to the variables @code{nnmail-expiry-wait} or
|
|
@code{nnmail-expiry-wait-function}, 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 and its successors weren'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 and 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{@key{TAB}} characters into @samp{@key{SPC}} characters.
|
|
|
|
@item nnmail-ignore-broken-references
|
|
@findex nnmail-ignore-broken-references
|
|
@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} 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{https://cr.yp.to/proto/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.
|
|
@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
|
|
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 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} and @code{dejanews}. 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{https://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.
|
|
|
|
@kindex G R @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 @key{RET} @key{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{utf-8-emacs}).
|
|
|
|
@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))))
|
|
|
|
(with-eval-after-load "gnus"
|
|
(define-key gnus-summary-mode-map
|
|
(kbd "<RET>") 'browse-nnrss-url))
|
|
(add-to-list 'nnmail-extra-headers nnrss-url-field)
|
|
@end lisp
|
|
|
|
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}.}
|
|
(with-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}, 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} 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 RFC 822 or its successors.
|
|
|
|
@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 Virtual Groups
|
|
@section Virtual Groups
|
|
|
|
Gnus allows combining articles from many sources, and combinations of
|
|
whole groups together into virtual groups.
|
|
|
|
@menu
|
|
* Selection Groups:: Combining articles from many groups.
|
|
* Combined Groups:: Combining multiple groups.
|
|
@end menu
|
|
|
|
|
|
@node Selection Groups
|
|
@subsection Select Groups
|
|
@cindex nnselect
|
|
@cindex select groups
|
|
@cindex selecting articles
|
|
|
|
|
|
Gnus provides the @dfn{nnselect} method for creating virtual groups
|
|
composed of collections of messages, even when these messages come
|
|
from groups that span multiple servers and backends. For the most
|
|
part these virtual groups behave like any other group: messages may be
|
|
threaded, marked, moved, deleted, copied, etc.; groups may be
|
|
ephemeral or persistent; groups may be created via
|
|
@code{gnus-group-make-group} or browsed as foreign via
|
|
@code{gnus-group-browse-foreign-server}.
|
|
|
|
The key to using an nnselect group is specifying the messages to
|
|
include. Each nnselect group has a group parameter
|
|
@code{nnselect-specs} which is an alist with two elements: a function
|
|
@code{nnselect-function}; and arguments @code{nnselect-args} to be
|
|
passed to the function, if any.
|
|
|
|
The function @code{nnselect-function} must return a vector. Each
|
|
element of this vector is in turn a 3-element vector corresponding to
|
|
one message. The 3 elements are: the fully-qualified group name; the
|
|
message number; and a "score" that can be used for additional sorting.
|
|
The values for the score are arbitrary, and are not used directly by
|
|
the nnselect method---they may, for example, all be set to 100.
|
|
|
|
Here is an example:
|
|
|
|
@lisp
|
|
(nnselect-specs
|
|
(nnselect-function . identity)
|
|
(nnselect-args
|
|
. [["nnimap+work:mail" 595 100]
|
|
["nnimap+home:sent" 223 100]
|
|
["nntp+news.gmane.org:gmane.emacs.gnus.general" 23666 100]]))
|
|
@end lisp
|
|
|
|
The function is the identity and the argument is just the list of
|
|
messages to include in the virtual group.
|
|
|
|
Or we may wish to create a group from the results of a search query:
|
|
|
|
@lisp
|
|
(nnselect-specs
|
|
(nnselect-function . gnus-search-run-query)
|
|
(nnselect-args
|
|
(search-query-spec
|
|
(query . "mark:flag"))
|
|
(search-group-spec
|
|
("nnimap:home")
|
|
("nnimap:work"))))
|
|
@end lisp
|
|
|
|
This creates a group including all flagged messages from all groups on
|
|
two IMAP servers, "home" and "work".
|
|
|
|
And one last example. Here is a function that runs a search query to
|
|
find all messages that have been received recently from certain groups:
|
|
|
|
@lisp
|
|
(defun my-recent-email (args)
|
|
(let ((query-spec
|
|
(list
|
|
(cons 'query
|
|
(format-time-string "SENTSINCE %d-%b-%Y"
|
|
(time-subtract nil
|
|
(days-to-time (car args)))))
|
|
(cons 'criteria "")))
|
|
(group-spec (cadr args)))
|
|
(gnus-search-run-query (list (cons 'search-query-spec query-spec)
|
|
(cons 'search-group-spec group-spec)))))
|
|
@end lisp
|
|
|
|
Then the following @code{nnselect-specs}:
|
|
|
|
@lisp
|
|
(nnselect-specs
|
|
(nnselect-function . my-recent-email)
|
|
(nnselect-args . (7 (("nnimap:home") ("nnimap:work")))))
|
|
@end lisp
|
|
|
|
will provide a group composed of all messages on the home and work
|
|
servers received in the last 7 days.
|
|
|
|
Refreshing the selection of an nnselect group by running the
|
|
@code{nnselect-function} may take a long time to complete.
|
|
Consequently nnselect groups are not refreshed by default when
|
|
@code{gnus-group-get-new-news} is invoked. In those cases where
|
|
running the function is not too time-consuming, a non-@code{nil} group
|
|
parameter of @code{nnselect-rescan} will allow automatic refreshing.
|
|
A refresh can always be invoked manually through
|
|
@code{gnus-group-get-new-news-this-group}.
|
|
|
|
By default a compressed version of the selection is stored (for
|
|
permanent groups) along with other group information in the newsrc.
|
|
For cases where this might be undesirable (for example if the
|
|
selection is a very long list that doesn't compress well) a
|
|
non-@code{nil} group parameter of @code{nnselect-always-regenerate}
|
|
will prevent the list from being stored, and instead regenerate the
|
|
list each time it is needed. If more flexibility is desired,
|
|
@code{nnselect-get-artlist-override-function} and
|
|
@code{nnselect-store-artlist-override-function} may be set to
|
|
functions that get and store the list of articles.
|
|
|
|
Gnus includes engines for searching a variety of backends. While the
|
|
details of each search engine vary, the result of a search is always a
|
|
vector of the sort used by the nnselect method, and the results of
|
|
queries are usually viewed using an nnselect group. Indeed the
|
|
standard search function @code{gnus-group-read-ephemeral-search-group}
|
|
just creates an ephemeral nnselect group with the appropriate search
|
|
query as the @code{nnselect-specs}.
|
|
|
|
@node Combined Groups
|
|
@subsection Combined 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.
|
|
@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-<something>}, @code{<something>} 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).
|
|
|
|
@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.
|
|
|
|
@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 nil) 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 @r{(Category)}
|
|
@findex gnus-category-exit
|
|
Return to the group buffer (@code{gnus-category-exit}).
|
|
|
|
@item e
|
|
@kindex e @r{(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 @r{(Category)}
|
|
@findex gnus-category-kill
|
|
Kill the current category (@code{gnus-category-kill}).
|
|
|
|
@item c
|
|
@kindex c @r{(Category)}
|
|
@findex gnus-category-copy
|
|
Copy the current category (@code{gnus-category-copy}).
|
|
|
|
@item a
|
|
@kindex a @r{(Category)}
|
|
@findex gnus-category-add
|
|
Add a new category (@code{gnus-category-add}).
|
|
|
|
@item p
|
|
@kindex p @r{(Category)}
|
|
@findex gnus-category-edit-predicate
|
|
Edit the predicate of the current category
|
|
(@code{gnus-category-edit-predicate}).
|
|
|
|
@item g
|
|
@kindex g @r{(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 @r{(Category)}
|
|
@findex gnus-category-edit-score
|
|
Edit the download score rule of the current category
|
|
(@code{gnus-category-edit-score}).
|
|
|
|
@item l
|
|
@kindex l @r{(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 @r{(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 @r{(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 @r{(Agent Group)}
|
|
@findex gnus-enter-category-buffer
|
|
Enter the Agent category buffer (@code{gnus-enter-category-buffer}).
|
|
|
|
@item J s
|
|
@kindex J s @r{(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 @r{(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 @r{(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 @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 @r{(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 # @r{(Agent Summary)}
|
|
@findex gnus-agent-mark-article
|
|
Mark the article for downloading (@code{gnus-agent-mark-article}).
|
|
|
|
@item J M-#
|
|
@kindex J M-# @r{(Agent Summary)}
|
|
@findex gnus-agent-unmark-article
|
|
Remove the downloading mark from the article
|
|
(@code{gnus-agent-unmark-article}).
|
|
|
|
@cindex %
|
|
@item @@
|
|
@kindex @@ @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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
|
|
@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.
|
|
|
|
The last (i.e., newest) article in a group will normally not be
|
|
expired (due to internal book-keeping reasons).
|
|
|
|
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
|
|
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
|
|
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-eagerly-store-articles
|
|
@vindex gnus-agent-eagerly-store-articles
|
|
If non-@code{nil} (which is the default), store all articles read in
|
|
agentized groups in the Agent 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 @r{(Summary)}
|
|
@findex gnus-summary-set-score
|
|
Set the score of the current article (@code{gnus-summary-set-score}).
|
|
|
|
@item V S
|
|
@kindex V S @r{(Summary)}
|
|
@findex gnus-summary-current-score
|
|
Display the score of the current article
|
|
(@code{gnus-summary-current-score}).
|
|
|
|
@item V t
|
|
@kindex V t @r{(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 @r{(Summary)}
|
|
@findex gnus-score-find-favorite-words
|
|
List words used in scoring (@code{gnus-score-find-favorite-words}).
|
|
|
|
@item V R
|
|
@kindex V R @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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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
|
|
|
|
@item body-strings
|
|
|
|
These match types are available on the @samp{head} and @code{body}
|
|
``header types''.
|
|
|
|
@table @kbd
|
|
|
|
@item z
|
|
Substring matching.
|
|
|
|
@item p
|
|
Regexp matching.
|
|
@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{@key{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 shortcuts
|
|
are not available for the body matches.)
|
|
|
|
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 @r{(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 @r{(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) (list "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?)
|
|
|
|
Finally, two actually useful match types for dates: @code{<} and
|
|
@code{>}. These will allow scoring on the relative age (in days) of
|
|
the articles. Here's an example score file using the method:
|
|
|
|
@example
|
|
(("date"
|
|
(7 10 nil <)
|
|
(7 -10 nil >)
|
|
(14 -10 nil >)))
|
|
@end example
|
|
|
|
This results in articles less than a week old getting a 10 point
|
|
increase, articles older than a week getting a 10 point decrease, and
|
|
articles older than two weeks getting a cumulative 20 point decrease.
|
|
|
|
The day can also be a floating point number: To score articles less
|
|
than an hour old, you can say @samp{(0.04 10 nil <)}.
|
|
|
|
@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 score-fn
|
|
The value of this entry should be one or more user-defined function
|
|
names in parentheses. Each function will be called in order and the
|
|
returned value is required to be an integer.
|
|
|
|
@example
|
|
(score-fn (custom-scoring))
|
|
@end example
|
|
|
|
The user-defined function is called with an association list with the
|
|
keys @code{number subject from date id refs chars lines xref extra}
|
|
followed by the article's score before the function is run.
|
|
|
|
The following (somewhat contrived) example shows how to use a
|
|
user-defined function that increases an article's score by 10 if the
|
|
year of the article's date is also mentioned in its subject.
|
|
|
|
@example
|
|
(defun custom-scoring (article-alist score)
|
|
(let ((subject (cdr (assoc 'subject article-alist)))
|
|
(date (cdr (assoc 'date article-alist))))
|
|
(if (string-match (number-to-string
|
|
(nth 5 (parse-time-string date)))
|
|
subject)
|
|
10)))
|
|
@end example
|
|
|
|
@code{score-fn} entries are permanent and can only be added or
|
|
modified directly in the @code{SCORE} file.
|
|
|
|
@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 @r{(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 @r{(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 @r{(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 @minus{}4, and
|
|
lowered by @code{Subject} by @minus{}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 @minus{}1, which
|
|
should be, unless I'm much mistaken, @minus{}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 @minus{}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
|
|
<x6u3u47icf.fsf@@eyesore.no>
|
|
<x6sp9o7ibw.fsf@@eyesore.no>
|
|
@end example
|
|
|
|
So ``my'' ident on this machine is @samp{x6}. This can be
|
|
exploited---the following rule will raise the score on all followups to
|
|
myself:
|
|
|
|
@lisp
|
|
("references"
|
|
("<x6[0-9a-z]+\\.fsf\\(_-_\\)?@@.*eyesore\\.no>"
|
|
1000 nil r))
|
|
@end lisp
|
|
|
|
Whether it's the first two or first three characters that are ``yours''
|
|
is system-dependent.
|
|
|
|
|
|
@node Scoring On Other Headers
|
|
@section Scoring On Other Headers
|
|
@cindex scoring on other headers
|
|
|
|
Gnus is quite fast when scoring the ``traditional''
|
|
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 @key{RET} <your name> @key{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 @r{(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 @r{(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 @r{(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 @r{(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}.
|
|
@c FIXME: The above URL no longer works.
|
|
|
|
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)))))))
|
|
(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 @minus{}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
|
|
|
|
Gnus has various ways of finding articles that match certain criteria
|
|
(from a particular author, on a certain subject, etc.). The simplest
|
|
method is to enter a group and then either "limit" the summary buffer
|
|
to the desired articles using the limiting commands (@pxref{Limiting}),
|
|
or searching through messages in the summary buffer (@pxref{Searching
|
|
for Articles}).
|
|
|
|
Limiting commands and summary buffer searching work on articles
|
|
already fetched from the servers, and these commands won't query the
|
|
server for additional articles. While simple, these methods are
|
|
therefore inadequate if the desired articles span multiple groups, or
|
|
if the group is so large that fetching all articles is impractical.
|
|
|
|
It's possible to search a backend more thoroughly using an associated
|
|
search engine. Some backends come with their own search engine: IMAP
|
|
servers, for instance, do their own searching. Other backends, for
|
|
example a local @code{nnmaildir} installation, might require the user
|
|
to manually set up some sort of search indexing. Default associations
|
|
between backends and engines can be defined in
|
|
@code{gnus-search-default-engines}, and engines can also be defined on
|
|
a per-backend basis (@pxref{Search Engines}).
|
|
|
|
Once the search engines are set up, you can search for messages in
|
|
groups from one or more backends, and show the results in a group.
|
|
The groups that hold search results are created on the nnselect
|
|
backend, and can be either ephemeral or persistent (@pxref{Creating
|
|
Search Groups}).
|
|
|
|
@vindex gnus-search-use-parsed-queries
|
|
Search queries can be specified one of two ways: either using the
|
|
syntax of the engine responsible for the group you're searching, or
|
|
using Gnus' generalized search syntax. Set the option
|
|
@code{gnus-search-use-parsed-queries} to a non-@code{nil} value to used the
|
|
generalized syntax. The advantage of this syntax is that, if you have
|
|
multiple backends indexed by different engines, you don't need to
|
|
remember which one you're searching---it's also possible to issue the
|
|
same query against multiple groups, indexed by different engines, at
|
|
the same time. It also provides a few other conveniences including
|
|
relative date parsing and tie-ins into other Emacs packages. For
|
|
details on Gnus' query language, see @ref{Search Queries}.
|
|
|
|
@menu
|
|
* Search Engines:: Selecting and configuring search engines.
|
|
* Creating Search Groups:: How and where.
|
|
* Search Queries:: Gnus' built-in search syntax.
|
|
* nnmairix:: Searching with Mairix.
|
|
* nnir::
|
|
@end menu
|
|
|
|
@node Search Engines
|
|
@section Search Engines
|
|
@cindex search engines
|
|
@cindex configuring search
|
|
|
|
In order to search for messages from any given server, that server
|
|
must have a search engine associated with it. IMAP servers do their
|
|
own searching, and searching IMAP groups will work with no additional
|
|
configuration, but in all other cases the user will have to manually
|
|
specify an engine to use. This can be done at two different levels:
|
|
by server type, or on a per-server basis.
|
|
|
|
@vindex gnus-search-default-engines
|
|
The option @code{gnus-search-default-engines} assigns search engines
|
|
by server type. Its value is an alist mapping symbols indicating a
|
|
server type (e.g.@: @code{nnmaildir} or @code{nnml}) to symbols
|
|
indicating a search engine class. The built-in search engine symbols
|
|
are:
|
|
|
|
@itemize
|
|
@item
|
|
@code{gnus-search-imap}
|
|
|
|
@item
|
|
@code{gnus-search-find-grep}
|
|
|
|
@item
|
|
@code{gnus-search-notmuch}
|
|
|
|
@item
|
|
@code{gnus-search-swish-e}
|
|
|
|
@item
|
|
@code{gnus-search-swish++}
|
|
|
|
@item
|
|
@code{gnus-search-mairix}
|
|
|
|
@item
|
|
@code{gnus-search-namazu}
|
|
|
|
@item
|
|
@code{gnus-search-mu}
|
|
@end itemize
|
|
|
|
If you need more granularity, you can specify a search engine in the
|
|
server definition, using the @code{gnus-search-engine} key, whether
|
|
that be in your @file{.gnus.el} config file, or through Gnus' server
|
|
buffer. That might look like:
|
|
|
|
@example
|
|
'(nnmaildir "My Mail"
|
|
(directory "/home/user/.mail")
|
|
(gnus-search-engine gnus-search-notmuch
|
|
(config-file "/home/user/.mail/.notmuch_config")))
|
|
@end example
|
|
|
|
Search engines like notmuch, namazu, mairix and mu are similar in
|
|
behavior: they use a local executable to create an index of a message
|
|
store, and run command line search queries against those messages,
|
|
and return a list of absolute file names of matching messages.
|
|
|
|
These engines have a handful of configuration parameters in common.
|
|
These common parameters are:
|
|
|
|
@table @code
|
|
@item program
|
|
The name of the executable. Defaults to the plain
|
|
program name such as @command{notmuch} or @command{namazu}.
|
|
|
|
@item config-file
|
|
The absolute filename of the configuration file for this search
|
|
engine.
|
|
|
|
@item remove-prefix
|
|
The directory part to be removed from the filenames returned by the
|
|
search query. This absolute path should include everything up to the
|
|
top level of the message store. Note that this is the path to the
|
|
location of the actual messages, not to the search engine's indexes
|
|
(nor, in the case of Mairix, to its symlink directories).
|
|
|
|
@item switches
|
|
Additional command-line switches to be fed to the search program. The
|
|
value of this parameter must be a list of strings, one string per
|
|
switch.
|
|
@end table
|
|
|
|
The options above can be set in one of two ways: using a customization
|
|
option that is set for all engines of that type, or on a per-engine
|
|
basis in your server configuration files.
|
|
|
|
The customization options are formed on the pattern
|
|
@code{gnus-search-@var{engine}-@var{parameter}}. For instance, to use a
|
|
non-standard notmuch program, you might set
|
|
@code{gnus-search-notmuch-program} to @file{/usr/local/bin/notmuch}.
|
|
This would apply to all notmuch engines. The engines that use these
|
|
options are: ``notmuch'', ``namazu'', ``mairix'', ``mu'', ``swish-e''
|
|
and ``swish++''.
|
|
|
|
Alternately, the options can be set directly on your Gnus server
|
|
definitions, for instance, in the @code{nnmaildir} example above.
|
|
Note that the server options are part of the @code{gnus-search-engine}
|
|
sexp, and the option symbol and value form a two-element list, not a
|
|
cons cell.
|
|
|
|
The namazu and swish-e engines each have one additional option,
|
|
specifying where to store their index files. For namazu it is
|
|
@code{index-directory}, and should be a single directory path. For
|
|
swish-e it is @code{index-files}, and should be a list of strings.
|
|
|
|
All indexed search engines come with their own method of updating
|
|
their search indexes to include newly-arrived messages. Gnus
|
|
currently provides no convenient interface for this, and you'll have
|
|
to manage updates yourself, though this will likely change in the
|
|
future.
|
|
|
|
Lastly, all search engines accept a @code{raw-queries-p} option. This
|
|
indicates that engines of this type (or this particular engine) should
|
|
always use raw queries, never parsed (@pxref{Search Queries}).
|
|
|
|
@node Creating Search Groups
|
|
@section Creating Search Groups
|
|
@cindex creating search groups
|
|
|
|
In the group buffer typing @kbd{G G} will search the group on the
|
|
current line by calling @code{gnus-group-read-ephemeral-search-group}.
|
|
This prompts for a query string, creates an ephemeral @code{nnselect}
|
|
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{nnselect} group made in this way is @code{ephemeral}: it
|
|
will disappear upon exit from the group. However changes made in the
|
|
group are permanently reflected in the real groups from which the
|
|
articles are drawn. If you want to create a @emph{persistent} group
|
|
that sticks around after exit from the summary buffer, you can call
|
|
@code{gnus-group-make-search-group} (bound to @kbd{G g}).
|
|
|
|
Unlike persistent groups, ephemeral groups by default do not run
|
|
articles through the expiry process on exiting. If you want expiry to
|
|
happen in ephemeral search groups you can customize the variable
|
|
@code{nnselect-allow-ephemeral-expiry}. In all cases the expiry
|
|
process uses the underlying group's expiry parameters.
|
|
|
|
So you just performed a search whose results are so fabulous you
|
|
wished you had done a persistent search rather than an ephemeral one?
|
|
No problem; you can create such a group by calling
|
|
@code{gnus-summary-make-group-from-search} (bound to @kbd{C-c C-p})
|
|
from the ephemeral summary buffer.
|
|
|
|
It is occasionally convenient to view articles found through searching
|
|
in their original group. 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}.
|
|
|
|
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? Initiating a search with the cursor on a topic
|
|
heading will search all the groups under that topic.
|
|
|
|
@vindex gnus-search-ignored-newsgroups
|
|
Still not enough? OK, in the server buffer
|
|
@code{gnus-group-read-ephemeral-search-group} (here 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{gnus-search-ignored-newsgroups}: groups matching this
|
|
regexp will not be searched.
|
|
|
|
@node Search Queries
|
|
@section Search Queries
|
|
@cindex search queries
|
|
@cindex search syntax
|
|
|
|
Gnus provides an optional unified search syntax that can be used
|
|
across all supported search engines. This can be convenient in that
|
|
you don't have to remember different search syntaxes; it's also
|
|
possible to mark multiple groups indexed by different engines and
|
|
issue a single search against them.
|
|
|
|
@vindex gnus-search-use-parsed-queries
|
|
Set the option @code{gnus-search-use-parsed-queries} to non-@code{nil}
|
|
to enable this---it is @code{nil} by default. Even if it is
|
|
non-@code{nil}, it's still possible to turn off parsing for a class of
|
|
engines or a single engine (@pxref{Search Engines}), or a single
|
|
search by giving a prefix argument to any of the search commands.
|
|
|
|
The search syntax is fairly simple: keys and values are separated by a
|
|
colon, multi-word values must be quoted, ``and'' is implicit, ``or''
|
|
is explicit, ``not'' will negate the following expression (or keys can
|
|
be prefixed with a ``-''),and parentheses can be used to group logical
|
|
sub-clauses. For example:
|
|
|
|
@example
|
|
(from:john or from:peter) subject:"lunch tomorrow" since:3d
|
|
@end example
|
|
|
|
The syntax is made to be accepted by a wide range of engines, and thus
|
|
will happily accept most input, valid or not. Some terms will only be
|
|
meaningful to some engines; other engines will drop them silently.
|
|
|
|
Key completion is offered on @key{TAB}, but it's also possible to
|
|
enter the query with abbreviated keys, which will be expanded during
|
|
parsing. If a key is abbreviated to the point of ambiguity (for
|
|
instance, ``s:'' could be ``subject:'' or ``since:''), an error will
|
|
be raised.
|
|
|
|
Supported keys include all the usual mail headers: ``from'',
|
|
``subject'', ``cc'', etc. Other keys are:
|
|
|
|
@table @samp
|
|
@item body
|
|
The body of the message.
|
|
@item recipient
|
|
Equivalent to @samp{to or cc or bcc}.
|
|
@item address
|
|
Equivalent to @samp{from or recipient}.
|
|
@item id
|
|
The keys @samp{message-id} and @samp{id} are equivalent.
|
|
@item mark
|
|
Accepts @samp{flag}, @samp{seen}, @samp{read} or @samp{replied}, or
|
|
any of Gnus' single-letter representations of those marks, e.g.@:
|
|
@samp{mark:R} for @samp{read}.
|
|
@item tag
|
|
This is interpreted as @samp{keyword} for IMAP and @samp{tag} for
|
|
notmuch.
|
|
@item attachment
|
|
Matches the attachment file name.
|
|
@item before
|
|
Date is exclusive; see below for date parsing.
|
|
@item after
|
|
Date is inclusive; can also use @samp{since}.
|
|
@item thread
|
|
Return entire message threads, not just individual messages.
|
|
@item raw
|
|
Do not parse this particular search.
|
|
@item limit
|
|
Limit the results to this many messages. When searching multiple
|
|
groups this may give undesired results, as the limiting happens before
|
|
sorting.
|
|
@item grep
|
|
Only applicable to ``local index'' engines such as mairix or notmuch.
|
|
On systems with a grep command, additionally filter the results by
|
|
using the value of this term as a grep regexp.
|
|
@end table
|
|
|
|
@vindex gnus-search-contact-tables
|
|
Elisp-based contact management packages (e.g.@: BBDB or EBDB) can push
|
|
completion tables onto the variable @code{gnus-search-contact-tables},
|
|
allowing auto-completion of contact names and addresses for keys like
|
|
@samp{from} or @samp{to}.
|
|
|
|
@subsection Date value parsing
|
|
|
|
@vindex gnus-search-date-keys
|
|
Date-type keys (see @code{gnus-search-date-keys}) will accept a wide
|
|
variety of values. First, anything that @code{parse-time-string} can
|
|
parse is acceptable. Dates with missing values will be interpreted as
|
|
the most recent occurrence thereof: for instance ``march 03'' is the
|
|
most recent March 3rd. Lastly, it's possible to use relative
|
|
specifications, such as ``3d'' (three days ago). This format also accepts
|
|
w, m and y.
|
|
|
|
When creating persistent search groups, the search is saved unparsed,
|
|
and re-parsed every time the group is updated. So a permanent search
|
|
group with a query like:
|
|
|
|
@example
|
|
from:"my boss" mark:flag since:1w
|
|
@end example
|
|
|
|
would always contain only messages from the past seven days.
|
|
|
|
@node nnmairix
|
|
@section nnmairix
|
|
|
|
@cindex mairix
|
|
@cindex nnmairix
|
|
|
|
This section is now mostly obsolete, as mairix can be used as a regular
|
|
search engine, including persistent search groups, with
|
|
@code{nnselect}.
|
|
|
|
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), macOS and Solaris. The website 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, 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.
|
|
|
|
@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-<NAME>-<NUMBER>} on this mail back end, but it will
|
|
present these folders in the Gnus front end only with @code{<NAME>}.
|
|
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{@key{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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @r{(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 @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 @r{(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 @r{(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 @r{(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 @r{(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 G G m
|
|
@kindex G G m @r{(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 G g
|
|
@kindex G G g @r{(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 G G t
|
|
@kindex G G t @r{(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 G G f
|
|
@kindex G G f @r{(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 G G o
|
|
@kindex G G o @r{(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 G G u
|
|
@kindex G G u @r{(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{G G 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-<NAME>-<NUMBER>}. 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-<NAME>-<NUMBER>}. 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
|
|
|
|
@node nnir
|
|
@section Migrating from nnir
|
|
|
|
@cindex nnir
|
|
|
|
Gnus' previous search engine was called nnir, and is obsolete as of
|
|
Emacs version 28. If you've upgraded Emacs and are now getting
|
|
obsolete-variable warnings about @code{nnir-*} variables, migration is
|
|
fairly straightforward. In addition to the variables raised by the
|
|
warnings, all previous engine-specific variables can be updated by
|
|
simply replacing the @code{nnir-} prefix with @code{gnus-search-}.
|
|
For instance, @code{nnir-notmuch-program} is now
|
|
@code{gnus-search-notmuch-program}.
|
|
|
|
|
|
@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.
|
|
* Tabbed Interface:: Configuring the Gnus tabs.
|
|
* 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:: Emacs 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.
|
|
* The Gnus Cloud:: A package for synchronizing Gnus marks.
|
|
* D-Bus Integration:: Closing Gnus servers on system sleep.
|
|
* 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 @r{(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.
|
|
|
|
Gnus does not use the font locking machinery used by most modes in
|
|
Emacs, so switching @code{font-lock-mode} on in the Gnus
|
|
group/summary/article buffers usually doesn't do anything
|
|
useful---instead it'll just mess up the faces that Gnus has already
|
|
put in the buffer. (This is also the case for other minor modes that
|
|
use the font locking machinery, like @code{whitespace-mode}.)
|
|
|
|
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.
|
|
@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.
|
|
|
|
@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} 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 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}.
|
|
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.
|
|
|
|
Lastly, it's possible to make Gnus window layouts ``atomic''
|
|
(@pxref{Atomic Windows, , Atomic Windows, elisp, The GNU Emacs Lisp
|
|
Reference Manual}) by setting @code{gnus-use-atomic-windows} to
|
|
@code{t}. This will ensure that pop-up buffers (e.g. help or
|
|
completion buffers), will appear below or to the side of the entire
|
|
Gnus window layout and not, for example, squashed between the summary
|
|
and article buffers.
|
|
|
|
@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 Tabbed Interface
|
|
@section Tabbed Interface
|
|
@cindex tabbed interface
|
|
@cindex tabs
|
|
|
|
Gnus supports display of different buffers in dedicated tabs
|
|
that you can select using the tab bar.
|
|
|
|
To open the group buffer in a new tab named @samp{Gnus}, use:
|
|
|
|
@lisp
|
|
(push '("\\`\\*Group\\*\\'" .
|
|
(display-buffer-in-tab
|
|
(tab-name . "Gnus")))
|
|
display-buffer-alist)
|
|
@end lisp
|
|
|
|
To read every summary in a separate explicitly named tab, use:
|
|
|
|
@lisp
|
|
(push '("\\`\\*Summary .*\\*\\'" .
|
|
(display-buffer-in-tab
|
|
(tab-name . (lambda (buffer _alist)
|
|
(setq buffer (buffer-name buffer))
|
|
(when (string-match "\\`\\*Summary \\(.*\\)\\*\\'" buffer)
|
|
(format "Group %s" (match-string 1 buffer)))))))
|
|
display-buffer-alist)
|
|
@end lisp
|
|
|
|
|
|
@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ì <pot@cnuce.cnr.it>
|
|
@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
|
|
|
|
Emacs is able to display pictures and stuff, so Gnus has taken
|
|
advantage of that.
|
|
|
|
@menu
|
|
* X-Face:: Display a funky, teensy black-and-white image.
|
|
* Face:: Display a funkier, teensier colored image.
|
|
* Smileys:: Show all those happy faces the way they were meant to be shown.
|
|
* Picons:: How to display pictures of what you're reading.
|
|
* Gravatars:: Display the avatar of people you read.
|
|
@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, 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. 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{https://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))}. 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
|
|
|
|
@xref{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.
|
|
@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{https://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.
|
|
|
|
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{emoji} (use emoji characters), @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{https://cs.indiana.edu/ftp/faces/picons/}.
|
|
|
|
If you are using Debian GNU/Linux, saying @samp{apt-get install
|
|
picon-.*} 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{https://en.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. If @code{nil}, this defaults to the
|
|
value of @code{gravatar-size}.
|
|
|
|
@item gnus-gravatar-properties
|
|
@vindex gnus-gravatar-properties
|
|
List of image properties applied to Gravatar images (@pxref{Image
|
|
Descriptors,,, elisp, The Emacs Lisp Reference Manual}).
|
|
|
|
@item gnus-gravatar-too-ugly
|
|
@vindex gnus-gravatar-too-ugly
|
|
Regexp that matches mail addresses or names of people whose avatars
|
|
should not be displayed, or @code{nil} to display all avatars. It
|
|
defaults to the value of @code{gnus-article-x-face-too-ugly}
|
|
(@pxref{X-Face}).
|
|
|
|
@end table
|
|
|
|
If you want to see gravatars 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
|
|
|
|
|
|
@subsubsection Tool bar
|
|
|
|
@table @code
|
|
|
|
@item gnus-group-tool-bar
|
|
@vindex gnus-group-tool-bar
|
|
Specifies the tool bar in the group buffer. It can be either a list
|
|
or a symbol referring to a list.
|
|
|
|
@item gnus-summary-tool-bar
|
|
@vindex gnus-summary-tool-bar
|
|
Specifies the tool bar in the summary buffer. It can be either a list
|
|
or a symbol referring to a list.
|
|
|
|
@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 spam 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
|
|
|
|
Spam comes from a wide variety of sources. It is simply impossible to
|
|
dispose of all spam without discarding useful messages.
|
|
|
|
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@@example.org}, you block
|
|
@samp{example.org}. 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 <larsi@@trym.ifi.uio.no>\n")
|
|
@end lisp
|
|
|
|
Then put the following split rule in @code{nnmail-split-fancy}
|
|
(@pxref{Fancy Mail Splitting}):
|
|
|
|
@lisp
|
|
(...
|
|
(to "larsi@@trym.ifi.uio.no"
|
|
(| ("subject" "re:.*" "misc")
|
|
("references" ".*@@.*" "misc")
|
|
"spam"))
|
|
...)
|
|
@end lisp
|
|
|
|
This says that all mail to this address is suspect, but if it has a
|
|
@code{Subject} that starts with a @samp{Re:} or has a @code{References}
|
|
header, it's probably ok. All the rest goes to the @samp{spam} group.
|
|
(This idea probably comes from Tim Pierce.)
|
|
|
|
In addition, many mail spammers talk directly to your @acronym{SMTP} server
|
|
and do not include your email address explicitly in the @code{To}
|
|
header. Why they do this is unknown---perhaps it's to thwart this
|
|
thwarting scheme? In any case, this is trivial to deal with---you just
|
|
put anything not addressed to you in the @samp{spam} group by ending
|
|
your fancy split rule in this way:
|
|
|
|
@lisp
|
|
(
|
|
...
|
|
(to "larsi" "misc")
|
|
"spam")
|
|
@end lisp
|
|
|
|
In my experience, this will sort virtually everything into the right
|
|
group. You still have to check the @samp{spam} group from time to time to
|
|
check for legitimate mail, though. If you feel like being a good net
|
|
citizen, you can even send off complaints to the proper authorities on
|
|
each spam---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 to
|
|
avoid spam are over. 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
|
|
|
|
One 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/}.
|
|
|
|
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. @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 $ @r{(Summary)}
|
|
@kindex M-d @r{(Summary)}
|
|
@kindex S x @r{(Summary)}
|
|
@kindex M s x @r{(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}. @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 <tzz@@lifelogs.com>.
|
|
@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 <reiner.steib@@gmx.de>.
|
|
|
|
My provider has set up bogofilter (in combination with @acronym{DCC}) on
|
|
the mail server (@acronym{IMAP}). Recognized spam goes to
|
|
@samp{spam.detected}, the rest goes through the normal filter rules,
|
|
i.e., to @samp{some.folder} or to @samp{INBOX}. Training on false
|
|
positives or negatives is done by copying or moving the article to
|
|
@samp{training.ham} or @samp{training.spam} respectively. A cron job on
|
|
the server feeds those to bogofilter with the suitable ham or spam
|
|
options and deletes them from the @samp{training.ham} and
|
|
@samp{training.spam} folders.
|
|
|
|
With the following entries in @code{gnus-parameters}, @code{spam.el}
|
|
does most of the job for me:
|
|
|
|
@lisp
|
|
("nnimap:spam\\.detected"
|
|
(gnus-article-sort-functions '(gnus-article-sort-by-chars))
|
|
(ham-process-destination "nnimap:INBOX" "nnimap:training.ham")
|
|
(spam-contents gnus-group-spam-classification-spam))
|
|
("nnimap:\\(INBOX\\|other-folders\\)"
|
|
(spam-process-destination . "nnimap:training.spam")
|
|
(spam-contents gnus-group-spam-classification-ham))
|
|
@end lisp
|
|
|
|
@itemize
|
|
|
|
@item @b{The Spam folder:}
|
|
|
|
In the folder @samp{spam.detected}, I have to check for false positives
|
|
(i.e., legitimate mails, that were wrongly judged as spam by
|
|
bogofilter or DCC).
|
|
|
|
Because of the @code{gnus-group-spam-classification-spam} entry, all
|
|
messages are marked as spam (with @code{$}). When I find a false
|
|
positive, I mark the message with some other ham mark
|
|
(@code{ham-marks}, @ref{Spam 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}
|
|
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 <reiner.steib@@gmx.de>.
|
|
|
|
With following entry in @code{gnus-parameters}, @kbd{S x}
|
|
(@code{gnus-summary-mark-as-spam}) marks articles in @code{gmane.*}
|
|
groups as spam and reports the to Gmane at group exit:
|
|
|
|
@lisp
|
|
("^gmane\\."
|
|
(spam-process (gnus-group-spam-exit-processor-report-gmane)))
|
|
@end lisp
|
|
|
|
Additionally, I use @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 was formerly 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
|
|
|
|
@defvar spam-stat-process-directory-age
|
|
Maximum age of files to be processed, in days. Without this filter,
|
|
re-training spam-stat with several thousand messages could take a long
|
|
time. The default is 90, but you might want to set this to a bigger
|
|
value during the initial training.
|
|
@end defvar
|
|
|
|
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: (file-attribute-size (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: (file-attribute-size (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-register-all
|
|
If this option is non-@code{nil}, the registry will register all messages, as
|
|
you see them. This is important to making split-to-parent and
|
|
Message-ID references work correctly, as the registry needs to know
|
|
where all messages are, but it can slow down group opening and the
|
|
saving of Gnus. If this option is nil, entries must be created
|
|
manually, for instance by storing a custom flag or keyword for the
|
|
message.
|
|
@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.
|
|
|
|
If @code{gnus-registry-register-all} is non-@code{nil} (the default), the
|
|
registry will perform splitting for all messages. If it is nil,
|
|
splitting will only happen for children of messages you've explicitly
|
|
registered.
|
|
|
|
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-set-article-mark
|
|
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}. If the option
|
|
@code{gnus-registry-register-all} is non-@code{nil}, this function will also
|
|
create an entry for @code{id} if one doesn't exist.
|
|
@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{(mark)} so the custom registry marks are
|
|
precious.
|
|
@end defvar
|
|
|
|
@node The Gnus Cloud
|
|
@section The Gnus Cloud
|
|
@cindex cloud
|
|
@cindex gnus-cloud
|
|
@cindex synchronization
|
|
@cindex sync
|
|
@cindex synch
|
|
|
|
The Gnus Cloud is a way to synchronize marks and general files and
|
|
data across multiple machines.
|
|
|
|
Very often, you want all your marks (what articles you've read, which
|
|
ones were important, and so on) to be synchronized between several
|
|
machines. With IMAP, that's built into the protocol, so you can read
|
|
nnimap groups from many machines and they are automatically
|
|
synchronized. But NNTP, nnrss, and many other backends do not store
|
|
marks, so you have to do it locally.
|
|
|
|
The Gnus Cloud package stores the marks, plus any files you choose, on
|
|
an IMAP server in a special folder. It's like a
|
|
DropTorrentSyncBoxOakTree(TM).@footnote{The name ``Gnus Cloud''
|
|
parodizes but otherwise has little to do with ``cloud computing'', a
|
|
@url{https://www.gnu.org/philosophy/words-to-avoid.html#CloudComputing,
|
|
misleading term normally best avoided}.}
|
|
|
|
@menu
|
|
* Gnus Cloud Setup::
|
|
* Gnus Cloud Usage::
|
|
@end menu
|
|
|
|
@node Gnus Cloud Setup
|
|
@subsection Gnus Cloud Setup
|
|
|
|
Setting up the Gnus Cloud takes less than a minute. From the Group
|
|
buffer:
|
|
|
|
Press @kbd{^} to go to the Server buffer. Here you'll see all the
|
|
servers that Gnus knows. @xref{Server Buffer}.
|
|
|
|
Then press @kbd{i} to mark any servers as cloud-synchronized (their marks are synchronized).
|
|
|
|
Then press @kbd{I} to mark a single server as the cloud host (it must
|
|
be an IMAP server, and will host a special IMAP folder with all the
|
|
synchronization data). This will set the variable
|
|
@code{gnus-cloud-method} (using the Customize facilities), then ask
|
|
you to optionally upload your first CloudSynchronizationDataPack(TM).
|
|
|
|
@node Gnus Cloud Usage
|
|
@subsection Gnus Cloud Usage
|
|
|
|
After setting up, you can use these shortcuts from the Group buffer:
|
|
|
|
@table @kbd
|
|
@item ~ @key{RET}
|
|
@item ~ d
|
|
@findex gnus-cloud-download-all-data
|
|
@cindex cloud, download
|
|
Download the latest Gnus Cloud data.
|
|
|
|
@item ~ u
|
|
@item ~ ~
|
|
@findex gnus-cloud-upload-all-data
|
|
@cindex cloud, download
|
|
Upload the local Gnus Cloud data. Creates a new
|
|
CloudSynchronizationDataPack(TM).
|
|
|
|
@end table
|
|
|
|
But wait, there's more. Of course there's more. So much more. You can
|
|
customize all of the following.
|
|
|
|
@defvar gnus-cloud-synced-files
|
|
These are the files that will be part of every
|
|
CloudSynchronizationDataPack(TM). They are included in every upload,
|
|
so don't synchronize a lot of large files. Files under 100Kb are best.
|
|
@end defvar
|
|
|
|
@defvar gnus-cloud-storage-method
|
|
This is a choice from several storage methods. It's highly recommended
|
|
to use the EPG facilities. It will be automatic if have GnuPG
|
|
installed and EPG loaded. Otherwise, you could use Base64+gzip,
|
|
Base64, or no encoding.
|
|
@end defvar
|
|
|
|
@defvar gnus-cloud-interactive
|
|
When this is set, and by default it is, the Gnus Cloud package will
|
|
ask you for confirmation here and there. Leave it on until you're
|
|
comfortable with the package.
|
|
@end defvar
|
|
|
|
|
|
@defvar gnus-cloud-method
|
|
The name of the IMAP server to store the
|
|
CloudSynchronizationDataPack(TM)s. It's easiest to set this from the
|
|
Server buffer (@pxref{Gnus Cloud Setup}).
|
|
@end defvar
|
|
|
|
@node D-Bus Integration
|
|
@section D-Bus Integration
|
|
@cindex dbus
|
|
@cindex D-Bus
|
|
@cindex gnus-dbus
|
|
@cindex system sleep
|
|
@cindex closing servers automatically
|
|
@cindex hung connections
|
|
|
|
When using laptops or other systems that have a sleep or hibernate
|
|
functionality, it's possible for long-running server connections to
|
|
become ``hung'', requiring the user to manually close and re-open the
|
|
connections after the system resumes. On systems compiled with D-Bus
|
|
support (check the value of @code{(featurep 'dbusbind)}), Gnus can
|
|
register a D-Bus signal to automatically close all server connections
|
|
before the system goes to sleep. To enable this, set
|
|
@code{gnus-dbus-close-on-sleep} to a non-@code{nil} value.
|
|
|
|
For more information about D-Bus and Emacs, @pxref{Top,,, dbus, D-Bus integration in Emacs}.
|
|
|
|
@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. 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}.
|
|
|
|
@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 MS Windows user you), you could say something like:
|
|
|
|
@lisp
|
|
@group
|
|
(setq nnheader-file-name-translation-alist
|
|
'((?: . ?_)))
|
|
@end group
|
|
@end lisp
|
|
|
|
In fact, this is (part of) the default value for this variable on 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
|
|
* 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 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{https://quimby.gnus.org/}. This used to be the primary
|
|
distribution point for the new and spiffy versions of Gnus, and was
|
|
known as The Site That Destroys Newsrcs And Drives People Mad, but
|
|
these days Gnus is developed in the Emacs repository.
|
|
|
|
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?
|
|
* Conformity:: Gnus tries to conform to all standards.
|
|
* 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.
|
|
|
|
Gnus 5.11 was bundled with GNU Emacs 22.1 in June 2007.
|
|
|
|
A version of No Gnus was released as Gnus 5.13 with GNU Emacs 23.1 in
|
|
July 2009.
|
|
|
|
On April 19, 2010 Gnus development was moved to Git.
|
|
|
|
On the January 31th 2012, Ma Gnus was begun.
|
|
|
|
Since then, Gnus has only been released together with Emacs.
|
|
|
|
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}.
|
|
|
|
|
|
@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 822
|
|
@cindex RFC 822
|
|
@cindex RFC 2822
|
|
@cindex RFC 5322
|
|
There are no known breaches of this standard or its successors
|
|
(currently RFCs 2822 and 5322).
|
|
|
|
@item RFC 1036
|
|
@cindex RFC 1036
|
|
There are no known breaches of this (now-obsolete) standard, either.
|
|
|
|
@item RFC 5536
|
|
@cindex RFC 5536
|
|
We do have some breaches of this standard, the successor of RFC 1036.
|
|
|
|
@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 was an IETF working group that produced Internet RFCs 5536 and 5537.
|
|
The Gnus towers will look into implementing the changes embodied by these
|
|
standards.
|
|
|
|
@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 Contributors
|
|
@subsection Contributors
|
|
@cindex contributors
|
|
|
|
The new Gnus version couldn't have been done without the help of all the
|
|
people on the (ding) mailing list. Every day for over a year I have
|
|
gotten billions of nice bug reports from them, filling me with joy,
|
|
every single one of them. Smooches. The people on the list have been
|
|
tried beyond endurance, what with my ``oh, that's a neat idea <type
|
|
type>, yup, I'll release it right away <ship off> no wait, that doesn't
|
|
work at all <type type>, yup, I'll ship that one off right away <ship
|
|
off> no, wait, that absolutely does not work'' policy for releases.
|
|
Micro$oft---bah. Amateurs. I'm @emph{much} worse. (Or is that
|
|
``worser''? ``much worser''? ``worsest''?)
|
|
|
|
I would like to take this opportunity to thank the Academy 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 Nikšić,
|
|
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
|
|
|
|
For summaries of more recent changes, see the normal Emacs @file{NEWS} files.
|
|
|
|
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 (@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 from
|
|
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-@key{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
|
|
@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 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: <old subject>)} from
|
|
subject lines (see @code{message-subject-trailing-was-query}). @kbd{C-c
|
|
M-m} and @kbd{C-c M-f} inserts markers indicating included text.
|
|
@kbd{C-c C-f a} adds a X-No-Archive: header. @kbd{C-c C-f x} inserts
|
|
appropriate headers and a note in the body for cross-postings and
|
|
followups (see the variables @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 @key{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 @key{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 @key{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 @key{RET} -tool-bar$} should get you started. This is a new
|
|
feature in Gnus 5.10.10.
|
|
|
|
@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} (@pxref{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-child-unplugged}
|
|
|
|
A new command which starts Gnus offline in child mode.
|
|
|
|
@end itemize
|
|
|
|
@end itemize
|
|
|
|
@node No Gnus
|
|
@subsubsection No Gnus
|
|
@cindex No Gnus
|
|
|
|
New features in No Gnus:
|
|
@c FIXME: Gnus 5.12?
|
|
|
|
@itemize @bullet
|
|
|
|
@item Supported Emacs versions
|
|
The following Emacs versions are supported by No Gnus:
|
|
@itemize @bullet
|
|
|
|
@item Emacs 22 and up
|
|
|
|
@end itemize
|
|
|
|
@item Installation changes
|
|
|
|
@itemize @bullet
|
|
@item Upgrading from previous (stable) version if you have used No Gnus.
|
|
|
|
If you have tried No Gnus (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 the
|
|
@file{~/News/marks} directory (perhaps selectively), so that flags are
|
|
read from your @file{~/.newsrc.eld} instead of from the stale marks
|
|
file, where this release will store flags for nntp. See a later entry
|
|
for more information about nntp marks. Note that downgrading isn't
|
|
safe in general.
|
|
|
|
@item Incompatibility when switching from Emacs 23 to Emacs 22
|
|
In Emacs 23, Gnus uses Emacs's new internal coding system @code{utf-8-emacs}
|
|
for saving articles drafts and @file{~/.newsrc.eld}. These files may not
|
|
be read correctly in Emacs 22 and below. If you want to use Gnus across
|
|
different Emacs versions, you may set @code{mm-auto-save-coding-system}
|
|
to @code{emacs-mule}.
|
|
@c FIXME: Untested. (Or did anyone test it?)
|
|
@c Cf. http://thread.gmane.org/gmane.emacs.gnus.general/66251/focus=66344
|
|
|
|
@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 The installation directory's name is allowed to have spaces and/or tabs.
|
|
@end itemize
|
|
|
|
@item New packages and libraries within Gnus
|
|
|
|
@itemize @bullet
|
|
|
|
@item New version of @code{nnimap}
|
|
|
|
@code{nnimap} has been reimplemented in a mostly-compatible way. See
|
|
the Gnus manual for a description of the new interface. In
|
|
particular, @code{nnimap-inbox} and the client side split method has
|
|
changed.
|
|
|
|
@item Gnus includes the Emacs Lisp @acronym{SASL} library.
|
|
|
|
This provides a clean @acronym{API} to @acronym{SASL} mechanisms from
|
|
within Emacs. The user visible aspects of this, compared to the earlier
|
|
situation, include support for @acronym{DIGEST}-@acronym{MD5} and
|
|
@acronym{NTLM}. @xref{Top, ,Emacs SASL, sasl, Emacs SASL}.
|
|
|
|
@item ManageSieve connections uses the @acronym{SASL} library by default.
|
|
|
|
The primary change this brings is support for @acronym{DIGEST-MD5} and
|
|
@acronym{NTLM}, when the server supports it.
|
|
|
|
@item Gnus includes a password cache mechanism in password.el.
|
|
|
|
It is enabled by default (see @code{password-cache}), with a short
|
|
timeout of 16 seconds (see @code{password-cache-expiry}). If
|
|
@acronym{PGG} is used as the @acronym{PGP} back end, the @acronym{PGP}
|
|
passphrase is managed by this mechanism. Passwords for ManageSieve
|
|
connections are managed by this mechanism, after querying the user
|
|
about whether to do so.
|
|
|
|
@item Using EasyPG with Gnus
|
|
When EasyPG, is available, Gnus will use it instead of @acronym{PGG}.
|
|
EasyPG is an Emacs user interface to GNU Privacy Guard. @xref{Top,
|
|
,EasyPG Assistant user's manual, epa, EasyPG Assistant user's manual}.
|
|
EasyPG is included in Emacs 23 and available separately as well.
|
|
@end itemize
|
|
|
|
@item Changes in group mode
|
|
@c ************************
|
|
|
|
@itemize @bullet
|
|
|
|
@item
|
|
Symbols like @code{gcc-self} now have the same precedence rules in
|
|
@code{gnus-parameters} as other ``real'' variables: The last match
|
|
wins instead of the first match.
|
|
|
|
@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 / No Gnus 0.8)
|
|
@c This entry is also present in the node "Oort Gnus".
|
|
|
|
@end itemize
|
|
|
|
@item Changes in summary and article mode
|
|
|
|
@itemize @bullet
|
|
|
|
@item There's now only one variable that determines how @acronym{HTML}
|
|
is rendered: @code{mm-text-html-renderer}.
|
|
|
|
@item Gnus now supports sticky article buffers. Those are article buffers
|
|
that are not reused when you select another article. @xref{Sticky
|
|
Articles}.
|
|
|
|
@c @item Bookmarks
|
|
@c FIXME: To be added
|
|
|
|
@item Gnus can selectively display @samp{text/html} articles
|
|
with a WWW browser with @kbd{K H}. @xref{MIME Commands}.
|
|
|
|
@c gnus-registry-marks
|
|
@c FIXME: To be added
|
|
|
|
@item International host names (@acronym{IDNA}) can now be decoded
|
|
inside article bodies using @kbd{W i}
|
|
(@code{gnus-summary-idna-message}). This requires that GNU Libidn
|
|
(@url{https://www.gnu.org/software/libidn/}) has been installed.
|
|
@c FIXME: Also mention @code{message-use-idna}?
|
|
|
|
@item The non-@acronym{ASCII} group names handling has been much
|
|
improved. The back ends that fully support non-@acronym{ASCII} group
|
|
names are now @code{nntp}, @code{nnml}, and @code{nnrss}. Also the
|
|
agent, the cache, and the marks features work with those back ends.
|
|
@xref{Non-ASCII Group Names}.
|
|
|
|
@item Gnus now displays @acronym{DNS} master files sent as text/dns
|
|
using dns-mode.
|
|
|
|
@item Gnus supports new limiting commands in the Summary buffer:
|
|
@kbd{/ r} (@code{gnus-summary-limit-to-replied}) and @kbd{/ R}
|
|
(@code{gnus-summary-limit-to-recipient}). @xref{Limiting}.
|
|
|
|
@item You can now fetch all ticked articles from the server using
|
|
@kbd{Y t} (@code{gnus-summary-insert-ticked-articles}). @xref{Summary
|
|
Generation Commands}.
|
|
|
|
@item Gnus supports a new sort command in the Summary buffer:
|
|
@kbd{C-c C-s C-t} (@code{gnus-summary-sort-by-recipient}). @xref{Summary
|
|
Sorting}.
|
|
|
|
@item @acronym{S/MIME} now features @acronym{LDAP} user certificate searches.
|
|
You need to configure the server in @code{smime-ldap-host-list}.
|
|
|
|
@item URLs inside Open@acronym{PGP} headers are retrieved and imported
|
|
to your PGP key ring when you click on them.
|
|
|
|
@item
|
|
Picons can be displayed right from the textual address, see
|
|
@code{gnus-picon-style}. @xref{Picons}.
|
|
|
|
@item @acronym{ANSI} @acronym{SGR} control sequences can be transformed
|
|
using @kbd{W A}.
|
|
|
|
@acronym{ANSI} sequences are used in some Chinese hierarchies for
|
|
highlighting articles (@code{gnus-article-treat-ansi-sequences}).
|
|
|
|
@item Gnus now MIME decodes articles even when they lack "MIME-Version" header.
|
|
This changes the default of @code{gnus-article-loose-mime}.
|
|
|
|
@item @code{gnus-decay-scores} can be a regexp matching score files.
|
|
For example, set it to @samp{\\.ADAPT\\'} and only adaptive score files
|
|
will be decayed. @xref{Score Decays}.
|
|
|
|
@item Strings prefixing to the @code{To} and @code{Newsgroup} headers in
|
|
summary lines when using @code{gnus-ignored-from-addresses} can be
|
|
customized with @code{gnus-summary-to-prefix} and
|
|
@code{gnus-summary-newsgroup-prefix}. @xref{To From Newsgroups}.
|
|
|
|
@item You can replace @acronym{MIME} parts with external bodies.
|
|
See @code{gnus-mime-replace-part} and @code{gnus-article-replace-part}.
|
|
@xref{MIME Commands}, @ref{Using MIME}.
|
|
|
|
@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 @acronym{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 "Oort Gnus".
|
|
|
|
@item Now the new command @kbd{S W}
|
|
(@code{gnus-article-wide-reply-with-original}) for a wide reply in the
|
|
article buffer yanks a text that is in the active region, if it is set,
|
|
as well as the @kbd{R} (@code{gnus-article-reply-with-original}) command.
|
|
Note that the @kbd{R} command in the article buffer no longer accepts a
|
|
prefix argument, which was used to make it do a wide reply.
|
|
@xref{Article Keymap}.
|
|
|
|
@item The new command @kbd{C-h b}
|
|
(@code{gnus-article-describe-bindings}) used in the article buffer now
|
|
shows not only the article commands but also the real summary commands
|
|
that are accessible from the article buffer.
|
|
|
|
@end itemize
|
|
|
|
@item Changes in Message mode
|
|
|
|
@itemize @bullet
|
|
@item Gnus now defaults to saving all outgoing messages in per-month
|
|
nnfolder archives.
|
|
|
|
@item Gnus now supports the ``hashcash'' client puzzle anti-spam mechanism.
|
|
Use @code{(setq message-generate-hashcash t)} to enable.
|
|
@xref{Hashcash}.
|
|
|
|
@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}.
|
|
|
|
@item The option @code{message-yank-empty-prefix} now controls how
|
|
empty lines are prefixed in cited text. @xref{Insertion Variables,
|
|
,Insertion Variables, message, Message Manual}.
|
|
|
|
@item Gnus uses narrowing to hide headers in Message buffers.
|
|
The @code{References} header is hidden by default. To make all
|
|
headers visible, use @code{(setq message-hidden-headers nil)}.
|
|
@xref{Message Headers, ,Message Headers, message, Message Manual}.
|
|
|
|
@item You can highlight different levels of citations like in the
|
|
article buffer. See @code{gnus-message-highlight-citation}.
|
|
|
|
@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}.
|
|
|
|
@item You can now store signature files in a special directory
|
|
named @code{message-signature-directory}.
|
|
|
|
@item The option @code{message-citation-line-format} controls the format
|
|
of the "Whomever writes:" line. You need to set
|
|
@code{message-citation-line-function} to
|
|
@code{message-insert-formatted-citation-line} as well.
|
|
@end itemize
|
|
|
|
@item Changes in Browse Server mode
|
|
|
|
@itemize @bullet
|
|
@item Gnus' sophisticated subscription methods are now available in
|
|
Browse Server buffers as well using the variable
|
|
@code{gnus-browse-subscribe-newsgroup-method}.
|
|
|
|
@end itemize
|
|
|
|
|
|
@item Changes in back ends
|
|
|
|
@itemize @bullet
|
|
@item The nntp back end stores article marks in @file{~/News/marks}.
|
|
|
|
The directory can be changed using the (customizable) variable
|
|
@code{nntp-marks-directory}, and marks can be disabled using the
|
|
(back end) variable @code{nntp-marks-is-evil}. The advantage of this
|
|
is that you can copy @file{~/News/marks} (using rsync, scp or
|
|
whatever) to another Gnus installation, and it will realize what
|
|
articles you have read and marked. The data in @file{~/News/marks}
|
|
has priority over the same data in @file{~/.newsrc.eld}.
|
|
|
|
@item
|
|
You can import and export your @acronym{RSS} subscriptions from
|
|
@acronym{OPML} files. @xref{RSS}.
|
|
|
|
@item @acronym{IMAP} identity (@acronym{RFC} 2971) is supported.
|
|
|
|
By default, Gnus does not send any information about itself, but you can
|
|
customize it using the variable @code{nnimap-id}.
|
|
|
|
@item The @code{nnrss} back end now supports multilingual text.
|
|
Non-@acronym{ASCII} group names for the @code{nnrss} groups are also
|
|
supported. @xref{RSS}.
|
|
|
|
@item Retrieving mail with @acronym{POP3} is supported over @acronym{SSL}/@acronym{TLS} and with StartTLS.
|
|
|
|
@item The nnml back end allows other compression programs beside @file{gzip}
|
|
for compressed message files. @xref{Mail Spool}.
|
|
|
|
@item The nnml back end supports group compaction.
|
|
|
|
This feature, accessible via the functions
|
|
@code{gnus-group-compact-group} (@kbd{G z} in the group buffer) and
|
|
@code{gnus-server-compact-server} (@kbd{z} in the server buffer)
|
|
renumbers all articles in a group, starting from 1 and removing gaps.
|
|
As a consequence, you get a correct total article count (until
|
|
messages are deleted again).
|
|
|
|
@c @item nnmairix.el
|
|
@c FIXME
|
|
|
|
@c @item nnir.el
|
|
@c FIXME
|
|
|
|
@end itemize
|
|
|
|
@item Appearance
|
|
@c Maybe it's not worth to separate this from "Miscellaneous"?
|
|
|
|
@itemize @bullet
|
|
|
|
@item The tool bar has been updated to use GNOME icons.
|
|
You can also customize the tool bars: @kbd{M-x customize-apropos @key{RET}
|
|
-tool-bar$} should get you started.
|
|
@c FIXME: Document this in the manual
|
|
|
|
@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.
|
|
@c FIXME: Document this in the manual
|
|
|
|
@end itemize
|
|
|
|
@item Miscellaneous changes
|
|
|
|
@itemize @bullet
|
|
@item Having edited the select-method for the foreign server in the
|
|
server buffer is immediately reflected to the subscription of the groups
|
|
which use the server in question. For instance, if you change
|
|
@code{nntp-via-address} into @samp{bar.example.com} from
|
|
@samp{foo.example.com}, Gnus will connect to the news host by way of the
|
|
intermediate host @samp{bar.example.com} from next time.
|
|
|
|
@item The @file{all.SCORE} file can be edited from the group buffer
|
|
using @kbd{W e}.
|
|
|
|
@item You can set @code{gnus-mark-copied-or-moved-articles-as-expirable}
|
|
to a non-@code{nil} value so that articles that have been read may be
|
|
marked as expirable automatically when copying or moving them to a group
|
|
that has auto-expire turned on. The default is @code{nil} and copying
|
|
and moving of articles behave as before; i.e., the expirable marks will
|
|
be unchanged except that the marks will be removed when copying or
|
|
moving articles to a group that has not turned auto-expire on.
|
|
@xref{Expiring Mail}.
|
|
|
|
@item NoCeM support has been removed.
|
|
|
|
@item Carpal mode has been removed.
|
|
|
|
@end itemize
|
|
|
|
@end itemize
|
|
|
|
|
|
@node Ma Gnus
|
|
@subsubsection Ma Gnus
|
|
@cindex Ma Gnus
|
|
|
|
It's really spelled 真Gnus. Ma Gnus was the code name for the
|
|
development version of Gnus started in 2012. These days, Gnus is only
|
|
released together with Emacs.
|
|
|
|
New features in Ma Gnus:
|
|
|
|
@itemize @bullet
|
|
|
|
@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.
|
|
@xref{Archived Messages}.
|
|
|
|
For more recent changes, see the Emacs @file{NEWS} files.
|
|
|
|
@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 data 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{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
|
|
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 2000 or
|
|
something like that.
|
|
@end enumerate
|
|
|
|
If all else fails, report the problem as a bug.
|
|
|
|
@cindex bugs
|
|
@cindex reporting bugs
|
|
|
|
@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 toggle-debug-on-error}, 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 in
|
|
the documentation buffer that leads you to the function definition,
|
|
then press @kbd{M-x edebug-defun @key{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{@key{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 Emacs Lisp 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 @key{RET} gnus} or @kbd{M-x elp-instrument-package
|
|
@key{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.
|
|
* 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 " " <error message> eol
|
|
valid-head = valid-message *header "." eol
|
|
valid-message = "221 " <number> " Article retrieved." eol
|
|
header = <text> eol
|
|
@end example
|
|
|
|
@cindex BNF
|
|
(The version of extended BNF used here is ABNF, the one used in Internet RFCs.
|
|
See RFC 5234.)
|
|
|
|
If the return value is @code{nov}, the data buffer should contain
|
|
@dfn{network overview database} lines. These are basically fields
|
|
separated by tabs.
|
|
|
|
@example
|
|
nov-buffer = *nov-line
|
|
nov-line = field 7*8[ <TAB> field ] eol
|
|
field = <text except TAB>
|
|
@end example
|
|
|
|
For a closer look at what should be in those fields,
|
|
@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<number> " " <Error message>
|
|
info = "211 " 3* [ <number> " " ] <string>
|
|
@end example
|
|
|
|
|
|
@item (nnchoke-close-group GROUP &optional SERVER)
|
|
|
|
Close @var{group} and free any resources connected to it. This will be
|
|
a no-op on most back ends.
|
|
|
|
There should be no data returned.
|
|
|
|
|
|
@item (nnchoke-request-list &optional SERVER)
|
|
|
|
Return a list of all groups available on @var{server}. And that means
|
|
@emph{all}.
|
|
|
|
Here's an example from a server that only carries two groups:
|
|
|
|
@example
|
|
ifi.test 0000002200 0000002000 y
|
|
ifi.discussion 3324 3300 n
|
|
@end example
|
|
|
|
On each line we have a group name, then the highest article number in
|
|
that group, the lowest article number, and finally a flag. If the group
|
|
contains no articles, the lowest article number should be reported as 1
|
|
and the highest as 0.
|
|
|
|
@example
|
|
active-file = *active-line
|
|
active-line = name " " <number> " " <number> " " flags eol
|
|
name = <string>
|
|
flags = "n" / "y" / "m" / "x" / "j" / "=" name
|
|
@end example
|
|
|
|
The flag says whether the group is read-only (@samp{n}), is moderated
|
|
(@samp{m}), is dead (@samp{x}), is aliased to some other group
|
|
(@samp{=other-group}) or none of the above (@samp{y}).
|
|
|
|
|
|
@item (nnchoke-request-post &optional SERVER)
|
|
|
|
This function should post the current buffer. It might return whether
|
|
the posting was successful or not, but that's not required. If, for
|
|
instance, the posting is done asynchronously, it has generally not been
|
|
completed by the time this function concludes. In that case, this
|
|
function should set up some kind of sentinel to beep the user loud and
|
|
clear if the posting could not be completed.
|
|
|
|
There should be no result data from this function.
|
|
|
|
@end table
|
|
|
|
|
|
@node Optional Back End Functions
|
|
@subsubsection Optional Back End Functions
|
|
|
|
@table @code
|
|
|
|
@item (nnchoke-retrieve-groups GROUPS &optional SERVER)
|
|
|
|
@var{groups} is a list of groups, and this function should request data
|
|
on all those groups. How it does it is of no concern to Gnus, but it
|
|
should attempt to do this in a speedy fashion.
|
|
|
|
The return value of this function can be either @code{active} or
|
|
@code{group}, which says what the format of the result data is. The
|
|
former is in the same format as the data from
|
|
@code{nnchoke-request-list}, while the latter is a buffer full of lines
|
|
in the same format as @code{nnchoke-request-group} gives.
|
|
|
|
@example
|
|
group-buffer = *active-line / *group-status
|
|
@end example
|
|
|
|
|
|
@item (nnchoke-request-update-info GROUP INFO &optional SERVER)
|
|
|
|
A Gnus group info (@pxref{Group Info}) is handed to the back end for
|
|
alterations. This comes in handy if the back end really carries all
|
|
the information (as is the case with virtual and imap groups). This
|
|
function should destructively alter the info to suit its needs, and
|
|
should return a 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 <TAB> description eol
|
|
name = <string>
|
|
description = <text>
|
|
@end example
|
|
|
|
@item (nnchoke-request-list-newsgroups &optional SERVER)
|
|
|
|
The result data from this function should be the description of all
|
|
groups available on the server.
|
|
|
|
@example
|
|
description-buffer = *description-line
|
|
@end example
|
|
|
|
|
|
@item (nnchoke-request-newgroups DATE &optional SERVER)
|
|
|
|
The result data from this function should be all groups that were
|
|
created after @samp{date}, which is in normal human-readable date format
|
|
(i.e., the date format used in mail and news headers, and returned by
|
|
the function @code{message-make-date} by default). The data should be
|
|
in the active buffer format.
|
|
|
|
It is okay for this function to return ``too many'' groups; some back ends
|
|
might find it cheaper to return the full list of groups, rather than
|
|
just the new groups. But don't do this for back ends with many groups.
|
|
Normally, if the user creates the groups herself, there won't be too
|
|
many groups, so @code{nnml} and the like are probably safe. But for
|
|
back ends like @code{nntp}, where the groups have been created by the
|
|
server, it is quite likely that there can be many groups.
|
|
|
|
|
|
@item (nnchoke-request-create-group GROUP &optional SERVER)
|
|
|
|
This function should create an empty group with name @var{group}.
|
|
|
|
There should be no return data.
|
|
|
|
|
|
@item (nnchoke-request-expire-articles ARTICLES &optional GROUP SERVER FORCE)
|
|
|
|
This function should run the expiry process on all articles in the
|
|
@var{articles} range (which is currently a simple list of article
|
|
numbers.) It is left up to the back end to decide how old articles
|
|
should be before they are removed by this function. If @var{force} is
|
|
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)
|
|
|
|
;;; @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 = <ascii 34>
|
|
string-header = "subject" / "from" / "references" / "message-id" /
|
|
"xref" / "body" / "head" / "all" / "followup"
|
|
number-header = "lines" / "chars"
|
|
date-header = "date"
|
|
string-match = "(" quote <string> quote [ "" / [ space score [ "" /
|
|
space date [ "" / [ space string-match-t ] ] ] ] ] ")"
|
|
score = "nil" / <integer>
|
|
date = "nil" / <natural number>
|
|
string-match-t = "nil" / "s" / "substring" / "S" / "Substring" /
|
|
"r" / "regex" / "R" / "Regex" /
|
|
"e" / "exact" / "E" / "Exact" /
|
|
"f" / "fuzzy" / "F" / "Fuzzy"
|
|
number-match = "(" <integer> [ "" / [ space score [ "" /
|
|
space date [ "" / [ space number-match-t ] ] ] ] ] ")"
|
|
number-match-t = "nil" / "=" / "<" / ">" / ">=" / "<="
|
|
date-match = "(" quote <string> quote [ "" / [ space score [ "" /
|
|
space date [ "" / [ space date-match-t ] ] ] ] ")"
|
|
date-match-t = "nil" / "at" / "before" / "after"
|
|
atom = "(" [ required-atom / optional-atom ] ")"
|
|
required-atom = mark / expunge / mark-and-expunge / files /
|
|
exclude-files / read-only / touched
|
|
optional-atom = adapt / local / eval
|
|
mark = "mark" space nil-or-number
|
|
nil-or-number = "nil" / <integer>
|
|
expunge = "expunge" space nil-or-number
|
|
mark-and-expunge = "mark-and-expunge" space nil-or-number
|
|
files = "files" *[ space <string> ]
|
|
exclude-files = "exclude-files" *[ space <string> ]
|
|
read-only = "read-only" [ space "nil" / space "t" ]
|
|
adapt = "adapt" [ space "ignore" / space "t" / space adapt-rule ]
|
|
adapt-rule = "(" *[ <string> *[ "(" <string> <integer> ")" ] ")"
|
|
local = "local" *[ space "(" <string> space <form> ")" ]
|
|
eval = "eval" space <form>
|
|
space = *[ " " / <TAB> / <NEWLINE> ]
|
|
@end example
|
|
|
|
Any unrecognized elements in a score file should be ignored, but not
|
|
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 5536 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 <string> quote
|
|
ralevel = rank / level
|
|
level = <integer in the range of 1 to inf>
|
|
rank = "(" level "." score ")"
|
|
score = <integer in the range of 1 to inf>
|
|
read = range
|
|
marks-lists = nil / "(" *marks ")"
|
|
marks = "(" <string> range ")"
|
|
method = "(" <string> *elisp-forms ")"
|
|
parameters = "(" *elisp-forms ")"
|
|
@end example
|
|
|
|
Actually that @samp{marks} rule is a fib. A @samp{marks} is a
|
|
@samp{<string>} 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 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 <NEWLINE>
|
|
group = <non-white-space string>
|
|
spc = " "
|
|
high-number = <non-negative integer>
|
|
low-number = <positive integer>
|
|
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 <NEWLINE>
|
|
group = <non-white-space string>
|
|
tab = <TAB>
|
|
description = <string>
|
|
@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 to 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:
|