MH-SEQUENCE(5mh)

πŸ“¦
version 1.8 Β· 3 versions
, in debian trixie, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

MH-SEQUENCE β€” the mh-sequence(5mh) page πŸ’…

ok bestie, so this is the whole entire vibe on sequences in the nmh message system. Sit down, grab a strawberry πŸ“, we're doing this.

✨ NAME ✨

mh-sequence β€” sequence specification for the nmh message system πŸŽ€


πŸ’– DESCRIPTION πŸ’–

A sequence (or sequence set, same thing, we're not doing formalities here) is a symbolic name that stands in for a message or a whole lil collection of messages. nmh ships with several sequences baked in, and also lets you β€” yes you, the main character πŸ‘‘ β€” define your own.

🌸 Message Specification and Pre-Defined Message Sequences 🌸

Most nmh commands will take a msg or a msgs argument. msg means one message, msgs means one or more. To point at a message you can either use its number (like 1, 10, 234, whatever) or one of these β€œreserved” names, which are lowkey iconic:

  • 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”

For commands that take a msg argument, the default is cur. And as a cute shorthand, . is literally the same as cur.

Example time, bestie: 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. slay, math is math ✨

Now, the word msgs means you can specify one or more messages. That spec is either one message designation, or several message designations as separate arguments. And a message designation is either a message name (as defined above) or a message range.

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

The spec name1-name2 grabs all currently existing messages from name1 to name2, inclusive. And the β€œreserved” name all is just shorthand for the range first-last.

The spec name:n grabs up to n messages. These start with name if name is a message number or one of the reserved names first, cur, or next. They end with name if name is prev or last. And you can override how n gets interpreted by sticking a plus or minus 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. Periodt.

Swapping = in for : (so, name=n) shrinks the selection from a range of up to n messages down to just the nth message. So like, while name:-3 selects the 3 messages ending with name, name=-3 selects just the 2nd previous message. And it is an error if the requested message doesn't exist β€” meaning there aren't enough messages in the folder. πŸ’€

In commands that accept a msgs argument, the default is either cur or all, depending on whichever makes more sense for that particular command (peep the individual man pages for the deets). And specifying the same message over and over does the exact same thing as specifying it once. No stacking, no bonus points, sorry.

There's also a special β€œreserved” message name new, which gets used by the mhpath command. πŸ¦‹

πŸ¦‹ User-Defined Message Sequences πŸ¦‹

On top of the β€œreserved” (pre-defined) names above, nmh supports user-defined sequence names. And bestie, this is where the power lives β€” you can bind a whole group of messages in the same folder to a meaningful symbolic name. It's giving organization. It's giving control.

The name you use for a message sequence has to be an alphabetic character followed by zero or more alphanumeric characters, and it can't 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.

Some forms of message ranges work with user-defined sequences too:

  • The spec name:n may be used, and it designates up to the first n messages (or the last n messages for -n) that 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) that 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, babe).
Heads up: the syntax of these message range specifications is subject to change in the future. πŸ‘€

Single messages (as opposed to ranges) can also be selected by swapping = in for :, like name=n. That shrinks the selection from being a range of up to n messages to being 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. And again β€” it's 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, so they don't roam around. They get defined using the pick and mark commands. πŸ’…

πŸŽ€ Public and Private User-Defined Sequences πŸŽ€

There are two flavours 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 you can override this with the switches -public and -private. BUT β€” if the folder is read-only, or if the mh-sequences profile entry is defined but empty, then private sequences get created instead. The universe has decided. 🌈

⭐ Sequence Negation ⭐

nmh lets you select all messages that are not elements of a user-defined sequence. To do it, you define the entry Sequence-Negation in the nmh profile file β€” its value can be any string. That string then gets used to preface an existing user-defined sequence name, and the whole spec refers to those messages that are not elements of the specified sequence name.

For example, if the profile entry is:

Sequence-Negation: not

then any time an nmh command gets notfoo as a msg or msgs argument, it would substitute all messages that are not elements of the sequence foo. chef's kiss 😌

Obviously, bestie, beware of defining sequences with names that begin with the value of the Sequence-Negation profile entry. That's just asking for chaos. πŸ™ˆ

πŸ’œ The Previous Sequence πŸ’œ

nmh can 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. iconic behaviour tbh.

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 every single time they run. If the Previous-Sequence profile entry is not included, only pick and mark will write to the .mh_sequences file. So like… choose wisely. πŸ’€

🫢 The Unseen Sequence 🫢

Finally (well, for this part), lots of users like to keep track of which messages they haven't seen yet. The commands flist, inc, mhshow, rcvstore, and show all 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. Unlike the behavior of the Previous-Sequence entry in the profile, though, the sequence(s) will not be zeroed by inc.

Similarly, whenever show, mhshow, next, or prev displays a message, that message gets removed from any sequences named by the Unseen-Sequence entry in the profile. bye girl, you've been seen πŸ‘‹

🌈 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 corresponding to messages that are part of the named sequence. And a contiguous range of messages can be represented as lownum-highnum. cute, efficient, we love.

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. Special little guy, gets special rules. 🧚

πŸ’… 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.

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 won't 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.

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. 😭

πŸŽ€ 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 profile entries that make the sequence magic happen. Four of them. Not three, not five. Four. Count them. πŸ’…

  • mh-sequences β€” this is the name of the file where your public sequences get stored. That's it, that's the job. It's the little home where the sequences that everybody can see go to live. 🏠✨
  • Sequence-Negation β€” used to designate messages that are not in a sequence. Yes queen, sometimes you gotta define a thing by what it isn't. The way that negation works?? Iconic. πŸ™ˆ
  • Previous-Sequence β€” holds the last message specification given. So like, whatever you specified most recently? That. It remembers it for you so you don't have to. Memory of a goldfish but make it a profile component. 🐠
  • Unseen-Sequence β€” the ones the user hasn't seen yet. Those messages. Still sitting there. Unread. Waiting for you like πŸ‘€. The unseen ones, fr fr.

πŸ¦‹ SEE ALSO πŸ¦‹

Go read these too, they're all part of the same friend group:


⭐ DEFAULTS ⭐

None.

Literally none. No defaults. Zero. Zilch. Nada. The default is that there are no defaults, and honestly? That's a vibe. 🌈


And that's the whole page, bestie β€” this was nmh-1.8, dated 2013-10-17, and yes she's an elder but she still eats. πŸ’– Go forth and sequence responsibly. 🫢✨

πŸ“¦ where this page comes from