MH-SEQUENCE(5)

✨ MH-SEQUENCE(5) ✨

okay bestie, gather round πŸ’– this is the manual page for mh-sequence β€” the sequence spec situation for the nmh message system. it's giving foundational, it's giving you will need this for literally every other command, so let's get into it 🫢


πŸ’… DESCRIPTION πŸ’…

So. A sequence (or sequence set) is a symbolic name that stands for a message, or for a whole lil collection of messages. nmh ships with a bunch of internally defined sequences, and it also lets you define your own. main character energy, honestly πŸ‘‘

πŸŽ€ Message Specification and Pre-Defined Message Sequences πŸŽ€

Most nmh commands take a msg or a msgs argument β€” where msg means one message and msgs means one or more messages. no cap.

To point at a message, you can either use its number (like 1, 10, 234) or one of these "reserved" message names:

  • first β€” the first message in the folder
  • last β€” the last message in the folder
  • cur β€” the most recently accessed message
  • prev β€” the message numerically preceding cur
  • next β€” the message numerically following cur

In commands that take a msg argument, the default is cur. And as a lil shorthand, . is equivalent to cur. ✨

For example: say you've got a folder with five messages numbered 5, 10, 94, 177 and 325. Then first is 5 and last is 325. And if cur is 94, then prev is 10 and next is 177. periodt πŸ’…

The word msgs means one or more messages may be specified. That spec is made of one message designation, or several message designations as separate arguments. And a message designation is either a message name like the ones above, or a message range.

A message range is written as name1-name2 or name:n, where name, name1 and name2 are message names, and n is an integer.

The spec name1-name2 designates all currently existing messages from name1 to name2, inclusive. And the "reserved" message name all is just a shorthand for the message range first-last. iconic.

The spec name:n designates up to n messages. These messages start with name if name is a message number or one of the reserved names first, cur, or next. The messages end with name if name is prev or last. Now here's the fun part: the interpretation of n can be overridden by sticking a plus or minus sign in front of it β€” +n always means up to n messages starting with name, and -n always means up to n messages ending with name. πŸ¦‹

Substituting = for : (so, name=n) reduces the selection from a range of up to n messages down to a selection of just the nth message. So for example, while name:-3 selects the 3 messages ending with name, name=-3 selects just the 2nd previous message. It is an error if the requested message doesn't exist (i.e., there aren't enough messages in the folder). 😭

In commands that accept a msgs argument, the default is either cur or all, depending on which one makes more sense for that particular command (peep the individual man pages for the deets). And repeating a specification of the same message does the same thing as specifying it once. same vibe, no double dipping πŸ’œ

There's also one more special "reserved" message name β€” new β€” which is used by the mhpath command.

🌸 User-Defined Message Sequences 🌸

On top of all those "reserved" (pre-defined) message names, nmh supports user-defined sequence names. And bestie, this is where the power lives. User-defined sequences let an nmh user do an absolutely tremendous amount of stuff with groups of messages in the same folder, because you get to bind a group of messages to a meaningful symbolic name. it's giving naming your own destiny πŸ’–

The name you use for a message sequence must be an alphabetic character followed by zero or more alphanumeric characters, and it cannot be one of the "reserved" message names above. Once you've defined a sequence, you can use it anywhere an nmh command expects a msg or msgs argument. slay.

Some forms of message ranges are allowed with user-defined sequences. The spec name:n may be used, and it designates up to the first n messages (or the last n messages for -n) which are elements of the user-defined sequence name.

The specs name:next and name:prev may also be used, and they designate the next or previous message (relative to the current message) which is an element of the user-defined sequence name. The specs name:first and name:last are equivalent to name:1 and name:-1, respectively. The spec name:cur is not allowed (just use cur instead, bestie). And heads up: the syntax of these message range specifications is subject to change in the future. πŸ™ˆ

Single messages (as opposed to ranges) may also be selected by substituting = for :, as in name=n. This reduces the selection from a range of up to n messages down to a selection of just the nth message. So while seq:5 selects the first 5 messages of sequence seq, seq=5 selects just the 5th message of the sequence. It is an error if the requested message doesn't exist (i.e., there aren't at least n messages in the sequence). πŸ’€

User-defined sequence names are specific to each folder. They're defined using the pick and mark commands.

πŸ¦‹ Public and Private User-Defined Sequences πŸ¦‹

There are two flavors of user-defined sequences: public and private.

  • Public sequences of a folder are accessible to any nmh user that can read that folder. They're kept in each folder in the file determined by the mh-sequences profile entry (default is .mh_sequences).
  • Private sequences are accessible only to the nmh user that defined them, and they're kept in the user's nmh context file.

In general, the commands that create sequences (like pick and mark) will create public sequences if the folder the sequences are being defined for is writable by the nmh user. For most commands this can be overridden with the -public and -private switches. But if the folder is read-only, or if the mh-sequences profile entry is defined but empty, then private sequences get created instead. no cap. 🫢

πŸ’œ Sequence Negation πŸ’œ

