MH & nmh: Email for Users & Programmers

May, 2006

More About Sequences

As you saw in the previous sections, an MH sequence is a list of message numbers. You choose names for the sequences. When you want to use the messages in the sequence, you can type the sequence name instead of typing all the numbers. Each folder can have up to 26 sequences (in earlier MH versions and on systems that aren't 32-bit, the limit is 10). Each sequence can have hundreds of messages. A sequence name can be made of letters only; it can't be one of the reserved message names like first, last, and so on (see the Section Find and Specify with scan, pick, Ranges, Sequences). This section has examples. Newer versions of the mh-sequence(5) manual page have a complete description; if you have an old version, see the Section Online Manual Pages.

Sequences are great for keeping track of certain messages -- temporarily or for weeks or months. In my user-consulting job, for instance, we kept a sequence named common in each folder -- a list of messages which answer common questions that we might want to reuse:

    % scan common +file_xfr
       3  03/23 To:ann@suxpr.mar.  Re: FTP in the background<<> Is
      19  06/02 To:xvhang          Re: UUEncode<<> Can Quark handle
      61  11/13 To:carolo          Re: .arc unpacking<<> A while ba
      63  11/17 To:danr            Re: shar type file packager<<Tha
      85  01/15 To:Rudy Valleyfor  Re: 7 & 8 bit switches<<> It is
You've seen that the pick command can create or add to sequences. The other MH command for working with sequences is mark. With mark, you can create, add messages to, delete messages from, or remove sequences.

Adding Messages to a Sequence

You can add messages to a sequence with mark -add. There are two ways to add messages to a sequence: -zero and -nozero.

If the sequence already exists and you want to change it completely, the -zero switch deletes any old message numbers from the list before adding the new ones. Or, to merge messages to an existing sequence without deleting existing message numbers, use -nozero. By default, mark uses -nozero. (The pick default is -zero.)

Here's an example. First pick creates or replaces a sequence named picked; it stores the message numbers from alison. Second, pick adds the message from steven to the same sequence. Third, the mark command adds the current message to the sequence. (If you don't tell mark which one to add, it adds the current message.) Fourth, I use scan to see what's in the sequence. Finally, I start forw to forward copies of the messages (4, 21, 23, 44) to allan@mukluk.bitnet, as shown in the following example:

    % pick -from alison -sequence picked
    2 hits
    % pick -from steven -sequence picked -nozero
    1 hit
    % mark -add -sequence picked
    % scan picked
       4  03/21 Alison Cosgreave   What's happening here at UMass<<
      21  04/01 Steven Dommer      Re: meeting minutes<<> A while ba
      23  04/02 Alison Cosgreave   Re: What's happening at Tek<<Not
      44+ 04/29  What we talked about at lunch<<Jo
    % forw picked
    To: allan@mukluk.bitnet
    Subject: Messages from Alison, Steven, and me
If you give mark the -sequence option, the default action is -add. (Otherwise, the default is -list.) So, to add messages 12-25 to the foo sequence, you can type:
    % mark -seq foo 12-25
Sometimes I need to save a message number in a folder that I can come back to later. The Section Make Message Bookmarks with mark shows an easy way to do that with a one-message sequence named here.

Deleting Messages from a Sequence

