# Showing and Printing Messages

By default, the show command puts all of your message, including "boring" header fields like `Received:`, onto your screen.

You can change the way that your message is shown by deleting these header fields, folding lines that are too long for your terminal, and so on. You can print your messages with neat margins and a header line at the top of the page. Here's how MH displays non-MIME messages. This is good background for the Section Reading MIME Messages, which explains how MIME messages are displayed.

## The Current Message

When you show a message with show, it becomes the current message. When you show a message with next or prev, MH actually runs the commands show next and show prev, respectively -- which also reset the current message. If you show a group of messages by typing, for example:

        % show 1 3 5
            ...

the last message (5) becomes the current message.

## Messages You Haven't Read

MH can track which messages you haven't read yet. When you incorporate new mail, the message numbers are added to a sequence automatically. rcvstore, which puts new mail into folders automatically, also adds messages to this sequence. As you read the messages (with show, next, and prev), the message numbers are taken out of the sequence. See the Section More About Sequences.

To set this up, pick a name for the unseen sequence (I call mine unseen).

(Note that MH will keep more than one unseen sequence, if you need that. Add other sequence names to the `Unseen-Sequence:` entry, separated with spaces. All the unseen sequences will have the same message lists in them. You can use the mark program to modify one or more of them, though.)

Put an entry in your MH profile:

        Unseen-Sequence: unseen

Remember that in MH, you can use a sequence name any place you can use message numbers. For example, to get a list of the messages you haven't read, you can use:

        % scan unseen

If you have MH 6.7.2 or later, you can tack on a range specification like `:first` or `:last`. For instance, to read the first unseen message, remove it, then read the rest of the unseen messages one-by-one:

`% show unseen:first`
...
`% rmm`
`% show unseen:next`
...
`% rmm`
`% !s` C shell history: repeats previous show command
...

If you've already read some of the messages -- that is, there are "gaps" in the unseen messages, `show unseen:next` will step through the unseen messages. When you've seen all the messages, you'll get "show: no unseen:next message."

Would you like an automatic list of your unread messages as you log in? Use lines like those in the Example below to your .login or .profile file. If there are messages in your unseen sequence, you'll get a scan listing.

Examples: Automatic scan of unread messages
C shell

        mhpath unseen +inbox >& /dev/null
        if ($status == 0) then
            echo "Unseen mail in inbox:"
            scan +inbox unseen
        endif

Bourne and Korn shells:

        if mhpath unseen +inbox >/dev/null 2>&1
        then
            echo "Unseen mail in inbox:"
            scan +inbox unseen
        fi

The flist command will list all folders that have messages in the unseen sequence.

Each folder keeps its own unseen sequence, but it's mostly useful in folders that get new mail. As of this writing, no version of xmh supports the unseen sequence.

## Weeding Out Before You Read

Do you get a group of messages you don't want -- system status reports that usually aren't worth reading, test messages to yourself, and so on? You might want to remove all of them with a .maildelivery file, as explained in the Chapter Processing New Mail Automatically. The Example below shows how you can decide, though, before removing some or all of the batch. (The same trick works for refiling, printing, and so on -- not just for removing.)

Our system manager and I get status reports from uucp. I ignore them unless he's out of the office. This Example shows how I delete them quickly:

Example: Finding and handling a group of messages quickly

        % inc
        Incorporating new mail into inbox...
         155+ 01/09 uucp               uu-status<<LCK..cuZ2: 23283 LCK..cuZ3
            ...
         189  01/09 Tim O'Reilly       New edition of MH & xmh<<How are the
        % pick -from uucp -seq temp cur-last
        12 hits
        % scan temp
         155+ 01/09 uucp               uu-status<<LCK..cuZ2: 23283 LCK..cuZ3
            ... more messages from uucp...
        % rmm temp

First I find the messages with pick and store them in the temp sequence. (I use `pick cur-last` because that'll be all the messages inc brought in. As the Section Messages You Haven't Read explains, `pick unseen` would check the same messages -- though it might also include older messages I hadn't read yet.) A quick review with scan (and maybe show on a few) makes sure there's nothing I need to see. So, I remove the messages. There's more about this in the Sections Find and Specify with scan, pick, Ranges, Sequences and Storing Message Numbers in MH Sequences.

What if I decide not to remove one of the messages in that temp sequence? I can use mark -delete to take the message out of the sequence before I run rmm.

## Where's the Next Message?

In the previous Example, I removed a group of messages without paying much attention to the message numbers. How could I read the first message that I didn't delete?

- If I had deleted the current message, it'd be easy: type `next`. (This works because rmm doesn't change the current message. Neither does scan, by the way.)
- But maybe I didn't delete the current message. Then next would be the wrong command; it would skip the current message.