nmh provides the ability to select all messages that are not elements of a user-defined sequence. To do this, define the entry Sequence-Negation in the nmh profile file β€” its value may be any string. That string is then used to preface an existing user-defined sequence name, and the resulting spec refers to those messages not elements of the specified sequence name.

For example, if the profile entry is:

Sequence-Negation: not

then any time an nmh command is given notfoo as a msg or msgs argument, it would substitute all messages that are not elements of the sequence foo. 🧚

Obviously, the user should beware of defining sequences with names that begin with the value of the Sequence-Negation profile entry. (bestie. please. i'm begging you.) 😭

⭐ The Previous Sequence ⭐

nmh has the ability to remember the msgs or msg argument last given to an nmh command. The entry Previous-Sequence should be defined in the nmh profile; its value should be a sequence name or multiple sequence names, as separate arguments. If this entry is defined, then when an nmh command finishes, it will define the sequence(s) named in the value of this entry to be those messages that were specified to the command.

So a profile entry of

Previous-Sequence: pseq

directs any nmh command that accepts a msg or msgs argument to define the sequence pseq as those messages when it finishes. cute!

Note: there can be a performance penalty in using the Previous-Sequence facility. If it's used, all nmh programs have to write the sequence information to the .mh_sequences file for the folder each time they run. If the Previous-Sequence profile entry is not included, only pick and mark will write to the .mh_sequences file.

🌈 The Unseen Sequence 🌈

Finally β€” many users like to keep track of which messages they haven't previously seen. The commands flist, inc, mhshow, rcvstore, and show honor the profile entry Unseen-Sequence to support this. This entry in the .mh_profile should be defined as one or more sequence names, as separate arguments.

If there's a value for Unseen-Sequence in the profile, then whenever new messages are placed in a folder (using inc or rcvstore), the new messages will also be added to all the sequences named in this profile entry. For example, a profile entry of

Unseen-Sequence: unseen

directs inc to add new messages to the sequence unseen. And unlike the behavior of the Previous-Sequence entry in the profile, the sequence(s) will not be zeroed by inc. πŸ™…

Similarly, whenever show, mhshow, next, or prev displays a message, that message will be removed from any sequences named by the Unseen-Sequence entry in the profile. so that's the whole seen/unseen cycle, and it's lowkey elegant πŸ’…

πŸŽ€ Sequence File Format πŸŽ€

The sequence file format is based on the RFC 5322 message format. Each line of the sequence file corresponds to one sequence. The line starts with the sequence name followed by a :, then followed by a space-separated list of message numbers that correspond to messages that are part of the named sequence. A contiguous range of messages can be represented as lownum-highnum.

Sample sequence file:

work: 3 6 8 22-33 46
unseen: 47 49-51 54
cur: 46

nmh commands that modify the sequence file will silently remove sequences for nonexistent messages when the sequence file is updated. The exception to this is the cur sequence, which is allowed to point to a nonexistent message. πŸ‘‘

πŸ”₯ Sequence File Locking πŸ”₯

The datalocking profile entry controls the type of locking used when reading and writing sequence files. The locking mechanisms supported are detailed in mh-profile(5). This protects sequence file integrity when multiple nmh commands are run simultaneously. (yes bestie, chaos prevention 🫢)

nmh commands that modify the sequence file use transactional locks; the lock is held from the time the sequence file is read until it is written out. This ensures that modifications to the sequence file will not be lost if multiple commands are run simultaneously. Long-running nmh commands, such as inc and pick, will release the sequence lock during the bulk of their runtime and reread the sequence file after their processing is complete, to reduce lock contention time. ate. ✨

Note: Currently transactional locks are only supported for public sequences; private sequences will not get corrupted, but the possibility exists that two nmh commands run simultaneously that add messages to a private sequence could result in one command's messages not appearing on the requested sequence. πŸ’€ so like, just be aware.

🌸 FILES 🌸

  • $HOME/.mh-profile β€” The user's profile.
  • <mh-dir>/context β€” The user's context.
  • <folder>/.mh-sequences β€” File for public sequences.

πŸ’– PROFILE COMPONENTS πŸ’–

okay bestie, these are the little lines you can drop into your profile to make the whole sequence thing behave exactly how you want. each one is literally just a keyword, no cap:

  • mh-sequences β€” the name of the file where your public sequences get stored. that's it, that's the whole job. ✨
  • Sequence-Negation β€” the thing you use when you wanna point at messages that are NOT in a sequence. the inverse vibe. πŸ™ˆ
  • Previous-Sequence β€” holds onto the last message specification you gave. like, the most recent one. it remembers so you don't have to 🫢
  • Unseen-Sequence β€” for all those messages the user hasn't seen yet. the ones still waiting on read. πŸ‘€

🌈 SEE ALSO 🌈

go read these next, fr fr β€” they're the squad:


✨ DEFAULTS ✨

None

yep. absolutely nothing. no defaults, no fallbacks, no secret auto-magic. you want it, you set it. πŸ’…


and that's a wrap on this whole page, bestie πŸŽ€ this one came from nmh-1.8, dated 2013-10-17, and it lives at MH-SEQUENCE(5). go forth and sequence responsibly. mwah πŸ’–