A foreign group is a group that is not read by the usual (or default) means. It could be, for instance, a group from a different 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 name and
a select method. To take the latter first, a select method is a
list where the first element says what backend to use (e.g. nntp
,
nnspool
, nnml
) and the second element is the server
name. There may be additional elements in the select method, where the
value may have special meaning for the backend in question.
One could say that a select method defines a virtual server---so we do just that (see section The Server Buffer).
The name of the group is the name the backend will recognize the group as.
For instance, the group `soc.motss' on the NNTP server
`some.where.edu' will have the name `soc.motss' and select
method (nntp "some.where.edu")
. Gnus will call this group
`nntp+some.where.edu:soc.motss', even though the nntp
backend just knows this group as `soc.motss'.
The different methods all have their peculiarities, of course.
Traditionally, a 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 backend 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 backend represents a virtual server.
For instance, the nntp
backend may be used to connect to several
different actual NNTP servers, or, perhaps, to many different ports
on the same actual NNTP server. You tell Gnus which backend to
use, and what parameters to set by specifying a select method.
These select methods specifications can sometimes become quite complicated--say, for instance, that you want to read from the NNTP server `news.funet.fi' on port number 13, which hangs if queried for NOV headers and has a buggy select. Ahem. Anyways, 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, user the ^
(gnus-group-enter-server-mode
) command in the group buffer.
gnus-server-mode-hook
is run when creating the server buffer.
You can change the look of the server buffer lines by changing the
gnus-server-line-format
variable. This is a format
-like
variable, with some simple extensions:
The mode line can also be customized by using the
gnus-server-mode-line-format
variable. The following specs are
understood:
Also see section Formatting Variables.
gnus-server-add-server
).
gnus-server-edit-server
).
gnus-server-read-server
).
gnus-server-exit
).
gnus-server-kill-server
).
gnus-server-yank-server
).
gnus-server-copy-server
).
gnus-server-list-servers
).
gnus-server-scan-server
). This is mainly sensible with mail
servers.
gnus-server-regenerate-server
). This can be useful if you have
a mail backend that has gotten out of synch.
Most select methods are pretty simple and self-explanatory:
(nntp "news.funet.fi")
Reading directly from the spool is even simpler:
(nnspool "")
As you can see, the first element in a select method is the name of the backend, and the second is the address, or name, if you will.
After these two elements, there may be a arbitrary number of (variable form) pairs.
To go back to the first example--imagine that you want to read from port 15 from that machine. This is what the select method should look like then:
(nntp "news.funet.fi" (nntp-port-number 15))
You should read the documentation to each backend to find out what
variables are relevant, but here's an nnmh
example.
nnmh
is a mail backend 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
you private mail:
(nnmh "private" (nnmh-directory "~/private/mail/"))
(This server is then called `private', but you may have guessed that.)
Here's the method for a public spool:
(nnmh "public" (nnmh-directory "/usr/information/spool/") (nnmh-get-new-mail nil))
If you are behind a firewall and only have access to the NNTP
server from the firewall machine, you can instruct Gnus to rlogin
on the firewall machine and telnet from there to the NNTP server.
Doing this can be rather fiddly, but your virtual server definition
should probably look something like this:
(nntp "firewall" (nntp-address "the.firewall.machine") (nntp-open-connection-function nntp-open-rlogin) (nntp-end-of-line "\n") (nntp-rlogin-parameters ("telnet" "the.real.nntp.host" "nntp")))
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 a command does that. It
would probably be best to use nnspool
to read the cache. You
could also use nnml
or nnmh
, though.
Type a nnspool RET cache RET.
You should now have a brand new nnspool
virtual server called
`cache'. You now need to edit it to have the right definitions.
Type e to edit the server. You'll be entered into a buffer that
will contain the following:
(nnspool "cache")
Change that to:
(nnspool "cache" (nnspool-spool-directory "~/News/cache/") (nnspool-nov-directory "~/News/cache/") (nnspool-active-file "~/News/cache/active"))
Type C-c C-c to return to the server buffer. If you now press 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.
One sticky point when defining variables (both on backends 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,
nnml-directory
is `~/Mail/' by default, and all nnml
directory variables are initialized from that variable, so
nnml-active-file
will be `~/Mail/active'. If you define a
new virtual nnml
server, it will not suffice to set just
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 backend, see each backend's section later in this
manual, but here's an example nnml
definition:
(nnml "public" (nnml-directory "~/my-mail/") (nnml-active-file "~/my-mail/active") (nnml-newsgroups-file "~/my-mail/newsgroups"))
Wherever you would normally use a select method
(e.g. 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.
If a server seems to be unreachable, Gnus will mark that server as
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 the server `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 from 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 (see section The Server Buffer) and poke it with the following commands:
gnus-server-open-server
).
gnus-server-close-server
).
gnus-server-deny-server
).
gnus-server-open-all-servers
).
gnus-server-close-all-servers
).
gnus-server-remove-denials
).
A newsreader is normally used for reading news. Gnus currently provides only two methods of getting news--it can read from an NNTP server, or it can read from a local spool.
Subscribing to a foreign group from an NNTP server is rather easy.
You just specify nntp
as method and the address of the NNTP
server as the, uhm, address.
If the 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 (see section 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 nntp
server:
nntp-server-opened-hook
nntp-server-opened-hook
is run after a connection has been made.
It can be used to send commands to the NNTP server after it has
been contacted. By default is sends the command MODE READER
to
the server with the nntp-send-mode-reader
function.
nntp-authinfo-function
nntp-send-authinfo
nntp-send-nosy-authinfo
nntp-send-authinfo-from-file
nntp-server-action-alist
(setq nntp-server-action-alist '(("innd" (ding))))You probably don't want to do that, though. The default value is
'(("nntpd 1\\.5\\.11t" (remove-hook 'nntp-server-opened-hook nntp-send-mode-reader)))This ensures that Gnus doesn't send the
MODE READER
command to
nntpd 1.5.11t, since that command chokes that server, I've been told.
nntp-maximum-request
head
commands. To
speed things up, the backend sends lots of these commands without
waiting for reply, and then reads all the replies. This is controlled
by the nntp-maximum-request
variable, and is 400 by default. If
your network is buggy, you should set this to 1.
nntp-connection-timeout
nntp
groups that you connect to
regularly, you're sure to have problems with 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 nntp-connection-timeout
. This is an integer
that says how many seconds the nntp
backend should wait for a
connection before giving up. If it is nil
, which is the default,
no timeouts are done.
nntp-command-timeout
nntp-retry-on-break
nil
, you can also C-g if Gnus
hangs. This will have much the same effect as the command timeout
described above.
nntp-server-hook
nntp-open-connection-function
nntp-open-network-stream
, which is the default, and
simply connects to some port or other on the remote system. The other
is nntp-open-rlogin
, which does an rlogin on the remote system,
and then does a telnet to the NNTP server available there.
nntp-rlogin-parameters
nntp-open-rlogin
as the
nntp-open-connection-function
, this list will be used as the
parameter list given to rsh
.
nntp-end-of-line
rlogin
to talk to the server.
nntp-rlogin-user-name
rlogin
connect
function.
nntp-address
nntp-port-number
nntp-open-network-stream
connect function.
nntp-buggy-select
nil
if your select routine is buggy.
nntp-nov-is-evil
t
, but nntp
usually checks whether NOV
can be used automatically.
nntp-xover-commands
("XOVER"
"XOVERVIEW")
.
nntp-nov-gap
nntp
normally sends just one big request for 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 nntp
will fetch 4999 NOV
lines that you do not want, and will not use. This variable says how
big a gap between two consecutive articles is allowed to be before the
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 nil
,
nntp
will never split requests.
nntp-prepare-server-hook
nntp-warn-about-losing-connection
nil
, some noise will be made when a
server closes connection.
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---`alt.binaries.pictures.furniture', for instance.
Anyways, you just specify nnspool
as the method and `' (or
anything else) as the address.
If you have access to a local spool, you should probably use that as the
native select method (see section Finding the News). It is normally faster
than using an nntp
select method, but might not be. It depends.
You just have to try to find out what's best at your site.
nnspool-inews-program
nnspool-inews-switches
nnspool-spool-directory
nnspool
looks for the articles. This is normally
`/usr/spool/news/'.
nnspool-nov-directory
nnspool
will look for NOV files. This is normally
`/usr/spool/news/over.view/'.
nnspool-lib-dir
nnspool-active-file
nnspool-newsgroups-file
nnspool-history-file
nnspool-active-times-file
nnspool-nov-is-evil
nil
, nnspool
won't try to use any NOV files
that it finds.
nnspool-sift-nov-with-sed
nil
, which is the default, use sed
to get the
relevant portion from the overview file. If nil, nnspool
will
load the entire file into a buffer and process it there.
Reading mail with a newsreader--isn't that just plain WeIrD? But of course.
It's quite easy to use Gnus to read your new mail. You just plonk the
mail backend of your choice into gnus-secondary-select-methods
,
and things will happen automatically.
For instance, if you want to use nnml
(which is a one file per
mail backend), you could put the following in your `.gnus' file:
(setq gnus-secondary-select-methods '((nnml "private")))
Now, the next time you start Gnus, this backend will be queried for new
articles, and it will move all the messages in your spool file to its
directory, which is ~/Mail/
by default. The new group that will
be created (`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:
(setq nnmail-split-methods '(("junk" "^From:.*Lars Ingebrigtsen") ("crazy" "^Subject:.*die\\|^Organization:.*flabby") ("other" "")))
This will result in three new nnml
mail groups being created:
`nnml:junk', `nnml:crazy', and `nnml:other'. All the
mail that doesn't fit into the first two groups will be placed in the
latter 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 see section Choosing a Mail Backend and see section Expiring Mail.
The nnmail-split-methods
variable says how the incoming mail is
to be split into groups.
(setq nnmail-split-methods '(("mail.junk" "^From:.*Lars Ingebrigtsen") ("mail.crazy" "^Subject:.*die\\|^Organization:.*flabby") ("mail.other" "")))
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 `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.
If the first element is the special symbol junk
, then messages
that match the regexp will disappear into the aether. Use with
extreme caution.
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-nil
value if it thinks that the
mail belongs in that group.
The last of these groups should always be a general one, and the regular expression should always be `' so that it matches any mails that haven't been matched by any of the other regexps. (These rules are processed from the beginning of the alist toward the end. The first rule to make a match will "win", unless you have crossposting enabled. In that case, all matching rules will "win".)
If you like to tinker with this yourself, you can set this variable to a function of your choice. This function will be called without any arguments in a buffer narrowed to the headers of an incoming mail message. The function should return a list of groups names that it thinks should carry this mail message.
Note that the mail backends are free to maul the poor, innocent
incoming headers all they want to. They all add Lines
headers;
some add X-Gnus-Group
headers; most rename the Unix mbox
From<SPACE>
line to something else.
The mail backends all support cross-posting. If several regexps match,
the mail will be "cross-posted" to all those groups.
nnmail-crosspost
says whether to use this mechanism or not. Note
that no articles are crossposted to the general (`') group.
nnmh
and nnml
makes crossposts by creating hard links to
the crossposted articles. However, not all files systems support hard
links. If that's the case for you, set
nnmail-crosspost-link-function
to copy-file
. (This
variable is add-name-to-file
by default.)
If you wish to see where the previous mail split put the messages, you can use the M-x nnmail-split-history command.
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.
These variables are (for the most part) pertinent to all the various mail backends.
nnmail-read-incoming-hook
nnmail-spool-file
nil
, the mail backends will never attempt to fetch mail by
themselves. If you are using a POP mail server and your name is
`larsi', you should set this variable to `po:larsi'. If
your name is not `larsi', you should probably modify that
slightly, but you may have guessed that already, you smart & handsome
devil! You can also set this variable to pop
, and Gnus will try
to figure out the POP mail string by itself. In any case, Gnus will
call movemail
which will contact the POP server named in the
MAILHOST
environment variable. If the POP server needs a
password, you can either set nnmail-pop-password-required
to
t
and be prompted for the password, or set
nnmail-pop-password
to the password itself.
nnmail-spool-file
can also be a list of mailboxes.
Your Emacs has to have been configured with `--with-pop' before
compilation. This is the default, but some installations have it
switched off.
When you use a mail backend, 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 backend--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.
nnmail-use-procmail
nil
, the mail backends will look in
nnmail-procmail-directory
for incoming mail. All the files in
that directory that have names ending in nnmail-procmail-suffix
will be considered incoming mailboxes, and will be searched for new
mail.
nnmail-crash-box
nnmail-prepare-incoming-hook
nnmail-split-hook
gnus-article-decode-rfc1522
is one likely function to add to this hook.
nnmail-pre-get-new-mail-hook
nnmail-post-get-new-mail-hook
nnmail-pre-get-new-mail-hook
(is called just before
starting to handle the new mail) and
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:
(add-hook 'gnus-pre-get-new-mail-hook (lambda () (set-default-file-modes 511))) (add-hook 'gnus-post-get-new-mail-hook (lambda () (set-default-file-modes 551)))
nnmail-tmp-directory
nil
,
it will be used instead.
nnmail-movemail-program
nnmail-delete-incoming
nil
, the mail backends will delete the temporary incoming
file after splitting mail into the proper groups. This is t
by
default.
(No Gnus release since (ding) Gnus 0.10 (or something like that) have
lost mail, I think, but that's not the point. (Except certain versions
of Red Gnus.)) By not deleting the Incoming* files, one can be sure to
not lose mail -- if Gnus totally whacks out, one can always recover what
was lost.
Delete the `Incoming*' files at will.
nnmail-use-long-file-names
nil
, the mail backends will use long file and directory
names. Groups like `mail.misc' will end up in directories like
`mail.misc/'. If it is nil
, the same group will end up in
`mail/misc/'.
nnmail-delete-file-function
delete-file
by default.
nnmail-cache-accepted-message-ids
nil
, put the Message-ID
s of articles imported into
the backend (via Gcc
, for instance) into the mail duplication
discovery cache. The default is nil
.
If the rather simple, standard method for specifying how to split mail
doesn't allow you to do what you want, you can set
nnmail-split-methods
to nnmail-split-fancy
. Then you can
play with the nnmail-split-fancy
variable.
Let's look at an example value of this variable first:
;; Messages from the mailer daemon are not crossposted to any of ;; the ordinary groups. Warnings are put in a separate group ;; from real errors. (| ("from" mail (| ("subject" "warn.*" "mail.warning") "mail.misc")) ;; Non-error messages are crossposted to all relevant ;; groups, but we don't crosspost between the group for the ;; (ding) list and the group for other (ding) related mail. (& (| (any "ding@ifi\\.uio\\.no" "ding.list") ("subject" "ding" "ding.misc")) ;; Other mailing lists... (any "procmail@informatik\\.rwth-aachen\\.de" "procmail.list") (any "SmartList@informatik\\.rwth-aachen\\.de" "SmartList.list") ;; People... (any "larsi@ifi\\.uio\\.no" "people.Lars_Magne_Ingebrigtsen")) ;; Unmatched mail goes to the catch all group. "misc.misc")
This variable has the format of a split. A split is a (possibly) recursive structure where each split may contain other splits. Here are the five possible split syntaxes:
|
(vertical bar), then process each SPLIT until one of them
matches. A SPLIT is said to match if it will cause the mail message to
be stored in one or more groups.
&
, then process all SPLITs in the list.
junk
: If the split is the symbol junk
, then don't save
this message anywhere.
:
, then the second element will be called as a
function with args given as arguments. The function should return
a SPLIT.
In these splits, FIELD must match a complete field name.
VALUE must match a complete word according to the fundamental mode
syntax table. You can use .*
in the regexps to match partial
field names or words. In other words, all VALUE's are wrapped in
`\<' and `\>' pairs.
FIELD and VALUE can also be lisp symbols, in that case they
are expanded as specified by the variable
nnmail-split-abbrev-alist
. This is an alist of cons cells, where
the car of the cells contains the key, and the cdr contains a string.
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, you can say things like:
(any "debian-\(\\w*\\)@lists.debian.org" "mail.debian.\\1")
That is, do replace-match
-like substitions in the group names.
Many people use procmail
(or some other mail filter program or
external delivery agent---slocal
, elm
, etc) to split
incoming mail into groups. If you do that, you should set
nnmail-spool-file
to procmail
to ensure that the mail
backends never ever try to fetch mail by themselves.
This also means that you probably don't want to set
nnmail-split-methods
either, which has some, perhaps, unexpected
side effects.
When a mail backend is queried for what groups it carries, it replies
with the contents of that variable, along with any groups it has figured
out that it carries by other means. None of the backends (except
nnmh
) actually go out to the disk and check what groups actually
exist. (It's not trivial to distinguish between what the user thinks is
a basis for a newsgroup and what is just a plain old file or directory.)
This means that you have to tell Gnus (and the backends) what groups exist by hand.
Let's take the nnmh
backend as an example.
The folders are located in nnmh-directory
, say, `~/Mail/'.
There are three folders, `foo', `bar' and `mail.baz'.
Go to the group buffer and type G m. When prompted, answer `foo' for the name and `nnmh' for the method. Repeat twice for the two other groups, `bar' and `mail.baz'. Be sure to include all your mail groups.
That's it. You are now set to read your mail. An active file for this method will be created automatically.
If you use nnfolder
or any other backend that store more than a
single article in each file, you should never have procmail add mails to
the file that Gnus sees. Instead, procmail should put all incoming mail
in nnmail-procmail-directory
. To arrive at the file name to put
the incoming mail in, append nnmail-procmail-suffix
to the group
name. The mail backends will read the mail from these files.
When Gnus reads a file called `mail.misc.spool', this mail will be
put in the mail.misc
, as one would expect. However, if you want
Gnus to split the mail the normal way, you could set
nnmail-resplit-incoming
to t
.
If you use procmail
to split things directory into an nnmh
directory (which you shouldn't do), you should set
nnmail-keep-last-article
to non-nil
to prevent Gnus from
ever expiring the final article (i. e., the article with the highest
article number) in a mail newsgroup. This is quite, quite important.
Here's an example setup: The incoming spools are located in
`~/incoming/' and have `""' as suffixes (i. e., the incoming
spool files have the same names as the equivalent groups). The
nnfolder
backend is to be used as the mail interface, and the
nnfolder
directory is `~/fMail/'.
(setq nnfolder-directory "~/fMail/") (setq nnmail-spool-file 'procmail) (setq nnmail-procmail-directory "~/incoming/") (setq gnus-secondary-select-methods '((nnfolder ""))) (setq nnmail-procmail-suffix "")
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 backends, 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 nnml
(see section Mail Spool), and have set nnmail-split-methods
to a
satisfactory value (see section Splitting Mail). You have an old Unix mbox
file filled with important, but old, mail. You want to move it into
your nnml
groups.
Here's how:
nndoc
group from the mbox file (see section Foreign Groups).
All the mail messages in the mbox file will now also be spread out over
all your 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 backend to another. Just respool all the mail in the old mail groups using the new mail backend.
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 expirable. This does not mean that the articles will disappear right away, however. In general, a mail article will be deleted from your system if, 1) it is marked as expirable, AND 2) it is more than one week old. If you do not mark an article as expirable, it will remain on your system until hell freezes over. This bears repeating one more time, with some spurious capitalizations: IF you do NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES.
You do not have to mark articles as expirable by hand. Groups that
match the regular expression gnus-auto-expirable-newsgroups
will
have all articles that you read marked as expirable automatically. All
articles that are marked as expirable have an `E' in the first
column in the summary buffer.
Note that making a group auto-expirable don't mean that all read articles are expired--only the articles that are marked as expirable will be expired. Also note the using the d command won't make groups 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:
(setq gnus-auto-expirable-newsgroups "mail.nonsense-list\\|mail.nice-list")
Another way to have auto-expiry happen is to have the element
auto-expire
in the group parameters of the group.
If you use adaptive scoring (see section Adaptive Scoring) and auto-expiring, you'll have problems. Auto-expiring and adaptive scoring doesn't really mix very well.
The nnmail-expiry-wait
variable supplies the default time an
expirable article has to live. Gnus starts counting days from when the
message arrived, not from when it was sent. The default is seven
days.
Gnus also supplies a function that lets you fine-tune how long articles are to live, based on what group they are in. Let's say you want to have one month expiry period in the `mail.private' group, a one day expiry period in the `mail.junk' group, and a six day expiry period everywhere else:
(setq nnmail-expiry-wait-function (lambda (group) (cond ((string= group "mail.private") 31) ((string= group "mail.junk") 1) ((string= group "important") 'never) (t 6))))
The group names that this function is fed are "unadorned" group names--no `nnml:' prefixes and the like.
The nnmail-expiry-wait
variable and
nnmail-expiry-wait-function
function can be either a number (not
necessarily an integer) or the symbols immediate
or
never
.
You can also use the expiry-wait
group parameter to selectively
change the expiry period (see section Group Parameters).
If nnmail-keep-last-article
is non-nil
, Gnus will never
expire the final article in a mail newsgroup. This is to make life
easier for procmail users.
By the way, that line up there about Gnus never expiring non-expirable
articles is a lie. If you put 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
gnus-total-expirable-newsgroups
variable. All groups that match
this regexp will have all read articles put through the expiry process,
which means that 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
man! Or a woman! Whatever you feel more comfortable
with! So there!
Most people make most of their mail groups total-expirable, though.
Mailers and list servers are notorious for doing all sorts of really,
really stupid things with mail. "Hey, RFC822 doesn't explicitly
prohibit us from adding the string wE aRe ElItE!!!!!1!!
to the
end of all lines passing through our server, so let's do that!!!!1!"
Yes, but RFC822 wasn't designed to be read by morons. Things that were
considered to be self-evident were not discussed. So. Here we are.
Case in point: The German version of Microsoft Exchange adds `AW: ' to the subjects of replies instead of `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 disc. For that purpose, we have three hooks and various functions that can be put in these hooks.
nnmail-prepare-incoming-hook
nnheader-ms-strip-cr
nnmail-prepare-incoming-header-hook
nnmail-remove-leading-whitespace
nnmail-remove-list-identifiers
Subject
headers. I'm sure that's nice for
people who use stone age mail readers. This function will remove
strings that match the nnmail-list-identifiers
regexp, which can
also be a list of regexp.
For instance, if you want to remove the `(idm)' and the
`nagnagnag' identifiers:
(setq nnmail-list-identifiers '("(idm)" "nagnagnag"))
nnmail-remove-tabs
nnmail-prepare-incoming-message-hook
article-de-quoted-unreadable
If you are a member of a couple of mailing list, you will sometime
receive two copies of the same mail. This can be quite annoying, so
nnmail
checks for and treats any duplicates it might find. To do
this, it keeps a cache of old Message-ID
s---
nnmail-message-id-cache-file
, which is `~/.nnmail-cache' by
default. The approximate maximum number of Message-ID
s stored
there is controlled by the nnmail-message-id-cache-length
variable, which is 1000 by default. (So 1000 Message-ID
s will be
stored.) If all this sounds scary to you, you can set
nnmail-treat-duplicates
to warn
(which is what it is by
default), and 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 Message-ID
as a parameter. The function must return either
nil
, warn
, or delete
.
You can turn this feature off completely by setting the variable to
nil
.
If you want all the duplicate mails to be put into a special duplicates group, you could do that using the normal mail split methods:
(setq nnmail-split-fancy '(| ;; Messages duplicates go to a separate group. ("gnus-warning" "duplication of message" "duplicate") ;; Message from daemons, postmaster, and the like to another. (any mail "mail.misc") ;; Other rules. [ ... ] ))
Or something like:
(setq nnmail-split-methods '(("duplicates" "^Gnus-Warning:") ;; Other rules. [...]))
Here's a neat feature: If you know that the recipient reads her mail
with Gnus, and that she has nnmail-treat-duplicates
set to
delete
, you can send her as many insults as you like, just by
using a 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!
If you start using any of the mail backends, 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 nnmail-spool-file
to nil
, none of the backends
will ever attempt to read incoming mail, which should help.
This might be too much, if, for instance, you are reading mail quite
happily with nnml
and just want to peek at some old RMAIL
file you have stashed away with nnbabyl
. All backends have
variables called backend-get-new-mail
. If you want to disable
the nnbabyl
mail reading, you edit the virtual server for the
group to have a setting where nnbabyl-get-new-mail
to nil
.
All the mail backends will call nn
*-prepare-save-mail-hook
narrowed to the article to be saved before saving it when reading
incoming mail.
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.
The nnmbox backend will use the standard Un*x mbox file to store
mail. nnmbox
will add extra headers to each mail article to say
which group it belongs in.
Virtual server settings:
nnmbox-mbox-file
nnmbox-active-file
nnmbox-get-new-mail
nil
, nnmbox
will read incoming mail and split it
into groups.
The nnbabyl backend will use a babyl mail box (aka. rmail
mbox) to store mail. nnbabyl
will add extra headers to each mail
article to say which group it belongs in.
Virtual server settings:
nnbabyl-mbox-file
nnbabyl-active-file
nnbabyl-get-new-mail
nil
, nnbabyl
will read incoming mail.
The nnml spool mail format isn't compatible with any other known format. It should be used with some caution.
If you use this backend, Gnus will split all incoming mail into files;
one file for each mail, and put the articles into the correct
directories under the directory specified by the nnml-directory
variable. The default value is `~/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 backend. 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.
nnml
is probably the slowest backend when it comes to article
splitting. It has to create lots of files, and it also generates
NOV databases for the incoming mails. This makes is the fastest
backend when it comes to reading mail.
Virtual server settings:
nnml-directory
nnml
directories will be placed under this directory.
nnml-active-file
nnml
server.
nnml-newsgroups-file
nnml
group descriptions file. See section Newsgroups File Format.
nnml-get-new-mail
nil
, nnml
will read incoming mail.
nnml-nov-is-evil
nil
, this backend will ignore any NOV files.
nnml-nov-file-name
nnml-prepare-save-mail-hook
If your nnml
groups and NOV files get totally out of whack,
you can do a complete update by typing M-x
nnml-generate-nov-databases. This command will trawl through the
entire 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 (see section Server Commands).
nnmh
is just like nnml
, except that is doesn't generate
NOV databases and it doesn't keep an active file. This makes
nnmh
a much slower backend than nnml
, but it also
makes it easier to write procmail scripts for.
Virtual server settings:
nnmh-directory
nnmh
directories will be located under this directory.
nnmh-get-new-mail
nil
, nnmh
will read incoming mail.
nnmh-be-safe
nil
, 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 t
will mean a serious slow-down. If you never
use anything but Gnus to read the nnmh
articles, you do not have
to set this variable to t
.
nnfolder
is a backend for storing each mail group in a separate
file. Each file is in the standard Un*x mbox format. nnfolder
will add extra headers to keep track of article numbers and arrival
dates.
Virtual server settings:
nnfolder-directory
nnfolder
mail boxes will be stored under this directory.
nnfolder-active-file
nnfolder-newsgroups-file
nnfolder-get-new-mail
nil
, nnfolder
will read incoming mail.
If you have lots of nnfolder
-like files you'd like to read with
nnfolder
, you can use the M-x nnfolder-generate-active-file
command to make nnfolder
aware of all likely files in
nnfolder-directory
.
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.
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 ange-ftp
, that most
wonderful of all wonderful Emacs packages. When I wrote nndir
, I
didn't think much about it--a backend to read directories. Big deal.
ange-ftp
changes that picture dramatically. For instance, if you
enter the ange-ftp
file name
`/ftp.hpc.uh.edu:/pub/emacs/ding-list/' as the the directory name,
ange-ftp
will actually allow you to read this directory over at
`sina' as a newsgroup. Distributed news ahoy!
nndir
will use NOV files if they are present.
nndir
is a "read-only" backend--you can't delete or expire
articles with this method. You can use nnmh
or nnml
for
whatever you use nndir
for, so you could switch to any of those
methods if you feel the need to have a non-read-only nndir
.
From the nndir
backend (which reads a single spool-like
directory), it's just a hop and a skip to nneething
, which
pretends that any arbitrary directory is a newsgroup. Strange, but
true.
When nneething
is presented with a directory, it will scan this
directory and assign article numbers to each file. When you enter such
a group, nneething
must create "headers" that Gnus can use.
After all, Gnus is a newsreader, in case you're
forgetting. 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), 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 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., 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 nneething
group the
normal way with 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 nneething
group, you will
be told how many unread articles it contains, etc., etc.
Some variables:
nneething-map-file-directory
nneething
groups will be stored
in this directory, which defaults to `~/.nneething/'.
nneething-exclude-files
nneething-map-file
nndoc
is a cute little thing that will let you read a single file
as a newsgroup. Several files types are supported:
babyl
mbox
mmdf
news
rnews
forward
mime-digest
standard-digest
slack-digest
You can also use the special "file type" guess
, which means
that nndoc
will try to guess what file type it is looking at.
digest
means that nndoc
should guess what digest type the
file is.
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 backend, nndoc
can probably help you with
that. Say you have an old `RMAIL' file with mail that you now want
to split into your new nnml
groups. You look at that file using
nndoc
(using the G f command in the group buffer
(see section Foreign Groups)), set the process mark on all the articles in
the buffer (M P b, for instance), and then re-spool (B r)
using nnml
. If all goes well, all the mail in the `RMAIL'
file is now also stored in lots of nnml
directories, and you can
delete that pesky `RMAIL' file. If you have the guts!
Virtual server variables:
nndoc-article-type
mbox
, babyl
, digest
,
mmdf
, forward
, rfc934
, rfc822-forward
,
news
, rnews
, mime-digest
, clari-briefs
, or
guess
.
nndoc-post-type
mail
(the default)
and news
.
Adding new document types to be recognized by 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 nndoc
.
First, here's an example document type definition:
(mmdf (article-begin . "^\^A\^A\^A\^A\n") (body-end . "^\^A\^A\^A\^A\n"))
The definition is simply a unique 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:
first-article
nndoc
will skip past all text until it finds
something that match this regexp. All text before this will be
totally ignored.
article-begin
head-begin-function
nndoc-head-begin
nndoc-head-end
body-begin-function
body-begin
body-end-function
body-end
nndoc-file-end
So, using these variables 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:
prepare-body-function
article-transform-function
generate-head-function
Let's look at the most complicated example I can come up with--standard digests:
(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))
We see that all text before a 70-width line of dashes is ignored; all
text after a line that starts with that `^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 nndoc-unquote-dashes
before being delivered.
To hook your own document definition into nndoc
, use the
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 nndoc-TYPE-type-p
is called for each
type. So nndoc-mmdf-type-p
is called to see whether a document
is of mmdf
type, and so on. These type predicates should return
nil
if the document is not of the correct type; 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 `0' being the lowest legal number.
In the PC world people often talk about "offline" newsreaders. These are thingies that are combined reader/news transport monstrosities. With built-in modem programs. Yecchh!
Of course, us Unix Weenie types of human beans use things like
uucp
and, like, nntpd
and set up proper news and mail
transport things like Ghod intended. And then we just use normal
newsreaders.
However, it can sometimes be convenient to do something a that's a bit easier on the brain if you have a very slow modem, and you're not really that interested in doing things properly.
A file format called SOUP has been developed for transporting news and mail from servers to home machines and back again. It can be a bit fiddly.
First some terminology:
awk
program), or you
can use Gnus to create the packet with its SOUP commands (O
s and/or G s b; and then G s p) (see section SOUP Commands).
nnsoup
backend as
the native or secondary server.
So you basically have a bipartite system--you use nnsoup
for
reading and Gnus for packing/sending these SOUP packets.
nnsoup
to take over mail and news.
These are commands for creating and manipulating SOUP packets.
gnus-group-brew-soup
). This command understands the
process/prefix convention.
gnus-soup-save-areas
).
gnus-soup-send-replies
).
gnus-soup-pack-packet
).
nnsoup-pack-replies
).
gnus-soup-add-article
). It understands the process/prefix
convention (see section Process/Prefix).
There are a few variables to customize where Gnus will put all these thingies:
gnus-soup-directory
gnus-soup-replies-directory
gnus-soup-prefix-file
gnus-soup-packer
gnus-soup-unpacker
gnus-soup-packet-directory
gnus-soup-packet-regexp
gnus-soup-packet-directory
.
nnsoup
is the backend for reading SOUP packets. It will
read incoming packets, unpack them, and put them in a directory where
you can read them at leisure.
These are the variables you can use to customize its behavior:
nnsoup-tmp-directory
nnsoup
unpacks a SOUP packet, it does it in this
directory. (`/tmp/' by default.)
nnsoup-directory
nnsoup
then moves each message and index file to this directory.
The default is `~/SOUP/'.
nnsoup-replies-directory
nnsoup-replies-format-type
nnsoup-replies-index-type
nnsoup-active-file
nnsoup
stores lots of information. This is not an "active
file" in the nntp
sense; it's an Emacs Lisp file. If you lose
this file or mess it up in any way, you're dead. The default is
`~/SOUP/active'.
nnsoup-packer
nnsoup-unpacker
nnsoup-packet-directory
nnsoup
will look for incoming packets. The default is
`~/'.
nnsoup-packet-regexp
Just using nnsoup
won't mean that your postings and mailings end
up in SOUP reply packets automagically. You have to work a bit
more for that to happen.
The nnsoup-set-variables
command will set the appropriate
variables to ensure that all your followups and replies end up in the
SOUP system.
In specific, this is what it does:
(setq message-send-news-function 'nnsoup-request-post) (setq message-send-mail-function 'nnsoup-request-mail)
And that's it, really. If you only want news to go into the SOUP system you just use the first line. If you only want mail to be SOUPed you use the second.
It's, like, too neat to search the Usenet for articles that match a string, but it, like, totally 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 rad, rilly, searches without having to use a browser.
The nnweb
backend allows an easy interface to the mighty search
engine. You create an nnweb
group, enter a search pattern, and
then enter the group and read the articles like you would any normal
group. The G w command in the group buffer (see section Foreign Groups) will do this in an easy-to-use fashion.
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 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 (Duplicate
Suppression
) will help, since nnweb
doesn't even know the
Message-ID
of the articles before reading them using some search
engines (DejaNews, for instance). The only possible way to keep track
of which articles you've read is by scoring on the Date
header--mark all articles that were posted before the last date you
read the group as read.
If the search engine changes its output substantially, 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 raison d'être is to
make money off of advertisements, not to provide services to the
community. Since nnweb
washes the ads off all the articles, one
might think that the providers might be somewhat miffed. We'll see.
You must have the url
and w3
package installed to be able
to use nnweb
.
Virtual server variables:
nnweb-type
dejanews
, altavista
and reference
.
nnweb-search
nnweb-max-hits
nnweb-type-definition
nnweb
should do
with the various search engine types. The following elements must be
present:
article
map
search
address
id
Message-ID
.
If your local nntp
server doesn't allow posting, for some reason
or other, you can post using one of the numerous mail-to-news gateways.
The nngateway
backend provides the interface.
Note that you can't read anything from this backend--it can only be used to post with.
Server variables:
nngateway-address
nngateway-header-transformation
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 To
header based on the
Newsgroups
header and the gateway address--an article with this
Newsgroups
header:
Newsgroups: alt.religion.emacswill get this
From
header inserted:
To: alt-religion-emacs@GATEWAY
So, to use this, simply say something like:
(setq gnus-post-method '(nngateway "GATEWAY.ADDRESS"))
Gnus allows combining a mixture of all the other group types into bigger groups.
An nnvirtual group is really nothing more than a collection of other groups.
For instance, if you are tired of reading many small group, 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 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.)
Here's an example nnvirtual
method that collects all Andrea Dworkin
newsgroups into one, big, happy newsgroup:
(nnvirtual "^alt\\.fan\\.andrea-dworkin$\\|^rec\\.dworkin.*")
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 `soc.motss' both from a server in Japan and a server in Norway, you could use the following as the group regexp:
"^nntp+some.server.jp:soc.motss$\\|^nntp+some.server.no:soc.motss$"
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 (see section Selecting a Group.
One limitation, however--all groups that are included in a virtual
group has to be alive (i.e., subscribed or unsubscribed). Killed or
zombie groups can't be component groups for nnvirtual
groups.
If the nnvirtual-always-rescan
is non-nil
,
nnvirtual
will always scan groups for unread articles when
entering a virtual group. If this variable is nil
(which is the
default) and you read articles in a component group after the virtual
group has been activated, the read articles from the component group
will show up when you enter the virtual group. You'll also see this
effect if you have two virtual groups that contain the same component
group. If that's the case, you should set this variable to t
.
Or you can just tap M-g
on the virtual group every time before
you enter it--it'll have much the same effect.
Kibozing is defined by OED as "grepping through (parts of)
the news feed". nnkiboze
is a backend that will do this for
you. Oh joy! Now you can grind any NNTP server down to a halt
with useless requests! Oh happiness!
To create a kibozed group, use the G k command in the group buffer.
The address field of the nnkiboze
method is, as with
nnvirtual
, a regexp to match groups to be "included" in the
nnkiboze
group. There most similarities between nnkiboze
and nnvirtual
ends.
In addition to this regexp detailing component groups, an nnkiboze
group
must have a score file to say what articles that are to be included in
the group (see section Scoring).
You must run M-x nnkiboze-generate-groups after creating the
nnkiboze
groups you want to have. This command will take time. Lots of
time. Oodles and oodles of time. Gnus has to fetch the headers from
all the articles in all the components groups and run them through the
scoring process to determine if there are any articles in the groups
that are to be part of the nnkiboze
groups.
Please limit the number of component groups by using restrictive regexps. Otherwise your sysadmin may become annoyed with you, and the NNTP site may throw you off and never let you back in again. Stranger things have happened.
nnkiboze
component groups do not have to be alive--they can be dead,
and they can be foreign. No restrictions.
The generation of an nnkiboze
group means writing two files in
nnkiboze-directory
, which is `~/News/' by default. One
contains the NOV header lines for all the articles in the group,
and the other is an additional `.newsrc' file to store information
on what groups that have been searched through to find component
articles.
Articles that are marked as read in the nnkiboze
group will have their
NOV lines removed from the NOV file.
Go to the first, previous, next, last section, table of contents.