Here's the trick:

        % show cur:1

In MH, cur has the current message number, even if it's been deleted. The `:1` is a range with one message in it -- your online mh-sequence(5) manual page has details. Of course, ranges usually have more than one message -- such as `first:10`, the first ten message numbers in the folder. But there's nothing wrong with `cur:1` -- it means "up to one message in the range beginning with the current message." If the current message doesn't exist, MH automatically finds the next message number in the folder.

If that command is too cryptic to remember, you might want to stick it in a shell alias or function named something like nx. Then you can use nx to read the current or next message, whichever.

## Changing Showproc for Viewing, Printing, and Editing

By default, MH show uses a pager (a screen-by-screen file viewer, like more(1)) to display the message on your terminal. In version 0.21 and above of nmh, the default is mhl, which formats the message and then (by default) uses a pager. To use a different viewer, like the program called less (which comes in the MH distribution), use the -showproc switch (or put it in your MH profile):

        % show -showproc less

If you like the less viewer or any other file viewer, you can make that viewer the default for all messages you read. If you aren't using mhl as your showproc, you can choose the viewer with an entry like this in your MH profile:

        showproc: less

If you are using mhl as your showproc, though, you should choose your pager by setting the moreproc.

Before show starts the showproc, it prints a header line with the folder name and message number:

        (Message inbox:24)

Usually, that's convenient. Sometimes it isn't. For example, when you're printing a message that fits onto a page exactly, the extra header line can make the page too long. The UNIX pr(1) program does that kind of message formatting. It formats a file for printing, with a header and page number, one message per page. By default, pr output goes to the terminal, not the printer. But you can use a standard UNIX pipe to send output to your printer program (often called lp or lpr). For example, here's how to print the last three messages, formatted with pr, on the lpr printer:

        % show -noheader -showproc pr last:3 | lpr

The -noheader switch tells show not to output `(Message folder:Number)`. Of course, that command line is pretty long. A shell alias or function can shorten it to something like:

        % msgpr last:3

The Section Custom Printing: showpr shows a shell program that does even more.

If you need to edit a message you've received from someone else, the show command can do that too! Just set your showproc to be...a text editor. The mhedit command version makes this convenient.

Setting the showproc doesn't work the same way for multipart MIME messages. The showproc may be run several times, once for each part, on temporary copies of the parts. (There are details in the Section Showing MIME Messages.) Even a single-part MIME message may still need to be decoded before you can print it. There are two fairly simple ways to print MIME messages:

- If you always want to print a message content, you can create an `mhn-store-` profile entry that "displays" that content subtype with a printer. The Section on MIME Configuration tells you how.
- The mimecat script in this book's online archive can decode and extract MIME message parts for printing. For example, to decode the quoted-printable French message 26 and send it to the printer lpr -Plaser:

            % mimecat 26 | lpr -Plaser

  You could also adapt mimecat to send contents directly to a printer; the details in the explanation of mimecat should help.

> CAUTION: Some graphic file formats may contain commands that can be dangerous security holes. For instance, PostScript files can hold commands that can change printer settings -- or even delete other files! If you get a PostScript or other interpreted file from someone you don't trust, be careful.

## Using mhl

A very useful showproc for viewing on the terminal is called mhl. It's an MH program that's designed for formatting mail messages. Section mhl explains how to customize mhl output, but a lot of people just use the default mhl settings.

mhl is the default showproc in nmh version 0.21 and above. If you aren't using it, try it yourself -- compare plain show in the first example below to show -showproc mhl in the example after it. (If you are using mhl, you can disable it temporarily with a command like show -showproc more, which uses the pager more to display the message.)