A message is automatically deleted from a sequence when you use commands like rmm or refile on the message -- if the message is removed from the folder, the sequence is updated for you. (The cur sequence (for the current message number, explained in Section The cur Sequence) won't be deleted.)

To take messages out of a sequence yourself, use mark -delete. To remove one or a few messages, just give the message numbers -- the first command below removes message numbers 1 and 3 from the sequence called info. To remove a sequence completely, use the sequence name as the message range -- as in the second command below, which removes the temp sequence from your current folder. Remember that you can abbreviate MH switches (in fact, you can abbreviate most mark switches to single letters, though I haven't here):

    % mark -del -seq info 1 3
    % mark -del -seq temp temp
There's a weird twist that you should know about. If you use -zero with -delete, it will add all messages from the folder to the sequence except the messages you name. An example will help here. Let's say that your current folder has messages numbered 1 through 10. The command:
    % mark -delete -zero -sequence most 1
would put messages 2 through 10 in the sequence called most. Even more surprising, that command will create the sequence if it doesn't exist!

You can delete from (or add to) more than one sequence at a time. For example, to remove all messages from the sequences march and april (and thereby remove the sequences too), type the following:

    % mark -del all -seq march -seq april

Listing Sequences

The switch -list shows you what's in one or more sequences. If you don't give a sequence name, it shows all sequences in your current folder:

    % mark -list
    cur: 2
    info: 4 6
    myinfo: 12-18 20 25-36
    % mark -list -sequence info
    info: 4 6
In fact, if you don't give a -sequence switch, the default is -list. So, to get a list of all sequences, just type mark.

The mark -list command lists message numbers two ways: in ranges like 12-18, and in single message numbers like 6. For example, the info sequence above has messages 4 and 6 in it. The myinfo sequence has messages 12, 13, 14, 15, 16, 17, and 18; message 20; and messages 25 through 36, inclusive.

The message ranges in mark -list output always contain exactly those messages, with no gaps. For instance, if your folder has messages 12, 14, and 16 in it, mark -list will always list those as:

    seqname: 12 14 16
and never as:
    seqname: 12-16
The special sequence named cur holds the current message number for the folder.

Previous-Sequence, Sequence-Negation

Here are two handy entries you can add to your MH profile.

If you edit your MH profile and add an entry like this:

    Previous-Sequence: pseq
then MH will save the message numbers from the previous MH command in a sequence named pseq (you can use any legal sequence name; I just like pseq). For example, if you scan four messages, you can show all of them on the next command line without typing their numbers -- just use pseq:
    % scan 1 2 113 227
       1  01/09 Joe Doe            Test message<<Hi!>>
       2  01/09 Joe Doe            Another test<<Well, this is anot
     113+ 01/11 Joe Doe            The latest on my project<<It's g
     227  01/13 Joe Doe            <<I can't get MH to work so I'm
    % show pseq
        ...Messages 1, 2, 113, 227 appear...
    % mark -list -seq pseq
    pseq: 1-2 113 227
NOTE: A Previous-Sequence: entry can cause trouble if your folders have hundreds or thousands of messages with gaps in the numbering. If you run a command like scan or refile all in those folders, MH puts a complete listing of all the folder's message numbers on a single line in the .mh_sequences file, like this:
      pseq: 1-2 5-7 9 12-16 18 20 25 31-33 36 39 45 47-61 ...
If the line gets too long, you'll see the error message xxx/.mh_sequences is poorly formatted.

To prevent this, keep big folders packed with folder -pack. Then the .mh_sequences line will look like this:

      pseq: 1-105

If the line gets too long, use the following five commands to delete the long line from the .mh_sequences file and pack the folder (these commands assume that your previous sequence is named pseq):

      % cd `mhpath`
      % mv .mh_sequences temp_sequences
      % sed /pseq:/d temp_sequences > .mh_sequences
      % folder -pack
      % rm temp_sequences
(If you aren't confident about this, check with an expert first.) I used the command sed /pseq:/d instead of grep -v pseq: because some versions of grep truncate long lines.

Here's the other useful entry. If you put something like this in your MH profile:

    Sequence-Negation: not
and put not before the name of a sequence, MH will use all messages from the current folder that are not in the sequence. For example, if your folder has messages numbered 1 through 10 and the sequence named important has messages 1, 3, 5, 7, and 9 in it, then typing the following line:
    % refile notimportant +junk
would move messages 2, 4, 6, 8, and 10 into the junk folder.

The sequence-negation shouldn't be part of a sequence name you already use. For example, a sequence named notes starts with the characters not, so not would be a bad sequence-negation. You can use nonalphabetic sequence-negation characters, like the exclamation point (!) and the tilde (~), but your shell may treat those as special characters and force you to type a backslash (\) before them. For example, if you set this entry in your MH profile:

    Sequence-Negation: !
the C shell makes you type \! before a sequence name, like this:
    % scan \!important
One compromise is a colon (:) character:
    Sequence-Negation: :
In the previous example, you could have typed the following cryptic-looking command:
    % refile :important +junk
If you never start your folder names with an uppercase X, you might use that letter for a sequence-negation, so a negated sequence could look like Ximportant.

The unseen Sequence

The inc command -- together with the show, next, and prev commands -- can cooperate to keep a sequence of all the messages which have never been read in a folder. For instance, this is a good way to be sure that you've read every message in your inbox. Read about the unseen sequence in the Section Messages You Haven't Read.

The cur Sequence

The current message number in each folder is kept in a sequence called cur. Each folder has its own cur sequence -- a single message number. MH commands update this sequence automatically.

A folder doesn't always have a cur sequence. For instance, when you first make a new folder, it won't have a current message.

If you remove or refile the current message, the cur sequence will not be deleted, though. That's so commands like next and prev will still be able to find the next or previous message.

Public and Private Sequences

The Section Sharing Other Users' Folders explains that useful MH capability. If anyone is sharing your mail folders and you make a sequence, the other person will be able to use the sequence too. This is called a public sequence. (If you've set your Mail directory and/or folders so that no one can access them, don't be concerned -- the name "public" doesn't mean that other users can override your security.)

(Public sequences are stored in a file named .mh_sequences in the folder directory. The .mh_sequences is mode 644, but users won't be able to read it unless they have access to the top-level mail directory and the folder. Private sequences are stored in the file named context in the user's MH directory. The context file is mode 600, and each user has his/her own context file; other users' context files are never used. See the Figure Important parts of a UNIX filesystem.)

When you define a sequence, or add to one, you can use the switch -nopublic to make it private. If the sequence was public before, now it'll be private.

Here's an example that shows the user of mark -nopublic changing a sequence from public to private. Compare the listings for the myinfo sequence in the two mark -list outputs:

    % mark -list
    cur: 2
    info: 4 6
    myinfo: 4-6
    % mark -add -seq myinfo -nopublic 8
    % mark -list
    cur: 2
    info: 4 6
    myinfo (private): 4-6 8
There is a bug in MH 6.6 through MH 6.8.3 (and maybe others). If you give mark -list the name of a private sequence, it won't show you that it's (private). Compare the listings of the previous myinfo sequence to the following:
    % mark -list -seq myinfo
    myinfo: 4-6 8
To make all sequences private, add the empty entry:
to your MH profile. See the Section Changing MH Directory Name for an example of where this is useful.

Searching for Sequences with flist

The flist program, which comes with nmh and exmh, summarizes sequence(s) in folder(s). (flist has evolved a lot, so watch for differences in your version. I'll explain the nmh-1.0 version of flist.) Probably the main use is to find which folders have messages that haven't been read -- messages listed in the unseen sequence. For example:

    % flist -all
    drafts          has   0 in sequence unseen; out of    2
    inbox+          has  50 in sequence unseen; out of  168
    jobs            has   0 in sequence unseen; out of    0
By default, flist searches just your current folder. To search all top-level folders, type flist -all or flists. To search subfolders, too, add the -recurse switch. Or, to search specific folders, name them (like +folder1 +folder2) on the command line. If you give both -all and one or more +folders, then flist will search the named folder(s) and all first-level subfolders; this can be faster than a complete recursive search of a deep folder tree.

flist will list folders that have no messages in the sequence ("0 in sequence unseen") unless you give the -noshowzero switch.

flist can check other sequences than unseen. For instance, to see which messages are in the urgent sequence, use flist -sequence urgent. To search more than one sequence, give multiple -sequence seqname arguments.

The -fast switch tells flist to show only the names of the folders it searches. This is handy when you also use -noshowzero; the combination prints the names of folders that contain messages in at least one of the sequences that flist checked. For example, here's a shell loop to scan all folders with those urgent messages:

    $ for folder in `flist -all -sequence urgent -fast -noshowzero`
    > do echo ========= $folder ===========
    > scan +$folder urgent
    > done
    ========= beta ===========
     121  09/17 Paula Robertson    Handle my duties next week? **rfl digest**
     147+ 09/24 To:webmaster       Broken links in update page<<Hello -- In the 
    ========= sys ===========
      80+ 09/24 Operator           alvernon hanging<<Jerry, The alvernon system
The folder names are sorted alphabetically if you use the -alpha switch or if you don't have an Flist-Order: entry in your MH profile. If you put an Flist-Order: entry in your MH profile, flist will prioritize the folders in that order. Each item in the Flist-Order: is either a folder name or a folder name pattern. The pattern uses * to match zero or more characters, just like shell filename wildcards. Longer matching patterns have precedence over shorter matching patterns. Here's an example from the flist manpage:
    Flist-Order: personal petproject mh* * admin *junk
This order puts a few interesting folders first: mail addressed to you personally, mail about a pet project, and mh-related things. It shoves uninteresting folders (names ending with junk) to the end, and it puts all other folders (the * by itself) in the middle in alphabetical order.
CAUTION: flist (with nmh-1.0, and probably before) doesn't understand relative folder names like @subfolder or @... For instance, flist @january won't change to the subfolder named january; it will set the current folder name to (literally) @january. Then, if you try to use any other nmh commands, they'll ask "Create folder @january?".

The workaround is to first change the current folder (for instance, with folder -fast @january), then run flist.