Example: Showing a message without mhl

        % show
        (Message inbox:14)
        Received: by mysun.xyz.edu (5.54/ACS)
                id AA22457; Mon, 09 Jan 1995 10:32:37 EST
        Received: from cliff.xyz.edu by asun.xyz.edu (4.1/CNS)
                id AA00488; Mon, 09 Jan 1995 10:24:44 EST
        Message-Id: <9501091524.AA00488@asun.xyz.edu>
        Received: by cliff.xyz.edu (4.1/SMI-4.0)
                id AA00220; Mon, 09 Jan 1995 10:24:42 EST
        To: jdpeek@mysun.xyz.edu, nancyp@hersun.xyz.edu
        To: ed@hissun.xyz.edu
        Subject: X Terminal Presentation/Demonstration next week; be there, please
        Date: Mon, 09 Jan 1995 10:24:39 -0500
        From: "Wilbur, Orville" <owilbur@asun.xyz.edu>

        Vince Molino from NAC Corp. will give a short presentation
            ...

Example: Showing a message with default mhl formatting

        % show -showproc mhl
        (Message inbox:14)
         -- using template mhl.format --
        Date:    Mon, 09 Jan 1995 10:24:39 EST
        To:      jdpeek@mysun.xyz.edu, nancyp@hersun.xyz.edu,
                 ed@hissun.xyz.edu

        From:    "Wilbur, Orville" <owilbur@asun.xyz.edu>
        Subject: X Terminal Presentation/Demonstration next week; be
             ***there, please
            ...

Unless your system has a different default or you customize it, mhl does what you saw in the second Example:

- Omits header fields like `Received:` and `Message-Id:`.
- Lines up the header fields neatly.
- Wraps long lines and puts three asterisks (`***`) at the start of continuations.
- Changes the date into a standard format.
- Runs the moreproc, a file-paging program like more(1) or less(1), otherwise uses its built-in paginator.

nmh has made some changes to the default mhl formatting. Some changes are subtle -- like decoding any encoded international (non-ASCII) characters in the `From:` and `Subject:` fields. The obvious changes are that you'll get a blank line instead of the line "using template mhl.format", and there isn't a blank line before the `From:` field.

> NOTE: When mhn and mhshow show MIME messages with mhl, they split the message into header and body parts; the parts are shown separately. The techniques in this section don't apply directly to MIME mail. There's more information in the Section Showing MIME Messages.

To use mhl on a single message, give it as the showproc on a command line:

        % show -showproc mhl

mhl is the default showproc in nmh-0.21 and above. If you use MH or earlier versions of nmh and you like mhl, you can use it to show all messages by putting this entry in your MH profile:

        showproc: mhl

Or you can add separate entries for individual mail-showing programs:

        show: -showproc mhl
        next: -showproc mhl
        prev: -showproc mhl

If mhl is your default showproc, you can override that default temporarily by typing the name of a different showproc on the command line:

        % show -showproc more
        % show -showproc pr 3-7 | lpr

mhl uses your moreproc to page through a message that's longer than the screen (see the manual page for all the conditions; it's pretty complex). The moreproc is typically more or less. You can choose a different pager than the system default by adding an entry to your MH profile:

        moreproc: mypager

mhl reads a format file that sets the appearance of your messages. The default format file is called mhl.format and is in the system MH library directory or nmh etcetera directory. You can copy the system mhl.format file into your MH directory and customize it. For example, to copy it and edit it with vi in MH:

        % cd Mail
        % cp /usr/local/lib/mh/mhl.format .
          (...or, in nmh, cp `mhparam etcdir`/mhl.format .)
        % vi mhl.format

The next example shows the message above with my customized mhl.format file and `showproc: mhl` in my MH profile:

Example: Showing a message with customized mhl formatting

        % show
        (Message inbox:14)
         -- using Jerry's mhl.format template --
        Date:    Mon, 09 Jan 1995 10:24:39 EST
        From:    "Wilbur, Orville" <owilbur@asun.xyz.edu>
        To:      jdpeek@mysun.xyz.edu, nancyp@hersun.xyz.edu,
                 ed@hissun.xyz.edu
        Subject: X Terminal Presentation/Demonstration next week; be
              ***there, please

        Vince Molino from NAC Corp. will be giving a short presentation
            ...

To make your own mhl.format file, see the Section Default mhl Format File for show.

## Without a showproc

To display a message exactly as it was received, with no formatting or pagination, use the -noshowproc switch. MH will display the message with cat(1). This is one way to see encoded MIME messages: if you use -noshowproc, show won't run mhn or mhshow. (In nmh, you can also use the -nocheckmime switch to prevent MIME processing, but get other normal processing.)

Of course, you can pipe the output of show -noshowproc to another program -- for instance, a separate pager like less(1), or a program like od -c or (on some systems) cat -v that displays "unprintable" characters. (The C shell alias showv sends output to a pager.) You can also use the shell's `>` and `>>` operators to redirect show output into a file.

## Multiple MH Sessions

By default, MH information like the current folder, sequences in each folder, and default options (from the MH profile) are shared between all your MH sessions. If you're logged into the same host more than once, or if you're logged into several hosts that share the same home directory, changes in one MH session will affect the others. For instance, if you type `folder +foo` in one window, the current folder and message in all the other windows will change. If you show a message in one window, you can forward it from another window by simply typing forw because the current folder and message will be the same in the other window. If you log out and log in later, the current folder and message are preserved.

That may not always be what you want! And it's a real surprise to people who have used monolithic user agents. If you don't want information to be shared between MH sessions, or kept after you log out, you can make separate context, sequence or MH profile files. The MH sessions that use separate copies of some or all of those files will be independent. Then you can do things like browsing through the messages in one folder while you remove messages from another folder; you don't need to constantly type folder-changing commands. This is also a way to stop accidental interactions between a standard MH session and a session with an MH front-end like xmh; otherwise, changing the current folder or message from MH without telling the front-end about the change can cause some real problems.

The Figure Important parts of a UNIX filesystem shows the parts of a UNIX filesystem that MH uses. Three files control the MH session:

- The context file holds the current folder name. It also holds private sequences, which you may not be using. By default, MH uses a file named context in your MH directory. You can use a different context file by storing its pathname in the MHCONTEXT environment variable.
- The .mh_sequences file in each folder holds the public sequences for that folder. You can choose a different filename by storing its name (not a pathname to another directory!) in the `mh-sequences:` MH profile entry.
- Your MH profile holds default options for MH commands and overall MH setup information. The default MH profile is .mh_profile in your home directory. To use a different MH profile, store its pathname in the MH environment variable.

Setting up a separate MH session is usually as simple as making a temporary context file. The next Example shows how to open a second window and work in a second folder with the C shell:

Example: Separate MH sessions with different current folders

        projects/beta folder        summaries folder

        % scan +projects/beta       % setenv MHCONTEXT /tmp/myctx$$
          ...scan listing...        % folder +summaries
        % show 27                     summaries+ has 1540 messages (  1-1826)
        (Message projects/beta:27)  % show last
          ...message appears...     (Message summaries:1826)
        %   ...                     ...message appears...
                                         ...
                                    % unsetenv MHCONTEXT
                                    % rm /tmp/myctx$$

The context filename can be any absolute pathname. I picked a temporary file, in /tmp, with a unique name that includes the shell's process ID number (from the `$$` shell variable). That name will be different in every shell running on a system. If you want to keep the same context, session-to-session, you should choose a filename somewhere else -- in your MH directory, for instance. If several people share the same account, you could make context files named context.carol, context.jake, and so on.

Changing the context file doesn't affect public sequences in a folder. If two people are working in the same folder, or you have two windows open on a folder, changing the current message in one session may cause grief in the other session. So, if the account isn't already set up to use private sequences, you can make one or both sessions use them. To do this, make an empty `mh-sequences:` entry (with no filename after it) in the MH profile. If you want one session to use public sequences, and another to use private sequences, make a copy of the MH profile and put an empty `mh-sequences:` entry in the copy. The next example shows that for the Bourne shell (and Korn shell, bash, etc.):

Example: A second session with different current folder and sequences

        $ cd
        $ cp .mh_profile /tmp/profile$$
        $ MH=/tmp/profile$$ MHCONTEXT=/tmp/context$$
        $ export MH MHCONTEXT
        $ emacs $MH
            ...edit temporary profile, add empty mh-sequences: entry
        $ show some-message +some-folder

In the Example above, the new context file won't have any sequences defined when you start. (Remember, the empty `mh-sequences:` entry means that sequences are stored in the context file.) If you have public sequences defined that you'd like to copy to the second session, you can copy the .mh_sequences file from the folder into your new context file. But the two file formats are different. A sequence in the .mh_sequences (public sequences) file looks like this:

        urgent: 2 4 9 16-19

A private sequence in the context file contains the folder pathname. Here's an example of the urgent sequence for the project folder:

        atr-urgent-/home/andy/Mail/project: 2 4 9 16-19

As you copy the sequences, you need to change the label at the beginning of each entry. Be careful not to break or truncate long entries. Worse, the format of public and private sequence files isn't documented (as far as I can tell), so it could change. If you do this often, you'll want a little Perl script to do the conversion automatically. And, when you're done in the private session, do you want to copy the sequences back to the folder's public sequence file? Maybe you should have defined a different public sequence filename in the temporary MH profile:

        mh-sequences: sequences.temp

As you can see, there are lots of possibilities. We're getting beyond the scope of this chapter. By understanding the principles in this section, though, you can do almost anything you need to do in multiple MH sessions.

## Custom Printing: showpr

You can print your mail messages like this (assuming your printer program is named lpr), but all the messages will be run together:

        % show 23 24 29 | lpr

Or, as the Section Changing Showproc for Viewing, Printing, and Editing shows, you can use pr(1) to make simple headers (with the folder and message number), to make page numbers, and to start each message on a new page:

        % show -showproc pr 23 24 29 | lpr

The showpr program, in this book's online archive, lets you do more. It can use mhl to clean up each message before printing. You can customize the page heading -- to include the message subject, for instance. And you can pass options to pr to tell it how to format your message. You can store default showpr options in your MH profile.

You can use mh-format strings on the showpr command line -- like the ones you'd give to the scan command.

Here are some examples. Some of these might look pretty complicated to type just for printing a message. But remember that you can store any set of options as defaults in your MH profile:

- To print the current message with the message subject in each page heading (assuming that you haven't put any showpr options in your MH profile):

            % showpr | lpr

- To print the last three messages with the message subject in each page heading, to format the messages with mhl, and to tell pr to use its options -f (separate pages with formfeeds) and -l50 (make page length 50 lines):

            % showpr -mhl -pr '-f -l50' last:3

  (You can shorten the options to `-m` and `-p`, if you want.)
- To print the last three messages with mhl formatting, with the `From:` address and message date in the heading as follows:

            Dec 17 08:49 1995  From: Al Bok  Date: 01/09/1995  Page 2

  Use a command line like this (split onto two lines here for readability):

            showpr -mhl -format 'From: %(friendly{from})  \
            Date: %(mon{date})/%(mday{date})/%(year{date})' last:3 | lpr

  To make that easier, you could put the following entry in your MH profile:

            showpr: -m -f 'From: %(friendly{from}) Date: %(mon{date})/%(mday{date})/%(year{date})'

  Then get that formatting and print your messages with:

            % showpr last:3 | lpr

Finally, a note about mhl. You can make an mhl format file named mhl.showpr and put it in your MH directory (like `/yourMHdir/mhl.showpr`). If you do, and if you use the -mhl option, then showpr will format your messages with mhl -form mhl.showpr. Otherwise, the -mhl option uses the standard mhl.format file.

Here's how to set up showpr.

## Showing Multiple Messages

When you give show more than one message number, things work a little differently:

        % show 1-5
            ...

By default -- except with MIME messages -- show hands each message separately to your pager program. When your showproc is a pager like more or less, your pager's "next file" command (like `:n`) will skip to the next message, Of course, you can also quit in the middle of the messages with your pager's "quit" command -- like `q` in more and less.

When you show more than one message at a time with mhl as your showproc, the messages will be shown in a stream:

        % show 1825 1826
        >>> inbox:1825

         -- using template mhl.format --
        Date:    Tue, 10 Jan 1995 15:24:39 EST
            ...
        >>> inbox:1826

         -- using template mhl.format --
        Date:    Wed, 11 Jan 1995 02:29:03 PST
            ...

This surprises people who've just started using mhl because the "next file" command in their pager program (like `:n` in more and less) doesn't skip to the next message anymore. You can work around the problem by using your pager's search command to find the message-number marker at the top of the next message. Searching for `>>>` may be enough. If messages contain that string, though, you can be more exact. For instance, if you're reading mail from the inbox folder -- as in the example above -- use the search command:

        /^>>> inbox:

and repeat it, using the pager's `n` command, to go to each following message.